1 /*
2 * Copyright (c) 2009-2021, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 //!
23 //! \file      mos_os_specific.c
24 //! \brief     Common interface used in MOS LINUX OS
25 //! \details   Common interface used in MOS LINUX OS
26 //!
27 
28 #include "mos_os.h"
29 #include "mos_util_debug.h"
30 #include "mos_resource_defs.h"
31 #include <unistd.h>
32 #include <dlfcn.h>
33 #include "hwinfo_linux.h"
34 #include "media_fourcc.h"
35 #include <stdlib.h>
36 
37 #include "mos_graphicsresource.h"
38 #include "mos_context_specific.h"
39 #include "mos_gpucontext_specific.h"
40 #include "mos_gpucontextmgr.h"
41 
42 #include "mos_graphicsresource_next.h"
43 #include "mos_context_specific_next.h"
44 #include "mos_gpucontext_specific_next.h"
45 #include "mos_gpucontextmgr_next.h"
46 #include "mos_interface.h"
47 
48 #if MOS_MEDIASOLO_SUPPORTED
49 #include "mos_os_solo.h"
50 #endif // MOS_MEDIASOLO_SUPPORTED
51 #include "mos_solo_generic.h"
52 
53 #ifndef ANDROID
54 #include <sys/ipc.h>
55 #include <sys/shm.h>
56 #include <sys/sem.h>
57 #include <sys/types.h>
58 #endif
59 
60 #include "mos_os_virtualengine.h"
61 #include "mos_util_user_interface.h"
62 
63 #include "mos_os_virtualengine_singlepipe_next.h"
64 #include "mos_os_virtualengine_scalability_next.h"
65 
66 #include "memory_policy_manager.h"
67 #include "mos_oca_interface_specific.h"
68 
69 //!
70 //! \brief DRM VMAP patch
71 //!
72 #define Y_TILE_WIDTH  128
73 #define Y_TILE_HEIGHT 32
74 #define X_TILE_WIDTH  512
75 #define X_TILE_HEIGHT 8
76 
77 #define MI_BATCHBUFFER_END 0x05000000
78 
79 //!
80 //! \brief Two VDBOX shared memory key
81 //!
82 #define DUAL_VDBOX_KEY ('D'<<24|'V'<<8|'X'<<0)
83 
84 //============= PRIVATE FUNCTIONS <BEGIN>=========================================
85 
SetupMediaSoloSwitch()86 bool SetupMediaSoloSwitch()
87 {
88     bool mediaSoloEnabled = false;
89     MosUtilities::MosReadMediaSoloEnabledUserFeature(mediaSoloEnabled);
90     return mediaSoloEnabled;
91 }
92 
SetupApoDdiSwitch(int32_t fd)93 bool SetupApoDdiSwitch(int32_t fd)
94 {
95     if (fd < 0)
96     {
97         return false;
98     }
99 
100     //Read user feature to determine if apg mos is enabled.
101     uint32_t    userfeatureValue = 0;
102     MOS_STATUS  estatus          = MosUtilities::MosReadApoDdiEnabledUserFeature(userfeatureValue);
103 
104     if(estatus == MOS_STATUS_SUCCESS)
105     {
106         return (userfeatureValue != 0);
107     }
108 
109     return false;
110 }
111 
SetupApoMosSwitch(int32_t fd)112 bool SetupApoMosSwitch(int32_t fd)
113 {
114     if (fd < 0)
115     {
116         return false;
117     }
118 
119     //Read user feature to determine if apg mos is enabled.
120     uint32_t    userfeatureValue = 0;
121     MOS_STATUS  estatus          = MosUtilities::MosReadApoMosEnabledUserFeature(userfeatureValue);
122 
123     if(estatus == MOS_STATUS_SUCCESS)
124     {
125         return (userfeatureValue != 0);
126     }
127     PRODUCT_FAMILY eProductFamily = IGFX_UNKNOWN;
128     HWInfo_GetGfxProductFamily(fd, eProductFamily);
129 
130     if (eProductFamily >= IGFX_TIGERLAKE_LP)
131     {
132         return true;
133     }
134 
135     return false;
136 }
137 
138 
139 //!
140 //! \brief    Clear Gpu Context
141 //! \details  OS GPU context clear
142 //! \param    PMOS_RESOURCE pContext
143 //!           [in] Pointer to OS context
144 //! \return   void
145 //!           Return NONE
146 //!
Mos_Specific_ClearGpuContext(MOS_CONTEXT * pContext)147 void Mos_Specific_ClearGpuContext(MOS_CONTEXT *pContext)
148 {
149     int32_t iLoop = 0;
150 
151     MOS_OS_FUNCTION_ENTER;
152 
153     if (nullptr == pContext)
154     {
155         MOS_OS_ASSERTMESSAGE("Input mos context is null");
156         return;
157     }
158 
159     for (iLoop = 0; iLoop < MOS_GPU_CONTEXT_MAX; iLoop++)
160     {
161         if (pContext->OsGpuContext[iLoop].pCB != nullptr)
162         {
163             MOS_FreeMemory(pContext->OsGpuContext[iLoop].pCB);
164             pContext->OsGpuContext[iLoop].pCB = nullptr;
165         }
166 
167         if (pContext->OsGpuContext[iLoop].pAllocationList != nullptr)
168         {
169             MOS_FreeMemory(pContext->OsGpuContext[iLoop].pAllocationList);
170             pContext->OsGpuContext[iLoop].pAllocationList = nullptr;
171         }
172 
173         if (pContext->OsGpuContext[iLoop].pPatchLocationList)
174         {
175             MOS_FreeMemory(pContext->OsGpuContext[iLoop].pPatchLocationList);
176             pContext->OsGpuContext[iLoop].pPatchLocationList = nullptr;
177         }
178 
179         if (pContext->OsGpuContext[iLoop].pResources != nullptr)
180         {
181             MOS_FreeMemory(pContext->OsGpuContext[iLoop].pResources);
182             pContext->OsGpuContext[iLoop].pResources = nullptr;
183         }
184 
185         if (pContext->OsGpuContext[iLoop].pbWriteMode != nullptr)
186         {
187             MOS_FreeMemory(pContext->OsGpuContext[iLoop].pbWriteMode);
188             pContext->OsGpuContext[iLoop].pbWriteMode = nullptr;
189         }
190 
191         pContext->OsGpuContext[iLoop].uiMaxNumAllocations    = 0;
192         pContext->OsGpuContext[iLoop].uiMaxPatchLocationsize = 0;
193     }
194 }
195 
196 //!
197 //! \brief    Unified OS get command buffer
198 //! \details  Return the pointer to the next available space in Cmd Buffer
199 //! \param    PMOS_CONTEXT pOsContext
200 //!           [in] Pointer to OS Context
201 //! \param    PMOS_COMMAND_BUFFER pCmdBuffer
202 //!           [out] Pointer to Command Buffer
203 //! \param    int32_t iSize
204 //!           [out] Size of command in bytes
205 //! \return   int32_t
206 //!           Return true is there is space
207 //!
Linux_GetCommandBuffer(PMOS_CONTEXT pOsContext,PMOS_COMMAND_BUFFER pCmdBuffer,int32_t iSize)208 int32_t Linux_GetCommandBuffer(
209     PMOS_CONTEXT            pOsContext,
210     PMOS_COMMAND_BUFFER     pCmdBuffer,
211     int32_t                 iSize)
212 {
213     int32_t                bResult  = false;
214     MOS_LINUX_BO           *cmd_bo = nullptr;
215 
216     if ( pOsContext == nullptr ||
217          pCmdBuffer == nullptr)
218     {
219         bResult = false;
220         MOS_OS_ASSERTMESSAGE("Linux_GetCommandBuffer:pOsContext == nullptr || pCmdBuffer == NULL");
221         goto finish;
222     }
223 
224     // Allocate the command buffer from GEM
225     cmd_bo = mos_bo_alloc(pOsContext->bufmgr,"MOS CmdBuf",iSize,4096, MOS_MEMPOOL_SYSTEMMEMORY);     // Align to page boundary
226     if (cmd_bo == nullptr)
227     {
228         MOS_OS_ASSERTMESSAGE("Allocation of command buffer failed.");
229         bResult = false;
230         goto finish;
231     }
232     //MOS_OS_NORMALMESSAGE("alloc CMB, bo is 0x%x.", cmd_bo);
233 
234     // Map command buffer to user virtual address
235     if (mos_bo_map(cmd_bo,1) != 0) // Write enable set
236     {
237         MOS_OS_ASSERTMESSAGE("Mapping of command buffer failed.");
238         bResult = false;
239         goto finish;
240     }
241 
242     Mos_ResetResource(&pCmdBuffer->OsResource);
243 
244     // Fill in resource information
245     pCmdBuffer->OsResource.Format = Format_Buffer;
246     pCmdBuffer->OsResource.iWidth = cmd_bo->size;
247     pCmdBuffer->OsResource.iHeight = 1;
248     pCmdBuffer->OsResource.iPitch = cmd_bo->size;
249     pCmdBuffer->OsResource.iSize =  pCmdBuffer->OsResource.iPitch * pCmdBuffer->OsResource.iHeight;
250     pCmdBuffer->OsResource.iCount = 1;
251     pCmdBuffer->OsResource.pData = (uint8_t*)cmd_bo->virt;
252     pCmdBuffer->OsResource.TileType = MOS_TILE_LINEAR;
253     pCmdBuffer->OsResource.bo = cmd_bo;
254     pCmdBuffer->OsResource.bMapped  = true;
255 
256     // for MOS wrapper to avoid memory leak
257     pCmdBuffer->OsResource.bConvertedFromDDIResource = true;
258 
259     pCmdBuffer->pCmdBase    = (uint32_t*)cmd_bo->virt;
260     pCmdBuffer->pCmdPtr     = (uint32_t*)cmd_bo->virt;
261     pCmdBuffer->iOffset     = 0;
262     pCmdBuffer->iRemaining  = cmd_bo->size;
263     pCmdBuffer->iCmdIndex   = -1;
264     pCmdBuffer->iVdboxNodeIndex = MOS_VDBOX_NODE_INVALID;
265     pCmdBuffer->iVeboxNodeIndex = MOS_VEBOX_NODE_INVALID;
266     pCmdBuffer->is1stLvlBB = true;
267     MOS_ZeroMemory(pCmdBuffer->pCmdBase, cmd_bo->size);
268     pCmdBuffer->iSubmissionType = SUBMISSION_TYPE_SINGLE_PIPE;
269     MOS_ZeroMemory(&pCmdBuffer->Attributes, sizeof(pCmdBuffer->Attributes));
270     bResult = true;
271 
272 finish:
273     if ((false == bResult)&&(nullptr != cmd_bo)){
274         //need to unreference command buffer allocated.
275         mos_bo_unreference(cmd_bo);
276     }
277     return bResult;
278 }
279 
280 //!
281 //! \brief    Get unused command buffer space
282 //! \details  Return unused command buffer space
283 //! \param    PMOS_CONTEXT pOsContext
284 //!           [in] Pointer to OS Context
285 //! \param    MOS_GPU_CONTEXT GpuContext
286 //!           [in] GPU context
287 //! \param    PMOS_COMMAND_BUFFER pCmdBuffer
288 //!           [out] Pointer to Command buffer
289 //! \return   void
290 //!
Linux_ReturnCommandBuffer(PMOS_CONTEXT pOsContext,MOS_GPU_CONTEXT GpuContext,PMOS_COMMAND_BUFFER pCmdBuffer)291 void Linux_ReturnCommandBuffer(
292     PMOS_CONTEXT            pOsContext,
293     MOS_GPU_CONTEXT         GpuContext,
294     PMOS_COMMAND_BUFFER     pCmdBuffer)
295 {
296     MOS_OS_GPU_CONTEXT *pOsGpuContext;
297 
298     if (pOsContext == nullptr || pCmdBuffer == nullptr ||
299         Mos_ResourceIsNull(&(pCmdBuffer->OsResource)))
300     {
301         MOS_OS_ASSERTMESSAGE("Invalid input parameter pOsContext or pCmdBuffer.");
302         goto finish;
303     }
304 
305     if (GpuContext == MOS_GPU_CONTEXT_INVALID_HANDLE)
306     {
307         MOS_OS_ASSERTMESSAGE("Invalid input parameter GpuContext.");
308         goto finish;
309     }
310 
311     pOsGpuContext = &pOsContext->OsGpuContext[GpuContext];
312     if (pOsContext == nullptr)
313     {
314         MOS_OS_ASSERTMESSAGE("Os gpucontext is null.");
315         goto finish;
316     }
317 
318     pOsGpuContext->pCB->iOffset    = pCmdBuffer->iOffset ;
319     pOsGpuContext->pCB->iRemaining = pCmdBuffer->iRemaining;
320     pOsGpuContext->pCB->pCmdPtr    = pCmdBuffer->pCmdPtr;
321     pOsGpuContext->pCB->iVdboxNodeIndex = pCmdBuffer->iVdboxNodeIndex;
322     pOsGpuContext->pCB->iVeboxNodeIndex = pCmdBuffer->iVeboxNodeIndex;
323     pOsGpuContext->pCB->is1stLvlBB = pCmdBuffer->is1stLvlBB;
324 
325 finish:
326     return;
327 }
328 
329 //!
330 //! \brief    Flush Command Buffer
331 //! \details  Flush Command Buffer space
332 //! \param    PMOS_CONTEXT pOsContext
333 //!           [in] Pointer to OS Context
334 //! \param    MOS_GPU_CONTEXT GpuContext
335 //!           [in] GPU context
336 //! \return   int32_t
337 //!           true if succeeded, false if failed or invalid parameters
338 //!
Linux_FlushCommandBuffer(PMOS_CONTEXT pOsContext,MOS_GPU_CONTEXT GpuContext)339 int32_t Linux_FlushCommandBuffer(
340     PMOS_CONTEXT           pOsContext,
341     MOS_GPU_CONTEXT        GpuContext)
342 {
343     PCOMMAND_BUFFER pCurrCB;
344     int32_t         bResult = false;
345     PMOS_OS_GPU_CONTEXT pOsGpuContext;
346 
347     if (pOsContext == nullptr)
348     {
349         MOS_OS_ASSERTMESSAGE("Invalid input parameter pOsContext.")
350         goto finish;
351     }
352 
353     if (GpuContext == MOS_GPU_CONTEXT_INVALID_HANDLE)
354     {
355         MOS_OS_ASSERTMESSAGE("Invalid input parameter GpuContext.");
356         goto finish;
357     }
358 
359     pOsGpuContext = &pOsContext->OsGpuContext[GpuContext];
360     if (pOsGpuContext == nullptr)
361     {
362         MOS_OS_ASSERTMESSAGE("Invalid OsGpuContext");
363         goto finish;
364     }
365 
366     // Refresh command buffer usage
367     pOsContext->pfnRefresh(pOsContext);
368 
369     pOsGpuContext->uiCurrentNumPatchLocations = 0;
370 
371     // CB already active
372     pCurrCB = pOsGpuContext->pCurrentCB;
373     if (pCurrCB == nullptr)
374     {
375         MOS_OS_ASSERTMESSAGE("Invalid current CB in OsGpuContext.");
376         goto finish;
377     }
378 
379     if (pCurrCB->bActive)
380     {
381         goto finish;
382     }
383 
384     pCurrCB->bActive  = true;
385     bResult = true;
386 
387 finish:
388     return bResult;
389 }
390 
391 //!
392 //! \brief    Init command buffer pool
393 //! \details  Initilize the command buffer pool
394 //! \param    PMOS_CONTEXT pOsContext
395 //!           [in] Pointer to OS Context
396 //! \return   void
397 //!
Linux_InitCmdBufferPool(PMOS_CONTEXT pOsContext)398 void Linux_InitCmdBufferPool(
399     PMOS_CONTEXT   pOsContext)
400 {
401     MOS_OS_FUNCTION_ENTER;
402 
403     MOS_ZeroMemory(&pOsContext->CmdBufferPool, sizeof(CMD_BUFFER_BO_POOL));
404     pOsContext->CmdBufferPool.iFetch = 0;
405 }
406 
407 //!
408 //! \brief    Wait and release command buffer
409 //! \details  Command buffer Wait and release
410 //! \param    PMOS_CONTEXT pOsContext
411 //!           [in] Pointer to OS context structure
412 //! \param    int32_t index
413 //!           [in] Command buffer's index in Command buffer pool
414 //! \return   MOS_STATUS
415 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
416 //!
Linux_WaitAndReleaseCmdBuffer(PMOS_CONTEXT pOsContext,int32_t index)417 MOS_STATUS Linux_WaitAndReleaseCmdBuffer(
418     PMOS_CONTEXT   pOsContext,
419     int32_t        index)
420 {
421     MOS_LINUX_BO   *cmd_bo;
422     MOS_STATUS     eStatus;
423 
424     MOS_OS_FUNCTION_ENTER;
425 
426     eStatus = MOS_STATUS_SUCCESS;
427 
428     MOS_OS_CHK_NULL(pOsContext);
429 
430     if (index < 0 || index >= MAX_CMD_BUF_NUM)
431     {
432         eStatus = MOS_STATUS_INVALID_PARAMETER;
433         goto finish;
434     }
435 
436     // According to the logic of CmdBufferPool now, the command buffer is used in a circular way.
437     // The input index always points to the next(oldest) buffer after the latest(newest) buffer.
438     // If the next buffer is not empty (!= nullptr), all the buffers in the pool will also be not empty.
439     // So it's not necessary to check all buffers to see whether there's empty buffer.
440     cmd_bo = pOsContext->CmdBufferPool.pCmd_bo[index];
441     if (cmd_bo != nullptr)
442     {
443         mos_bo_wait_rendering(cmd_bo);
444         mos_bo_unreference(cmd_bo);
445         pOsContext->CmdBufferPool.pCmd_bo[index] = nullptr;
446     }
447 
448 finish:
449     return eStatus;
450 }
451 
452 //!
453 //! \brief    Release command buffer pool
454 //! \details  Release command buffer pool until all of commands are finished.
455 //! \param    PMOS_CONTEXT pOsContext
456 //!           [in] Pointer to OS context structure
457 //! \return   MOS_STATUS
458 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
459 //!
Linux_ReleaseCmdBufferPool(PMOS_CONTEXT pOsContext)460 MOS_STATUS Linux_ReleaseCmdBufferPool(PMOS_CONTEXT   pOsContext)
461 {
462     int32_t         i;
463     MOS_STATUS      eStatus;
464 
465     MOS_OS_FUNCTION_ENTER;
466 
467     eStatus = MOS_STATUS_SUCCESS;
468 
469     MOS_OS_CHK_NULL(pOsContext);
470 
471     for (i = 0; i < MAX_CMD_BUF_NUM; i++)
472     {
473         MOS_OS_CHK_STATUS(Linux_WaitAndReleaseCmdBuffer(pOsContext, i));
474     }
475 
476 finish:
477     return eStatus;
478 }
479 
480 //!
481 //! \brief    Wait for the fetch command
482 //! \details  Wait for the fetch command bo until it is available
483 //! \param    PMOS_CONTEXT pOsContext
484 //!           [in] Pointer to OS context structure
485 //! \return   MOS_STATUS
486 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
487 //!
Linux_WaitForAvailableCmdBo(PMOS_CONTEXT pOsContext)488 MOS_STATUS Linux_WaitForAvailableCmdBo(
489     PMOS_CONTEXT   pOsContext)
490 {
491     int32_t         index;
492     MOS_STATUS      eStatus;
493 
494     MOS_OS_FUNCTION_ENTER;
495 
496     eStatus = MOS_STATUS_SUCCESS;
497 
498     MOS_OS_CHK_NULL(pOsContext);
499 
500     index = pOsContext->CmdBufferPool.iFetch;
501     MOS_OS_CHK_STATUS(Linux_WaitAndReleaseCmdBuffer(pOsContext, index));
502 
503 finish:
504     return eStatus;
505 }
506 
507 //!
508 //! \brief    Insert command buffer
509 //! \details  Insert command buffer into pool
510 //! \param    PMOS_CONTEXT pOsContext
511 //!           [in] Pointer to OS context structure
512 //! \param    PMOS_COMMAND_BUFFER    pCmdBuffer
513 //!           [in] Pointer to command buffer struct
514 //! \return   MOS_STATUS
515 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
516 //!
Linux_InsertCmdBufferToPool(PMOS_CONTEXT pOsContext,PMOS_COMMAND_BUFFER pCmdBuffer)517 MOS_STATUS Linux_InsertCmdBufferToPool(
518     PMOS_CONTEXT           pOsContext,
519     PMOS_COMMAND_BUFFER    pCmdBuffer)
520 {
521     int32_t         index = 0;
522     MOS_STATUS      eStatus;
523 
524     MOS_OS_FUNCTION_ENTER;
525 
526     eStatus = MOS_STATUS_SUCCESS;
527 
528     MOS_OS_CHK_NULL(pOsContext);
529     MOS_OS_CHK_NULL(pCmdBuffer);
530     MOS_OS_CHK_STATUS(Linux_WaitForAvailableCmdBo(pOsContext));
531 
532     index = pOsContext->CmdBufferPool.iFetch;
533 
534     pOsContext->CmdBufferPool.pCmd_bo[index] = pCmdBuffer->OsResource.bo;
535     pCmdBuffer->iCmdIndex = index;
536 
537     pOsContext->CmdBufferPool.iFetch++;
538     if (pOsContext->CmdBufferPool.iFetch >= MAX_CMD_BUF_NUM)
539     {
540         pOsContext->CmdBufferPool.iFetch     = 0;
541     }
542 
543 finish:
544     return eStatus;
545 }
546 
547 //!
548 //! \brief    Linux Refresh
549 //! \details  Linux Refresh
550 //! \param    MOS_CONTEXT * pOsContext
551 //!           [in] Pointer to OS context structure
552 //! \return   int32_t
553 //!           true always
554 //!
Linux_Refresh(MOS_CONTEXT * pOsContext)555 int32_t Linux_Refresh(MOS_CONTEXT *pOsContext)
556 {
557     MOS_UNUSED(pOsContext);
558     return true;
559 }
560 
561 #ifndef ANDROID
562 
563 #define MOS_LINUX_IPC_INVALID_ID -1
564 #define MOS_LINUX_SHM_INVALID (void *)-1
565 #define MOS_LINUX_SEM_MAX_TRIES 10
566 
DetachDestroyShm(int32_t shmid,void * pShm)567 static MOS_STATUS DetachDestroyShm(int32_t shmid, void  *pShm)
568 {
569     struct shmid_ds buf;
570     MOS_ZeroMemory(&buf, sizeof(buf));
571 
572     if (shmid < 0)
573     {
574         return MOS_STATUS_UNKNOWN;
575     }
576 
577     if ((pShm != MOS_LINUX_SHM_INVALID) && (pShm != nullptr) && shmdt(pShm) < 0)
578     {
579         return MOS_STATUS_UNKNOWN;
580     }
581 
582     if (shmctl(shmid, IPC_STAT, &buf) < 0)
583     {
584         return MOS_STATUS_UNKNOWN;
585     }
586 
587     if (buf.shm_nattch == 0)
588     {
589         if (shmctl(shmid, IPC_RMID, nullptr) < 0)
590         {
591             return MOS_STATUS_UNKNOWN;
592         }
593     }
594     return MOS_STATUS_SUCCESS;
595 }
596 
ConnectCreateShm(long key,uint32_t size,int32_t * pShmid,void ** ppShm)597 static MOS_STATUS ConnectCreateShm(long key, uint32_t size, int32_t *pShmid, void  **ppShm)
598 {
599     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
600     MOS_OS_CHK_NULL_RETURN(pShmid);
601     MOS_OS_CHK_NULL_RETURN(ppShm);
602 
603     struct shmid_ds buf;
604     int32_t         shmid     = -1;
605     key_t           key_value = (key_t)key;
606     void *          shmptr    = nullptr;
607     MOS_ZeroMemory(&buf, sizeof(buf));
608 
609     shmid = shmget(key_value, size, IPC_CREAT | 0666);
610     if (shmid < 0)
611     {
612         return MOS_STATUS_UNKNOWN;
613     }
614 
615     shmptr = shmat(shmid, 0, 0);
616     if (shmptr == MOS_LINUX_SHM_INVALID)
617     {
618         DetachDestroyShm(shmid, shmptr);
619         return MOS_STATUS_UNKNOWN;
620     }
621 
622     if (shmctl(shmid, IPC_STAT, &buf) < 0)
623     {
624         // can't get any status info
625         DetachDestroyShm(shmid, shmptr);
626         return MOS_STATUS_UNKNOWN;
627     }
628 
629     *ppShm = shmptr;
630     *pShmid = shmid;
631 
632     return MOS_STATUS_SUCCESS;
633 }
634 
ConnectCreateSemaphore(long key,int32_t * pSemid)635 static MOS_STATUS ConnectCreateSemaphore(long key, int32_t *pSemid)
636 {
637     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
638     MOS_OS_CHK_NULL_RETURN(pSemid);
639     int32_t         semid = -1;
640     struct sembuf   sop;
641     struct semid_ds buf;
642     uint32_t        i         = 0;
643     key_t           key_value = (key_t)key;
644     int32_t         val       = 0;
645     MOS_ZeroMemory(&sop, sizeof(sop));
646     MOS_ZeroMemory(&buf, sizeof(buf));
647 
648     semid = semget(key, 1, IPC_CREAT | IPC_EXCL | 0666);
649 
650     if (semid != MOS_LINUX_IPC_INVALID_ID)
651     {
652         // initialize it to 0
653         if (semctl(semid, 0, SETVAL, val) == -1)
654         {
655             return MOS_STATUS_UNKNOWN;
656         }
657 
658         // Perform a "no-op" semaphore operation - changes sem_otime
659         // so other processes can see we've initialized the set.
660         sop.sem_num = 0;
661         sop.sem_op  = 0; //Wait for value to equal 0
662         sop.sem_flg = 0;
663         if (semop(semid, &sop, 1) == -1)
664         {
665             return MOS_STATUS_UNKNOWN;
666         }
667 
668     }
669     else
670     {
671         // errno EEXIST
672         semid = semget(key, 1, 0666);
673         if (semid == MOS_LINUX_IPC_INVALID_ID)
674         {
675             return MOS_STATUS_UNKNOWN;
676         }
677     }
678 
679     *pSemid = semid;
680 
681     return MOS_STATUS_SUCCESS;
682 }
683 
DestroySemaphore(int32_t semid)684 static MOS_STATUS DestroySemaphore(int32_t semid)
685 {
686     int32_t nwait = -1;
687 
688     if (semid < 0)
689     {
690         return MOS_STATUS_UNKNOWN;
691     }
692 
693     nwait = semctl(semid, 0, GETZCNT, 0);
694 
695     if (nwait > 0)
696     {
697         return MOS_STATUS_SUCCESS;
698     }
699 
700     if (semctl(semid, 0, IPC_RMID, nullptr) < 0)
701     {
702         return MOS_STATUS_UNKNOWN;
703     }
704 
705     return MOS_STATUS_SUCCESS;
706 }
707 
ShmAttachedNumber(int32_t shmid)708 static int16_t ShmAttachedNumber(int32_t shmid)
709 {
710     struct shmid_ds buf;
711     MOS_ZeroMemory(&buf, sizeof(buf));
712 
713     if (shmctl(shmid, IPC_STAT, &buf) < 0)
714     {
715         return -1;
716     }
717 
718     return buf.shm_nattch;
719 }
720 
LockSemaphore(int32_t semid)721 static MOS_STATUS LockSemaphore(int32_t semid)
722 {
723     struct sembuf op[2] = {};
724     op[0].sem_num = 0; // wait for [0] to be 0
725     op[0].sem_op  = 0;
726     op[0].sem_flg = 0;
727     op[1].sem_num = 0;
728     op[1].sem_op  = 1; // increment
729     op[1].sem_flg = SEM_UNDO;
730 
731     if (semid < 0)
732     {
733         return MOS_STATUS_UNKNOWN;
734     }
735 
736     if (semop(semid, op, 2) < 0)
737     {
738         return MOS_STATUS_UNKNOWN;
739     }
740 
741     return MOS_STATUS_SUCCESS;
742 }
743 
UnLockSemaphore(int32_t semid)744 static MOS_STATUS UnLockSemaphore(int32_t semid)
745 {
746     struct sembuf op;
747     op.sem_num = 0;
748     op.sem_op  = -1; // decrement back to 0
749     op.sem_flg = SEM_UNDO;
750 
751     if (semid < 0)
752     {
753         return MOS_STATUS_UNKNOWN;
754     }
755 
756     if (semop(semid, &op, 1) < 0)
757     {
758         return MOS_STATUS_UNKNOWN;
759     }
760 
761     return MOS_STATUS_SUCCESS;
762 }
763 
DestroyIPC(PMOS_CONTEXT pOsContext)764 void DestroyIPC(PMOS_CONTEXT pOsContext)
765 {
766     if (MOS_LINUX_IPC_INVALID_ID != pOsContext->semid)
767     {
768         int16_t iAttachedNum = 0;
769 
770         if (MOS_LINUX_IPC_INVALID_ID != pOsContext->shmid)
771         {
772             LockSemaphore(pOsContext->semid);
773             iAttachedNum = ShmAttachedNumber(pOsContext->shmid);
774 
775             DetachDestroyShm(pOsContext->shmid, pOsContext->pShm);
776             pOsContext->shmid = MOS_LINUX_IPC_INVALID_ID;
777             pOsContext->pShm = MOS_LINUX_SHM_INVALID;
778 
779             if (iAttachedNum) --iAttachedNum;
780             UnLockSemaphore(pOsContext->semid);
781         }
782     }
783 }
784 
CreateIPC(PMOS_CONTEXT pOsContext)785 MOS_STATUS CreateIPC(PMOS_CONTEXT pOsContext)
786 {
787     MOS_STATUS eStatus;
788 
789     MOS_OS_CHK_NULL(pOsContext);
790     pOsContext->semid = MOS_LINUX_IPC_INVALID_ID;
791     pOsContext->shmid = MOS_LINUX_IPC_INVALID_ID;
792     pOsContext->pShm = MOS_LINUX_SHM_INVALID;
793 
794     struct semid_ds buf;
795     MOS_ZeroMemory(&buf, sizeof(buf));
796 
797     //wait and retry untill to get a valid semaphore
798     for (int i = 0; i < MOS_LINUX_SEM_MAX_TRIES; i ++)
799     {
800         ConnectCreateSemaphore(DUAL_VDBOX_KEY, &pOsContext->semid);
801 
802         //check whether the semid is initialized or not
803         if (semctl(pOsContext->semid, 0, IPC_STAT, &buf) == -1)
804         {
805             return MOS_STATUS_UNKNOWN;
806         }
807         if (buf.sem_otime != 0)
808         {
809             break;
810         }
811 
812         MosUtilities::MosSleep(1);  //wait and retry
813     }
814 
815     LockSemaphore(pOsContext->semid);
816     eStatus = ConnectCreateShm(DUAL_VDBOX_KEY, sizeof(VDBOX_WORKLOAD), &pOsContext->shmid, &pOsContext->pShm);
817     UnLockSemaphore(pOsContext->semid);
818     MOS_CHK_STATUS_SAFE(eStatus);
819 
820 finish:
821     return eStatus;
822 }
823 #endif
824 
Linux_GetGpuContext(PMOS_INTERFACE pOsInterface,uint32_t gpuContextHandle)825 GpuContextSpecific* Linux_GetGpuContext(PMOS_INTERFACE pOsInterface, uint32_t gpuContextHandle)
826 {
827     MOS_OS_FUNCTION_ENTER;
828 
829     if (pOsInterface == nullptr || pOsInterface->osContextPtr == nullptr)
830     {
831         MOS_OS_ASSERTMESSAGE("invalid input parameters!");
832         return nullptr;
833     }
834 
835     auto osCxtSpecific = static_cast<OsContextSpecific*>(pOsInterface->osContextPtr);
836 
837     auto gpuContextMgr = osCxtSpecific->GetGpuContextMgr();
838     if (gpuContextMgr == nullptr)
839     {
840         MOS_OS_ASSERTMESSAGE("m_gpuContextMgr cannot be nullptr");
841         return nullptr;
842     }
843 
844     auto gpuContext = gpuContextMgr->GetGpuContext(gpuContextHandle);
845     if (gpuContext == nullptr)
846     {
847         MOS_OS_ASSERTMESSAGE("cannot find the gpuContext corresponding to the active gpuContextHandle");
848         return nullptr;
849     }
850 
851     auto gpuContextSpecific = static_cast<GpuContextSpecific *>(gpuContext);
852 
853     return gpuContextSpecific;
854 }
855 
856 //!
857 //! \brief    Initialize the GPU Status Buffer
858 //! \details  Initialize the GPU Status Buffer
859 //! \param    MOS_CONTEXT * pOsContext
860 //!           [in, out] Pointer to OS context structure
861 //! \return   MOS_STATUS
862 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
863 //!
Linux_InitGPUStatus(PMOS_CONTEXT pOsContext)864 MOS_STATUS Linux_InitGPUStatus(
865     PMOS_CONTEXT    pOsContext)
866 {
867     MOS_LINUX_BO    *bo     = nullptr;
868     MOS_STATUS      eStatus = MOS_STATUS_SUCCESS;
869 
870     if (pOsContext == nullptr)
871     {
872         MOS_OS_ASSERTMESSAGE("Linux_InitGPUStatus:pOsContext == NULL");
873         eStatus = MOS_STATUS_NULL_POINTER;
874         goto finish;
875     }
876 
877     pOsContext->pGPUStatusBuffer      =
878                 (MOS_RESOURCE*)MOS_AllocAndZeroMemory(sizeof(MOS_RESOURCE) * MOS_GPU_CONTEXT_MAX);
879     if (nullptr == pOsContext->pGPUStatusBuffer)
880     {
881         MOS_OS_ASSERTMESSAGE("pContext->pGPUStatusBuffer malloc failed.");
882         eStatus = MOS_STATUS_NO_SPACE;
883         goto finish;
884     }
885 
886     // Allocate the command buffer from GEM
887     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
888     if (bo == nullptr)
889     {
890         MOS_OS_ASSERTMESSAGE("Allocation of GPU Status Buffer failed.");
891         eStatus = MOS_STATUS_NO_SPACE;
892         goto finish;
893     }
894 
895     // Map command buffer to user virtual address
896     if (mos_bo_map(bo, 1) != 0) // Write enable set
897     {
898         MOS_OS_ASSERTMESSAGE("Mapping of GPU Status Buffer failed.");
899         eStatus = MOS_STATUS_INVALID_HANDLE;
900         goto finish;
901     }
902 
903     Mos_ResetResource(pOsContext->pGPUStatusBuffer);
904 
905     // Fill in resource information
906     pOsContext->pGPUStatusBuffer->Format   = Format_Buffer;
907     pOsContext->pGPUStatusBuffer->iWidth   = bo->size;
908     pOsContext->pGPUStatusBuffer->iHeight  = 1;
909     pOsContext->pGPUStatusBuffer->iPitch   = bo->size;
910     pOsContext->pGPUStatusBuffer->iCount   = 1;
911     pOsContext->pGPUStatusBuffer->pData    = (uint8_t*)bo->virt;
912     pOsContext->pGPUStatusBuffer->TileType = MOS_TILE_LINEAR;
913     pOsContext->pGPUStatusBuffer->bo       = bo;
914     pOsContext->pGPUStatusBuffer->bMapped  = true;
915 
916     MOS_ZeroMemory(pOsContext->pGPUStatusBuffer->pData, bo->size);
917 
918 finish:
919     return eStatus;
920 }
921 
922 //!
923 //! \brief    Release the GPU Status Buffer
924 //! \details  Release the GPU Status Buffer
925 //! \param    MOS_CONTEXT * pOsContext
926 //!           [in, out] Pointer to OS context structure
927 //! \return   void
928 //!
Linux_ReleaseGPUStatus(PMOS_CONTEXT pOsContext)929 void Linux_ReleaseGPUStatus(
930     PMOS_CONTEXT    pOsContext)
931 {
932     MOS_LINUX_BO    *bo = nullptr;
933 
934     if ( pOsContext == nullptr || pOsContext->pGPUStatusBuffer == nullptr)
935     {
936         return;
937     }
938 
939     bo = pOsContext->pGPUStatusBuffer->bo;
940     if (bo != nullptr)
941     {
942         mos_bo_unmap(bo);
943         mos_bo_wait_rendering(bo);
944         mos_bo_unreference(bo);
945     }
946     pOsContext->pGPUStatusBuffer->bo = nullptr;
947 
948     MOS_FreeMemAndSetNull(pOsContext->pGPUStatusBuffer);
949 }
950 
951 //!
952 //! \brief    Get GPU status tag for the given GPU context
953 //! \details  Get GPU status tag for the given GPU context
954 //! \param    MOS_CONTEXT * pOsContext
955 //!           [in] Pointer to OS context structure
956 //! \param    MOS_GPU_CONTEXT GpuContext
957 //!           [in, out] GPU Context
958 //! \return   uint32_t
959 //!           GPU status tag
960 //!
Linux_GetGpuCtxBufferTag(PMOS_CONTEXT pOsContext,MOS_GPU_CONTEXT GpuContext)961 uint32_t Linux_GetGpuCtxBufferTag(
962     PMOS_CONTEXT    pOsContext,
963     MOS_GPU_CONTEXT GpuContext)
964 {
965     if ( pOsContext == nullptr)
966     {
967         MOS_OS_ASSERTMESSAGE("Invalid pOsContext.");
968         return 0;
969     }
970 
971     if (GpuContext == MOS_GPU_CONTEXT_INVALID_HANDLE)
972     {
973         MOS_OS_ASSERTMESSAGE("Invalid input parameter GpuContext.");
974         return 0;
975     }
976 
977     return pOsContext->OsGpuContext[GpuContext].uiGPUStatusTag;
978 }
979 
980 //!
981 //! \brief    Increment GPU status tag for the given GPU context
982 //! \details  Increment GPU status tag for the given GPU context
983 //! \param    MOS_CONTEXT * pOsContext
984 //!           [in] Pointer to OS context structure
985 //! \param    MOS_GPU_CONTEXT GpuContext
986 //!           [in] GPU Context
987 //! \return   void
988 //!
Linux_IncGpuCtxBufferTag(PMOS_CONTEXT pOsContext,MOS_GPU_CONTEXT GpuContext)989 void Linux_IncGpuCtxBufferTag(
990         PMOS_CONTEXT               pOsContext,
991         MOS_GPU_CONTEXT            GpuContext)
992 {
993     uint32_t uiGPUStatusTag;
994 
995     if ( pOsContext == nullptr)
996     {
997         MOS_OS_ASSERTMESSAGE("Invalid pOsContext.");
998         return;
999     }
1000 
1001     if (GpuContext == MOS_GPU_CONTEXT_INVALID_HANDLE)
1002     {
1003         MOS_OS_ASSERTMESSAGE("Invalid input parameter GpuContext.");
1004         return;
1005     }
1006 
1007     uiGPUStatusTag = pOsContext->OsGpuContext[GpuContext].uiGPUStatusTag;
1008 
1009     pOsContext->OsGpuContext[GpuContext].uiGPUStatusTag = uiGPUStatusTag % UINT_MAX + 1;
1010     if(pOsContext->OsGpuContext[GpuContext].uiGPUStatusTag == 0)
1011     {
1012         pOsContext->OsGpuContext[GpuContext].uiGPUStatusTag = 1;
1013     }
1014 }
1015 
Linux_GetGmmClientContext(PMOS_CONTEXT pOsContext)1016 GMM_CLIENT_CONTEXT* Linux_GetGmmClientContext(PMOS_CONTEXT pOsContext)
1017 {
1018     if (pOsContext == nullptr)
1019     {
1020         return nullptr;
1021     }
1022     return pOsContext->pGmmClientContext;
1023 }
1024 
Linux_GetOcaInterface()1025 MosOcaInterface* Linux_GetOcaInterface()
1026 {
1027     return nullptr;
1028 }
1029 
1030 //!
1031 //! \brief    Get GPU tag for the given GPU context from the status buffer
1032 //! \details  Get GPU tag for the given GPU context from the status buffer
1033 //! \param    MOS_CONTEXT * pOsContext
1034 //!           [in] Pointer to OS context structure
1035 //! \param    MOS_GPU_CONTEXT GpuContext
1036 //!           [in] GPU Context
1037 //! \return   uint32_t
1038 //!           GPU tag
1039 //!
Linux_GetGPUTag(PMOS_INTERFACE pOsInterface,MOS_GPU_CONTEXT mosGpuCtx)1040 uint32_t Linux_GetGPUTag(
1041         PMOS_INTERFACE             pOsInterface,
1042         MOS_GPU_CONTEXT            mosGpuCtx)
1043 {
1044     MOS_OS_FUNCTION_ENTER;
1045 
1046     if (pOsInterface == nullptr)
1047     {
1048         MOS_OS_ASSERTMESSAGE("invalid input parameters!");
1049         return 0;
1050     }
1051 
1052     if (mosGpuCtx == MOS_GPU_CONTEXT_INVALID_HANDLE)
1053     {
1054         MOS_OS_ASSERTMESSAGE("Invalid input parameter GpuContext.");
1055         return 0;
1056     }
1057 
1058     if (pOsInterface->modularizedGpuCtxEnabled && !Mos_Solo_IsEnabled(nullptr))
1059     {
1060         if (pOsInterface->osContextPtr == nullptr)
1061         {
1062             MOS_OS_ASSERTMESSAGE("invalid input parameters!");
1063             return 0;
1064         }
1065 
1066         auto osCxtSpecific = static_cast<OsContextSpecific*>(pOsInterface->osContextPtr);
1067 
1068         auto handle = osCxtSpecific->GetGpuContextHandle(mosGpuCtx);
1069 
1070         if (pOsInterface->apoMosEnabled)
1071         {
1072             PMOS_RESOURCE gpuStatusResource = nullptr;
1073             MOS_OS_CHK_STATUS_RETURN(MosInterface::GetGpuStatusBufferResource(pOsInterface->osStreamState, gpuStatusResource, handle));
1074             MOS_OS_CHK_NULL_RETURN(gpuStatusResource);
1075             auto gpuStatusData = (MOS_GPU_STATUS_DATA *)gpuStatusResource->pData;
1076             if (gpuStatusData == nullptr)
1077             {
1078                 MOS_OS_ASSERTMESSAGE("cannot find ");
1079                 return 0;
1080             }
1081             return gpuStatusData->GPUTag;
1082         }
1083 
1084         auto gpuContext = Linux_GetGpuContext(pOsInterface, handle);
1085 
1086         if (gpuContext == nullptr)
1087         {
1088             MOS_OS_ASSERTMESSAGE("cannot get corresponding gpu context!");
1089             return 0;
1090         }
1091 
1092         auto resource = gpuContext->GetStatusBufferResource();
1093 
1094         if (resource == nullptr)
1095         {
1096             MOS_OS_ASSERTMESSAGE("cannot find the gpuContext corresponding to the active resource.");
1097             return 0;
1098         }
1099 
1100         MOS_RESOURCE gpuStatusResource;
1101         MOS_OS_CHK_STATUS_RETURN(resource->ConvertToMosResource(&gpuStatusResource));
1102         auto gpuStatusData = (MOS_GPU_STATUS_DATA *)gpuStatusResource.pData;
1103         if (gpuStatusData == nullptr)
1104         {
1105             MOS_OS_ASSERTMESSAGE("cannot find ");
1106             return 0;
1107         }
1108         return gpuStatusData->GPUTag;
1109     }
1110 
1111     MOS_GPU_STATUS_DATA  *pGPUStatusData = nullptr;
1112 
1113     if ( pOsInterface->pOsContext == nullptr ||
1114          pOsInterface->pOsContext->pGPUStatusBuffer == nullptr ||
1115          pOsInterface->pOsContext->pGPUStatusBuffer->pData == nullptr)
1116     {
1117         return 0;
1118     }
1119 
1120     pGPUStatusData = (MOS_GPU_STATUS_DATA *)(pOsInterface->pOsContext->pGPUStatusBuffer->pData + (sizeof(MOS_GPU_STATUS_DATA) * mosGpuCtx));
1121     if (pGPUStatusData == nullptr)
1122     {
1123         MOS_OS_ASSERTMESSAGE("cannot find the gpuContext corresponding to the active resource");
1124         return 0;
1125     }
1126     return pGPUStatusData->GPUTag;
1127 }
1128 
1129 //!
1130 //! \brief    Destroy Linux context
1131 //! \details  Destroy Linux context
1132 //! \param    PMOS_CONTEXT pOsContext
1133 //!           [in] Pointer to OS context structure
1134 //! \return   void
1135 //!
Linux_Destroy(PMOS_CONTEXT pOsContext,int32_t MODSEnabled,int32_t modularizedGpuCtxEnabled)1136 void Linux_Destroy(
1137     PMOS_CONTEXT       pOsContext,
1138     int32_t            MODSEnabled,
1139     int32_t            modularizedGpuCtxEnabled)
1140 {
1141     PCOMMAND_BUFFER pCurrCB = nullptr;
1142     PCOMMAND_BUFFER pNextCB = nullptr;
1143     int32_t         iSize   = 0;
1144     int             i       = 0;
1145     if (pOsContext == nullptr)
1146     {
1147         MOS_OS_ASSERTMESSAGE("OsContext is null.");
1148         return;
1149     }
1150 
1151  #ifndef ANDROID
1152     if (pOsContext->bKMDHasVCS2)
1153     {
1154         DestroyIPC(pOsContext);
1155     }
1156  #endif
1157 
1158     if (!modularizedGpuCtxEnabled)
1159     {
1160         Linux_ReleaseCmdBufferPool(pOsContext);
1161 
1162         for (i = 0; i < MOS_GPU_CONTEXT_MAX; i++)
1163         {
1164             MOS_FreeMemAndSetNull(pOsContext->OsGpuContext[i].pCB);
1165 
1166             pCurrCB = pOsContext->OsGpuContext[i].pStartCB;
1167             for (; (pCurrCB); pCurrCB = pNextCB)
1168             {
1169                 pNextCB = pCurrCB->pNext;
1170                 MOS_FreeMemAndSetNull(pCurrCB);
1171             }
1172         }
1173 
1174         Linux_ReleaseGPUStatus(pOsContext);
1175     }
1176 
1177     if (pOsContext->contextOffsetList.size())
1178     {
1179          pOsContext->contextOffsetList.clear();
1180          pOsContext->contextOffsetList.shrink_to_fit();
1181     }
1182 
1183     if (!MODSEnabled && (pOsContext->intel_context))
1184     {
1185         if (pOsContext->intel_context->vm)
1186         {
1187             mos_gem_vm_destroy(pOsContext->intel_context->bufmgr,pOsContext->intel_context->vm);
1188             pOsContext->intel_context->vm = nullptr;
1189         }
1190         mos_gem_context_destroy(pOsContext->intel_context);
1191     }
1192 
1193     MOS_FreeMemAndSetNull(pOsContext);
1194 }
1195 
1196 //!
1197 //! \brief    Get DMA Buffer ID
1198 //! \details  Get the DMA perf Buffer ID
1199 //! \param    PMOS_CONTEXT pOsContext
1200 //!           [in] Pointer to OS context structure
1201 //! \return   uint32_t
1202 //!           Return the buffer ID
1203 //!
Linux_GetDmaBufID(PMOS_CONTEXT pOsContext)1204 uint32_t Linux_GetDmaBufID (PMOS_CONTEXT pOsContext )
1205 {
1206     if (pOsContext == nullptr)
1207     {
1208         MOS_OS_ASSERTMESSAGE("OsContext is null.");
1209         return 0;
1210     }
1211 
1212     uint32_t dmaBufID = 0;
1213     if (pOsContext->pPerfData != nullptr)
1214     {
1215         dmaBufID = pOsContext->pPerfData->dmaBufID;
1216     }
1217     return dmaBufID;
1218 }
1219 
1220 //!
1221 //! \brief    Get Buffer Type
1222 //! \details  Returns the type of buffer, 1D, 2D or volume
1223 //! \param    PMOS_RESOURCE pOsResource
1224 //!           [in] Pointer to OS Resource
1225 //! \return   GFX resource Type
1226 //!
GetResType(PMOS_RESOURCE pOsResource)1227 MOS_GFXRES_TYPE GetResType(PMOS_RESOURCE pOsResource)
1228 {
1229     GMM_RESOURCE_INFO *pGmmResourceInfo = nullptr;
1230     MOS_GFXRES_TYPE    ResType          = MOS_GFXRES_INVALID;
1231     GMM_RESOURCE_TYPE  GMMResType       = RESOURCE_INVALID;
1232 
1233     if (pOsResource == nullptr)
1234     {
1235         MOS_OS_ASSERTMESSAGE("OsContext is null.");
1236         return MOS_GFXRES_INVALID;
1237     }
1238 
1239     pGmmResourceInfo = (GMM_RESOURCE_INFO *)pOsResource->pGmmResInfo;
1240     GMMResType = pGmmResourceInfo->GetResourceType();
1241 
1242     switch (GMMResType)
1243     {
1244     case RESOURCE_BUFFER:
1245         ResType = MOS_GFXRES_BUFFER;
1246         break;
1247     case RESOURCE_3D:
1248         ResType = MOS_GFXRES_VOLUME;
1249         break;
1250     case RESOURCE_2D:
1251         ResType = MOS_GFXRES_2D;
1252         break;
1253     default:
1254         break;
1255     }
1256     return ResType;
1257 }
1258 //!
1259 //! \brief    Set the DMA Buffer ID
1260 //! \details  Sets the buffer ID in perf data
1261 //! \param    PMOS_CONTEXT pOsContext
1262 //!           [in] Pointer to OS context structure
1263 //! \param    uint32_t dwDmaBufID
1264 //!           [in] Buffer ID to be set
1265 //! \return   void
1266 //!
Linux_SetDmaBufID(PMOS_CONTEXT pOsContext,uint32_t dwDmaBufID)1267 void Linux_SetDmaBufID ( PMOS_CONTEXT pOsContext, uint32_t dwDmaBufID )
1268 {
1269     if (pOsContext == nullptr)
1270     {
1271         MOS_OS_ASSERTMESSAGE("OsContext is null.");
1272         return;
1273     }
1274 
1275     if (pOsContext->pPerfData != nullptr)
1276     {
1277         pOsContext->pPerfData->dmaBufID = dwDmaBufID;
1278     }
1279 }
1280 
1281 //!
1282 //! \brief    Set the DMA Kernel ID
1283 //! \details  Sets the Kernel ID in perf data
1284 //! \param    PMOS_CONTEXT pOsContext
1285 //!           [in] Pointer to OS context structure
1286 //! \param    uint32_t KernelID
1287 //!           [in] Buffer ID to be set
1288 //! \return   void
1289 //!
Linux_SetPerfHybridKernelID(PMOS_CONTEXT pOsContext,uint32_t KernelID)1290 void Linux_SetPerfHybridKernelID ( PMOS_CONTEXT pOsContext, uint32_t KernelID)
1291 {
1292     if (pOsContext == nullptr)
1293     {
1294         MOS_OS_ASSERTMESSAGE("OsContext is null.");
1295         return;
1296     }
1297 
1298     if (pOsContext->pPerfData != nullptr)
1299     {
1300         pOsContext->pPerfData->dmaBufID = (pOsContext->pPerfData->dmaBufID & 0xF0FF) | ((KernelID <<8) & 0x0F00);
1301     }
1302 }
1303 
1304 //!
1305 //! \brief    Init Linux context
1306 //! \details  Initialize the linux context
1307 //! \param    MOS_OS_CONTEXT * pContext
1308 //!           [in] Pointer to OS context structure
1309 //! \param    PMOS_CONTEXT pOsDriverContext
1310 //!           [in] Pointer to OS Driver context
1311 //! \return   MOS_STATUS
1312 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
1313 //!
Linux_InitContext(MOS_OS_CONTEXT * pContext,PMOS_CONTEXT pOsDriverContext,int32_t MODSEnabled,int32_t modularizedGpuCtxEnabled)1314 MOS_STATUS Linux_InitContext(
1315     MOS_OS_CONTEXT      *pContext,
1316     PMOS_CONTEXT         pOsDriverContext,
1317     int32_t              MODSEnabled,
1318     int32_t              modularizedGpuCtxEnabled)
1319 {
1320     int32_t    iDeviceId = -1;
1321     MOS_STATUS eStatus;
1322     int32_t    i = -1;
1323 
1324     MOS_OS_FUNCTION_ENTER;
1325 
1326     eStatus = MOS_STATUS_SUCCESS;
1327 
1328     if (nullptr == pContext ||
1329         nullptr == pOsDriverContext ||
1330         nullptr == pOsDriverContext->bufmgr ||
1331         (nullptr == pOsDriverContext->m_gpuContextMgr && modularizedGpuCtxEnabled && !pOsDriverContext->m_apoMosEnabled) ||
1332         (nullptr == pOsDriverContext->m_cmdBufMgr && modularizedGpuCtxEnabled && !pOsDriverContext->m_apoMosEnabled) ||
1333         0 >= pOsDriverContext->fd)
1334     {
1335         MOS_OS_ASSERT(false);
1336         return MOS_STATUS_INVALID_HANDLE;
1337     }
1338     pContext->bufmgr          = pOsDriverContext->bufmgr;
1339     pContext->m_gpuContextMgr = pOsDriverContext->m_gpuContextMgr;
1340     pContext->m_cmdBufMgr     = pOsDriverContext->m_cmdBufMgr;
1341     pContext->fd              = pOsDriverContext->fd;
1342     pContext->pPerfData       = pOsDriverContext->pPerfData;
1343     pContext->m_auxTableMgr   = pOsDriverContext->m_auxTableMgr;
1344 
1345     mos_bufmgr_gem_enable_reuse(pOsDriverContext->bufmgr);
1346 
1347     // DDI layer can pass over the DeviceID.
1348     iDeviceId = pOsDriverContext->iDeviceId;
1349     if (0 == iDeviceId)
1350     {
1351         //Such as CP, it calls InitMosInterface() dretly without creating MediaContext.
1352         iDeviceId = mos_bufmgr_gem_get_devid(pOsDriverContext->bufmgr);
1353         pOsDriverContext->iDeviceId = iDeviceId;
1354 
1355         MOS_OS_CHK_STATUS_MESSAGE(
1356             HWInfo_GetGfxInfo(pOsDriverContext->fd, pOsDriverContext->bufmgr, &pContext->platform, &pContext->SkuTable, &pContext->WaTable, &pContext->gtSystemInfo),
1357             "Fatal error - unsuccesfull Sku/Wa/GtSystemInfo initialization");
1358 
1359         pOsDriverContext->SkuTable     = pContext->SkuTable;
1360         pOsDriverContext->WaTable      = pContext->WaTable;
1361         pOsDriverContext->gtSystemInfo = pContext->gtSystemInfo;
1362         pOsDriverContext->platform     = pContext->platform;
1363         MOS_OS_NORMALMESSAGE("DeviceID was created DeviceID = %d, platform product %d", iDeviceId, pContext->platform.eProductFamily);
1364     }
1365     else
1366     {
1367         // pOsDriverContext's parameters were passed by CmCreateDevice.
1368         // Get SkuTable/WaTable/systemInfo/platform from OSDriver directly.
1369         pContext->SkuTable     = pOsDriverContext->SkuTable;
1370         pContext->WaTable      = pOsDriverContext->WaTable;
1371         pContext->gtSystemInfo = pOsDriverContext->gtSystemInfo;
1372         pContext->platform     = pOsDriverContext->platform;
1373     }
1374 
1375     pContext->bUse64BitRelocs = true;
1376     pContext->bUseSwSwizzling = pContext->bSimIsActive || MEDIA_IS_SKU(&pContext->SkuTable, FtrUseSwSwizzling);
1377     pContext->bTileYFlag      = MEDIA_IS_SKU(&pContext->SkuTable, FtrTileY);
1378     // when MODS enabled, intel_context will be created by pOsContextSpecific, should not recreate it here, or will cause memory leak.
1379     if (!MODSEnabled)
1380     {
1381        pContext->intel_context = mos_gem_context_create_ext(pOsDriverContext->bufmgr,0);
1382        if (!Mos_Solo_IsEnabled(nullptr) && pContext->intel_context)
1383        {
1384            pContext->intel_context->vm = mos_gem_vm_create(pOsDriverContext->bufmgr);
1385            if (pContext->intel_context->vm == nullptr)
1386            {
1387                MOS_OS_ASSERTMESSAGE("Failed to create vm.\n");
1388                return MOS_STATUS_UNKNOWN;
1389            }
1390        }
1391        else //try legacy context create ioctl if DRM_IOCTL_I915_GEM_CONTEXT_CREATE_EXT is not supported
1392        {
1393            pContext->intel_context = mos_gem_context_create(pOsDriverContext->bufmgr);
1394            if (pContext->intel_context)
1395            {
1396                pContext->intel_context->vm = nullptr;
1397            }
1398        }
1399 
1400        if (pContext->intel_context == nullptr)
1401        {
1402             MOS_OS_ASSERTMESSAGE("Failed to create drm intel context");
1403             return MOS_STATUS_UNKNOWN;
1404        }
1405     }
1406 
1407     pContext->intel_context->pOsContext = pContext;
1408 
1409     pContext->bIsAtomSOC = IS_ATOMSOC(iDeviceId);
1410 
1411     if(!modularizedGpuCtxEnabled)
1412     {
1413         Linux_InitCmdBufferPool(pContext);
1414 
1415         // Initialize GPU Status Buffer
1416         eStatus = Linux_InitGPUStatus(pContext);
1417         if (MOS_STATUS_SUCCESS != eStatus)
1418         {
1419             goto finish;
1420         }
1421 
1422         for (i = 0; i < MOS_GPU_CONTEXT_MAX; i++)
1423         {
1424             pContext->OsGpuContext[i].pStartCB            = nullptr;
1425             pContext->OsGpuContext[i].pCurrentCB          = nullptr;
1426             pContext->OsGpuContext[i].bCBFlushed          = true;
1427             pContext->OsGpuContext[i].uiCommandBufferSize = COMMAND_BUFFER_SIZE;
1428             pContext->OsGpuContext[i].pCB                 =
1429                 (PMOS_COMMAND_BUFFER)MOS_AllocAndZeroMemory(sizeof(MOS_COMMAND_BUFFER));
1430 
1431             if (nullptr == pContext->OsGpuContext[i].pCB)
1432             {
1433                 MOS_OS_ASSERTMESSAGE("No More Avaliable Memory");
1434                 eStatus = MOS_STATUS_NO_SPACE;
1435                 goto finish;
1436             }
1437 
1438             // each thread has its own GPU context, so do not need any lock as guarder here
1439             pContext->OsGpuContext[i].pAllocationList =
1440                 (ALLOCATION_LIST*)MOS_AllocAndZeroMemory(sizeof(ALLOCATION_LIST) * ALLOCATIONLIST_SIZE);
1441             if (nullptr == pContext->OsGpuContext[i].pAllocationList)
1442             {
1443                 MOS_OS_ASSERTMESSAGE("pContext->OsGpuContext[%d].pAllocationList malloc failed.", i);
1444                 eStatus = MOS_STATUS_NO_SPACE;
1445                 goto finish;
1446             }
1447             pContext->OsGpuContext[i].uiMaxNumAllocations = ALLOCATIONLIST_SIZE;
1448 
1449             pContext->OsGpuContext[i].pPatchLocationList =
1450                 (PATCHLOCATIONLIST*)MOS_AllocAndZeroMemory(sizeof(PATCHLOCATIONLIST) * PATCHLOCATIONLIST_SIZE);
1451             if (nullptr == pContext->OsGpuContext[i].pPatchLocationList)
1452             {
1453                 MOS_OS_ASSERTMESSAGE("pContext->OsGpuContext[%d].pPatchLocationList malloc failed.", i);
1454                 eStatus = MOS_STATUS_NO_SPACE;
1455                 goto finish;
1456             }
1457             pContext->OsGpuContext[i].uiMaxPatchLocationsize = PATCHLOCATIONLIST_SIZE;
1458 
1459             pContext->OsGpuContext[i].pResources    =
1460                 (PMOS_RESOURCE)MOS_AllocAndZeroMemory(sizeof(MOS_RESOURCE) * ALLOCATIONLIST_SIZE);
1461             if (nullptr == pContext->OsGpuContext[i].pResources)
1462             {
1463                 MOS_OS_ASSERTMESSAGE("pContext->OsGpuContext[%d].pResources malloc failed.", i);
1464                 eStatus = MOS_STATUS_NO_SPACE;
1465                 goto finish;
1466             }
1467 
1468             pContext->OsGpuContext[i].pbWriteMode    =
1469                 (int32_t*)MOS_AllocAndZeroMemory(sizeof(int32_t) * ALLOCATIONLIST_SIZE);
1470             if (nullptr == pContext->OsGpuContext[i].pbWriteMode)
1471             {
1472                 MOS_OS_ASSERTMESSAGE("pContext->OsGpuContext[%d].pbWriteMode malloc failed.", i);
1473                 eStatus = MOS_STATUS_NO_SPACE;
1474                 goto finish;
1475             }
1476 
1477             pContext->OsGpuContext[i].uiGPUStatusTag = 1;
1478         }
1479     }
1480 
1481 #ifndef ANDROID
1482     {
1483         drm_i915_getparam_t gp;
1484         int32_t             ret   = -1;
1485         int32_t             value = 0;
1486 
1487         //KMD support VCS2?
1488         gp.value = &value;
1489         gp.param = I915_PARAM_HAS_BSD2;
1490         if (pContext->fd < 0)
1491         {
1492             MOS_OS_ASSERTMESSAGE("pContext->fd is not valid.");
1493             eStatus = MOS_STATUS_INVALID_PARAMETER;
1494             goto finish;
1495         }
1496         ret = drmIoctl(pContext->fd, DRM_IOCTL_I915_GETPARAM, &gp);
1497         if (ret == 0 && value != 0)
1498         {
1499             pContext->bKMDHasVCS2 = true;
1500         }
1501         else
1502         {
1503             pContext->bKMDHasVCS2 = false;
1504         }
1505     }
1506     if (pContext->bKMDHasVCS2)
1507     {
1508         eStatus = CreateIPC(pContext);
1509         MOS_CHK_STATUS_SAFE(eStatus);
1510     }
1511 #endif
1512 
1513     pContext->pTranscryptedKernels      = nullptr;
1514     pContext->uiTranscryptedKernelsSize = 0;
1515 
1516     // For Media Memory compression
1517     pContext->ppMediaMemDecompState     = pOsDriverContext->ppMediaMemDecompState;
1518     pContext->pfnMemoryDecompress       = pOsDriverContext->pfnMemoryDecompress;
1519     pContext->pfnMediaMemoryCopy        = pOsDriverContext->pfnMediaMemoryCopy;
1520     pContext->pfnMediaMemoryCopy2D      = pOsDriverContext->pfnMediaMemoryCopy2D;
1521 
1522     // Set interface functions
1523     pContext->pfnDestroy                 = Linux_Destroy;
1524     pContext->pfnGetCommandBuffer        = Linux_GetCommandBuffer;
1525     pContext->pfnReturnCommandBuffer     = Linux_ReturnCommandBuffer;
1526     pContext->pfnFlushCommandBuffer      = Linux_FlushCommandBuffer;
1527     pContext->pfnInsertCmdBufferToPool   = Linux_InsertCmdBufferToPool;
1528     pContext->pfnWaitAndReleaseCmdBuffer = Linux_WaitAndReleaseCmdBuffer;
1529     pContext->pfnRefresh                 = Linux_Refresh;
1530     pContext->GetDmaBufID                = Linux_GetDmaBufID;
1531     pContext->SetDmaBufID                = Linux_SetDmaBufID;
1532     pContext->SetPerfHybridKernelID      = Linux_SetPerfHybridKernelID;
1533     pContext->pfnGetGpuCtxBufferTag      = Linux_GetGpuCtxBufferTag;
1534     pContext->pfnIncGpuCtxBufferTag      = Linux_IncGpuCtxBufferTag;
1535     pContext->GetGPUTag                  = Linux_GetGPUTag;
1536     pContext->GetGmmClientContext        = Linux_GetGmmClientContext;
1537     pContext->GetOcaInterface            = Linux_GetOcaInterface;
1538 
1539 finish:
1540     if (!modularizedGpuCtxEnabled)
1541     {
1542         // init context failed, roll back
1543         if (eStatus != MOS_STATUS_SUCCESS)
1544             Mos_Specific_ClearGpuContext(pContext);
1545     }
1546 
1547     return eStatus;
1548 }
1549 //============= PRIVATE FUNCTIONS <END>=========================================
1550 
1551 //!
1552 //! \brief    Set GPU context
1553 //! \details  Set GPU context for the following rendering operations
1554 //! \param    MOS_OS_CONTEXT * pContext
1555 //!           [in] Pointer to OS context structure
1556 //! \param    MOS_GPU_CONTEXT GpuContext
1557 //!           [in] GPU Context
1558 //! \return   MOS_STATUS
1559 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
1560 //!
Mos_Specific_SetGpuContext(PMOS_INTERFACE pOsInterface,MOS_GPU_CONTEXT GpuContext)1561 MOS_STATUS Mos_Specific_SetGpuContext(
1562     PMOS_INTERFACE     pOsInterface,
1563     MOS_GPU_CONTEXT    GpuContext)
1564 {
1565     MOS_OS_FUNCTION_ENTER;
1566 
1567     MOS_OS_CHK_NULL_RETURN(pOsInterface);
1568 
1569     if (GpuContext == MOS_GPU_CONTEXT_INVALID_HANDLE)
1570     {
1571         MOS_OS_ASSERTMESSAGE("Invalid input parameter GpuContext.");
1572         return MOS_STATUS_INVALID_PARAMETER;
1573     }
1574 
1575     // Set GPU context handle
1576     pOsInterface->CurrentGpuContextOrdinal = GpuContext;
1577 
1578     if (pOsInterface->modularizedGpuCtxEnabled && !Mos_Solo_IsEnabled(nullptr))
1579     {
1580         MOS_OS_CHK_NULL_RETURN(pOsInterface->osContextPtr);
1581 
1582         auto pOsContextSpecific = static_cast<OsContextSpecific*>(pOsInterface->osContextPtr);
1583         MOS_OS_CHK_NULL_RETURN(pOsContextSpecific);
1584 
1585         // Set GPU context handle
1586         pOsInterface->CurrentGpuContextHandle = pOsContextSpecific->GetGpuContextHandle(GpuContext);
1587 
1588         if (pOsInterface->apoMosEnabled)
1589         {
1590             MOS_OS_CHK_STATUS_RETURN(MosInterface::SetGpuContext(
1591                 pOsInterface->osStreamState,
1592                 pOsContextSpecific->GetGpuContextHandle(GpuContext)));
1593         }
1594     }
1595 
1596     return MOS_STATUS_SUCCESS;
1597 }
1598 
Mos_Specific_SetGpuContextFromHandle(MOS_INTERFACE * osInterface,MOS_GPU_CONTEXT contextName,GPU_CONTEXT_HANDLE contextHandle)1599 MOS_STATUS Mos_Specific_SetGpuContextFromHandle(MOS_INTERFACE *osInterface,
1600                                                 MOS_GPU_CONTEXT contextName,
1601                                                 GPU_CONTEXT_HANDLE contextHandle)
1602 {
1603     MOS_OS_FUNCTION_ENTER;
1604     MOS_OS_CHK_NULL_RETURN(osInterface);
1605 
1606     if (MOS_GPU_CONTEXT_INVALID_HANDLE == contextName)
1607     {
1608         MOS_OS_ASSERTMESSAGE("Invalid input parameter contextName.");
1609         return MOS_STATUS_INVALID_PARAMETER;
1610     }
1611 
1612     // Set GPU context handle
1613     osInterface->CurrentGpuContextOrdinal = contextName;
1614 
1615     if (osInterface->modularizedGpuCtxEnabled && !Mos_Solo_IsEnabled(nullptr))
1616     {
1617         MOS_OS_CHK_NULL_RETURN(osInterface->osContextPtr);
1618 
1619         auto os_context_specific
1620                 = static_cast<OsContextSpecific*>(osInterface->osContextPtr);
1621         MOS_OS_CHK_NULL_RETURN(os_context_specific);
1622 
1623         // Set GPU context handle
1624         osInterface->CurrentGpuContextHandle = contextHandle;
1625 
1626         if (osInterface->apoMosEnabled)
1627         {
1628             MOS_OS_CHK_STATUS_RETURN(
1629                 MosInterface::SetGpuContext(osInterface->osStreamState,
1630                                             contextHandle));
1631         }
1632     }
1633 
1634     return MOS_STATUS_SUCCESS;
1635 }
1636 
1637 //!
1638 //! \brief    Get current GPU context
1639 //! \details  Get current GPU context for the following rendering operations
1640 //! \param    PMOS_INTERFACE pOsInterface
1641 //!           [in] Pointer to OS Interface
1642 //! \return   MOS_GPU_CONTEXT
1643 //!           Return current GPU context
1644 //!
Mos_Specific_GetGpuContext(PMOS_INTERFACE pOsInterface)1645 MOS_GPU_CONTEXT Mos_Specific_GetGpuContext(
1646     PMOS_INTERFACE     pOsInterface)
1647 {
1648     if (pOsInterface == nullptr)
1649     {
1650         MOS_OS_ASSERTMESSAGE("OsInterface is null.");
1651         return MOS_GPU_CONTEXT_INVALID_HANDLE;
1652     }
1653 
1654     return pOsInterface->CurrentGpuContextOrdinal;
1655 }
1656 
1657 //!
1658 //! \brief    Set GPU context Handle
1659 //! \details  Set GPU context handle for the following rendering operations
1660 //! \param    PMOS_INTERFACE pOsInterface
1661 //!           [in] Pointer to OS Interface
1662 //! \param    GPU_CONTEXT_HANDLE gpuContextHandle
1663 //!           [in] GPU Context Handle
1664 //! \param    MOS_GPU_CONTEXT GpuContext
1665 //!           [in] GPU Context
1666 //! \return   MOS_STATUS
1667 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
1668 //!
Mos_Specific_SetGpuContextHandle(PMOS_INTERFACE pOsInterface,GPU_CONTEXT_HANDLE gpuContextHandle,MOS_GPU_CONTEXT GpuContext)1669 MOS_STATUS Mos_Specific_SetGpuContextHandle(
1670     PMOS_INTERFACE     pOsInterface,
1671     GPU_CONTEXT_HANDLE gpuContextHandle,
1672     MOS_GPU_CONTEXT    GpuContext)
1673 {
1674     MOS_OS_FUNCTION_ENTER;
1675 
1676     MOS_OS_CHK_NULL_RETURN(pOsInterface);
1677     MOS_OS_CHK_NULL_RETURN(pOsInterface->osContextPtr);
1678 
1679     auto pOsContextSpecific = static_cast<OsContextSpecific*>(pOsInterface->osContextPtr);
1680     MOS_OS_CHK_NULL_RETURN(pOsContextSpecific);
1681 
1682     pOsContextSpecific->SetGpuContextHandle(GpuContext, gpuContextHandle);
1683 
1684     return MOS_STATUS_SUCCESS;
1685 }
1686 
1687 //!
1688 //! \brief    Get GPU context pointer
1689 //! \details  Get GPU context pointer
1690 //! \param    PMOS_INTERFACE pOsInterface
1691 //!           [in] Pointer to OS Interface
1692 //! \param    GPU_CONTEXT_HANDLE gpuContextHandle
1693 //!           [in] GPU Context Handle
1694 //! \return   void *
1695 //!           a pointer to a gpu context
1696 //!
Mos_Specific_GetGpuContextbyHandle(PMOS_INTERFACE pOsInterface,GPU_CONTEXT_HANDLE gpuContextHandle)1697 void *Mos_Specific_GetGpuContextbyHandle(
1698     PMOS_INTERFACE     pOsInterface,
1699     GPU_CONTEXT_HANDLE gpuContextHandle)
1700 {
1701     MOS_OS_FUNCTION_ENTER;
1702 
1703     if (!pOsInterface)
1704     {
1705         MOS_OS_ASSERTMESSAGE("Invalid nullptr");
1706         return nullptr;
1707     }
1708 
1709     if (pOsInterface->apoMosEnabled)
1710     {
1711         return MosInterface::GetGpuContextbyHandle(pOsInterface->osStreamState, gpuContextHandle);
1712     }
1713 
1714     OsContextSpecific *pOsContextSpecific = static_cast<OsContextSpecific *>(pOsInterface->osContextPtr);
1715     if(!pOsContextSpecific)
1716     {
1717         MOS_OS_ASSERTMESSAGE("Invalid nullptr");
1718         return nullptr;
1719     }
1720 
1721     GpuContextMgr *gpuContextMgr = pOsContextSpecific->GetGpuContextMgr();
1722     if (!gpuContextMgr)
1723     {
1724         MOS_OS_ASSERTMESSAGE("Invalid nullptr");
1725         return nullptr;
1726     }
1727 
1728     GpuContext *gpuContext = gpuContextMgr->GetGpuContext(gpuContextHandle);
1729     if (!gpuContext)
1730     {
1731         MOS_OS_ASSERTMESSAGE("Invalid nullptr");
1732         return nullptr;
1733     }
1734 
1735     return (void *)gpuContext;
1736 }
1737 
1738 //!
1739 //! \brief    Get GPU context Manager
1740 //! \param    PMOS_INTERFACE pOsInterface
1741 //!           [in] Pointer to OS Interface
1742 //! \return   GpuContextMgr
1743 //!           GPU context Manager got from Os interface
1744 //!
Mos_Specific_GetGpuContextMgr(PMOS_INTERFACE pOsInterface)1745 GpuContextMgr* Mos_Specific_GetGpuContextMgr(
1746     PMOS_INTERFACE     pOsInterface)
1747 {
1748     MOS_OS_FUNCTION_ENTER;
1749 
1750     if (pOsInterface && pOsInterface->osContextPtr)
1751     {
1752         auto pOsContextSpecific = static_cast<OsContextSpecific*>(pOsInterface->osContextPtr);
1753         return pOsContextSpecific->GetGpuContextMgr();
1754     }
1755     else
1756     {
1757         return nullptr;
1758     }
1759 }
1760 
1761 //!
1762 //! \brief    Get current GMM client context
1763 //! \details  Get current GMM client context
1764 //! \param    PMOS_INTERFACE pOsInterface
1765 //!           [in] Pointer to OS Interface
1766 //! \return   GMM_CLIENT_CONTEXT
1767 //!           Return current GMM client context
1768 //!
Mos_Specific_GetGmmClientContext(PMOS_INTERFACE pOsInterface)1769 GMM_CLIENT_CONTEXT *Mos_Specific_GetGmmClientContext(
1770     PMOS_INTERFACE pOsInterface)
1771 {
1772     if (pOsInterface == nullptr)
1773     {
1774         MOS_OS_ASSERTMESSAGE("OsInterface is null.");
1775         return nullptr;
1776     }
1777 
1778     if (pOsInterface->apoMosEnabled)
1779     {
1780         return MosInterface::GetGmmClientContext(pOsInterface->osStreamState);
1781     }
1782 
1783     if (pOsInterface->modulizedMosEnabled && !Mos_Solo_IsEnabled(nullptr))
1784     {
1785         OsContextSpecific *pOsContextSpecific = static_cast<OsContextSpecific *>(pOsInterface->osContextPtr);
1786         if (pOsContextSpecific)
1787         {
1788             return pOsContextSpecific->GetGmmClientContext();
1789         }
1790     }
1791     else
1792     {
1793         if (pOsInterface->pOsContext)
1794         {
1795             return pOsInterface->pOsContext->GetGmmClientContext(pOsInterface->pOsContext);
1796         }
1797     }
1798     return nullptr;
1799 }
1800 
1801 //!
1802 //! \brief    Get Platform
1803 //! \details  Get platform info
1804 //! \param    PMOS_INTERFACE pOsInterface
1805 //!           [in] Pointer to OS Interface
1806 //! \param    PLATFORM pPlatform
1807 //!           [out] Pointer to platform
1808 //! \return   MOS_STATUS
1809 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
1810 //!
Mos_Specific_GetPlatform(PMOS_INTERFACE pOsInterface,PLATFORM * pPlatform)1811 void Mos_Specific_GetPlatform(
1812     PMOS_INTERFACE          pOsInterface,
1813     PLATFORM                *pPlatform)
1814 {
1815     MOS_STATUS          eStatus;
1816 
1817     eStatus = MOS_STATUS_SUCCESS;
1818 
1819     MOS_OS_CHK_NULL(pOsInterface);
1820     MOS_OS_CHK_NULL(pOsInterface->pOsContext);
1821     MOS_OS_CHK_NULL(pPlatform);
1822 
1823     if (pOsInterface->apoMosEnabled)
1824     {
1825         // apo wrapper
1826         auto platform = MosInterface::GetPlatform(pOsInterface->osStreamState);
1827         if (platform)
1828         {
1829             *pPlatform = *platform;
1830         }
1831         return;
1832     }
1833 
1834     *pPlatform = pOsInterface->pOsContext->platform;
1835 
1836 finish:
1837     return;
1838 }
1839 
Mos_DestroyInterface(PMOS_INTERFACE pOsInterface)1840 MOS_STATUS Mos_DestroyInterface(PMOS_INTERFACE pOsInterface)
1841 {
1842     MOS_OS_CHK_NULL_RETURN(pOsInterface);
1843 
1844     MOS_STREAM_HANDLE streamState = pOsInterface->osStreamState;
1845     MOS_OS_CHK_NULL_RETURN(streamState);
1846 
1847     auto deviceContext = streamState->osDeviceContext;
1848     MOS_OS_CHK_NULL_RETURN(deviceContext);
1849 
1850     if (!Mos_Solo_IsEnabled((PMOS_CONTEXT)streamState->perStreamParameters))
1851     {
1852         OsContext *pOsContext = pOsInterface->osContextPtr;
1853         MOS_OS_CHK_NULL_RETURN(pOsContext);
1854         // APO MOS destory GPU contexts here instead of inside osContextPtr
1855         OsContextSpecific *pOsContextSpecific = static_cast<OsContextSpecific *>(pOsContext);
1856 
1857         auto gpuContextMgr = deviceContext->GetGpuContextMgr();
1858         for (uint32_t i = 0; i < MOS_GPU_CONTEXT_MAX; i++)
1859         {
1860             if (pOsContextSpecific->GetGpuContextHandleByIndex(i) != MOS_GPU_CONTEXT_INVALID_HANDLE)
1861             {
1862                 if (gpuContextMgr == nullptr)
1863                 {
1864                     MOS_OS_ASSERTMESSAGE("GpuContextMgr is null when destroy GpuContext");
1865                     break;
1866                 }
1867                 auto gpuContext = gpuContextMgr->GetGpuContext(pOsContextSpecific->GetGpuContextHandleByIndex(i));
1868                 if (gpuContext == nullptr)
1869                 {
1870                     MOS_OS_ASSERTMESSAGE("cannot find the gpuContext corresponding to the active gpuContextHandle");
1871                     continue;
1872                 }
1873                 gpuContextMgr->DestroyGpuContext(gpuContext);
1874                 pOsContextSpecific->SetGpuContextHandleByIndex(i, MOS_GPU_CONTEXT_INVALID_HANDLE);
1875             }
1876         }
1877 
1878         pOsContext->CleanUp();
1879 
1880         MOS_Delete(pOsContext);
1881         pOsInterface->osContextPtr = nullptr;
1882     }
1883 
1884     if (pOsInterface->osCpInterface)
1885     {
1886         Delete_MosCpInterface(pOsInterface->osCpInterface);
1887         pOsInterface->osCpInterface = NULL;
1888     }
1889 
1890     PMOS_CONTEXT perStreamParameters = (PMOS_CONTEXT)streamState->perStreamParameters;
1891 
1892     if (perStreamParameters && perStreamParameters->bFreeContext)
1893     {
1894         perStreamParameters->SkuTable.reset();
1895         perStreamParameters->WaTable.reset();
1896         Mos_Specific_ClearGpuContext(perStreamParameters);
1897 
1898         if (perStreamParameters->contextOffsetList.size())
1899         {
1900             perStreamParameters->contextOffsetList.clear();
1901             perStreamParameters->contextOffsetList.shrink_to_fit();
1902         }
1903 
1904         if(Mos_Solo_IsEnabled(perStreamParameters))
1905         {
1906             Linux_ReleaseCmdBufferPool(perStreamParameters);
1907             PCOMMAND_BUFFER pCurrCB = nullptr;
1908             PCOMMAND_BUFFER pNextCB = nullptr;
1909             for (uint32_t i = 0; i < MOS_GPU_CONTEXT_MAX; i++)
1910             {
1911                 MOS_FreeMemAndSetNull(perStreamParameters->OsGpuContext[i].pCB);
1912 
1913                 pCurrCB = perStreamParameters->OsGpuContext[i].pStartCB;
1914                 for (; (pCurrCB); pCurrCB = pNextCB)
1915                 {
1916                     pNextCB = pCurrCB->pNext;
1917                     MOS_FreeMemAndSetNull(pCurrCB);
1918                 }
1919             }
1920             Linux_ReleaseGPUStatus(perStreamParameters);
1921         }
1922         if (perStreamParameters->intel_context)
1923         {
1924             if (perStreamParameters->intel_context->vm)
1925             {
1926                 mos_gem_vm_destroy(perStreamParameters->intel_context->bufmgr, perStreamParameters->intel_context->vm);
1927                 perStreamParameters->intel_context->vm = nullptr;
1928             }
1929             mos_gem_context_destroy(perStreamParameters->intel_context);
1930             perStreamParameters->intel_context = nullptr;
1931         }
1932         MOS_FreeMemAndSetNull(perStreamParameters);
1933         streamState->perStreamParameters = nullptr;
1934     }
1935 
1936     MosInterface::DestroyVirtualEngineState(streamState);
1937     MOS_FreeMemAndSetNull(pOsInterface->pVEInterf);
1938 
1939     MOS_OS_CHK_STATUS_RETURN(MosInterface::DestroyOsStreamState(streamState));
1940     pOsInterface->osStreamState = nullptr;
1941     return MOS_STATUS_SUCCESS;
1942 }
1943 //!
1944 //! \brief    Destroys OS specific allocations
1945 //! \details  Destroys OS specific allocations including destroying OS context
1946 //! \param    PMOS_INTERFACE pOsInterface
1947 //!           [in] Pointer to OS Interface
1948 //! \param    int32_t bDestroyVscVppDeviceTag
1949 //!           [in] Destroy VscVppDeviceTagId Flag, no use in Linux
1950 //! \return   void
1951 //!
Mos_Specific_Destroy(PMOS_INTERFACE pOsInterface,int32_t bDestroyVscVppDeviceTag)1952 void Mos_Specific_Destroy(
1953     PMOS_INTERFACE pOsInterface,
1954     int32_t        bDestroyVscVppDeviceTag)
1955 {
1956     MOS_UNUSED(bDestroyVscVppDeviceTag);
1957 
1958     if (nullptr == pOsInterface)
1959     {
1960         MOS_OS_ASSERTMESSAGE("input parameter, pOsInterface is NULL.");
1961         return;
1962     }
1963 
1964     if (pOsInterface->apoMosEnabled)
1965     {
1966         MOS_STATUS status = Mos_DestroyInterface(pOsInterface);
1967         if (status != MOS_STATUS_SUCCESS)
1968         {
1969             MOS_OS_ASSERTMESSAGE("Mos Destroy Interface failed.");
1970         }
1971         return;
1972     }
1973 
1974     if (pOsInterface->modulizedMosEnabled && !Mos_Solo_IsEnabled(nullptr))
1975     {
1976         OsContext* pOsContext = pOsInterface->osContextPtr;
1977         if (pOsContext == nullptr)
1978         {
1979             MOS_OS_ASSERTMESSAGE("Unable to get the active OS context.");
1980             return;
1981         }
1982 
1983         // APO MOS destory GPU contexts here instead of inside osContextPtr
1984         if (pOsInterface->apoMosEnabled)
1985         {
1986             OsContextSpecific* pOsContextSpecific = static_cast<OsContextSpecific*>(pOsContext);
1987             if (pOsInterface->osStreamState == nullptr)
1988             {
1989                 MOS_OS_ASSERTMESSAGE("osStreamState is null when destroy GpuContext");
1990                 return;
1991             }
1992             if (pOsInterface->osStreamState->osDeviceContext == nullptr)
1993             {
1994                 MOS_OS_ASSERTMESSAGE("osDeviceContext is null when destroy GpuContext");
1995                 return;
1996             }
1997             auto gpuContextMgr = pOsInterface->osStreamState->osDeviceContext->GetGpuContextMgr();
1998             for (uint32_t i = 0; i < MOS_GPU_CONTEXT_MAX; i++)
1999             {
2000                 if (pOsContextSpecific->GetGpuContextHandleByIndex(i) != MOS_GPU_CONTEXT_INVALID_HANDLE)
2001                 {
2002                     if (gpuContextMgr == nullptr)
2003                     {
2004                         MOS_OS_ASSERTMESSAGE("GpuContextMgr is null when destroy GpuContext");
2005                         break;
2006                     }
2007                     auto gpuContext = gpuContextMgr->GetGpuContext(pOsContextSpecific->GetGpuContextHandleByIndex(i));
2008                     if (gpuContext == nullptr)
2009                     {
2010                         MOS_OS_ASSERTMESSAGE("cannot find the gpuContext corresponding to the active gpuContextHandle");
2011                         continue;
2012                     }
2013                     gpuContextMgr->DestroyGpuContext(gpuContext);
2014                     pOsContextSpecific->SetGpuContextHandleByIndex(i, MOS_GPU_CONTEXT_INVALID_HANDLE);
2015                 }
2016             }
2017         }
2018         pOsContext->CleanUp();
2019 
2020         MOS_Delete(pOsContext);
2021         pOsInterface->osContextPtr = nullptr;
2022     }
2023 
2024     if (pOsInterface->osCpInterface)
2025     {
2026         Delete_MosCpInterface(pOsInterface->osCpInterface);
2027         pOsInterface->osCpInterface = NULL;
2028     }
2029 
2030     if (pOsInterface &&
2031         pOsInterface->pOsContext &&
2032         pOsInterface->pOsContext->bFreeContext)
2033     {
2034         pOsInterface->pOsContext->SkuTable.reset();
2035         pOsInterface->pOsContext->WaTable.reset();
2036         Mos_Specific_ClearGpuContext(pOsInterface->pOsContext);
2037         bool modularizedGpuCtxEnabled = pOsInterface->modularizedGpuCtxEnabled && !Mos_Solo_IsEnabled(nullptr);
2038         pOsInterface->pOsContext->pfnDestroy(pOsInterface->pOsContext, pOsInterface->modulizedMosEnabled, modularizedGpuCtxEnabled);
2039         pOsInterface->pOsContext = nullptr;
2040     }
2041     if (pOsInterface->pVEInterf)
2042     {
2043         if (pOsInterface->apoMosEnabled && pOsInterface->pVEInterf->veInterface)
2044         {
2045             pOsInterface->pVEInterf->veInterface->Destroy();
2046             MOS_Delete(pOsInterface->pVEInterf->veInterface);
2047         }
2048         MOS_FreeMemAndSetNull(pOsInterface->pVEInterf);
2049     }
2050 
2051     if (pOsInterface->apoMosEnabled)
2052     {
2053         auto status = MosInterface::DestroyOsStreamState(pOsInterface->osStreamState);
2054         if (status != MOS_STATUS_SUCCESS)
2055         {
2056             MOS_OS_ASSERTMESSAGE("Failed to destroy stream state.");
2057             return;
2058         }
2059     }
2060 }
2061 
2062 //!
2063 //! \brief    Gets the SKU table
2064 //! \details  Gets the SKU table for the platform
2065 //! \param    PMOS_INTERFACE pOsInterface
2066 //!           [in] Pointer to OS Interface
2067 //! \return   MEDIA_FEATURE_TABLE *
2068 //!           Returns the pointer to sku table
2069 //!
Mos_Specific_GetSkuTable(PMOS_INTERFACE pOsInterface)2070 MEDIA_FEATURE_TABLE *Mos_Specific_GetSkuTable(
2071     PMOS_INTERFACE pOsInterface)
2072 {
2073     if (pOsInterface && pOsInterface->apoMosEnabled)
2074     {
2075         // apo wrapper
2076         return MosInterface::GetSkuTable(pOsInterface->osStreamState);
2077     }
2078 
2079     if (pOsInterface && pOsInterface->pOsContext)
2080     {
2081         return &pOsInterface->pOsContext->SkuTable;
2082     }
2083     return nullptr;
2084 }
2085 
2086 //!
2087 //! \brief    Gets the WA table
2088 //! \details  Gets the WA table for the platform
2089 //! \param    PMOS_INTERFACE pOsInterface
2090 //!           [in] Pointer to OS Interface
2091 //! \return   MEDIA_WA_TABLE *
2092 //!           Returns the pointer to WA table
2093 //!
Mos_Specific_GetWaTable(PMOS_INTERFACE pOsInterface)2094 MEDIA_WA_TABLE *Mos_Specific_GetWaTable(
2095     PMOS_INTERFACE pOsInterface)
2096 {
2097     if (pOsInterface && pOsInterface->apoMosEnabled)
2098     {
2099         // apo wrapper
2100         return MosInterface::GetWaTable(pOsInterface->osStreamState);
2101     }
2102 
2103     if (pOsInterface && pOsInterface->pOsContext)
2104     {
2105         return &pOsInterface->pOsContext->WaTable;
2106     }
2107     return nullptr;
2108 }
2109 
2110 //!
2111 //! \brief    Gets the GT System Info
2112 //! \details  Gets the GT System Info
2113 //! \param    PMOS_INTERFACE pOsInterface
2114 //!           [in] OS Interface
2115 //! \return   MEDIA_SYSTEM_INFO *
2116 //!           pointer to the GT System Info
2117 //!
Mos_Specific_GetGtSystemInfo(PMOS_INTERFACE pOsInterface)2118 MEDIA_SYSTEM_INFO *Mos_Specific_GetGtSystemInfo(
2119     PMOS_INTERFACE     pOsInterface)
2120 {
2121     if( nullptr == pOsInterface)
2122     {
2123         MOS_OS_ASSERTMESSAGE("input parameter pOsInterface is NULL.");
2124         return  nullptr;
2125     }
2126 
2127     if (pOsInterface->apoMosEnabled)
2128     {
2129         // apo wrapper
2130         return MosInterface::GetGtSystemInfo(pOsInterface->osStreamState);
2131     }
2132 
2133     if( nullptr == pOsInterface->pOsContext)
2134     {
2135         MOS_OS_ASSERTMESSAGE("pOsContext is NULL.");
2136         return  nullptr;
2137     }
2138 
2139     return &pOsInterface->pOsContext->gtSystemInfo;
2140 }
2141 
Mos_Specific_GetMediaEngineInfo(PMOS_INTERFACE pOsInterface,MEDIA_ENGINE_INFO & info)2142 MOS_STATUS Mos_Specific_GetMediaEngineInfo(
2143     PMOS_INTERFACE pOsInterface, MEDIA_ENGINE_INFO &info)
2144 {
2145     if (pOsInterface == nullptr)
2146     {
2147         MOS_OS_ASSERTMESSAGE("Invalid pointer!");
2148         return MOS_STATUS_INVALID_PARAMETER;
2149     }
2150 
2151     if (pOsInterface->apoMosEnabled)
2152     {
2153         // apo wrapper
2154         MOS_OS_CHK_STATUS_RETURN(MosInterface::GetMediaEngineInfo(pOsInterface->osStreamState, info));
2155         return MOS_STATUS_SUCCESS;
2156     }
2157 
2158     auto systemInfo = pOsInterface->pfnGetGtSystemInfo(pOsInterface);
2159     MOS_OS_CHK_NULL_RETURN(systemInfo);
2160     MosUtilities::MosZeroMemory(&info, sizeof(info));
2161     info.VDBoxInfo = systemInfo->VDBoxInfo;
2162     info.VEBoxInfo = systemInfo->VEBoxInfo;
2163 
2164     return MOS_STATUS_SUCCESS;
2165 }
2166 
2167 //!
2168 //! \brief    Resets OS States
2169 //! \details  Resets OS States for linux
2170 //! \param    PMOS_INTERFACE pOsInterface
2171 //!           [in] Pointer to OS Interface
2172 //! \return   void
2173 //!
Mos_Specific_ResetOsStates(PMOS_INTERFACE pOsInterface)2174 void Mos_Specific_ResetOsStates(
2175     PMOS_INTERFACE pOsInterface)                                           // [in] OS Interface
2176 {
2177     MOS_OS_FUNCTION_ENTER;
2178 
2179     PMOS_OS_CONTEXT     pOsContext;
2180     PMOS_OS_GPU_CONTEXT pOsGpuContext;
2181 
2182     if (pOsInterface == nullptr ||
2183         pOsInterface->pOsContext == nullptr)
2184     {
2185         return;
2186     }
2187 
2188     if (pOsInterface->apoMosEnabled)
2189     {
2190         auto status = MosInterface::ResetCommandBuffer(pOsInterface->osStreamState, 0);
2191         if (MOS_FAILED(status))
2192         {
2193             MOS_OS_ASSERTMESSAGE("ResetCommandBuffer failed.");
2194         }
2195         return;
2196     }
2197 
2198     if (pOsInterface->modularizedGpuCtxEnabled && !Mos_Solo_IsEnabled(nullptr))
2199     {
2200         auto gpuContext = Linux_GetGpuContext(pOsInterface, pOsInterface->CurrentGpuContextHandle);
2201         if (gpuContext == nullptr)
2202         {
2203             MOS_OS_ASSERTMESSAGE("GPU Context pointer is nullptr!");
2204             return;
2205         }
2206 
2207         gpuContext->ResetGpuContextStatus();
2208         return;
2209     }
2210 
2211     pOsContext = pOsInterface->pOsContext;
2212     pOsGpuContext = &pOsContext->OsGpuContext[pOsInterface->CurrentGpuContextOrdinal];
2213     // Reset resource allocation
2214     pOsGpuContext->uiNumAllocations = 0;
2215     MOS_ZeroMemory(pOsGpuContext->pAllocationList, sizeof(ALLOCATION_LIST) * pOsGpuContext->uiMaxNumAllocations);
2216     pOsGpuContext->uiCurrentNumPatchLocations = 0;
2217     MOS_ZeroMemory(pOsGpuContext->pPatchLocationList, sizeof(PATCHLOCATIONLIST) * pOsGpuContext->uiMaxPatchLocationsize);
2218     pOsGpuContext->uiResCount = 0;
2219 
2220     MOS_ZeroMemory(pOsGpuContext->pResources, sizeof(MOS_RESOURCE) * pOsGpuContext->uiMaxNumAllocations);
2221     MOS_ZeroMemory(pOsGpuContext->pbWriteMode, sizeof(int32_t) * pOsGpuContext->uiMaxNumAllocations);
2222 
2223     if((pOsGpuContext->bCBFlushed == true) && pOsGpuContext->pCB->OsResource.bo)
2224     {
2225         pOsGpuContext->pCB->OsResource.bo = nullptr;
2226     }
2227 
2228  }
2229 
2230 //!
2231 //! \brief    Convert MOS format to gmm format
2232 //! \details  convert MOS format to gmm format
2233 //! \param    MOS_FORMAT format
2234 //!           [in] Surface
2235 //! \return   MEDIA_WA_TABLE *
2236 //!           Returns the pointer to WA table
2237 //!
Mos_Specific_ConvertMosFmtToGmmFmt(MOS_FORMAT format)2238 GMM_RESOURCE_FORMAT Mos_Specific_ConvertMosFmtToGmmFmt(
2239     MOS_FORMAT format)
2240 {
2241     switch (format)
2242     {
2243         case Format_Buffer      : return GMM_FORMAT_GENERIC_8BIT;
2244         case Format_Buffer_2D   : return GMM_FORMAT_GENERIC_8BIT;               // matching size as format
2245         case Format_L8          : return GMM_FORMAT_GENERIC_8BIT;               // matching size as format
2246         case Format_L16         : return GMM_FORMAT_L16_UNORM_TYPE;
2247         case Format_STMM        : return GMM_FORMAT_R8_UNORM_TYPE;              // matching size as format
2248         case Format_AI44        : return GMM_FORMAT_GENERIC_8BIT;               // matching size as format
2249         case Format_IA44        : return GMM_FORMAT_GENERIC_8BIT;               // matching size as format
2250         case Format_R5G6B5      : return GMM_FORMAT_B5G6R5_UNORM_TYPE;
2251         case Format_R8G8B8      : return GMM_FORMAT_R8G8B8_UNORM;
2252         case Format_X8R8G8B8    : return GMM_FORMAT_B8G8R8X8_UNORM_TYPE;
2253         case Format_A8R8G8B8    : return GMM_FORMAT_B8G8R8A8_UNORM_TYPE;
2254         case Format_X8B8G8R8    : return GMM_FORMAT_R8G8B8X8_UNORM_TYPE;
2255         case Format_A8B8G8R8    : return GMM_FORMAT_R8G8B8A8_UNORM_TYPE;
2256         case Format_R32F        : return GMM_FORMAT_R32_FLOAT_TYPE;
2257         case Format_V8U8        : return GMM_FORMAT_GENERIC_16BIT;              // matching size as format
2258         case Format_YUY2        : return GMM_FORMAT_YUY2;
2259         case Format_UYVY        : return GMM_FORMAT_UYVY;
2260         case Format_P8          : return GMM_FORMAT_RENDER_8BIT_TYPE;           // matching size as format
2261         case Format_A8          : return GMM_FORMAT_A8_UNORM_TYPE;
2262         case Format_AYUV        : return GMM_FORMAT_R8G8B8A8_UINT_TYPE;
2263         case Format_NV12        : return GMM_FORMAT_NV12_TYPE;
2264         case Format_NV21        : return GMM_FORMAT_NV21_TYPE;
2265         case Format_YV12        : return GMM_FORMAT_YV12_TYPE;
2266         case Format_R32U        : return GMM_FORMAT_R32_UINT_TYPE;
2267         case Format_R32S        : return GMM_FORMAT_R32_SINT_TYPE;
2268         case Format_RAW         : return GMM_FORMAT_GENERIC_8BIT;
2269         case Format_444P        : return GMM_FORMAT_MFX_JPEG_YUV444_TYPE;
2270         case Format_422H        : return GMM_FORMAT_MFX_JPEG_YUV422H_TYPE;
2271         case Format_422V        : return GMM_FORMAT_MFX_JPEG_YUV422V_TYPE;
2272         case Format_IMC3        : return GMM_FORMAT_IMC3_TYPE;
2273         case Format_411P        : return GMM_FORMAT_MFX_JPEG_YUV411_TYPE;
2274         case Format_411R        : return GMM_FORMAT_MFX_JPEG_YUV411R_TYPE;
2275         case Format_RGBP        : return GMM_FORMAT_RGBP_TYPE;
2276         case Format_BGRP        : return GMM_FORMAT_BGRP_TYPE;
2277         case Format_R8U         : return GMM_FORMAT_R8_UINT_TYPE;
2278         case Format_R8UN        : return GMM_FORMAT_R8_UNORM;
2279         case Format_R16U        : return GMM_FORMAT_R16_UINT_TYPE;
2280         case Format_R16F        : return GMM_FORMAT_R16_FLOAT_TYPE;
2281         case Format_P010        : return GMM_FORMAT_P010_TYPE;
2282         case Format_P016        : return GMM_FORMAT_P016_TYPE;
2283         case Format_Y216        : return GMM_FORMAT_Y216_TYPE;
2284         case Format_Y416        : return GMM_FORMAT_Y416_TYPE;
2285         case Format_P208        : return GMM_FORMAT_P208_TYPE;
2286         case Format_Y210        : return GMM_FORMAT_Y210_TYPE;
2287         case Format_Y410        : return GMM_FORMAT_Y410_TYPE;
2288         default                 : return GMM_FORMAT_INVALID;
2289     }
2290 }
2291 
2292 //!
2293 //! \brief    Allocate resource
2294 //! \details  To Allocate Buffer, pass Format as Format_Buffer and set the iWidth as size of the buffer.
2295 //! \param    PMOS_INTERFACE pOsInterface
2296 //!           [in] Pointer to OS Interface
2297 //! \param    PMOS_ALLOC_GFXRES_PARAMS pParams
2298 //!           [in] Pointer to resource params
2299 //! \param    PMOS_RESOURCE pOsResource
2300 //!           [in/out] Pointer to OS resource
2301 //! \return   MOS_STATUS
2302 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
2303 //!
Mos_Specific_AllocateResource(PMOS_INTERFACE pOsInterface,PMOS_ALLOC_GFXRES_PARAMS pParams,PCCHAR functionName,PCCHAR filename,int32_t line,PMOS_RESOURCE pOsResource)2304 MOS_STATUS Mos_Specific_AllocateResource(
2305     PMOS_INTERFACE           pOsInterface,
2306     PMOS_ALLOC_GFXRES_PARAMS pParams,
2307 #if MOS_MESSAGES_ENABLED
2308     PCCHAR                   functionName,
2309     PCCHAR                   filename,
2310     int32_t                  line,
2311 #endif // MOS_MESSAGES_ENABLED
2312     PMOS_RESOURCE            pOsResource)
2313 {
2314     void *               caller = nullptr;
2315     const char *         bufname;
2316     void *               ptr;
2317     int32_t              iSize = 0;
2318     int32_t              iPitch = 0;
2319     unsigned long        ulPitch = 0;
2320     MOS_STATUS           eStatus;
2321     MOS_LINUX_BO *       bo = nullptr;
2322     MOS_TILE_TYPE        tileformat;
2323     uint32_t             tileformat_linux = 0;
2324     int32_t              iHeight = 0;
2325     int32_t              iAlignedHeight = 0;
2326     GMM_RESCREATE_PARAMS GmmParams;
2327     GMM_RESOURCE_INFO *  pGmmResourceInfo = nullptr;
2328     GMM_RESOURCE_TYPE    resourceType = RESOURCE_INVALID;
2329     int                  mem_type = MOS_MEMPOOL_VIDEOMEMORY;
2330 
2331     MOS_OS_FUNCTION_ENTER;
2332 
2333     MOS_ZeroMemory(&GmmParams, sizeof(GmmParams));
2334 
2335     if( nullptr == pOsResource)
2336     {
2337         MOS_OS_ASSERTMESSAGE("input parameter pOSResource is NULL.");
2338         return  MOS_STATUS_INVALID_PARAMETER;
2339     }
2340 
2341     if( nullptr == pOsInterface)
2342     {
2343         MOS_OS_ASSERTMESSAGE("input parameter pOsInterface is NULL.");
2344         return  MOS_STATUS_INVALID_PARAMETER;
2345     }
2346 
2347     bufname                                = pParams->pBufName;
2348     pOsResource->bConvertedFromDDIResource = false;
2349 
2350     bool osContextValid = false;
2351     if (pOsInterface->osContextPtr != nullptr)
2352     {
2353         if (pOsInterface->osContextPtr->GetOsContextValid() == true)
2354         {
2355             osContextValid = true;
2356         }
2357     }
2358 
2359     if (pOsInterface->apoMosEnabled)
2360     {
2361         pParams->bBypassMODImpl = !((pOsInterface->modulizedMosEnabled) && (!Mos_Solo_IsEnabled(nullptr)) && (osContextValid == true));
2362 
2363         MOS_OS_CHK_NULL_RETURN(pOsInterface->osStreamState);
2364 
2365         pOsInterface->osStreamState->component = pOsInterface->Component;
2366 
2367         eStatus = MosInterface::AllocateResource(
2368             pOsInterface->osStreamState,
2369             pParams,
2370             pOsResource
2371 #if MOS_MESSAGES_ENABLED
2372             ,
2373             functionName,
2374             filename,
2375             line
2376 #endif  // MOS_MESSAGES_ENABLED
2377         );
2378 
2379         return eStatus;
2380     }
2381 
2382     if ((pOsInterface->modulizedMosEnabled) && (!Mos_Solo_IsEnabled(nullptr)) && (osContextValid == true))
2383     {
2384         pOsResource->pGfxResource = GraphicsResource::CreateGraphicResource(GraphicsResource::osSpecificResource);
2385         if (pOsResource->pGfxResource == nullptr)
2386         {
2387             MOS_OS_ASSERTMESSAGE("input nullptr returned by GraphicsResource::CreateGraphicResource.");
2388             return MOS_STATUS_INVALID_HANDLE;
2389         }
2390 
2391         if (pOsInterface->osContextPtr == nullptr)
2392         {
2393             MOS_OS_ASSERTMESSAGE("invalid osContextPtr.");
2394             return MOS_STATUS_INVALID_HANDLE;
2395         }
2396 
2397         GraphicsResource::SetMemAllocCounterGfx(MosUtilities::m_mosMemAllocCounterGfx);
2398 
2399         GraphicsResource::CreateParams params(pParams);
2400         eStatus = pOsResource->pGfxResource->Allocate(pOsInterface->osContextPtr, params);
2401         if (eStatus != MOS_STATUS_SUCCESS)
2402         {
2403             MOS_OS_ASSERTMESSAGE("Allocate graphic resource failed");
2404             return MOS_STATUS_INVALID_HANDLE;
2405         }
2406 
2407         eStatus = pOsResource->pGfxResource->ConvertToMosResource(pOsResource);
2408         if (eStatus != MOS_STATUS_SUCCESS)
2409         {
2410             MOS_OS_ASSERTMESSAGE("Convert graphic resource failed");
2411             return MOS_STATUS_INVALID_HANDLE;
2412         }
2413 
2414         MosUtilities::m_mosMemAllocCounterGfx = GraphicsResource::GetMemAllocCounterGfx();
2415         MOS_OS_CHK_NULL(pOsResource->pGmmResInfo);
2416         MOS_MEMNINJA_GFX_ALLOC_MESSAGE(pOsResource->pGmmResInfo, bufname, pOsInterface->Component,
2417             (uint32_t)pOsResource->pGmmResInfo->GetSizeSurface(), pParams->dwArraySize, functionName, filename, line);
2418 
2419         return eStatus;
2420     }
2421 
2422     caller              = nullptr;
2423     tileformat_linux    = I915_TILING_NONE;
2424     iAlignedHeight      = iHeight = pParams->dwHeight;
2425     eStatus             = MOS_STATUS_SUCCESS;
2426     resourceType        = RESOURCE_2D;
2427     tileformat          = pParams->TileType;
2428 
2429     MOS_ZeroMemory(&GmmParams, sizeof(GmmParams));
2430 
2431     if( nullptr == pOsInterface->pOsContext )
2432     {
2433         MOS_OS_ASSERTMESSAGE("input parameter pOsInterface is NULL.");
2434         return  MOS_STATUS_INVALID_PARAMETER;
2435     }
2436     switch (pParams->Format)
2437     {
2438         case Format_Buffer:
2439         case Format_RAW:
2440             resourceType                = RESOURCE_BUFFER;
2441             iAlignedHeight              = 1;
2442             //indicate buffer Restriction is Vertex.
2443             GmmParams.Flags.Gpu.State   = true;
2444             break;
2445         case Format_L8:
2446         case Format_L16:
2447         case Format_STMM:
2448         case Format_AI44:
2449         case Format_IA44:
2450         case Format_R5G6B5:
2451         case Format_R8G8B8:
2452         case Format_X8R8G8B8:
2453         case Format_A8R8G8B8:
2454         case Format_X8B8G8R8:
2455         case Format_A8B8G8R8:
2456         case Format_R32S:
2457         case Format_R32F:
2458         case Format_V8U8:
2459         case Format_YUY2:
2460         case Format_UYVY:
2461         case Format_P8:
2462         case Format_A8:
2463         case Format_AYUV:
2464         case Format_NV12:
2465         case Format_NV21:
2466         case Format_YV12:
2467         case Format_Buffer_2D:
2468         case Format_R32U:
2469         case Format_444P:
2470         case Format_422H:
2471         case Format_422V:
2472         case Format_IMC3:
2473         case Format_411P:
2474         case Format_411R:
2475         case Format_RGBP:
2476         case Format_BGRP:
2477         case Format_R16U:
2478         case Format_R8U:
2479         case Format_R8UN:
2480         case Format_P010:
2481         case Format_P016:
2482         case Format_Y216:
2483         case Format_Y416:
2484         case Format_P208:
2485         case Format_Y210:
2486         case Format_Y410:
2487         case Format_R16F:
2488             resourceType                = RESOURCE_2D;
2489             //indicate buffer Restriction is Planar surface restrictions.
2490             GmmParams.Flags.Gpu.Video   = true;
2491             break;
2492         default:
2493             MOS_OS_ASSERTMESSAGE("Unsupported format");
2494             eStatus = MOS_STATUS_UNIMPLEMENTED;
2495             goto finish;
2496     }
2497 
2498     // Create GmmResourceInfo
2499     GmmParams.BaseWidth             = pParams->dwWidth;
2500     GmmParams.BaseHeight            = iAlignedHeight;
2501     GmmParams.ArraySize             = 1;
2502     GmmParams.Type                  = resourceType;
2503     GmmParams.Format                = Mos_Specific_ConvertMosFmtToGmmFmt(pParams->Format);
2504 
2505     MOS_OS_CHECK_CONDITION(GmmParams.Format == GMM_FORMAT_INVALID,
2506                          "Unsupported format",
2507                          MOS_STATUS_UNKNOWN);
2508 
2509     switch(tileformat)
2510     {
2511         case MOS_TILE_Y:
2512             tileformat_linux               = I915_TILING_Y;
2513             if (pParams->bIsCompressible && MEDIA_IS_SKU(&pOsInterface->pOsContext->SkuTable, FtrE2ECompression))
2514             {
2515                 GmmParams.Flags.Gpu.MMC = true;
2516                 GmmParams.Flags.Info.MediaCompressed = 1;
2517                 GmmParams.Flags.Gpu.CCS = 1;
2518                 GmmParams.Flags.Gpu.RenderTarget = 1;
2519                 GmmParams.Flags.Gpu.UnifiedAuxSurface = 1;
2520 
2521                 if (pParams->CompressionMode == MOS_MMC_RC)
2522                 {
2523                     GmmParams.Flags.Info.MediaCompressed = 0;
2524                     GmmParams.Flags.Info.RenderCompressed = 1;
2525                 }
2526                 else
2527                 {
2528                     GmmParams.Flags.Info.MediaCompressed = 1;
2529                     GmmParams.Flags.Info.RenderCompressed = 0;
2530                 }
2531 
2532                 if(MEDIA_IS_SKU(&pOsInterface->pOsContext->SkuTable, FtrFlatPhysCCS))
2533                 {
2534                     GmmParams.Flags.Gpu.UnifiedAuxSurface = 0;
2535                 }
2536             }
2537             break;
2538         case MOS_TILE_X:
2539             GmmParams.Flags.Info.TiledX    = true;
2540             tileformat_linux               = I915_TILING_X;
2541             break;
2542         default:
2543             GmmParams.Flags.Info.Linear    = true;
2544             tileformat_linux               = I915_TILING_NONE;
2545     }
2546     GmmParams.Flags.Info.LocalOnly = MEDIA_IS_SKU(&pOsInterface->pOsContext->SkuTable, FtrLocalMemory);
2547 
2548     pOsResource->pGmmResInfo = pGmmResourceInfo = pOsInterface->pOsContext->pGmmClientContext->CreateResInfoObject(&GmmParams);
2549 
2550     MOS_OS_CHK_NULL(pGmmResourceInfo);
2551 
2552     switch (pGmmResourceInfo->GetTileType())
2553     {
2554         case GMM_TILED_X:
2555             tileformat = MOS_TILE_X;
2556             tileformat_linux               = I915_TILING_X;
2557             break;
2558         case GMM_TILED_Y:
2559             tileformat = MOS_TILE_Y;
2560             tileformat_linux               = I915_TILING_Y;
2561             break;
2562         case GMM_NOT_TILED:
2563             tileformat = MOS_TILE_LINEAR;
2564             tileformat_linux               = I915_TILING_NONE;
2565             break;
2566         default:
2567             tileformat = MOS_TILE_Y;
2568             tileformat_linux               = I915_TILING_Y;
2569             break;
2570     }
2571 
2572     if (pParams->TileType == MOS_TILE_Y)
2573     {
2574         pGmmResourceInfo->SetMmcMode((GMM_RESOURCE_MMC_INFO)pParams->CompressionMode, 0);
2575     }
2576 
2577     iPitch      = GFX_ULONG_CAST(pGmmResourceInfo->GetRenderPitch());
2578     iSize       = GFX_ULONG_CAST(pGmmResourceInfo->GetSizeSurface());
2579     iHeight     = pGmmResourceInfo->GetBaseHeight();
2580 
2581     MemoryPolicyParameter memPolicyPar;
2582     MOS_ZeroMemory(&memPolicyPar, sizeof(MemoryPolicyParameter));
2583 
2584     memPolicyPar.skuTable         = &pOsInterface->pOsContext->SkuTable;
2585     memPolicyPar.waTable          = &pOsInterface->pOsContext->WaTable;
2586     memPolicyPar.resInfo          = pGmmResourceInfo;
2587     memPolicyPar.resName          = pParams->pBufName;
2588     memPolicyPar.preferredMemType = pParams->dwMemType;
2589 
2590     mem_type = MemoryPolicyManager::UpdateMemoryPolicy(&memPolicyPar);
2591 
2592     // Only Linear and Y TILE supported
2593     if( tileformat_linux == I915_TILING_NONE )
2594     {
2595         bo = mos_bo_alloc(pOsInterface->pOsContext->bufmgr, bufname, iSize, 4096, mem_type);
2596     }
2597     else
2598     {
2599         bo = mos_bo_alloc_tiled(pOsInterface->pOsContext->bufmgr, bufname, iPitch, iSize/iPitch, 1, &tileformat_linux, &ulPitch, 0, mem_type);
2600         iPitch = (int32_t)ulPitch;
2601     }
2602 
2603     pOsResource->bMapped = false;
2604     if (bo)
2605     {
2606         pOsResource->Format          = pParams->Format;
2607         pOsResource->iWidth          = pParams->dwWidth;
2608         pOsResource->iHeight         = iHeight;
2609         pOsResource->iPitch          = iPitch;
2610         pOsResource->iCount          = 0;
2611         pOsResource->bufname         = bufname;
2612         pOsResource->bo              = bo;
2613         pOsResource->TileType        = tileformat;
2614         pOsResource->TileModeGMM     = (MOS_TILE_MODE_GMM)pGmmResourceInfo->GetTileModeSurfaceState();
2615         pOsResource->bGMMTileEnabled = true;
2616         pOsResource->pData           = (uint8_t *)bo->virt;  //It is useful for batch buffer to fill commands
2617         if (pParams->ResUsageType == MOS_CODEC_RESOURCE_USAGE_BEGIN_CODEC ||
2618             pParams->ResUsageType >= MOS_HW_RESOURCE_USAGE_MEDIA_BATCH_BUFFERS)
2619         {
2620             pOsResource->memObjCtrlState = MosInterface::GetCachePolicyMemoryObject(pOsInterface->pOsContext->pGmmClientContext, MOS_MP_RESOURCE_USAGE_DEFAULT);
2621             pOsResource->mocsMosResUsageType = MOS_MP_RESOURCE_USAGE_DEFAULT;
2622         }
2623         else
2624         {
2625             pOsResource->memObjCtrlState = MosInterface::GetCachePolicyMemoryObject(pOsInterface->pOsContext->pGmmClientContext, pParams->ResUsageType);
2626             pOsResource->mocsMosResUsageType = pParams->ResUsageType;
2627         }
2628 
2629         MOS_OS_VERBOSEMESSAGE("Alloc %7d bytes (%d x %d resource).",iSize, pParams->dwWidth, iHeight);
2630     }
2631     else
2632     {
2633         MOS_OS_ASSERTMESSAGE("Fail to Alloc %7d bytes (%d x %d resource).",iSize, pParams->dwWidth, pParams->dwHeight);
2634         eStatus = MOS_STATUS_NO_SPACE;
2635     }
2636 
2637     MosUtilities::m_mosMemAllocCounterGfx++;
2638     MOS_MEMNINJA_GFX_ALLOC_MESSAGE(pOsResource->pGmmResInfo, bufname, pOsInterface->Component,
2639         (uint32_t)pOsResource->pGmmResInfo->GetSizeSurface(), pParams->dwArraySize, functionName, filename, line);
2640 
2641 finish:
2642     return eStatus;
2643 }
2644 
2645 //!
2646 //! \brief    Get Resource Information
2647 //! \details  Linux get resource info
2648 //! \param    PMOS_INTERFACE pOsInterface
2649 //!           [in] Pointer to OS interface structure
2650 //! \param    PMOS_RESOURCE pOsResource
2651 //!           [in] Pointer to input OS resource
2652 //! \param    PMOS_SURFACE pResDetails
2653 //!           [out] Pointer to output resource information details
2654 //! \return   MOS_STATUS
2655 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
2656 //!
Mos_Specific_GetResourceInfo(PMOS_INTERFACE pOsInterface,PMOS_RESOURCE pOsResource,PMOS_SURFACE pResDetails)2657 MOS_STATUS Mos_Specific_GetResourceInfo(
2658     PMOS_INTERFACE              pOsInterface,
2659     PMOS_RESOURCE               pOsResource,
2660     PMOS_SURFACE                pResDetails)
2661 {
2662     GMM_RESOURCE_INFO * pGmmResourceInfo = nullptr;
2663     GMM_DISPLAY_FRAME   gmmChannel = GMM_DISPLAY_FRAME_MAX;
2664     GMM_REQ_OFFSET_INFO reqInfo[3] = {};
2665     GMM_RESOURCE_FLAG   GmmFlags = {};
2666     MOS_STATUS          eStatus;
2667 
2668     MOS_OS_FUNCTION_ENTER;
2669 
2670     eStatus = MOS_STATUS_SUCCESS;
2671 
2672     MOS_OS_CHK_NULL(pOsInterface);
2673     MOS_OS_CHK_NULL(pOsResource);
2674     MOS_OS_CHK_NULL(pResDetails);
2675 
2676     if (pOsInterface->apoMosEnabled)
2677     {
2678         return MosInterface::GetResourceInfo(pOsInterface->osStreamState, pOsResource, *pResDetails);
2679     }
2680 
2681     // Get Gmm resource info
2682     pGmmResourceInfo = (GMM_RESOURCE_INFO*)pOsResource->pGmmResInfo;
2683     MOS_OS_CHK_NULL(pGmmResourceInfo);
2684 
2685     GmmFlags = pGmmResourceInfo->GetResFlags();
2686 
2687     pResDetails->dwWidth         = GFX_ULONG_CAST(pGmmResourceInfo->GetBaseWidth());
2688     pResDetails->dwHeight        = pGmmResourceInfo->GetBaseHeight();
2689     pResDetails->dwPitch         = GFX_ULONG_CAST(pGmmResourceInfo->GetRenderPitch());
2690     pResDetails->dwSize          = GFX_ULONG_CAST(pGmmResourceInfo->GetSizeSurface());
2691     pResDetails->dwDepth         = MOS_MAX(1, pGmmResourceInfo->GetBaseDepth());
2692     pResDetails->dwLockPitch     = GFX_ULONG_CAST(pGmmResourceInfo->GetRenderPitch());
2693     if (GFX_GET_CURRENT_RENDERCORE(pOsInterface->pfnGetGmmClientContext(pOsInterface)->GetPlatformInfo().Platform) < IGFX_GEN8_CORE)
2694     {
2695         pResDetails->bArraySpacing = pGmmResourceInfo->IsArraySpacingSingleLod();
2696     }
2697     if (GFX_GET_CURRENT_RENDERCORE(pOsInterface->pfnGetGmmClientContext(pOsInterface)->GetPlatformInfo().Platform) >= IGFX_GEN9_CORE)
2698     {
2699         pResDetails->dwQPitch = pGmmResourceInfo->GetQPitch();
2700     }
2701 
2702     pResDetails->bCompressible   = GmmFlags.Gpu.MMC ?
2703         (pGmmResourceInfo->GetMmcHint(0) == GMM_MMC_HINT_ON) : false;
2704     pResDetails->bIsCompressed   = pGmmResourceInfo->IsMediaMemoryCompressed(0);
2705     pResDetails->CompressionMode = (MOS_RESOURCE_MMC_MODE)pGmmResourceInfo->GetMmcMode(0);
2706 
2707     if (0 == pResDetails->dwPitch)
2708     {
2709         MOS_OS_ASSERTMESSAGE("Pitch from GmmResource is 0, unexpected.");
2710         return MOS_STATUS_INVALID_PARAMETER;
2711     }
2712     // check resource's tile type
2713     pResDetails->TileModeGMM       = (MOS_TILE_MODE_GMM)pGmmResourceInfo->GetTileModeSurfaceState();
2714     pResDetails->bGMMTileEnabled   = true;
2715     switch (pGmmResourceInfo->GetTileType())
2716     {
2717     case GMM_TILED_Y:
2718           if (GmmFlags.Info.TiledYf)
2719           {
2720               pResDetails->TileType = MOS_TILE_YF;
2721           }
2722           else if (GmmFlags.Info.TiledYs)
2723           {
2724               pResDetails->TileType = MOS_TILE_YS;
2725           }
2726           else
2727           {
2728               pResDetails->TileType = MOS_TILE_Y;
2729           }
2730           break;
2731     case GMM_TILED_X:
2732           pResDetails->TileType = MOS_TILE_X;
2733           break;
2734     case GMM_NOT_TILED:
2735           pResDetails->TileType = MOS_TILE_LINEAR;
2736           break;
2737     default:
2738           pResDetails->TileType = MOS_TILE_Y;
2739           break;
2740     }
2741     pResDetails->Format   = pOsResource->Format;
2742 
2743     MOS_ZeroMemory(reqInfo, sizeof(reqInfo));
2744     gmmChannel = GMM_DISPLAY_BASE;
2745     // Get the base offset of the surface (plane Y)
2746     reqInfo[2].ReqRender = true;
2747     reqInfo[2].Plane     = GMM_PLANE_Y;
2748     reqInfo[2].Frame     = gmmChannel;
2749     reqInfo[2].CubeFace  = __GMM_NO_CUBE_MAP;
2750     reqInfo[2].ArrayIndex = 0;
2751     pGmmResourceInfo->GetOffset(reqInfo[2]);
2752     pResDetails->RenderOffset.YUV.Y.BaseOffset = reqInfo[2].Render.Offset;
2753 
2754     // Get U/UV plane information (plane offset, X/Y offset)
2755     reqInfo[0].ReqRender = true;
2756     reqInfo[0].Plane     = GMM_PLANE_U;
2757     reqInfo[0].Frame     = gmmChannel;
2758     reqInfo[0].CubeFace  = __GMM_NO_CUBE_MAP;
2759     reqInfo[0].ArrayIndex = 0;
2760     pGmmResourceInfo->GetOffset(reqInfo[0]);
2761 
2762     pResDetails->RenderOffset.YUV.U.BaseOffset = reqInfo[0].Render.Offset;
2763     pResDetails->RenderOffset.YUV.U.XOffset    = reqInfo[0].Render.XOffset;
2764     pResDetails->RenderOffset.YUV.U.YOffset    = reqInfo[0].Render.YOffset;
2765 
2766     // Get V plane information (plane offset, X/Y offset)
2767     reqInfo[1].ReqRender = true;
2768     reqInfo[1].Plane     = GMM_PLANE_V;
2769     reqInfo[1].Frame     = gmmChannel;
2770     reqInfo[1].CubeFace  = __GMM_NO_CUBE_MAP;
2771     reqInfo[1].ArrayIndex = 0;
2772     pGmmResourceInfo->GetOffset(reqInfo[1]);
2773 
2774     pResDetails->RenderOffset.YUV.V.BaseOffset = reqInfo[1].Render.Offset;
2775     pResDetails->RenderOffset.YUV.V.XOffset    = reqInfo[1].Render.XOffset;
2776     pResDetails->RenderOffset.YUV.V.YOffset    = reqInfo[1].Render.YOffset;
2777 
2778 finish:
2779     return eStatus;
2780 }
2781 
2782 //!
2783 //! \brief    Free the resource
2784 //! \details  Free the allocated resource
2785 //! \param    PMOS_INTERFACE pOsInterface
2786 //!           [in] Pointer to OS interface structure
2787 //! \param    PMOS_RESOURCE pOsResource
2788 //!           [in] Pointer to input OS resource
2789 //! \return   void
2790 //!
Mos_Specific_FreeResource(PMOS_INTERFACE pOsInterface,PCCHAR functionName,PCCHAR filename,int32_t line,PMOS_RESOURCE pOsResource)2791 void Mos_Specific_FreeResource(
2792     PMOS_INTERFACE   pOsInterface,
2793 #if MOS_MESSAGES_ENABLED
2794     PCCHAR           functionName,
2795     PCCHAR           filename,
2796     int32_t          line,
2797 #endif // MOS_MESSAGES_ENABLED
2798     PMOS_RESOURCE    pOsResource)
2799 {
2800     MOS_OS_FUNCTION_ENTER;
2801 
2802     if( nullptr == pOsInterface )
2803     {
2804         MOS_OS_ASSERTMESSAGE("input parameter pOsInterface is NULL.");
2805         return;
2806     }
2807 
2808     if( nullptr == pOsResource )
2809     {
2810         MOS_OS_ASSERTMESSAGE("input parameter pOsResource is NULL.");
2811         return;
2812     }
2813 
2814     bool osContextValid = false;
2815     if (pOsInterface->osContextPtr != nullptr)
2816     {
2817         if (pOsInterface->osContextPtr->GetOsContextValid() == true)
2818         {
2819             osContextValid = true;
2820         }
2821     }
2822 
2823     if (pOsInterface->apoMosEnabled)
2824     {
2825         MosInterface::FreeResource(
2826             pOsInterface->osStreamState,
2827             pOsResource,
2828             0
2829 #if MOS_MESSAGES_ENABLED
2830             ,
2831             functionName,
2832             filename,
2833             line
2834 #endif
2835         );
2836 
2837         return;
2838     }
2839 
2840     if ((pOsInterface->modulizedMosEnabled)
2841      && (!pOsResource->bConvertedFromDDIResource)
2842      && (osContextValid == true)
2843      && (!Mos_Solo_IsEnabled(nullptr))
2844      && (pOsResource->pGfxResource))
2845     {
2846         if (pOsInterface->osContextPtr == nullptr)
2847         {
2848             MOS_OS_ASSERTMESSAGE("invalid osContextPtr.");
2849             return;
2850         }
2851 
2852         GraphicsResource::SetMemAllocCounterGfx(MosUtilities::m_mosMemAllocCounterGfx);
2853 
2854         if (pOsResource && pOsResource->pGfxResource)
2855         {
2856             pOsResource->pGfxResource->Free(pOsInterface->osContextPtr);
2857         }
2858         else
2859         {
2860             MOS_OS_VERBOSEMESSAGE("Received an empty Graphics Resource, skip free");
2861         }
2862         MOS_Delete(pOsResource->pGfxResource);
2863         pOsResource->pGfxResource = nullptr;
2864 
2865         MosUtilities::m_mosMemAllocCounterGfx = GraphicsResource::GetMemAllocCounterGfx();
2866         MOS_MEMNINJA_GFX_FREE_MESSAGE(pOsResource->pGmmResInfo, functionName, filename, line);
2867         MOS_ZeroMemory(pOsResource, sizeof(*pOsResource));
2868         return;
2869     }
2870 
2871     if (pOsResource && pOsResource->bo)
2872     {
2873         OsContextSpecific *osCtx = static_cast<OsContextSpecific *>(pOsInterface->osContextPtr);
2874         if(osCtx == nullptr)
2875         {
2876             MOS_OS_ASSERTMESSAGE("osCtx is nullptr!");
2877             return;
2878         }
2879         else
2880         {
2881             AuxTableMgr *auxTableMgr = osCtx->GetAuxTableMgr();
2882 
2883             // Unmap Resource from Aux Table
2884             if (auxTableMgr)
2885             {
2886                 auxTableMgr->UnmapResource(pOsResource->pGmmResInfo, pOsResource->bo);
2887             }
2888         }
2889 
2890         mos_bo_unreference((MOS_LINUX_BO *)(pOsResource->bo));
2891 
2892         if ( pOsInterface->pOsContext != nullptr && pOsInterface->pOsContext->contextOffsetList.size())
2893         {
2894           MOS_CONTEXT *pOsCtx = pOsInterface->pOsContext;
2895           auto item_ctx = pOsCtx->contextOffsetList.begin();
2896 
2897           for (;item_ctx != pOsCtx->contextOffsetList.end();)
2898           {
2899              if (item_ctx->target_bo == pOsResource->bo)
2900              {
2901                 item_ctx = pOsCtx->contextOffsetList.erase(item_ctx);
2902              }
2903              else
2904              {
2905                 item_ctx++;
2906              }
2907           }
2908         }
2909 
2910         pOsResource->bo = nullptr;
2911         if (pOsResource->pGmmResInfo != nullptr &&
2912             pOsInterface->pOsContext != nullptr &&
2913             pOsInterface->pOsContext->pGmmClientContext != nullptr)
2914         {
2915             MosUtilities::m_mosMemAllocCounterGfx--;
2916             MOS_MEMNINJA_GFX_FREE_MESSAGE(pOsResource->pGmmResInfo, functionName, filename, line);
2917 
2918             pOsInterface->pOsContext->pGmmClientContext->DestroyResInfoObject(pOsResource->pGmmResInfo);
2919             pOsResource->pGmmResInfo = nullptr;
2920         }
2921     }
2922 
2923 }
2924 
2925 //!
2926 //! \brief    Free OS resource
2927 //! \details  Free OS resource
2928 //! \param    PMOS_INTERFACE pOsInterface
2929 //!           [in] OS Interface
2930 //! \param    PMOS_RESOURCE pOsResource
2931 //!           [in/out] OS Resource to be freed
2932 //! \param    uint32_t uiFlag
2933 //!           [in] Flag to free resources. This one is useless on Linux, just for compatibility.
2934 //! \return   void
2935 //!
Mos_Specific_FreeResourceWithFlag(PMOS_INTERFACE pOsInterface,PMOS_RESOURCE pOsResource,PCCHAR functionName,PCCHAR filename,int32_t line,uint32_t uiFlag)2936 void Mos_Specific_FreeResourceWithFlag(
2937     PMOS_INTERFACE    pOsInterface,
2938     PMOS_RESOURCE     pOsResource,
2939 #if MOS_MESSAGES_ENABLED
2940     PCCHAR            functionName,
2941     PCCHAR            filename,
2942     int32_t           line,
2943 #endif // MOS_MESSAGES_ENABLED
2944     uint32_t          uiFlag)
2945 {
2946     MOS_UNUSED(uiFlag);
2947 
2948     if (pOsInterface == nullptr ||
2949         pOsResource == nullptr)
2950     {
2951         return;
2952     }
2953 
2954 #if MOS_MESSAGES_ENABLED
2955     Mos_Specific_FreeResource(pOsInterface, functionName, filename, line, pOsResource);
2956 #else
2957     Mos_Specific_FreeResource(pOsInterface, pOsResource);
2958 #endif // MOS_MESSAGES_ENABLED
2959 }
2960 
2961 //!
2962 //! \brief    Locks Resource request
2963 //! \details  Locks Resource request
2964 //! \param    PMOS_INTERFACE pOsInterface
2965 //!           [in] pointer to OS Interface structure
2966 //! \param    PMOS_RESOURCE pOsResource
2967 //!           [in/out] Resource object
2968 //! \param    PMOS_LOCK_PARAMS pLockFlags
2969 //!           [in] Lock Flags
2970 //! \return   MOS_STATUS
2971 //!           MOS_STATUS_SUCCESS if successful
2972 //!
Mos_Specific_LockSyncRequest(PMOS_INTERFACE pOsInterface,PMOS_RESOURCE pOsResource,PMOS_LOCK_PARAMS pLockFlags)2973 MOS_STATUS Mos_Specific_LockSyncRequest(
2974     PMOS_INTERFACE        pOsInterface,
2975     PMOS_RESOURCE         pOsResource,
2976     PMOS_LOCK_PARAMS      pLockFlags)
2977 {
2978     MOS_UNUSED(pOsInterface);
2979     MOS_UNUSED(pOsInterface);
2980     MOS_UNUSED(pOsInterface);
2981 
2982     return MOS_STATUS_SUCCESS;
2983 }
2984 
2985 //!
2986 //! \brief    Lock resource
2987 //! \details  Lock allocated resource
2988 //! \param    PMOS_INTERFACE pOsInterface
2989 //!           [in] Pointer to OS interface structure
2990 //! \param    PMOS_RESOURCE pOsResource
2991 //!           [in] Pointer to input OS resource
2992 //! \param    PMOS_LOCK_PARAMS pLockFlags
2993 //!           [in] Lock Flags - MOS_LOCKFLAG_* flags
2994 //! \return   void *
2995 //!
Mos_Specific_LockResource(PMOS_INTERFACE pOsInterface,PMOS_RESOURCE pOsResource,PMOS_LOCK_PARAMS pLockFlags)2996 void  *Mos_Specific_LockResource(
2997     PMOS_INTERFACE     pOsInterface,
2998     PMOS_RESOURCE      pOsResource,
2999     PMOS_LOCK_PARAMS   pLockFlags)
3000 {
3001     void                *pData = nullptr;
3002     MOS_OS_CONTEXT      *pContext = nullptr;
3003 
3004     MOS_OS_FUNCTION_ENTER;
3005 
3006     MOS_OS_ASSERT(pOsInterface);
3007     MOS_OS_ASSERT(pOsResource);
3008     MOS_OS_ASSERT(pOsInterface->pOsContext);
3009 
3010     if( nullptr == pOsInterface )
3011     {
3012         MOS_OS_ASSERTMESSAGE("input parameter pOsInterface is NULL.");
3013         return nullptr;
3014     }
3015 
3016     if( nullptr == pOsResource)
3017     {
3018         MOS_OS_ASSERTMESSAGE("input parameter pOsInterface is NULL.");
3019         return nullptr;
3020     }
3021 
3022     bool osContextValid = false;
3023     if (pOsInterface->osContextPtr != nullptr)
3024     {
3025         if (pOsInterface->osContextPtr->GetOsContextValid() == true)
3026         {
3027             osContextValid = true;
3028         }
3029     }
3030 
3031     if (pOsInterface->apoMosEnabled)
3032     {
3033         return MosInterface::LockMosResource(pOsInterface->osStreamState, pOsResource, pLockFlags);
3034     }
3035 
3036     if ((pOsInterface->modulizedMosEnabled)
3037        && (!pOsResource->bConvertedFromDDIResource)
3038        && (osContextValid == true)
3039        && (!Mos_Solo_IsEnabled(nullptr))
3040        && (pOsResource->pGfxResource))
3041     {
3042         if (nullptr == pOsInterface->osContextPtr)
3043         {
3044             MOS_OS_ASSERTMESSAGE("invalid osContextPtr, skip lock");
3045         }
3046 
3047         if (pOsResource->pGfxResource)
3048         {
3049             GraphicsResource::LockParams params(pLockFlags);
3050             pData = pOsResource->pGfxResource->Lock(pOsInterface->osContextPtr, params);
3051         }
3052         else
3053         {
3054             MOS_OS_ASSERTMESSAGE("Received an empty Graphics Resource, skip lock");
3055         }
3056         return pData;
3057     }
3058 
3059     pContext = pOsInterface->pOsContext;
3060     if (pOsResource && pOsResource->bo && pOsResource->pGmmResInfo)
3061     {
3062         MOS_LINUX_BO *bo = pOsResource->bo;
3063         GMM_RESOURCE_FLAG GmmFlags;
3064 
3065         MOS_ZeroMemory(&GmmFlags, sizeof(GmmFlags));
3066         GmmFlags = pOsResource->pGmmResInfo->GetResFlags();
3067 
3068         // Do decompression for a compressed surface before lock
3069         if (!pLockFlags->NoDecompress &&
3070             (((GmmFlags.Gpu.MMC || GmmFlags.Gpu.CCS) && GmmFlags.Gpu.UnifiedAuxSurface)||
3071              pOsResource->pGmmResInfo->IsMediaMemoryCompressed(0)))
3072         {
3073             PMOS_CONTEXT pOsContext = pOsInterface->pOsContext;
3074 
3075             MOS_OS_ASSERT(pOsContext);
3076             MOS_OS_ASSERT(pOsContext->ppMediaMemDecompState);
3077             MOS_OS_ASSERT(pOsContext->pfnMemoryDecompress);
3078             pOsContext->pfnMemoryDecompress(pOsContext, pOsResource);
3079         }
3080 
3081         if(false == pOsResource->bMapped)
3082         {
3083             if (pContext->bIsAtomSOC)
3084             {
3085                 mos_gem_bo_map_gtt(bo);
3086             }
3087             else
3088             {
3089                 if (pOsResource->TileType != MOS_TILE_LINEAR && !pLockFlags->TiledAsTiled)
3090                 {
3091                     if (pContext->bUseSwSwizzling)
3092                     {
3093                         mos_bo_map(bo, (OSKM_LOCKFLAG_WRITEONLY&pLockFlags->WriteOnly));
3094                         pOsResource->MmapOperation = MOS_MMAP_OPERATION_MMAP;
3095                         if (pOsResource->pSystemShadow == nullptr)
3096                         {
3097                             pOsResource->pSystemShadow = (uint8_t *)MOS_AllocMemory(bo->size);
3098                             MOS_OS_CHECK_CONDITION((pOsResource->pSystemShadow == nullptr), "Failed to allocate shadow surface", nullptr);
3099                         }
3100                         if (pOsResource->pSystemShadow)
3101                         {
3102                             int32_t flags = pContext->bTileYFlag ? 0 : 1;
3103                             MOS_OS_CHECK_CONDITION((pOsResource->TileType != MOS_TILE_Y), "Unsupported tile type", nullptr);
3104                             MOS_OS_CHECK_CONDITION((bo->size <= 0 || pOsResource->iPitch <= 0), "Invalid BO size or pitch", nullptr);
3105                             Mos_SwizzleData((uint8_t*)bo->virt, pOsResource->pSystemShadow,
3106                                     MOS_TILE_Y, MOS_TILE_LINEAR, bo->size / pOsResource->iPitch, pOsResource->iPitch, flags);
3107                         }
3108                     }
3109                     else
3110                     {
3111                         mos_gem_bo_map_gtt(bo);
3112                         pOsResource->MmapOperation = MOS_MMAP_OPERATION_MMAP_GTT;
3113                     }
3114                 }
3115                 else if (pLockFlags->Uncached)
3116                 {
3117                     mos_gem_bo_map_wc(bo);
3118                     pOsResource->MmapOperation = MOS_MMAP_OPERATION_MMAP_WC;
3119                 }
3120                 else
3121                 {
3122                     mos_bo_map(bo, (OSKM_LOCKFLAG_WRITEONLY&pLockFlags->WriteOnly));
3123                     pOsResource->MmapOperation = MOS_MMAP_OPERATION_MMAP;
3124                 }
3125             }
3126             pOsResource->pData   = pOsResource->pSystemShadow ? pOsResource->pSystemShadow : (uint8_t*)bo->virt;
3127             pOsResource->bMapped = true;
3128         }
3129 
3130         pData = pOsResource->pData;
3131 
3132     }
3133 
3134 finish:
3135     MOS_OS_ASSERT(pData);
3136     return pData;
3137 }
3138 
3139 //!
3140 //! \brief    Unlock resource
3141 //! \details  Unlock the locked resource
3142 //! \param    PMOS_INTERFACE pOsInterface
3143 //!           [in] Pointer to OS interface structure
3144 //! \param    PMOS_RESOURCE pOsResource
3145 //!           [in] Pointer to input OS resource
3146 //! \return   MOS_STATUS
3147 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
3148 //!
Mos_Specific_UnlockResource(PMOS_INTERFACE pOsInterface,PMOS_RESOURCE pOsResource)3149 MOS_STATUS Mos_Specific_UnlockResource(
3150     PMOS_INTERFACE       pOsInterface,
3151     PMOS_RESOURCE        pOsResource)
3152 {
3153     MOS_STATUS           eStatus;
3154 
3155     eStatus = MOS_STATUS_SUCCESS;
3156 
3157     MOS_OS_CONTEXT      *pContext = nullptr;
3158 
3159     MOS_OS_FUNCTION_ENTER;
3160 
3161     MOS_OS_CHK_NULL(pOsInterface);
3162     MOS_OS_CHK_NULL(pOsResource);
3163     MOS_OS_CHK_NULL(pOsInterface->pOsContext);
3164 
3165     if (pOsInterface->apoMosEnabled)
3166     {
3167         return MosInterface::UnlockMosResource(pOsInterface->osStreamState, pOsResource);
3168     }
3169 
3170     bool osContextValid;
3171     osContextValid = false;
3172     if (pOsInterface->osContextPtr != nullptr)
3173     {
3174         if (pOsInterface->osContextPtr->GetOsContextValid() == true)
3175         {
3176             osContextValid = true;
3177         }
3178     }
3179 
3180     if ((pOsInterface->modulizedMosEnabled)
3181      && (!pOsResource->bConvertedFromDDIResource)
3182      && (osContextValid == true)
3183      && (!Mos_Solo_IsEnabled(nullptr))
3184      && (pOsResource->pGfxResource))
3185     {
3186         if (nullptr == pOsInterface->osContextPtr)
3187         {
3188             MOS_OS_ASSERTMESSAGE("invalid osContextPtr, skip lock");
3189         }
3190 
3191         if (pOsResource->pGfxResource)
3192         {
3193             eStatus = pOsResource->pGfxResource->Unlock(pOsInterface->osContextPtr);
3194         }
3195         else
3196         {
3197             MOS_OS_VERBOSEMESSAGE("Received an empty Graphics Resource, skip unlock");
3198         }
3199         return eStatus;
3200     }
3201 
3202     pContext = pOsInterface->pOsContext;
3203 
3204     if(pOsResource->bo)
3205     {
3206         if(true == pOsResource->bMapped)
3207         {
3208            if (pContext->bIsAtomSOC)
3209            {
3210                mos_gem_bo_unmap_gtt(pOsResource->bo);
3211            }
3212            else
3213            {
3214                if (pOsResource->pSystemShadow)
3215                {
3216                    int32_t flags = pContext->bTileYFlag ? 0 : 1;
3217                    Mos_SwizzleData(pOsResource->pSystemShadow, (uint8_t*)pOsResource->bo->virt,
3218                            MOS_TILE_LINEAR, MOS_TILE_Y, pOsResource->bo->size / pOsResource->iPitch, pOsResource->iPitch, flags);
3219                    MOS_FreeMemory(pOsResource->pSystemShadow);
3220                    pOsResource->pSystemShadow = nullptr;
3221                }
3222 
3223                switch(pOsResource->MmapOperation)
3224                {
3225                    case MOS_MMAP_OPERATION_MMAP_GTT:
3226                         mos_gem_bo_unmap_gtt(pOsResource->bo);
3227                         break;
3228                    case MOS_MMAP_OPERATION_MMAP_WC:
3229                         mos_gem_bo_unmap_wc(pOsResource->bo);
3230                         break;
3231                    case MOS_MMAP_OPERATION_MMAP:
3232                         mos_bo_unmap(pOsResource->bo);
3233                         break;
3234                    default:
3235                         MOS_OS_ASSERTMESSAGE("Invalid mmap operation type");
3236                         break;
3237                }
3238            }
3239            pOsResource->bo->virt = nullptr;
3240            pOsResource->bMapped  = false;
3241         }
3242         pOsResource->pData       = nullptr;
3243     }
3244 
3245 finish:
3246     return eStatus;
3247 }
3248 
3249 //!
3250 //! \brief    Decompress Resource
3251 //! \details  Decompress Resource
3252 //! \param    PMOS_INTERFACE pOsInterface
3253 //!           [in] pointer to OS Interface structure
3254 //! \param    PMOS_RESOURCE pOsResource
3255 //!           [in/out] Resource object
3256 //! \return   MOS_STATUS
3257 //!           MOS_STATUS_SUCCESS if successful
3258 //!
Mos_Specific_DecompResource(PMOS_INTERFACE pOsInterface,PMOS_RESOURCE pOsResource)3259 MOS_STATUS Mos_Specific_DecompResource(
3260     PMOS_INTERFACE        pOsInterface,
3261     PMOS_RESOURCE         pOsResource)
3262 {
3263     MOS_STATUS              eStatus = MOS_STATUS_UNKNOWN;
3264     MOS_OS_CONTEXT          *pContext = nullptr;
3265 
3266     //---------------------------------------
3267     MOS_OS_CHK_NULL(pOsInterface);
3268     MOS_OS_CHK_NULL(pOsResource);
3269     MOS_OS_CHK_NULL(pOsInterface->pOsContext);
3270     //---------------------------------------
3271 
3272     if (pOsInterface->apoMosEnabled)
3273     {
3274         return MosInterface::DecompResource(pOsInterface->osStreamState, pOsResource);
3275     }
3276 
3277     pContext = pOsInterface->pOsContext;
3278 
3279     if (pOsResource && pOsResource->bo && pOsResource->pGmmResInfo)
3280     {
3281         MOS_LINUX_BO *bo = pOsResource->bo;
3282         if (pOsResource->pGmmResInfo->IsMediaMemoryCompressed(0))
3283         {
3284             PMOS_CONTEXT pOsContext = pOsInterface->pOsContext;
3285 
3286             MOS_OS_CHK_NULL(pOsContext);
3287             MOS_OS_CHK_NULL(pOsContext->ppMediaMemDecompState);
3288             MOS_OS_CHK_NULL(pOsContext->pfnMemoryDecompress);
3289             pOsContext->pfnMemoryDecompress(pOsContext, pOsResource);
3290         }
3291     }
3292 
3293     eStatus = MOS_STATUS_SUCCESS;
3294 
3295 finish:
3296     return eStatus;
3297 }
3298 
3299 //!
3300 //! \brief    Decompress and Copy Resource to Another Buffer
3301 //! \details  Decompress and Copy Resource to Another Buffer
3302 //! \param    PMOS_INTERFACE pOsInterface
3303 //!           [in] pointer to OS Interface structure
3304 //! \param    PMOS_RESOURCE inputOsResource
3305 //!           [in] Input Resource object
3306 //! \param    PMOS_RESOURCE outputOsResource
3307 //!           [out] output Resource object
3308 //! \param    [in] bOutputCompressed
3309 //!            true means apply compression on output surface, else output uncompressed surface
3310 //! \return   MOS_STATUS
3311 //!           MOS_STATUS_SUCCESS if successful
3312 //!
Mos_Specific_DoubleBufferCopyResource(PMOS_INTERFACE osInterface,PMOS_RESOURCE inputOsResource,PMOS_RESOURCE outputOsResource,bool bOutputCompressed)3313 MOS_STATUS Mos_Specific_DoubleBufferCopyResource(
3314     PMOS_INTERFACE        osInterface,
3315     PMOS_RESOURCE         inputOsResource,
3316     PMOS_RESOURCE         outputOsResource,
3317     bool                  bOutputCompressed)
3318 {
3319     MOS_STATUS              eStatus = MOS_STATUS_UNKNOWN;
3320     MOS_OS_CONTEXT          *pContext = nullptr;
3321 
3322     //---------------------------------------
3323     MOS_OS_CHK_NULL(osInterface);
3324     MOS_OS_CHK_NULL(inputOsResource);
3325     MOS_OS_CHK_NULL(outputOsResource);
3326     //---------------------------------------
3327 
3328     if (osInterface->apoMosEnabled)
3329     {
3330         return MosInterface::DoubleBufferCopyResource(osInterface->osStreamState, inputOsResource, outputOsResource, bOutputCompressed);
3331     }
3332 
3333     pContext = osInterface->pOsContext;
3334 
3335     if (inputOsResource && inputOsResource->bo && inputOsResource->pGmmResInfo &&
3336         outputOsResource && outputOsResource->bo && outputOsResource->pGmmResInfo)
3337     {
3338         // Double Buffer Copy can support any tile status surface with/without compression
3339         pContext->pfnMediaMemoryCopy(pContext, inputOsResource, outputOsResource, bOutputCompressed);
3340     }
3341 
3342     eStatus = MOS_STATUS_SUCCESS;
3343 
3344 finish:
3345     return eStatus;
3346 }
3347 
3348 //!
3349 //! \brief    Decompress and Copy Resource to Another Buffer
3350 //! \details  Decompress and Copy Resource to Another Buffer
3351 //! \param    PMOS_INTERFACE pOsInterface
3352 //!           [in] pointer to OS Interface structure
3353 //! \param    PMOS_RESOURCE inputOsResource
3354 //!           [in] Input Resource object
3355 //! \param    PMOS_RESOURCE outputOsResource
3356 //!           [out] output Resource object
3357 //! \param    [in] copyWidth
3358 //!            The 2D surface Width
3359 //! \param    [in] copyHeight
3360 //!            The 2D surface height
3361 //! \param    [in] copyInputOffset
3362 //!            The offset of copied surface from
3363 //! \param    [in] copyOutputOffset
3364 //!            The offset of copied to
3365 //! \param    [in] bOutputCompressed
3366 //!            true means apply compression on output surface, else output uncompressed surface
3367 //! \return   MOS_STATUS
3368 //!           MOS_STATUS_SUCCESS if successful
3369 //!
Mos_Specific_MediaCopyResource2D(PMOS_INTERFACE osInterface,PMOS_RESOURCE inputOsResource,PMOS_RESOURCE outputOsResource,uint32_t copyWidth,uint32_t copyHeight,uint32_t copyInputOffset,uint32_t copyOutputOffset,uint32_t bpp,bool bOutputCompressed)3370 MOS_STATUS Mos_Specific_MediaCopyResource2D(
3371     PMOS_INTERFACE        osInterface,
3372     PMOS_RESOURCE         inputOsResource,
3373     PMOS_RESOURCE         outputOsResource,
3374     uint32_t              copyWidth,
3375     uint32_t              copyHeight,
3376     uint32_t              copyInputOffset,
3377     uint32_t              copyOutputOffset,
3378     uint32_t              bpp,
3379     bool                  bOutputCompressed)
3380 {
3381     MOS_STATUS              eStatus = MOS_STATUS_UNKNOWN;
3382     MOS_OS_CONTEXT          *pContext = nullptr;
3383 
3384     //---------------------------------------
3385     MOS_OS_CHK_NULL(osInterface);
3386     MOS_OS_CHK_NULL(inputOsResource);
3387     MOS_OS_CHK_NULL(outputOsResource);
3388     //---------------------------------------
3389 
3390     if (osInterface->apoMosEnabled)
3391     {
3392         return MosInterface::MediaCopyResource2D(osInterface->osStreamState, inputOsResource, outputOsResource,
3393             copyWidth, copyHeight, copyInputOffset, copyOutputOffset, bpp, bOutputCompressed);
3394     }
3395 
3396     pContext = osInterface->pOsContext;
3397 
3398     if (inputOsResource && inputOsResource->bo && inputOsResource->pGmmResInfo &&
3399         outputOsResource && outputOsResource->bo && outputOsResource->pGmmResInfo)
3400     {
3401         // Double Buffer Copy can support any tile status surface with/without compression
3402         pContext->pfnMediaMemoryCopy2D(pContext, inputOsResource, outputOsResource, copyWidth, copyHeight, copyInputOffset, copyOutputOffset, bpp, bOutputCompressed);
3403     }
3404 
3405     eStatus = MOS_STATUS_SUCCESS;
3406 
3407 finish:
3408     return eStatus;
3409 }
3410 
3411 //!
3412 //! \brief    Get Mos Context
3413 //! \details  Get Mos Context info
3414 //! \param    PMOS_INTERFACE pOsInterface
3415 //!           [in] Pointer to OS interface structure
3416 //! \param    mosContext void **
3417 //!           [out] pointer of mos_context
3418 //! \return   MOS_STATUS
3419 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
3420 //!
Mos_Specific_GetMosContext(PMOS_INTERFACE osInterface,PMOS_CONTEXT * mosContext)3421 MOS_STATUS Mos_Specific_GetMosContext(
3422         PMOS_INTERFACE        osInterface,
3423         PMOS_CONTEXT*         mosContext)
3424 {
3425     MOS_OS_CHK_NULL_RETURN(osInterface);
3426     if (osInterface->apoMosEnabled)
3427     {
3428         void *apo_mos_context = nullptr;
3429         MOS_OS_CHK_STATUS_RETURN(MosInterface::GetperStreamParameters(osInterface->osStreamState, &apo_mos_context));
3430         *mosContext = (PMOS_CONTEXT)apo_mos_context;
3431     }
3432     else
3433     {
3434         *mosContext = (PMOS_CONTEXT)osInterface->pOsContext;
3435     }
3436 
3437     return MOS_STATUS_SUCCESS;
3438 }
3439 
3440 //!
3441 //! \brief    Set patch entry
3442 //! \details  Sets the patch entry in MS's patch list
3443 //! \param    PMOS_INTERFACE pOsInterface
3444 //!           [in] Pointer to OS interface structure
3445 //! \param    PMOS_PATCH_ENTRY_PARAMS pParams
3446 //!           [in] patch entry params
3447 //! \return   MOS_STATUS
3448 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
3449 //!
Mos_Specific_SetPatchEntry(PMOS_INTERFACE pOsInterface,PMOS_PATCH_ENTRY_PARAMS pParams)3450 MOS_STATUS Mos_Specific_SetPatchEntry(
3451     PMOS_INTERFACE              pOsInterface,
3452     PMOS_PATCH_ENTRY_PARAMS     pParams)
3453 {
3454     MOS_OS_FUNCTION_ENTER;
3455 
3456     MOS_OS_CHK_NULL_RETURN(pOsInterface);
3457     MOS_OS_CHK_NULL_RETURN(pParams);
3458 
3459 #if (_DEBUG || _RELEASE_INTERNAL)
3460     if (!pParams->bUpperBoundPatch && pParams->presResource)
3461     {
3462         uint32_t handle = pParams->presResource->bo?pParams->presResource->bo->handle:0;
3463         uint32_t eventData[] = {handle, pParams->uiResourceOffset,
3464                                 pParams->uiPatchOffset, pParams->bWrite,
3465                                 pParams->HwCommandType, pParams->forceDwordOffset,
3466                                 pParams->patchType};
3467         MOS_TraceEventExt(EVENT_RESOURCE_PATCH, EVENT_TYPE_INFO2,
3468                           &eventData, sizeof(eventData),
3469                           nullptr, 0);
3470     }
3471 #endif
3472     if (pOsInterface->apoMosEnabled)
3473     {
3474         return MosInterface::SetPatchEntry(pOsInterface->osStreamState, pParams);
3475     }
3476 
3477     if (pOsInterface->modularizedGpuCtxEnabled && !Mos_Solo_IsEnabled(nullptr))
3478     {
3479         auto gpuContext = Linux_GetGpuContext(pOsInterface, pOsInterface->CurrentGpuContextHandle);
3480         MOS_OS_CHK_NULL_RETURN(gpuContext);
3481 
3482         return (gpuContext->SetPatchEntry(pOsInterface, pParams));
3483     }
3484 
3485     PMOS_OS_CONTEXT         pOsContext;
3486     MOS_OS_GPU_CONTEXT      *pOsGpuContext;
3487     PPATCHLOCATIONLIST      pPatchList;
3488     MOS_STATUS              eStatus = MOS_STATUS_SUCCESS;
3489 
3490     pOsContext      = pOsInterface->pOsContext;
3491     pOsGpuContext   = &pOsContext->OsGpuContext[pOsInterface->CurrentGpuContextOrdinal];
3492     pPatchList      = pOsGpuContext->pPatchLocationList;
3493 
3494     pPatchList[pOsGpuContext->uiCurrentNumPatchLocations].AllocationIndex     = pParams->uiAllocationIndex;
3495     pPatchList[pOsGpuContext->uiCurrentNumPatchLocations].AllocationOffset    = pParams->uiResourceOffset;
3496     pPatchList[pOsGpuContext->uiCurrentNumPatchLocations].PatchOffset         = pParams->uiPatchOffset;
3497     pPatchList[pOsGpuContext->uiCurrentNumPatchLocations].uiWriteOperation    = pParams->bWrite ? true : false;
3498 
3499     if (pOsInterface->osCpInterface &&
3500         pOsInterface->osCpInterface->IsHMEnabled())
3501     {
3502         pOsInterface->osCpInterface->RegisterPatchForHM(
3503             (uint32_t*)(pParams->cmdBufBase + pParams->uiPatchOffset),
3504             pParams->bWrite,
3505             pParams->HwCommandType,
3506             pParams->forceDwordOffset,
3507             pParams->presResource,
3508             &pPatchList[pOsGpuContext->uiCurrentNumPatchLocations]);
3509     }
3510 
3511     pOsGpuContext->uiCurrentNumPatchLocations++;
3512 
3513     return eStatus;
3514 }
3515 
3516 //!
3517 //! \brief    Update resource usage type
3518 //! \details  update the resource usage for cache policy
3519 //! \param    PMOS_RESOURCE pOsResource
3520 //!           [in/out] Pointer to OS Resource
3521 //! \param    MOS_HW_RESOURCE_DEF resUsageType
3522 //!           [in] resosuce usage type
3523 //! \return   MOS_STATUS
3524 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
3525 //!
Mos_Specific_UpdateResourceUsageType(PMOS_RESOURCE pOsResource,MOS_HW_RESOURCE_DEF resUsageType)3526 MOS_STATUS Mos_Specific_UpdateResourceUsageType(
3527     PMOS_RESOURCE           pOsResource,
3528     MOS_HW_RESOURCE_DEF     resUsageType)
3529 {
3530     return MosInterface::UpdateResourceUsageType(pOsResource, resUsageType);
3531 }
3532 
3533 //!
3534 //! \brief    Registers Resource
3535 //! \details  Set the Allocation Index in OS resource structure
3536 //! \param    PMOS_INTERFACE pOsInterface
3537 //!           [in] Pointer to OS Interface
3538 //! \param    PMOS_RESOURCE pOsResource
3539 //!           [in/out] Pointer to OS Resource
3540 //! \param    int32_t bWrite
3541 //!           [in] Write Flag
3542 //! \param    int32_t bWritebSetResourceSyncTag
3543 //!           [in] Resource registration Flag, no use for Linux
3544 //! \return   MOS_STATUS
3545 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
3546 //!
Mos_Specific_RegisterResource(PMOS_INTERFACE pOsInterface,PMOS_RESOURCE pOsResource,int32_t bWrite,int32_t bWritebSetResourceSyncTag)3547 MOS_STATUS Mos_Specific_RegisterResource (
3548     PMOS_INTERFACE      pOsInterface,
3549     PMOS_RESOURCE       pOsResource,
3550     int32_t             bWrite,
3551     int32_t             bWritebSetResourceSyncTag)
3552 {
3553     MOS_OS_FUNCTION_ENTER;
3554 
3555     MOS_OS_CHK_NULL_RETURN(pOsInterface);
3556     MOS_OS_CHK_NULL_RETURN(pOsResource);
3557 
3558     if (pOsInterface->apoMosEnabled)
3559     {
3560 #if MOS_COMMAND_RESINFO_DUMP_SUPPORTED
3561         GpuCmdResInfoDumpNext::GetInstance(pOsInterface->pOsContext)->StoreCmdResPtr(pOsInterface, (const void *)pOsResource);
3562 #endif  // MOS_COMMAND_RESINFO_DUMP_SUPPORTED
3563 
3564         return MosInterface::RegisterResource(
3565             pOsInterface->osStreamState,
3566             pOsResource,
3567             bWrite);
3568     }
3569 
3570     if (pOsInterface->modularizedGpuCtxEnabled && !Mos_Solo_IsEnabled(nullptr))
3571     {
3572         auto gpuContext = Linux_GetGpuContext(pOsInterface, pOsInterface->CurrentGpuContextHandle);
3573         MOS_OS_CHK_NULL_RETURN(gpuContext);
3574 
3575     #if MOS_COMMAND_RESINFO_DUMP_SUPPORTED
3576         GpuCmdResInfoDump::GetInstance(pOsInterface->pOsContext)->StoreCmdResPtr(pOsInterface, (const void *)pOsResource);
3577     #endif // MOS_COMMAND_RESINFO_DUMP_SUPPORTED
3578 
3579         return (gpuContext->RegisterResource(pOsResource, bWrite));
3580     }
3581 
3582     PMOS_OS_CONTEXT     pOsContext = nullptr;
3583     PMOS_RESOURCE       pResources = nullptr;
3584     uint32_t            uiAllocation = 0;
3585     MOS_STATUS          eStatus = MOS_STATUS_SUCCESS;
3586     MOS_OS_GPU_CONTEXT  *pOsGpuContext = nullptr;
3587     MOS_UNUSED(bWritebSetResourceSyncTag);
3588 
3589     MOS_OS_ASSERT(pOsInterface);
3590     MOS_OS_ASSERT(pOsInterface->pOsContext);
3591 
3592     pOsContext          = pOsInterface->pOsContext;
3593 
3594     if (pOsInterface->CurrentGpuContextOrdinal == MOS_GPU_CONTEXT_INVALID_HANDLE)
3595     {
3596         MOS_OS_ASSERTMESSAGE("CurrentGpuContextOrdinal exceed max.");
3597         return  MOS_STATUS_INVALID_PARAMETER;
3598     }
3599     pOsGpuContext       = &pOsContext->OsGpuContext[pOsInterface->CurrentGpuContextOrdinal];
3600 
3601     // Find previous registration
3602     pResources = pOsGpuContext->pResources;
3603     if( nullptr == pResources)
3604     {
3605         MOS_OS_ASSERTMESSAGE("pResource is NULL.");
3606         return MOS_STATUS_SUCCESS;
3607     }
3608     for (uiAllocation = 0;
3609          uiAllocation < pOsGpuContext->uiResCount;
3610          uiAllocation++, pResources++)
3611     {
3612         if (pOsResource->bo == pResources->bo) break;
3613     }
3614     // Allocation list to be updated
3615     if (uiAllocation < pOsGpuContext->uiMaxNumAllocations)
3616     {
3617         // New buffer
3618         if (uiAllocation == pOsGpuContext->uiResCount)
3619         {
3620             pOsGpuContext->uiResCount++;
3621         }
3622 
3623         // Set allocation
3624         pOsResource->iAllocationIndex[pOsInterface->CurrentGpuContextOrdinal] = uiAllocation;
3625         pOsGpuContext->pResources[uiAllocation]                     = *pOsResource;
3626         pOsGpuContext->pbWriteMode[uiAllocation]                   |= bWrite;
3627         pOsGpuContext->pAllocationList[uiAllocation].hAllocation    = &pOsGpuContext->pResources[uiAllocation];
3628         pOsGpuContext->pAllocationList[uiAllocation].WriteOperation|= bWrite;
3629         pOsGpuContext->uiNumAllocations                             = pOsGpuContext->uiResCount;
3630     }
3631     else
3632     {
3633         MOS_OS_ASSERTMESSAGE("Reached max # registrations.");
3634         eStatus = MOS_STATUS_UNKNOWN;
3635     }
3636     return eStatus;
3637 }
3638 
3639 //!
3640 //! \brief    Verify command buffer size
3641 //! \details  Verifys the buffer to be used for rendering GPU commands is large enough
3642 //! \param    PMOS_INTERFACE pOsInterface
3643 //!           [in] Pointer to OS interface structure
3644 //! \param    uint32_t dwRequestedSize
3645 //!           [in] Buffer size requested
3646 //! \return   MOS_STATUS
3647 //!           Return MOS_STATUS_SUCCESS if successful (command buffer will be large enough to hold dwMaxSize)
3648 //!           otherwise failed
3649 //!
Mos_Specific_VerifyCommandBufferSize(PMOS_INTERFACE pOsInterface,uint32_t dwRequestedSize,uint32_t dwFlags)3650 MOS_STATUS Mos_Specific_VerifyCommandBufferSize(
3651     PMOS_INTERFACE          pOsInterface,
3652     uint32_t                dwRequestedSize,
3653     uint32_t                dwFlags)
3654 {
3655     MOS_OS_FUNCTION_ENTER;
3656 
3657     MOS_OS_CHK_NULL_RETURN(pOsInterface);
3658 
3659     if (pOsInterface->apoMosEnabled)
3660     {
3661         return MosInterface::VerifyCommandBufferSize(pOsInterface->osStreamState, 0, dwRequestedSize, dwFlags);
3662     }
3663 
3664     if (pOsInterface->modularizedGpuCtxEnabled && !Mos_Solo_IsEnabled(nullptr))
3665     {
3666         auto gpuContext = Linux_GetGpuContext(pOsInterface, pOsInterface->CurrentGpuContextHandle);
3667         MOS_OS_CHK_NULL_RETURN(gpuContext);
3668 
3669         return (gpuContext->VerifyCommandBufferSize(dwRequestedSize));
3670     }
3671 
3672     PMOS_OS_CONTEXT    pOsContext = nullptr;
3673     MOS_OS_GPU_CONTEXT OsGpuContext;
3674 
3675     //---------------------------------------
3676     MOS_UNUSED(dwFlags);
3677     MOS_OS_ASSERT(pOsInterface);
3678     MOS_OS_ASSERT(pOsInterface->pOsContext);
3679     //---------------------------------------
3680 
3681     if (pOsInterface->CurrentGpuContextOrdinal == MOS_GPU_CONTEXT_INVALID_HANDLE)
3682     {
3683         MOS_OS_ASSERTMESSAGE("CurrentGpuContextOrdinal exceed max.");
3684         return  MOS_STATUS_INVALID_PARAMETER;
3685     }
3686 
3687     pOsContext      = pOsInterface->pOsContext;
3688     OsGpuContext    = pOsContext->OsGpuContext[pOsInterface->CurrentGpuContextOrdinal];
3689 
3690     if (OsGpuContext.uiCommandBufferSize < dwRequestedSize)
3691     {
3692         return MOS_STATUS_UNKNOWN;
3693     }
3694 
3695     return MOS_STATUS_SUCCESS;
3696 }
3697 
3698 //!
3699 //! \brief    Resets Resource Allocation
3700 //! \details  Resets Resource Allocation
3701 //! \param    PMOS_INTERFACE pOsInterface
3702 //!           [in] Pointer to OS interface structure
3703 //! \param    PMOS_RESOURCE pOsResource
3704 //!           [in] Pointer to input OS resource
3705 //! \return   void
3706 //!
Mos_Specific_ResetResourceAllocationIndex(PMOS_INTERFACE pOsInterface,PMOS_RESOURCE pOsResource)3707 void Mos_Specific_ResetResourceAllocationIndex (
3708     PMOS_INTERFACE   pOsInterface,
3709     PMOS_RESOURCE    pOsResource)
3710 {
3711     int32_t i;
3712     MOS_UNUSED(pOsInterface);
3713 
3714     if( nullptr == pOsResource)
3715     {
3716         MOS_OS_ASSERTMESSAGE("pOsResource is NULL.");
3717         return;
3718     }
3719 
3720     for (i = 0; i < MOS_GPU_CONTEXT_MAX; i++)
3721     {
3722         pOsResource->iAllocationIndex[i] = MOS_INVALID_ALLOC_INDEX;
3723     }
3724 }
3725 
3726 //!
3727 //! \brief    Get command buffer
3728 //! \details  Retrieves buffer to be used for rendering GPU commands
3729 //! \param    PMOS_INTERFACE pOsInterface
3730 //!           [in] Pointer to OS interface structure
3731 //! \param    PMOS_COMMAND_BUFFER pCmdBuffer
3732 //!           [out] Pointer to Command Buffer control structure
3733 //! \return   MOS_STATUS
3734 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
3735 //!
Mos_Specific_GetCommandBuffer(PMOS_INTERFACE pOsInterface,PMOS_COMMAND_BUFFER pCmdBuffer,uint32_t dwFlags)3736 MOS_STATUS Mos_Specific_GetCommandBuffer(
3737     PMOS_INTERFACE          pOsInterface,
3738     PMOS_COMMAND_BUFFER     pCmdBuffer,
3739     uint32_t                dwFlags)
3740 {
3741     MOS_OS_FUNCTION_ENTER;
3742 
3743     MOS_OS_CHK_NULL_RETURN(pOsInterface);
3744     MOS_OS_CHK_NULL_RETURN(pCmdBuffer);
3745 
3746     if (pOsInterface->apoMosEnabled)
3747     {
3748         return MosInterface::GetCommandBuffer(pOsInterface->osStreamState, pCmdBuffer, dwFlags);
3749     }
3750 
3751     if (pOsInterface->modularizedGpuCtxEnabled && !Mos_Solo_IsEnabled(nullptr))
3752     {
3753         auto gpuContext = Linux_GetGpuContext(pOsInterface, pOsInterface->CurrentGpuContextHandle);
3754         MOS_OS_CHK_NULL_RETURN(gpuContext);
3755 
3756         return (gpuContext->GetCommandBuffer(pCmdBuffer, dwFlags));
3757     }
3758 
3759     PMOS_OS_CONTEXT         pOsContext = nullptr;
3760     MOS_STATUS              eStatus = MOS_STATUS_SUCCESS;
3761     PMOS_OS_GPU_CONTEXT     pOsGpuContext = nullptr;
3762     uint32_t                uiCommandBufferSize = 0;
3763 
3764     MOS_UNUSED(dwFlags);
3765     MOS_OS_CHK_NULL(pOsInterface);
3766     MOS_OS_CHK_NULL(pOsInterface->pOsContext);
3767     MOS_OS_CHK_NULL(pCmdBuffer);
3768 
3769     if (pOsInterface->CurrentGpuContextOrdinal == MOS_GPU_CONTEXT_INVALID_HANDLE)
3770     {
3771         MOS_OS_ASSERTMESSAGE("Invalid input parameter GpuContext.");
3772         eStatus = MOS_STATUS_INVALID_PARAMETER;
3773         goto finish;
3774     }
3775 
3776     // Activate software context
3777     pOsContext = pOsInterface->pOsContext;
3778     pOsGpuContext        = &pOsContext->OsGpuContext[pOsInterface->CurrentGpuContextOrdinal];
3779     uiCommandBufferSize = pOsGpuContext->uiCommandBufferSize;
3780 
3781     if(pOsGpuContext->bCBFlushed == true)
3782     {
3783         if (pOsContext->pfnGetCommandBuffer(pOsContext,
3784             pCmdBuffer,
3785             uiCommandBufferSize))
3786         {
3787             MOS_OS_CHK_STATUS(pOsContext->pfnInsertCmdBufferToPool(pOsContext, pCmdBuffer));
3788             pOsGpuContext->bCBFlushed = false;
3789             eStatus = MOS_SecureMemcpy(pOsGpuContext->pCB, sizeof(MOS_COMMAND_BUFFER), pCmdBuffer, sizeof(MOS_COMMAND_BUFFER));
3790             MOS_OS_CHECK_CONDITION((eStatus != MOS_STATUS_SUCCESS), "Failed to copy command buffer", eStatus);
3791         }
3792         else
3793         {
3794             MOS_OS_ASSERTMESSAGE("Failed to activate command buffer.");
3795             eStatus = MOS_STATUS_UNKNOWN;
3796             goto finish;
3797         }
3798     }
3799 
3800     MOS_OS_CHK_STATUS(pOsInterface->pfnRegisterResource(pOsInterface, &(pOsGpuContext->pCB->OsResource), false, false));
3801     eStatus = MOS_SecureMemcpy(pCmdBuffer, sizeof(MOS_COMMAND_BUFFER), pOsGpuContext->pCB, sizeof(MOS_COMMAND_BUFFER));
3802     MOS_OS_CHECK_CONDITION((eStatus != MOS_STATUS_SUCCESS), "Failed to copy command buffer", eStatus);
3803 
3804 finish:
3805     return eStatus;
3806 }
3807 
3808 //!
3809 //! \brief    Set indirect state size
3810 //! \details  Sets indirect state size to be used for rendering purposes
3811 //! \param    PMOS_INTERFACE pOsInterface
3812 //!           [in] Pointer to OS interface structure
3813 //! \param    uint32_t uSize
3814 //!           [in] State size
3815 //! \return   MOS_STATUS
3816 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
3817 //!
Mos_Specific_SetIndirectStateSize(PMOS_INTERFACE pOsInterface,uint32_t uSize)3818 MOS_STATUS Mos_Specific_SetIndirectStateSize(
3819     PMOS_INTERFACE              pOsInterface,
3820     uint32_t                    uSize)
3821 {
3822     MOS_OS_FUNCTION_ENTER;
3823 
3824     MOS_OS_CHK_NULL_RETURN(pOsInterface);
3825 
3826     if (pOsInterface->apoMosEnabled)
3827     {
3828         return MosInterface::SetupIndirectState(pOsInterface->osStreamState, uSize);
3829     }
3830 
3831     if (pOsInterface->modularizedGpuCtxEnabled && !Mos_Solo_IsEnabled(nullptr))
3832     {
3833         auto gpuContext = Linux_GetGpuContext(pOsInterface, pOsInterface->CurrentGpuContextHandle);
3834         MOS_OS_CHK_NULL_RETURN(gpuContext);
3835 
3836         MOS_OS_CHK_STATUS_RETURN(gpuContext->SetIndirectStateSize(uSize));
3837     }
3838 
3839     PMOS_CONTEXT   pOsContext = nullptr;
3840     MOS_STATUS     eStatus;
3841 
3842     MOS_OS_CHK_NULL(pOsInterface);
3843 
3844     eStatus = MOS_STATUS_SUCCESS;
3845 
3846     pOsContext = pOsInterface->pOsContext;
3847     MOS_OS_CHK_NULL(pOsContext);
3848 
3849     pOsContext->uIndirectStateSize = uSize;
3850 
3851 finish:
3852     return eStatus;
3853 }
3854 
3855 //!
3856 //! \brief    Set indirect state size
3857 //! \details  Retrieves indirect state to be used for rendering purposes
3858 //! \param    PMOS_INTERFACE pOsInterface
3859 //!           [in] Pointer to OS interface structure
3860 //! \param    uint32_t *puOffset
3861 //!           [out] Pointer to indirect buffer offset
3862 //! \param    uint32_t *puSize
3863 //!           [out] Pointer to indirect buffer size
3864 //! \return   MOS_STATUS
3865 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
3866 //!
Mos_Specific_GetIndirectState(PMOS_INTERFACE pOsInterface,uint32_t * puOffset,uint32_t * puSize)3867 MOS_STATUS Mos_Specific_GetIndirectState(
3868     PMOS_INTERFACE           pOsInterface,
3869     uint32_t                *puOffset,
3870     uint32_t                *puSize)
3871 {
3872     MOS_OS_FUNCTION_ENTER;
3873 
3874     MOS_OS_CHK_NULL_RETURN(pOsInterface);
3875     MOS_OS_CHK_NULL_RETURN(puOffset);
3876     MOS_OS_CHK_NULL_RETURN(puSize);
3877 
3878     if (pOsInterface->apoMosEnabled)
3879     {
3880         uint32_t offset = 0;
3881         uint32_t size   = 0;
3882         auto eStatus = MosInterface::GetIndirectState(pOsInterface->osStreamState, nullptr, offset, size);
3883         *puOffset = offset;
3884         *puSize   = size;
3885         return eStatus;
3886     }
3887 
3888    if (pOsInterface->CurrentGpuContextHandle == MOS_GPU_CONTEXT_INVALID_HANDLE)
3889     {
3890         MOS_OS_ASSERTMESSAGE("Invalid input parameter GpuContext.");
3891         return MOS_STATUS_INVALID_PARAMETER;
3892     }
3893 
3894     if (pOsInterface->modularizedGpuCtxEnabled && !Mos_Solo_IsEnabled(nullptr))
3895     {
3896         auto gpuContext = Linux_GetGpuContext(pOsInterface, pOsInterface->CurrentGpuContextHandle);
3897         MOS_OS_CHK_NULL_RETURN(gpuContext);
3898 
3899         return (gpuContext->GetIndirectState(puOffset, puSize));
3900     }
3901 
3902     PMOS_CONTEXT       pOsContext = nullptr;
3903     MOS_OS_GPU_CONTEXT OsGpuContext;
3904 
3905     pOsContext = pOsInterface->pOsContext;
3906     if (pOsContext)
3907     {
3908         OsGpuContext = pOsContext->OsGpuContext[pOsInterface->CurrentGpuContextOrdinal];
3909 
3910         if (puOffset)
3911         {
3912             *puOffset = OsGpuContext.uiCommandBufferSize - pOsContext->uIndirectStateSize;
3913         }
3914 
3915         if (puSize)
3916         {
3917             *puSize = pOsContext->uIndirectStateSize;
3918         }
3919     }
3920     return MOS_STATUS_SUCCESS;
3921 }
3922 
3923 //!
3924 //! \brief    Get Resource Allocation Index
3925 //! \details  Get Resource Allocation Index
3926 //! \param    PMOS_INTERFACE pOsInterface
3927 //!           [in] Pointer to OS interface structure
3928 //! \param    PMOS_RESOURCE pResource
3929 //!           [in] Pointer to input OS resource
3930 //! \return   int32_t
3931 //!           return the allocation index
3932 //!
Mos_Specific_GetResourceAllocationIndex(PMOS_INTERFACE pOsInterface,PMOS_RESOURCE pResource)3933 int32_t Mos_Specific_GetResourceAllocationIndex(
3934     PMOS_INTERFACE      pOsInterface,
3935     PMOS_RESOURCE       pResource)
3936 {
3937     MOS_OS_FUNCTION_ENTER;
3938 
3939     if (pResource && pOsInterface)
3940     {
3941 
3942        if (pOsInterface->CurrentGpuContextHandle == MOS_GPU_CONTEXT_INVALID_HANDLE)
3943        {
3944            MOS_OS_ASSERTMESSAGE("Invalid input parameter GpuContext.");
3945            return MOS_STATUS_INVALID_PARAMETER;
3946        }
3947 
3948         return(pResource->iAllocationIndex[pOsInterface->CurrentGpuContextOrdinal]);
3949     }
3950 
3951     return MOS_INVALID_ALLOC_INDEX;
3952 
3953 }
3954 
3955 //!
3956 //! \brief    Get Indirect State Pointer
3957 //! \details  Get Indirect State Pointer
3958 //! \param    PMOS_INTERFACE pOsInterface
3959 //!           [in] Pointer to OS interface structure
3960 //! \param    uint8_t **pIndirectState
3961 //!           [out] Pointer to Indirect State Buffer
3962 //! \return   MOS_STATUS
3963 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
3964 //!
Mos_Specific_GetIndirectStatePointer(PMOS_INTERFACE pOsInterface,uint8_t ** pIndirectState)3965 MOS_STATUS Mos_Specific_GetIndirectStatePointer(
3966     PMOS_INTERFACE      pOsInterface,
3967     uint8_t             **pIndirectState)
3968 {
3969     PMOS_OS_CONTEXT     pOsContext = nullptr;
3970     MOS_OS_GPU_CONTEXT  OsGpuContext = {};
3971     MOS_STATUS          eStatus = MOS_STATUS_SUCCESS;
3972 
3973     MOS_OS_FUNCTION_ENTER;
3974 
3975     MOS_OS_CHK_NULL_RETURN(pOsInterface);
3976     MOS_OS_CHK_NULL_RETURN(pIndirectState);
3977 
3978     if (pOsInterface->apoMosEnabled)
3979     {
3980         uint32_t offset = 0;
3981         uint32_t size   = 0;
3982         return MosInterface::GetIndirectState(pOsInterface->osStreamState, pIndirectState, offset, size);
3983     }
3984 
3985     if (pOsInterface->modularizedGpuCtxEnabled && !Mos_Solo_IsEnabled(nullptr))
3986     {
3987         auto gpuContext = Linux_GetGpuContext(pOsInterface, pOsInterface->CurrentGpuContextHandle);
3988         MOS_OS_CHK_NULL_RETURN(gpuContext);
3989 
3990         return (gpuContext->GetIndirectStatePointer(pIndirectState));
3991     }
3992 
3993     eStatus    = MOS_STATUS_UNKNOWN;
3994 
3995     pOsContext = (pOsInterface) ? pOsInterface->pOsContext : nullptr;
3996 
3997     if (pOsContext)
3998     {
3999         if (pOsInterface->CurrentGpuContextHandle == MOS_GPU_CONTEXT_INVALID_HANDLE)
4000         {
4001         MOS_OS_ASSERTMESSAGE("Invalid input parameter GpuContext.");
4002         return MOS_STATUS_INVALID_PARAMETER;
4003         }
4004 
4005         OsGpuContext = pOsContext->OsGpuContext[pOsInterface->CurrentGpuContextOrdinal];
4006 
4007         if (OsGpuContext.pCB && OsGpuContext.pCB->pCmdBase)
4008         {
4009             *pIndirectState =
4010                 (uint8_t*)OsGpuContext.pCB->pCmdBase   +
4011                 OsGpuContext.uiCommandBufferSize    -
4012                 pOsContext->uIndirectStateSize;
4013 
4014             eStatus = MOS_STATUS_SUCCESS;
4015         }
4016     }
4017 
4018     return eStatus;
4019 }
4020 
4021 //!
4022 //! \brief    Return command buffer space
4023 //! \details  Return unused command buffer space
4024 //! \param    PMOS_INTERFACE pOsInterface
4025 //!           [in] Pointer to OS interface structure
4026 //! \param    PMOS_COMMAND_BUFFER pCmdBuffer
4027 //!           [out] Pointer to Command Buffer control structure
4028 //! \return   void
4029 //!
Mos_Specific_ReturnCommandBuffer(PMOS_INTERFACE pOsInterface,PMOS_COMMAND_BUFFER pCmdBuffer,uint32_t dwFlags)4030 void Mos_Specific_ReturnCommandBuffer(
4031     PMOS_INTERFACE          pOsInterface,
4032     PMOS_COMMAND_BUFFER     pCmdBuffer,
4033     uint32_t                dwFlags)
4034 {
4035     MOS_OS_FUNCTION_ENTER;
4036 
4037     if (pOsInterface == nullptr || pCmdBuffer == nullptr)
4038     {
4039         MOS_OS_ASSERTMESSAGE("Invalid parameters.");
4040         return;
4041     }
4042 
4043     // Need to ensure 4K extra padding for HW requirement.
4044     if (pCmdBuffer && pCmdBuffer->iRemaining < EXTRA_PADDING_NEEDED)
4045     {
4046         MOS_OS_ASSERTMESSAGE("Need to ensure 4K extra padding for HW requirement.");
4047     }
4048 
4049     if (pOsInterface->apoMosEnabled)
4050     {
4051         auto status = MosInterface::ReturnCommandBuffer(pOsInterface->osStreamState, pCmdBuffer, dwFlags);
4052         if (MOS_FAILED(status))
4053         {
4054             MOS_OS_ASSERTMESSAGE("ReturnCommandBuffer failed.");
4055         }
4056         return;
4057     }
4058 
4059     if (pOsInterface->modularizedGpuCtxEnabled && !Mos_Solo_IsEnabled(nullptr))
4060     {
4061         auto gpuContext = Linux_GetGpuContext(pOsInterface, pOsInterface->CurrentGpuContextHandle);
4062 
4063         if (gpuContext)
4064         {
4065             gpuContext->ReturnCommandBuffer(pCmdBuffer, dwFlags);
4066         }
4067         else
4068         {
4069             MOS_OS_ASSERTMESSAGE("Cannot get valid Gpu context!");
4070         }
4071 
4072         return;
4073     }
4074 
4075     PMOS_OS_CONTEXT         pOsContext = nullptr;
4076     int32_t                 bResult;
4077 
4078     MOS_UNUSED(dwFlags);
4079 
4080     bResult = false;
4081 
4082     // Validate parameters
4083     pOsContext = (pOsInterface) ? pOsInterface->pOsContext : nullptr;
4084     if (pOsContext == nullptr || pCmdBuffer == nullptr)
4085     {
4086         MOS_OS_ASSERTMESSAGE("Invalid parameters.");
4087         goto finish;
4088     }
4089 
4090     pOsContext->pfnReturnCommandBuffer(pOsContext,pOsInterface->CurrentGpuContextOrdinal, pCmdBuffer);
4091 
4092 finish:
4093         return;
4094 }
4095 #if (_DEBUG || _RELEASE_INTERNAL)
Mos_GetNopCommandBuffer_Linux(PMOS_INTERFACE pOsInterface)4096 MOS_LINUX_BO * Mos_GetNopCommandBuffer_Linux(
4097     PMOS_INTERFACE        pOsInterface)
4098 {
4099     int j;
4100     uint32_t *buf = nullptr;
4101     MOS_LINUX_BO* bo = nullptr;
4102 
4103     j = 0;
4104 
4105     if(pOsInterface == nullptr || pOsInterface->pOsContext == nullptr)
4106     {
4107         return nullptr;
4108     }
4109 
4110     bo = mos_bo_alloc(pOsInterface->pOsContext->bufmgr, "NOP_CMD_BO", 4096, 4096, MOS_MEMPOOL_SYSTEMMEMORY);
4111     if(bo == nullptr)
4112     {
4113         return nullptr;
4114     }
4115 
4116     mos_bo_map(bo, 1);
4117     buf = (uint32_t*)bo->virt;
4118     if(buf == nullptr)
4119     {
4120         mos_bo_unreference(bo);
4121         return nullptr;
4122     }
4123 
4124     buf[j++] = 0x05000000; // MI_BATCH_BUFFER_END
4125 
4126     mos_bo_unmap(bo);
4127 
4128     return bo;
4129 }
4130 
Mos_GetBadCommandBuffer_Linux(PMOS_INTERFACE pOsInterface)4131 MOS_LINUX_BO * Mos_GetBadCommandBuffer_Linux(
4132     PMOS_INTERFACE        pOsInterface)
4133 {
4134     int j;
4135     uint32_t *buf = nullptr;
4136     MOS_LINUX_BO* bo = nullptr;
4137 
4138     j = 0;
4139 
4140     if(pOsInterface == nullptr || pOsInterface->pOsContext == nullptr)
4141     {
4142         return nullptr;
4143     }
4144 
4145     bo = mos_bo_alloc(pOsInterface->pOsContext->bufmgr, "BAD_CMD_BO", 4096, 4096, MOS_MEMPOOL_SYSTEMMEMORY);
4146     if(bo == nullptr)
4147     {
4148         return nullptr;
4149     }
4150 
4151     mos_bo_map(bo, 1);
4152     buf = (uint32_t*)bo->virt;
4153     if(buf == nullptr)
4154     {
4155         mos_bo_unreference(bo);
4156         return nullptr;
4157     }
4158 
4159     /* Hanging batch buffer */
4160     // Semaphore setup:
4161     // Set up GTT buffer, polling mode with
4162     // comparison: address > op data (0xffffffff),
4163     // which should never resolve since nothing
4164     // is bigger than 0xffffffff. This semaphore
4165     // should result in a hang that TDR will have
4166     // to handle.
4167     //
4168     // 31:29 = 0
4169     // 28:23 = 0x1c
4170     // ---> 31:24 = 0x0e, 23=0x0
4171     // 22:22 = 0x1    (GTT, must be secure batch)
4172     // 21:16 = 0x0
4173     // ---> 23:20 = 0x4, 19:16=0x0
4174     // 15:15 = 0x1 (polling mode)
4175     // 14:12 = 0x0: memory data > op data (set op data = 0xffffffff and we should never have a match... if the comparison is unsigned)
4176     // ---> 15:12 = 0x8
4177     // 11:08 = 0x0
4178     // 07:00 = 0x2
4179     // ---> 07:04 = 0x0, 03:00 = 0x2
4180     // 31:0 = 0xffffffff
4181     //
4182     buf[j++]    = 0x0e008002;
4183 
4184     // semaphore data
4185     //
4186     buf[j++] = 0xffffffff;
4187 
4188     // semaphore address
4189     //
4190     buf[j++] = 0x0;
4191     buf[j++] = 0x0;
4192 
4193     buf[j++] = 0x0; /* MI_NOOP */
4194     buf[j++] = 0x05000000; // MI_BATCH_BUFFER_END
4195 
4196     mos_bo_unmap(bo);
4197 
4198     return bo;
4199 }
4200 #endif // _DEBUG || _RELEASE_INTERNAL
4201 
Mos_Specific_GetVcsExecFlag(PMOS_INTERFACE pOsInterface,PMOS_COMMAND_BUFFER pCmdBuffer,MOS_GPU_NODE GpuNode)4202 uint32_t Mos_Specific_GetVcsExecFlag(PMOS_INTERFACE pOsInterface,
4203                             PMOS_COMMAND_BUFFER pCmdBuffer,
4204                             MOS_GPU_NODE GpuNode)
4205 {
4206     MOS_OS_ASSERT(pOsInterface);
4207     MOS_OS_ASSERT(pCmdBuffer);
4208     uint32_t VcsExecFlag = I915_EXEC_BSD | I915_EXEC_BSD_RING1;
4209 
4210     if (MOS_VDBOX_NODE_INVALID == pCmdBuffer->iVdboxNodeIndex)
4211     {
4212        // That's those case when BB did not have any VDBOX# specific commands.
4213        // Thus, we need to select VDBOX# here. Alternatively we can rely on KMD
4214        // to make balancing for us, i.e. rely on Virtual Engine support.
4215        pCmdBuffer->iVdboxNodeIndex = pOsInterface->pfnGetVdboxNodeId(pOsInterface, pCmdBuffer);
4216        if (MOS_VDBOX_NODE_INVALID == pCmdBuffer->iVdboxNodeIndex)
4217        {
4218            pCmdBuffer->iVdboxNodeIndex = (GpuNode == MOS_GPU_NODE_VIDEO)?
4219                MOS_VDBOX_NODE_1: MOS_VDBOX_NODE_2;
4220        }
4221      }
4222 
4223      if (MOS_VDBOX_NODE_1 == pCmdBuffer->iVdboxNodeIndex)
4224      {
4225          VcsExecFlag = I915_EXEC_BSD | I915_EXEC_BSD_RING1;
4226      }
4227      else if (MOS_VDBOX_NODE_2 == pCmdBuffer->iVdboxNodeIndex)
4228      {
4229          VcsExecFlag = I915_EXEC_BSD | I915_EXEC_BSD_RING2;
4230      }
4231 
4232      return VcsExecFlag;
4233 }
4234 
4235 //!
4236 //! \brief    Submit command buffer
4237 //! \details  Submit the command buffer
4238 //! \param    PMOS_INTERFACE pOsInterface
4239 //!           [in] Pointer to OS interface structure
4240 //! \param    PMOS_COMMAND_BUFFER pCmdBuffer
4241 //!           [in] Pointer to Command Buffer control structure
4242 //! \param    int32_t bNullRendering
4243 //!           [in] boolean null rendering
4244 //! \return   MOS_STATUS
4245 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
4246 //!
Mos_Specific_SubmitCommandBuffer(PMOS_INTERFACE pOsInterface,PMOS_COMMAND_BUFFER pCmdBuffer,int32_t bNullRendering)4247 MOS_STATUS Mos_Specific_SubmitCommandBuffer(
4248     PMOS_INTERFACE        pOsInterface,
4249     PMOS_COMMAND_BUFFER   pCmdBuffer,
4250     int32_t               bNullRendering)
4251 {
4252     MOS_OS_FUNCTION_ENTER;
4253 
4254     MOS_OS_CHK_NULL_RETURN(pOsInterface);
4255     MOS_OS_CHK_NULL_RETURN(pCmdBuffer);
4256 
4257     if (pOsInterface->apoMosEnabled)
4258     {
4259         return MosInterface::SubmitCommandBuffer(pOsInterface->osStreamState, pCmdBuffer, bNullRendering);
4260     }
4261 
4262     if (pOsInterface->modularizedGpuCtxEnabled && !Mos_Solo_IsEnabled(nullptr))
4263     {
4264         auto gpuContext = Linux_GetGpuContext(pOsInterface, pOsInterface->CurrentGpuContextHandle);
4265         MOS_OS_CHK_NULL_RETURN(gpuContext);
4266 
4267     #if MOS_COMMAND_RESINFO_DUMP_SUPPORTED
4268         GpuCmdResInfoDump::GetInstance(pOsInterface->pOsContext)->Dump(pOsInterface);
4269         GpuCmdResInfoDump::GetInstance(pOsInterface->pOsContext)->ClearCmdResPtrs(pOsInterface);
4270     #endif // MOS_COMMAND_RESINFO_DUMP_SUPPORTED
4271 
4272         return (gpuContext->SubmitCommandBuffer(pOsInterface, pCmdBuffer, bNullRendering));
4273     }
4274 
4275     PMOS_CONTEXT            pOsContext;
4276     PMOS_RESOURCE           pResource;
4277     PMOS_OS_GPU_CONTEXT     pOsGpuContext;
4278     MOS_GPU_CONTEXT         GpuContext;
4279     MOS_GPU_NODE            GpuNode;
4280     uint32_t                PatchIndex, CmdBufferSize;
4281     MOS_STATUS              eStatus;
4282     PPATCHLOCATIONLIST      pPatchList,pCurrentPatch;
4283     MOS_LINUX_BO            *alloc_bo, *cmd_bo;
4284 #if (_DEBUG || _RELEASE_INTERNAL)
4285     MOS_LINUX_BO            *bad_cmd_bo;
4286     MOS_LINUX_BO            *nop_cmd_bo;
4287     uint32_t                dwComponentTag;
4288     uint32_t                dwCallType;
4289 #endif // (_DEBUG || _RELEASE_INTERNAL)
4290     uint32_t                dwBatchBufferEndCmd;
4291     uint32_t                            cpCmdProps;
4292     int32_t                             PerfData;
4293     uint32_t                            ExecFlag;
4294     drm_clip_rect_t                     *cliprects;
4295     int32_t                             num_cliprects;
4296     int32_t                             DR4, ret;
4297     uint64_t                            boOffset;
4298 
4299     boOffset = 0;
4300     eStatus  = MOS_STATUS_SUCCESS;
4301     ret      = 0;
4302 
4303     MOS_OS_CHK_NULL(pOsInterface);
4304     MOS_OS_CHK_NULL(pOsInterface->osCpInterface);
4305 
4306     pOsContext = pOsInterface->pOsContext;
4307     MOS_OS_CHK_NULL(pOsContext);
4308 
4309     GpuContext = pOsInterface->CurrentGpuContextOrdinal;
4310     GpuNode    = OSKMGetGpuNode(GpuContext);
4311     ExecFlag   = GpuNode;
4312 
4313     MOS_OS_CHK_NULL(pOsContext->OsGpuContext);
4314     pOsGpuContext = &pOsContext->OsGpuContext[GpuContext];
4315     MOS_OS_CHK_NULL(pOsGpuContext);
4316 
4317     pPatchList = pOsGpuContext->pPatchLocationList;
4318     MOS_OS_CHK_NULL(pPatchList);
4319 
4320     // Allocate command buffer from video memory
4321     CmdBufferSize = (pCmdBuffer->pCmdPtr - pCmdBuffer->pCmdBase)*4;// pCmdBuffer->OsResource.iPitch;        // ??? Not 100% sure about this ...
4322 
4323     // Command buffer object DRM pointer
4324     pOsGpuContext->bCBFlushed = true;
4325     cmd_bo = pCmdBuffer->OsResource.bo;
4326 
4327     // Now, the patching will be done, based on the patch list.
4328     for (PatchIndex = 0; PatchIndex <  pOsGpuContext->uiCurrentNumPatchLocations; PatchIndex++)
4329     {
4330         pCurrentPatch   = &pPatchList[PatchIndex];
4331         MOS_OS_CHK_NULL(pCurrentPatch);
4332 
4333         // This is the resource for which patching will be done
4334         pResource       = (PMOS_RESOURCE)pOsGpuContext->pAllocationList[pCurrentPatch->AllocationIndex].hAllocation;
4335         MOS_OS_CHK_NULL(pResource);
4336 
4337         // For now, we'll assume the system memory's DRM bo pointer
4338         // is NULL.  If nullptr is detected, then the resource has been
4339         // placed inside the command buffer's indirect state area.
4340         // We'll simply set alloc_bo to the command buffer's bo pointer.
4341         MOS_OS_ASSERT(pResource->bo);
4342 
4343         alloc_bo = (pResource->bo) ? pResource->bo : cmd_bo;
4344 
4345         MOS_OS_CHK_STATUS(pOsInterface->osCpInterface->PermeatePatchForHM(
4346             cmd_bo->virt,
4347             pCurrentPatch,
4348             pResource));
4349 
4350         boOffset = alloc_bo->offset64;
4351         if (alloc_bo != cmd_bo)
4352         {
4353           auto item_ctx = pOsContext->contextOffsetList.begin();
4354           for (; item_ctx != pOsContext->contextOffsetList.end(); item_ctx++)
4355           {
4356              if (item_ctx->intel_context == pOsContext->intel_context && item_ctx->target_bo == alloc_bo)
4357              {
4358                boOffset = item_ctx->offset64;
4359                break;
4360              }
4361           }
4362         }
4363         if (pOsContext->bUse64BitRelocs)
4364         {
4365             *((uint64_t*)((uint8_t*)cmd_bo->virt + pCurrentPatch->PatchOffset)) =
4366                     boOffset + pCurrentPatch->AllocationOffset;
4367         }
4368         else
4369         {
4370             *((uint32_t*)((uint8_t*)cmd_bo->virt + pCurrentPatch->PatchOffset)) =
4371                     boOffset + pCurrentPatch->AllocationOffset;
4372         }
4373 
4374         if(mos_gem_bo_is_softpin(alloc_bo))
4375         {
4376             if (alloc_bo != cmd_bo)
4377             {
4378                 ret = mos_bo_add_softpin_target(cmd_bo, alloc_bo, pCurrentPatch->uiWriteOperation);
4379             }
4380         }
4381         else
4382         {
4383             // This call will patch the command buffer with the offsets of the indirect state region of the command buffer
4384             ret = mos_bo_emit_reloc2(
4385                         cmd_bo,                                                              // Command buffer
4386                         pCurrentPatch->PatchOffset,                                          // Offset in the command buffer
4387                         alloc_bo,                                                            // Allocation object for which the patch will be made.
4388                         pCurrentPatch->AllocationOffset,                                     // Offset to the indirect state
4389                         I915_GEM_DOMAIN_RENDER,                                              // Read domain
4390                         (pCurrentPatch->uiWriteOperation) ? I915_GEM_DOMAIN_RENDER : 0x0,   // Write domain
4391                         boOffset);
4392         }
4393 
4394         if (ret != 0)
4395         {
4396             MOS_OS_ASSERTMESSAGE("Error patching alloc_bo = 0x%x, cmd_bo = 0x%x.",
4397                                (uintptr_t)alloc_bo,(uintptr_t)cmd_bo);
4398             eStatus = MOS_STATUS_UNKNOWN;
4399             goto finish;
4400         }
4401     }
4402 
4403     //Add Batch buffer End Command
4404     dwBatchBufferEndCmd = MI_BATCHBUFFER_END;
4405     if (MOS_FAILED(Mos_AddCommand(
4406                        pCmdBuffer,
4407                        &dwBatchBufferEndCmd,
4408                        sizeof(uint32_t))))
4409     {
4410         MOS_OS_ASSERTMESSAGE("Inserting BB_END failed!");
4411         eStatus = MOS_STATUS_UNKNOWN;
4412         goto finish;
4413     }
4414 
4415     // Now, we can unmap the video command buffer, since we don't need CPU access anymore.
4416     mos_bo_unmap(cmd_bo);
4417 
4418     if(pOsContext->pPerfData != nullptr)
4419     {
4420         PerfData = *(int32_t *)(pOsContext->pPerfData);
4421     }
4422     else
4423     {
4424         PerfData = 0;
4425     }
4426 
4427     cliprects = nullptr;
4428     num_cliprects = 0;
4429     DR4 = pOsContext->uEnablePerfTag ? PerfData : 0;
4430 
4431     //Since CB2 command is not supported, remove it and set cliprects to nullprt as default.
4432     if (GpuNode != I915_EXEC_RENDER)
4433     {
4434         if (pOsContext->bKMDHasVCS2)
4435         {
4436             if (pOsContext->bPerCmdBufferBalancing && pOsInterface->pfnGetVdboxNodeId)
4437             {
4438                 ExecFlag = Mos_Specific_GetVcsExecFlag(pOsInterface, pCmdBuffer, GpuNode);
4439             }
4440             else if (GpuNode == MOS_GPU_NODE_VIDEO)
4441             {
4442                 ExecFlag = I915_EXEC_BSD | I915_EXEC_BSD_RING1;
4443             }
4444             else if (GpuNode == MOS_GPU_NODE_VIDEO2)
4445             {
4446                 ExecFlag = I915_EXEC_BSD | I915_EXEC_BSD_RING2;
4447             }
4448         }
4449         else
4450         {
4451             ExecFlag = I915_EXEC_BSD | I915_EXEC_BSD_RING1;
4452         }
4453     }
4454 
4455 #if (_DEBUG || _RELEASE_INTERNAL)
4456     // trigger GPU HANG if bTriggerCodecHang is set
4457     bad_cmd_bo = nullptr;
4458 
4459     //dwComponentTag 3: decode,5: vpp,6: encode
4460     //dwCallType     8: PAK(CODECHAL_ENCODE_PERFTAG_CALL_PAK_ENGINE)
4461     //               34:PREENC
4462     //               5: VPP
4463     dwComponentTag = (PerfData & 0xF000) >> 12;
4464     dwCallType     = (PerfData & 0xFC) >> 2;
4465 
4466     if(pOsInterface->bTriggerCodecHang &&
4467         (dwComponentTag == 3 || (dwComponentTag == 6 && dwCallType == 8) ||
4468         (dwComponentTag == 6 && dwCallType == 34) ||
4469         (dwComponentTag == 5 && dwCallType == 5))
4470       )
4471     {
4472         bad_cmd_bo = Mos_GetBadCommandBuffer_Linux(pOsInterface);
4473         if(bad_cmd_bo)
4474         {
4475             ret = mos_bo_mrb_exec(bad_cmd_bo,
4476                                         4096,
4477                                         nullptr,
4478                                         0,
4479                                         0,
4480                                         ExecFlag);
4481         }
4482         {
4483             MOS_OS_ASSERTMESSAGE("Mos_GetBadCommandBuffer_Linux failed!");
4484         }
4485     }
4486     else if (pOsInterface->bTriggerVPHang == true)
4487     {
4488         bad_cmd_bo = Mos_GetBadCommandBuffer_Linux(pOsInterface);
4489 
4490         if (bad_cmd_bo)
4491         {
4492             ret = mos_bo_mrb_exec(bad_cmd_bo,
4493                                         4096,
4494                                         nullptr,
4495                                         0,
4496                                         0,
4497                                         ExecFlag);
4498         }
4499         {
4500             MOS_OS_ASSERTMESSAGE("Mos_GetBadCommandBuffer_Linux failed!");
4501         }
4502 
4503         pOsInterface->bTriggerVPHang = false;
4504     }
4505 
4506     nop_cmd_bo = nullptr;
4507     if (bNullRendering == true)
4508     {
4509         nop_cmd_bo = Mos_GetNopCommandBuffer_Linux(pOsInterface);
4510 
4511         if(nop_cmd_bo)
4512         {
4513             ret = mos_bo_mrb_exec(nop_cmd_bo,
4514                                         4096,
4515                                         nullptr,
4516                                         0,
4517                                         0,
4518                                         ExecFlag);
4519         }
4520         {
4521             MOS_OS_ASSERTMESSAGE("Mos_GetNopCommandBuffer_Linux failed!");
4522         }
4523     }
4524 
4525 #endif //(_DEBUG || _RELEASE_INTERNAL)
4526 
4527     if (GpuNode != I915_EXEC_RENDER &&
4528         pOsInterface->osCpInterface->IsTearDownHappen())
4529     {
4530         // to skip PAK command when CP tear down happen to avoid of GPU hang
4531         // conditonal batch buffer start PoC is in progress
4532     }
4533     else if (bNullRendering == false)
4534     {
4535 
4536      ret = mos_gem_bo_context_exec2(cmd_bo,
4537                                        pOsGpuContext->uiCommandBufferSize,
4538                                        pOsContext->intel_context,
4539                                        cliprects,
4540                                        num_cliprects,
4541                                        DR4,
4542                                        ExecFlag,
4543                                        nullptr);
4544       if (ret != 0) {
4545           eStatus = MOS_STATUS_UNKNOWN;
4546       }
4547     }
4548 
4549     if (eStatus != MOS_STATUS_SUCCESS)
4550     {
4551         MOS_OS_ASSERTMESSAGE("Command buffer submission failed!");
4552     }
4553 
4554 #if MOS_COMMAND_BUFFER_DUMP_SUPPORTED
4555     if (pOsInterface->bDumpCommandBuffer)
4556     {
4557         mos_bo_map(cmd_bo, 0);
4558         pOsInterface->pfnDumpCommandBuffer(pOsInterface, pCmdBuffer);
4559         mos_bo_unmap(cmd_bo);
4560     }
4561 #endif // MOS_COMMAND_BUFFER_DUMP_SUPPORTED
4562 
4563 #if (_DEBUG || _RELEASE_INTERNAL)
4564     if(bad_cmd_bo)
4565     {
4566         mos_bo_wait_rendering(bad_cmd_bo);
4567         mos_bo_unreference(bad_cmd_bo);
4568     }
4569     if(nop_cmd_bo)
4570     {
4571         mos_bo_unreference(nop_cmd_bo);
4572     }
4573 #endif //(_DEBUG || _RELEASE_INTERNAL)
4574 
4575     //clear command buffer relocations to fix memory leak issue
4576     mos_gem_bo_clear_relocs(cmd_bo, 0);
4577 
4578     // Reset resource allocation
4579     pOsGpuContext->uiNumAllocations = 0;
4580     MOS_ZeroMemory(pOsGpuContext->pAllocationList, sizeof(ALLOCATION_LIST) * pOsGpuContext->uiMaxNumAllocations);
4581     pOsGpuContext->uiCurrentNumPatchLocations = 0;
4582     MOS_ZeroMemory(pOsGpuContext->pPatchLocationList, sizeof(PATCHLOCATIONLIST) * pOsGpuContext->uiMaxPatchLocationsize);
4583     pOsGpuContext->uiResCount = 0;
4584 
4585     MOS_ZeroMemory(pOsGpuContext->pbWriteMode, sizeof(int32_t) * pOsGpuContext->uiMaxNumAllocations);
4586 finish:
4587     return eStatus;
4588 }
4589 
4590 //!
4591 //! \brief    Wait and release command buffer
4592 //! \details  Wait and release command buffer
4593 //! \param    PMOS_INTERFACE pOsInterface
4594 //!           [in] Pointer to OS interface structure
4595 //! \param    PMOS_COMMAND_BUFFER pCmdBuffer
4596 //!           [in] Pointer to Command Buffer control structure
4597 //! \return   MOS_STATUS
4598 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
4599 //!
Mos_Specific_WaitAndReleaseCmdBuffer(PMOS_INTERFACE pOsInterface,PMOS_COMMAND_BUFFER pCmdBuffer)4600 MOS_STATUS Mos_Specific_WaitAndReleaseCmdBuffer(
4601     PMOS_INTERFACE        pOsInterface,
4602     PMOS_COMMAND_BUFFER   pCmdBuffer)
4603 {
4604     MOS_OS_CHK_NULL_RETURN(pOsInterface);
4605     MOS_OS_CHK_NULL_RETURN(pCmdBuffer);
4606     if (pOsInterface->modularizedGpuCtxEnabled && !Mos_Solo_IsEnabled(nullptr))
4607     {
4608         auto cmd_bo = pCmdBuffer->OsResource.bo;
4609         MOS_OS_CHK_NULL_RETURN(cmd_bo);
4610 
4611         // only wait rendering here, release will covered by gpucontext
4612         mos_bo_wait_rendering(cmd_bo);
4613 
4614         return MOS_STATUS_SUCCESS;
4615     }
4616 
4617     PMOS_CONTEXT            pOsContext;
4618     MOS_STATUS              eStatus;
4619 
4620     eStatus = MOS_STATUS_SUCCESS;
4621 
4622     MOS_OS_CHK_NULL(pOsInterface);
4623     MOS_OS_CHK_NULL(pCmdBuffer);
4624 
4625     pOsContext = pOsInterface->pOsContext;
4626     MOS_OS_CHK_NULL(pOsContext);
4627 
4628     MOS_OS_CHK_STATUS(pOsContext->pfnWaitAndReleaseCmdBuffer(pOsContext, pCmdBuffer->iCmdIndex));
4629 
4630 finish:
4631     return eStatus;
4632 }
4633 
4634 //!
4635 //! \brief    Get resource gfx address
4636 //! \details  Get resource gfx address
4637 //! \param    PMOS_INTERFACE pOsInterface
4638 //!           [in] Pointer to OS interface structure
4639 //! \param    PMOS_RESOURCE pResource
4640 //!           [in] Pointer to resource
4641 //! \return   uint64_t
4642 //!           Return resource gfx address
4643 //!
Mos_Specific_GetResourceGfxAddress(PMOS_INTERFACE pOsInterface,PMOS_RESOURCE pResource)4644 uint64_t Mos_Specific_GetResourceGfxAddress(
4645     PMOS_INTERFACE   pOsInterface,
4646     PMOS_RESOURCE    pResource)
4647 {
4648     MOS_OS_CHK_NULL_RETURN(pOsInterface);
4649     MOS_OS_CHK_NULL_RETURN(pResource);
4650 
4651     if (pOsInterface->apoMosEnabled)
4652     {
4653         return MosInterface::GetResourceGfxAddress(pOsInterface->osStreamState, pResource);
4654     }
4655 
4656     if (!mos_gem_bo_is_softpin(pResource->bo))
4657     {
4658         mos_bo_set_softpin(pResource->bo);
4659     }
4660     return pResource->bo->offset64;
4661 }
4662 
4663 //!
4664 //! \brief    Resizes the buffer to be used for rendering GPU commands
4665 //! \details  return true if succeeded - command buffer will be large enough to hold dwMaxSize
4666 //!           return false if failed or invalid parameters
4667 //! \param    PMOS_INTERFACE pOsInterface
4668 //!           [in] Pointer to OS interface structure
4669 //! \param    uint32_t dwRequestedCommandBufferSize
4670 //!           [in] requested command buffer size
4671 //! \param    uint32_t dwRequestedPatchListSize
4672 //!           [in] requested patch list size
4673 //! \return   MOS_STATUS
4674 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
4675 //!
Mos_Specific_ResizeCommandBufferAndPatchList(PMOS_INTERFACE pOsInterface,uint32_t dwRequestedCommandBufferSize,uint32_t dwRequestedPatchListSize,uint32_t dwFlags)4676 MOS_STATUS Mos_Specific_ResizeCommandBufferAndPatchList(
4677     PMOS_INTERFACE          pOsInterface,
4678     uint32_t                dwRequestedCommandBufferSize,
4679     uint32_t                dwRequestedPatchListSize,
4680     uint32_t                dwFlags)
4681 {
4682     MOS_OS_FUNCTION_ENTER;
4683 
4684     MOS_OS_CHK_NULL_RETURN(pOsInterface);
4685 
4686     if (pOsInterface->apoMosEnabled)
4687     {
4688         return MosInterface::ResizeCommandBufferAndPatchList(pOsInterface->osStreamState, 0, dwRequestedCommandBufferSize, dwRequestedPatchListSize, dwFlags);
4689     }
4690 
4691     if (pOsInterface->modularizedGpuCtxEnabled && !Mos_Solo_IsEnabled(nullptr))
4692     {
4693         auto gpuContext = Linux_GetGpuContext(pOsInterface, pOsInterface->CurrentGpuContextHandle);
4694         MOS_OS_CHK_NULL_RETURN(gpuContext);
4695 
4696         return (gpuContext->ResizeCommandBufferAndPatchList(dwRequestedCommandBufferSize, dwRequestedPatchListSize, dwFlags));
4697     }
4698 
4699     PMOS_CONTEXT            pOsContext;
4700     PMOS_OS_GPU_CONTEXT     pOsGpuContext;
4701     PPATCHLOCATIONLIST      pNewPatchList;
4702     MOS_STATUS              eStatus;
4703 
4704     MOS_OS_FUNCTION_ENTER;
4705 
4706     //---------------------------------------
4707     MOS_UNUSED(dwFlags);
4708     MOS_OS_ASSERT(pOsInterface);
4709     MOS_OS_ASSERT(pOsInterface->pOsContext);
4710     //---------------------------------------
4711 
4712     eStatus = MOS_STATUS_SUCCESS;
4713 
4714     pOsContext    = pOsInterface->pOsContext;
4715     pOsGpuContext = &(pOsContext->OsGpuContext[pOsInterface->CurrentGpuContextOrdinal]);
4716 
4717     // uiCommandBufferSize is used for allocate command buffer and submit command buffer, in this moment, command buffer has not allocated yet.
4718     // Linux KMD requires command buffer size align to 8 bytes, or it will not execute the commands.
4719     pOsGpuContext->uiCommandBufferSize = MOS_ALIGN_CEIL(dwRequestedCommandBufferSize, 8);
4720 
4721     if (dwRequestedPatchListSize > pOsGpuContext->uiMaxPatchLocationsize)
4722     {
4723         pNewPatchList = (PPATCHLOCATIONLIST)realloc(
4724             pOsGpuContext->pPatchLocationList,
4725             sizeof(PATCHLOCATIONLIST) * dwRequestedPatchListSize);
4726         if (nullptr == pNewPatchList)
4727         {
4728             MOS_OS_ASSERTMESSAGE("pOsGpuContext->pPatchLocationList realloc failed.");
4729             eStatus = MOS_STATUS_NO_SPACE;
4730             goto finish;
4731         }
4732 
4733         pOsGpuContext->pPatchLocationList = pNewPatchList;
4734 
4735         // now zero the extended portion
4736         MOS_ZeroMemory(
4737             (pOsGpuContext->pPatchLocationList + pOsGpuContext->uiMaxPatchLocationsize),
4738             sizeof(PATCHLOCATIONLIST) * (dwRequestedPatchListSize - pOsGpuContext->uiMaxPatchLocationsize));
4739         pOsGpuContext->uiMaxPatchLocationsize = dwRequestedPatchListSize;
4740     }
4741 
4742 finish:
4743     return eStatus;
4744 }
4745 
4746 //!
4747 //! \brief    Resizes the buffer to be used for rendering GPU commands
4748 //! \details  return true if succeeded - command buffer will be large enough to hold dwMaxSize
4749 //!           return false if failed or invalid parameters
4750 //! \param    PMOS_INTERFACE pOsInterface
4751 //!           [in] Pointer to OS interface structure
4752 //! \param    uint32_t dwRequestedSize
4753 //!           [in] requested size
4754 //! \return   MOS_STATUS
4755 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
4756 //!
Mos_Specific_ResizeCommandBuffer(PMOS_INTERFACE pOsInterface,uint32_t dwRequestedSize)4757 MOS_STATUS Mos_Specific_ResizeCommandBuffer(
4758     PMOS_INTERFACE          pOsInterface,
4759     uint32_t                dwRequestedSize)
4760 {
4761     MOS_OS_FUNCTION_ENTER;
4762 
4763     MOS_OS_CHK_NULL_RETURN(pOsInterface);
4764 
4765     if (pOsInterface->modularizedGpuCtxEnabled && !Mos_Solo_IsEnabled(nullptr))
4766     {
4767         auto gpuContext = Linux_GetGpuContext(pOsInterface, pOsInterface->CurrentGpuContextHandle);
4768         MOS_OS_CHK_NULL_RETURN(gpuContext);
4769 
4770         return (gpuContext->ResizeCommandBuffer(dwRequestedSize));
4771     }
4772 
4773     PMOS_CONTEXT          pOsContext;
4774     PMOS_OS_GPU_CONTEXT   pOsGpuContext;
4775     MOS_GPU_CONTEXT       GpuContext;
4776     MOS_STATUS            eStatus;
4777 
4778     eStatus = MOS_STATUS_SUCCESS;
4779 
4780     MOS_OS_CHK_NULL(pOsInterface);
4781     MOS_OS_CHK_NULL(pOsInterface->pOsContext);
4782 
4783     pOsContext = &pOsInterface->pOsContext[pOsInterface->CurrentGpuContextOrdinal];
4784     MOS_OS_CHK_NULL(pOsContext);
4785 
4786     GpuContext = pOsInterface->CurrentGpuContextOrdinal;
4787 
4788     MOS_OS_CHK_NULL(pOsContext->OsGpuContext);
4789     pOsGpuContext = &pOsContext->OsGpuContext[GpuContext];
4790     MOS_OS_CHK_NULL(pOsGpuContext);
4791 
4792     pOsGpuContext->uiCommandBufferSize = dwRequestedSize;
4793 
4794 finish:
4795     return eStatus;
4796 }
4797 
4798 //!
4799 //! \brief    Create GPU context
4800 //! \details  Create GPU context
4801 //! \param    PMOS_INTERFACE pOsInterface
4802 //!           [in] Pointer to OS interface structure
4803 //! \param    MOS_GPU_CONTEXT GpuContext
4804 //!           [in] GPU Context
4805 //! \param    MOS_GPU_NODE GpuNode
4806 //!           [in] GPU Node
4807 //! \return   MOS_STATUS
4808 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
4809 //!
Mos_Specific_CreateGpuContext(PMOS_INTERFACE pOsInterface,MOS_GPU_CONTEXT mosGpuCxt,MOS_GPU_NODE GpuNode,PMOS_GPUCTX_CREATOPTIONS createOption)4810 MOS_STATUS Mos_Specific_CreateGpuContext(
4811     PMOS_INTERFACE        pOsInterface,
4812     MOS_GPU_CONTEXT       mosGpuCxt,
4813     MOS_GPU_NODE          GpuNode,
4814     PMOS_GPUCTX_CREATOPTIONS createOption)
4815 {
4816     MOS_OS_FUNCTION_ENTER;
4817 
4818     MOS_OS_CHK_NULL_RETURN(pOsInterface);
4819 
4820     if (mosGpuCxt == MOS_GPU_CONTEXT_INVALID_HANDLE)
4821     {
4822         MOS_OS_ASSERTMESSAGE("Invalid input parameter GpuContext.");
4823         return MOS_STATUS_INVALID_PARAMETER;
4824     }
4825 
4826     if (pOsInterface->modularizedGpuCtxEnabled && !Mos_Solo_IsEnabled(nullptr))
4827     {
4828         MOS_OS_CHK_NULL_RETURN(pOsInterface->osContextPtr);
4829 
4830         auto pOsContextSpecific = static_cast<OsContextSpecific*>(pOsInterface->osContextPtr);
4831         MOS_OS_CHK_NULL_RETURN(pOsContextSpecific);
4832 
4833         auto gpuContextMgr = pOsContextSpecific->GetGpuContextMgr();
4834         if (!pOsInterface->apoMosEnabled)
4835         {
4836             MOS_OS_CHK_NULL_RETURN(gpuContextMgr);
4837         }
4838 
4839         auto cmdBufMgr = pOsContextSpecific->GetCmdBufMgr();
4840         if (!pOsInterface->apoMosEnabled)
4841         {
4842             MOS_OS_CHK_NULL_RETURN(cmdBufMgr);
4843         }
4844 
4845         MOS_OS_CHK_NULL_RETURN(createOption);
4846         if (GpuNode == MOS_GPU_NODE_3D && createOption->SSEUValue != 0)
4847         {
4848             struct drm_i915_gem_context_param_sseu sseu;
4849             MOS_ZeroMemory(&sseu, sizeof(sseu));
4850             sseu.engine.engine_class = I915_ENGINE_CLASS_RENDER;
4851             sseu.engine.engine_instance = 0;
4852 
4853             if (mos_get_context_param_sseu(pOsInterface->pOsContext->intel_context, &sseu))
4854             {
4855                 MOS_OS_ASSERTMESSAGE("Failed to get sseu configuration.");
4856                 return MOS_STATUS_UNKNOWN;
4857             };
4858 
4859             if (mos_hweight8(sseu.subslice_mask) > createOption->packed.SubSliceCount)
4860             {
4861                 sseu.subslice_mask = mos_switch_off_n_bits(sseu.subslice_mask,
4862                         mos_hweight8(sseu.subslice_mask)-createOption->packed.SubSliceCount);
4863             }
4864 
4865             if (mos_set_context_param_sseu(pOsInterface->pOsContext->intel_context, sseu))
4866             {
4867                 MOS_OS_ASSERTMESSAGE("Failed to set sseu configuration.");
4868                 return MOS_STATUS_UNKNOWN;
4869             };
4870         }
4871 
4872         createOption->gpuNode = GpuNode;
4873         if (pOsInterface->apoMosEnabled)
4874         {
4875             // Update ctxBasedScheduling from legacy OsInterface
4876             pOsInterface->osStreamState->ctxBasedScheduling = pOsInterface->ctxBasedScheduling;
4877             if (pOsContextSpecific->GetGpuContextHandle(mosGpuCxt) == MOS_GPU_CONTEXT_INVALID_HANDLE)
4878             {
4879                 auto osDeviceContext = pOsInterface->osStreamState->osDeviceContext;
4880                 MOS_OS_CHK_NULL_RETURN(osDeviceContext);
4881                 auto gpuContextMgr = osDeviceContext->GetGpuContextMgr();
4882                 MOS_OS_CHK_NULL_RETURN(gpuContextMgr);
4883                 auto cmdBufMgr = osDeviceContext->GetCmdBufferMgr();
4884                 MOS_OS_CHK_NULL_RETURN(cmdBufMgr);
4885 
4886                 auto gpuContext = gpuContextMgr->CreateGpuContext(GpuNode, cmdBufMgr);
4887                 MOS_OS_CHK_NULL_RETURN(gpuContext);
4888 
4889                 auto gpuContextSpecific  = static_cast<GpuContextSpecificNext *>(gpuContext);
4890                 MOS_OS_CHK_NULL_RETURN(gpuContextSpecific);
4891 
4892                 MOS_OS_CHK_STATUS_RETURN(gpuContextSpecific->Init(gpuContextMgr->GetOsContext(), pOsInterface->osStreamState, createOption));
4893                 gpuContextSpecific->SetGpuContext(mosGpuCxt);
4894 
4895                 pOsContextSpecific->SetGpuContextHandle(mosGpuCxt, gpuContextSpecific->GetGpuContextHandle());
4896             }
4897 
4898             return MOS_STATUS_SUCCESS;
4899         }
4900 
4901         if (pOsContextSpecific->GetGpuContextHandle(mosGpuCxt) == MOS_GPU_CONTEXT_INVALID_HANDLE)
4902         {
4903             auto gpuContext = gpuContextMgr->CreateGpuContext(GpuNode, cmdBufMgr, mosGpuCxt);
4904             MOS_OS_CHK_NULL_RETURN(gpuContext);
4905 
4906             auto gpuContextSpecific  = static_cast<GpuContextSpecific *>(gpuContext);
4907             MOS_OS_CHK_NULL_RETURN(gpuContextSpecific);
4908 
4909             MOS_OS_CHK_STATUS_RETURN(gpuContextSpecific->Init(gpuContextMgr->GetOsContext(), pOsInterface, GpuNode, createOption));
4910 
4911             pOsContextSpecific->SetGpuContextHandle(mosGpuCxt, gpuContextSpecific->GetGpuContextHandle());
4912         }
4913 
4914         return MOS_STATUS_SUCCESS;
4915     }
4916 
4917     MOS_UNUSED(pOsInterface);
4918     MOS_UNUSED(mosGpuCxt);
4919     MOS_UNUSED(GpuNode);
4920     MOS_UNUSED(createOption);
4921     return MOS_STATUS_SUCCESS;
4922 }
4923 
4924 GPU_CONTEXT_HANDLE
Mos_Specific_CreateGpuComputeContext(MOS_INTERFACE * osInterface,MOS_GPU_CONTEXT contextName,MOS_GPUCTX_CREATOPTIONS * createOption)4925 Mos_Specific_CreateGpuComputeContext(MOS_INTERFACE *osInterface,
4926                                      MOS_GPU_CONTEXT contextName,
4927                                      MOS_GPUCTX_CREATOPTIONS *createOption)
4928 {
4929     MOS_OS_FUNCTION_ENTER;
4930     MOS_OS_CHK_NULL_RETURN(osInterface);
4931 
4932     if (MOS_GPU_CONTEXT_CM_COMPUTE != contextName
4933         && MOS_GPU_CONTEXT_COMPUTE != contextName)
4934     {
4935         MOS_OS_ASSERTMESSAGE("Invalid input parameter contextName.");
4936         return MOS_GPU_CONTEXT_INVALID_HANDLE;
4937     }
4938 
4939     if (osInterface->modularizedGpuCtxEnabled && !Mos_Solo_IsEnabled(nullptr))
4940     {
4941         if (nullptr == createOption)
4942         {
4943             MOS_OS_ASSERTMESSAGE("Invalid pointer (nullptr).");
4944             return MOS_GPU_CONTEXT_INVALID_HANDLE;
4945         }
4946 
4947         if (osInterface->apoMosEnabled)
4948         {
4949             if (nullptr == osInterface->osStreamState)
4950             {
4951                 MOS_OS_ASSERTMESSAGE("Invalid pointer (nullptr).");
4952                 return MOS_GPU_CONTEXT_INVALID_HANDLE;
4953             }
4954 
4955             // Update ctxBasedScheduling from legacy OsInterface
4956             osInterface->osStreamState->ctxBasedScheduling
4957                     = osInterface->ctxBasedScheduling;
4958 
4959             // Only wrapper will contain re-creation check based on stream Index and MOS_GPU_CONTEXT
4960             createOption->gpuNode = MOS_GPU_NODE_COMPUTE;
4961             GPU_CONTEXT_HANDLE context_handle = MOS_GPU_CONTEXT_INVALID_HANDLE;
4962             MOS_STATUS status
4963                     = MosInterface::CreateGpuContext(osInterface->osStreamState,
4964                                                      *createOption, context_handle);
4965             if (MOS_FAILED(status))
4966             {
4967                 return MOS_GPU_CONTEXT_INVALID_HANDLE;
4968             }
4969 
4970             auto os_device_context = osInterface->osStreamState->osDeviceContext;
4971             auto gpu_context_mgr = os_device_context->GetGpuContextMgr();
4972             if (nullptr == gpu_context_mgr)
4973             {
4974                 return MOS_GPU_CONTEXT_INVALID_HANDLE;
4975             }
4976             GpuContextNext *context_next
4977                     = gpu_context_mgr->GetGpuContext(context_handle);
4978             auto context_specific_next
4979                     = static_cast<GpuContextSpecificNext*>(context_next);
4980             if (nullptr == context_specific_next)
4981             {
4982                 return MOS_GPU_CONTEXT_INVALID_HANDLE;
4983             }
4984             context_specific_next->SetGpuContext(contextName);
4985             return context_handle;
4986         }
4987         else
4988         {
4989             auto os_context_specific
4990                     = static_cast<OsContextSpecific*>(osInterface->osContextPtr);
4991             if (nullptr == os_context_specific)
4992             {
4993                 return MOS_GPU_CONTEXT_INVALID_HANDLE;
4994             }
4995             auto gpu_context_mgr = os_context_specific->GetGpuContextMgr();
4996             if (nullptr == gpu_context_mgr)
4997             {
4998                 return MOS_GPU_CONTEXT_INVALID_HANDLE;
4999             }
5000             auto cmd_buffer_mgr = os_context_specific->GetCmdBufMgr();
5001             if (nullptr == cmd_buffer_mgr)
5002             {
5003                 return MOS_GPU_CONTEXT_INVALID_HANDLE;
5004             }
5005 
5006             GpuContext *gpu_context
5007                     = gpu_context_mgr->CreateGpuContext(MOS_GPU_NODE_COMPUTE,
5008                                                         cmd_buffer_mgr,
5009                                                         contextName);
5010             auto *context_specific = static_cast<GpuContextSpecific*>(gpu_context);
5011             if (nullptr == context_specific)
5012             {
5013                 return MOS_GPU_CONTEXT_INVALID_HANDLE;
5014             }
5015             MOS_STATUS status
5016                     = context_specific->Init(gpu_context_mgr->GetOsContext(),
5017                                              osInterface, MOS_GPU_NODE_COMPUTE,
5018                                              createOption);
5019             if (MOS_STATUS_SUCCESS != status)
5020             {
5021                 return MOS_GPU_CONTEXT_INVALID_HANDLE;
5022             }
5023             return context_specific->GetGpuContextHandle();
5024         }
5025     }
5026     return MOS_GPU_CONTEXT_INVALID_HANDLE;
5027 }
5028 
5029 //!
5030 //! \brief    Destroy GPU context
5031 //! \details  Destroy GPU context
5032 //!           [in] Pointer to OS interface structure
5033 //! \param    MOS_GPU_CONTEXT GpuContext
5034 //!           [in] GPU Context
5035 //! \return   MOS_STATUS
5036 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
5037 //!
Mos_Specific_DestroyGpuContext(PMOS_INTERFACE pOsInterface,MOS_GPU_CONTEXT mosGpuCxt)5038 MOS_STATUS Mos_Specific_DestroyGpuContext(
5039     PMOS_INTERFACE        pOsInterface,
5040     MOS_GPU_CONTEXT       mosGpuCxt)
5041 {
5042     MOS_OS_FUNCTION_ENTER;
5043 
5044     MOS_OS_CHK_NULL_RETURN(pOsInterface);
5045 
5046     if (mosGpuCxt == MOS_GPU_CONTEXT_INVALID_HANDLE)
5047     {
5048         MOS_OS_ASSERTMESSAGE("Invalid input parameter GpuContext.");
5049         return MOS_STATUS_INVALID_PARAMETER;
5050     }
5051 
5052     if (pOsInterface->modularizedGpuCtxEnabled && !Mos_Solo_IsEnabled(nullptr))
5053     {
5054         MOS_OS_CHK_NULL_RETURN(pOsInterface->osContextPtr);
5055 
5056         OsContextSpecific *pOsContextSpecific = static_cast<OsContextSpecific *>(pOsInterface->osContextPtr);
5057         MOS_OS_CHK_NULL_RETURN(pOsContextSpecific);
5058 
5059         GPU_CONTEXT_HANDLE gpuContextHandle = pOsContextSpecific->GetGpuContextHandle(mosGpuCxt);
5060 
5061         if (pOsInterface->apoMosEnabled)
5062         {
5063             return MosInterface::DestroyGpuContext(pOsInterface->osStreamState, gpuContextHandle);
5064         }
5065 
5066         GpuContextMgr *gpuContextMgr = pOsContextSpecific->GetGpuContextMgr();
5067         MOS_OS_CHK_NULL_RETURN(gpuContextMgr);
5068         GpuContext *gpuContext = gpuContextMgr->GetGpuContext(gpuContextHandle);
5069         MOS_OS_CHK_NULL_RETURN(gpuContext);
5070 
5071         gpuContextMgr->DestroyGpuContext(gpuContext);
5072         return MOS_STATUS_SUCCESS;
5073     }
5074 
5075     MOS_STATUS                  eStatus = MOS_STATUS_SUCCESS;
5076     MOS_UNUSED(pOsInterface);
5077     MOS_UNUSED(mosGpuCxt);
5078     return eStatus;
5079 }
5080 
5081 //!
5082 //! \brief    Destroy Compute GPU context
5083 //! \details  Destroy Compute GPU context
5084 //!           [in] Pointer to OS interface structure
5085 //! \param    GPU_CONTEXT_HANDLE gpuContextHandle
5086 //!           [in] GPU Context handle
5087 //! \return   MOS_STATUS
5088 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
5089 //!
Mos_Specific_DestroyGpuComputeContext(PMOS_INTERFACE osInterface,GPU_CONTEXT_HANDLE gpuContextHandle)5090 MOS_STATUS Mos_Specific_DestroyGpuComputeContext(
5091     PMOS_INTERFACE        osInterface,
5092     GPU_CONTEXT_HANDLE    gpuContextHandle)
5093 {
5094     MOS_OS_FUNCTION_ENTER;
5095 
5096     MOS_OS_CHK_NULL_RETURN(osInterface);
5097     if(MOS_GPU_CONTEXT_INVALID_HANDLE == gpuContextHandle)
5098     {
5099         MOS_OS_ASSERTMESSAGE("Invalid compute gpu context handle.");
5100         return MOS_STATUS_INVALID_HANDLE;
5101     }
5102     if (!osInterface->modularizedGpuCtxEnabled || Mos_Solo_IsEnabled(nullptr))
5103     {
5104         return MOS_STATUS_SUCCESS;
5105     }
5106 
5107     OsContextSpecific *pOsContextSpecific = static_cast<OsContextSpecific *>(osInterface->osContextPtr);
5108     MOS_OS_CHK_NULL_RETURN(pOsContextSpecific);
5109 
5110     GPU_CONTEXT_HANDLE iGpuContextHandle = pOsContextSpecific->GetGpuContextHandle(MOS_GPU_CONTEXT_CM_COMPUTE);
5111     if(iGpuContextHandle == gpuContextHandle)
5112     {
5113         MOS_OS_ASSERTMESSAGE("It will be destroyed in osInterface destroy.");
5114         return MOS_STATUS_SUCCESS;
5115     }
5116 
5117     iGpuContextHandle = pOsContextSpecific->GetGpuContextHandle(MOS_GPU_CONTEXT_COMPUTE);
5118     if(iGpuContextHandle == gpuContextHandle)
5119     {
5120         MOS_OS_ASSERTMESSAGE("It will be destroyed in osInterface destroy.");
5121         return MOS_STATUS_SUCCESS;
5122     }
5123 
5124     if (osInterface->apoMosEnabled)
5125     {
5126         auto gpuContext = MosInterface::GetGpuContext(osInterface->osStreamState, gpuContextHandle);
5127         MOS_OS_CHK_NULL_RETURN(gpuContext);
5128 
5129         MOS_GPU_CONTEXT gpuContextName = gpuContext->GetCpuContextID();
5130         if(gpuContextName != MOS_GPU_CONTEXT_CM_COMPUTE && gpuContextName != MOS_GPU_CONTEXT_COMPUTE)
5131         {
5132             MOS_OS_ASSERTMESSAGE("It is not compute gpu context and it will be destroyed in osInterface destroy.");
5133             return MOS_STATUS_SUCCESS;
5134         }
5135         return MosInterface::DestroyGpuContext(osInterface->osStreamState, gpuContextHandle);
5136     }
5137 
5138     GpuContextMgr *gpuContextMgr = pOsContextSpecific->GetGpuContextMgr();
5139     MOS_OS_CHK_NULL_RETURN(gpuContextMgr);
5140     GpuContext *gpuContext = gpuContextMgr->GetGpuContext(gpuContextHandle);
5141     MOS_OS_CHK_NULL_RETURN(gpuContext);
5142 
5143     MOS_GPU_CONTEXT gpuContextName = gpuContext->GetCpuContextID();
5144     if(gpuContextName != MOS_GPU_CONTEXT_CM_COMPUTE && gpuContextName != MOS_GPU_CONTEXT_COMPUTE)
5145     {
5146         MOS_OS_ASSERTMESSAGE("It is not compute gpu context and it will be destroyed in osInterface destroy.");
5147         return MOS_STATUS_SUCCESS;
5148     }
5149 
5150     gpuContextMgr->DestroyGpuContext(gpuContext);
5151     return MOS_STATUS_SUCCESS;
5152  }
5153 
5154 //!
5155 //! \brief    Sets the perf tag
5156 //! \details  Sets the perf tag
5157 //! \param    PMOS_INTERFACE pOsInterface
5158 //!           [in] Pointer to OS interface structure
5159 //! \param    uint32_t PerfTag
5160 //!           [in] Perf tag
5161 //! \return   void
5162 //!
Mos_Specific_SetPerfTag(PMOS_INTERFACE pOsInterface,uint32_t PerfTag)5163 void Mos_Specific_SetPerfTag(
5164     PMOS_INTERFACE    pOsInterface,
5165     uint32_t          PerfTag)
5166 {
5167     uint32_t ComponentTag;
5168 
5169     MOS_OS_CHK_NULL_NO_STATUS_RETURN(pOsInterface);
5170 
5171     if (pOsInterface->apoMosEnabled)
5172     {
5173         MOS_OS_CHK_NULL_NO_STATUS_RETURN(pOsInterface->osStreamState);
5174         pOsInterface->osStreamState->component = pOsInterface->Component;
5175         return MosInterface::SetPerfTag(pOsInterface->osStreamState, PerfTag);
5176     }
5177 
5178     PMOS_CONTEXT pOsContext =(PMOS_CONTEXT)pOsInterface->pOsContext;
5179 
5180     if(pOsContext)
5181     {
5182         switch (pOsInterface->Component)
5183         {
5184             case COMPONENT_VPreP:
5185             case COMPONENT_VPCommon:
5186                 ComponentTag = PERFTAG_VPREP;
5187                 break;
5188 
5189             case COMPONENT_LibVA:
5190                 ComponentTag = PERFTAG_LIBVA;
5191                 break;
5192 
5193             case COMPONENT_CM:
5194                 ComponentTag = PERFTAG_CM;
5195                 break;
5196 
5197             case COMPONENT_Decode:
5198                 ComponentTag = PERFTAG_DECODE;
5199                 break;
5200 
5201             case COMPONENT_Encode:
5202                 ComponentTag = PERFTAG_ENCODE;
5203                 break;
5204 
5205             default:
5206                 ComponentTag = 0xF000 & pOsContext->GetDmaBufID(pOsContext);
5207                 break;
5208         }
5209 
5210         pOsContext->SetDmaBufID(pOsContext, ComponentTag | (PerfTag&0x0fff));
5211     }
5212 
5213 }
5214 
5215 //!
5216 //! \brief    Resets the perf tag
5217 //! \details  Resets the perf tag
5218 //! \param    PMOS_INTERFACE pOsInterface
5219 //!           [in] Pointer to OS interface structure
5220 //! \return   void
5221 //!
Mos_Specific_ResetPerfBufferID(PMOS_INTERFACE pOsInterface)5222 void Mos_Specific_ResetPerfBufferID(
5223     PMOS_INTERFACE pOsInterface)
5224 {
5225     MOS_OS_CHK_NULL_NO_STATUS_RETURN(pOsInterface);
5226 
5227     if (pOsInterface->apoMosEnabled)
5228     {
5229         return MosInterface::ResetPerfBufferID(pOsInterface->osStreamState);
5230     }
5231 
5232     PMOS_CONTEXT pOsContext = (PMOS_CONTEXT)pOsInterface->pOsContext;
5233     MOS_OS_CHK_NULL_NO_STATUS_RETURN(pOsContext);
5234     MOS_OS_CHK_NULL_NO_STATUS_RETURN(pOsContext->pPerfData);
5235     pOsContext->pPerfData->bufferID = 0;
5236     return;
5237 }
5238 
5239 //!
5240 //! \brief    Increment the perf tag for buffer ID
5241 //! \details  Increment the perf tag for buffer ID
5242 //! \param    PMOS_INTERFACE pOsInterface
5243 //!           [in] Pointer to OS interface structure
5244 //! \return   void
5245 //!
Mos_Specific_IncPerfBufferID(PMOS_INTERFACE pOsInterface)5246 void Mos_Specific_IncPerfBufferID(
5247     PMOS_INTERFACE pOsInterface)
5248 {
5249     MOS_OS_CHK_NULL_NO_STATUS_RETURN(pOsInterface);
5250 
5251     if (pOsInterface->apoMosEnabled)
5252     {
5253         return MosInterface::IncPerfBufferID(pOsInterface->osStreamState);
5254     }
5255 
5256     PMOS_CONTEXT pOsContext = (PMOS_CONTEXT)pOsInterface->pOsContext;
5257 
5258     MOS_OS_CHK_NULL_NO_STATUS_RETURN(pOsContext);
5259     MOS_OS_CHK_NULL_NO_STATUS_RETURN(pOsContext->pPerfData);
5260 
5261     pOsContext->pPerfData->bufferID++;
5262     return;
5263 }
5264 
5265 //!
5266 //! \brief    Increment the perf tag for Frame ID
5267 //! \details  Increment the perf tag for frame ID
5268 //! \param    PMOS_INTERFACE pOsInterface
5269 //!           [in] Pointer to OS interface structure
5270 //! \return   void
5271 //!
Mos_Specific_IncPerfFrameID(PMOS_INTERFACE pOsInterface)5272 void Mos_Specific_IncPerfFrameID(
5273     PMOS_INTERFACE pOsInterface)
5274 {
5275     MOS_OS_CHK_NULL_NO_STATUS_RETURN(pOsInterface);
5276 
5277     if (pOsInterface->apoMosEnabled)
5278     {
5279         return MosInterface::IncPerfFrameID(pOsInterface->osStreamState);
5280     }
5281 
5282     PMOS_CONTEXT pOsContext = (PMOS_CONTEXT)pOsInterface->pOsContext;
5283 
5284     MOS_OS_CHK_NULL_NO_STATUS_RETURN(pOsContext);
5285     MOS_OS_CHK_NULL_NO_STATUS_RETURN(pOsContext->pPerfData);
5286 
5287     pOsContext->pPerfData->frameID++;
5288 
5289 }
5290 
5291 //!
5292 //! \brief    Gets the perf tag
5293 //! \details  Gets the perf tag
5294 //! \param    PMOS_INTERFACE pOsInterface
5295 //!           [in] Pointer to OS interface structure
5296 //! \return   uint32_t
5297 //!           Return perf tag
5298 //!
Mos_Specific_GetPerfTag(PMOS_INTERFACE pOsInterface)5299 uint32_t Mos_Specific_GetPerfTag(
5300     PMOS_INTERFACE pOsInterface)
5301 {
5302     uint32_t                perfTag;
5303 
5304     if (pOsInterface == nullptr)
5305     {
5306         MOS_OS_ASSERTMESSAGE("pOsInterface invalid nullptr");
5307         return 0;
5308     }
5309 
5310     if (pOsInterface->apoMosEnabled)
5311     {
5312         return MosInterface::GetPerfTag(pOsInterface->osStreamState);
5313     }
5314 
5315     PMOS_CONTEXT osContext = (PMOS_CONTEXT)pOsInterface->pOsContext;
5316 
5317     if (osContext == nullptr)
5318     {
5319         return 0;
5320     }
5321 
5322     perfTag = *(uint32_t *)(osContext->pPerfData);
5323     return perfTag;
5324 }
5325 
5326 //!
5327 //! \brief    Set Hybrid Kernel ID
5328 //! \details  Set Hybrid Kernel ID
5329 //! \param    PMOS_INTERFACE pOsInterface
5330 //!           [in] OS Interface
5331 //! \param    uint32_t KernelID
5332 //!           [in] Hybrid Decoder Kernel ID
5333 //! \return   void
5334 //!
Mos_Specific_SetPerfHybridKernelID(PMOS_INTERFACE pOsInterface,uint32_t KernelID)5335 void Mos_Specific_SetPerfHybridKernelID(
5336     PMOS_INTERFACE     pOsInterface,
5337     uint32_t           KernelID)
5338 {
5339     PMOS_CONTEXT pOsContext;
5340 
5341     MOS_OS_CHK_NULL_NO_STATUS_RETURN(pOsInterface);
5342 
5343     if (pOsInterface->apoMosEnabled)
5344     {
5345         return MosInterface::SetPerfHybridKernelID(pOsInterface->osStreamState, KernelID);
5346     }
5347 
5348     MOS_OS_CHK_NULL_NO_STATUS_RETURN(pOsInterface->pOsContext);
5349 
5350     pOsContext = (PMOS_CONTEXT)pOsInterface->pOsContext;
5351     pOsContext->SetPerfHybridKernelID(pOsContext,KernelID);
5352 }
5353 
5354 //!
5355 //! \brief    Check if Perf Tag is already set
5356 //! \details  Check if Perf Tag is already set
5357 //! \param    PMOS_INTERFACE pOsInterface
5358 //!           [in] OS Interface
5359 //! \return   int32_t
5360 //!
Mos_Specific_IsPerfTagSet(PMOS_INTERFACE pOsInterface)5361 int32_t Mos_Specific_IsPerfTagSet(
5362     PMOS_INTERFACE     pOsInterface)
5363 {
5364     uint32_t     ComponentTag;
5365     int32_t      bRet = false;
5366     PMOS_CONTEXT pOsContext;
5367 
5368     if(pOsInterface == nullptr)
5369     {
5370         MOS_OS_ASSERTMESSAGE("pOsInterface invalid nullptr");
5371         return bRet;
5372     }
5373 
5374     if (pOsInterface->apoMosEnabled)
5375     {
5376         return MosInterface::IsPerfTagSet(pOsInterface->osStreamState);
5377     }
5378 
5379     MOS_OS_ASSERT(pOsInterface->pOsContext);
5380 
5381     pOsContext = (pOsInterface) ? (PMOS_CONTEXT)pOsInterface->pOsContext : nullptr;
5382     bRet       = false;
5383 
5384     if (pOsContext)
5385     {
5386         ComponentTag = 0xF000 & pOsContext->GetDmaBufID(pOsContext);
5387 
5388         switch (ComponentTag)
5389         {
5390             case PERFTAG_ENCODE:
5391             case PERFTAG_DECODE:
5392                 bRet = true;
5393                 break;
5394 
5395             default:
5396                 bRet = false;
5397                 break;
5398         }
5399     }
5400 
5401     return bRet;
5402 }
5403 
5404 //!
5405 //! \brief    Convet from OS to Mos format
5406 //! \details  need to refactor this function after libva ddi interface done, or after OS format defined
5407 //!          for Linux/Android
5408 //! \param    MOS_OS_FORMAT format
5409 //!           [in] OS surface format
5410 //! \return   MOS_FORMAT
5411 //!           Return Mos format
5412 //!
Mos_Specific_FmtOsToMos(MOS_OS_FORMAT format)5413 MOS_FORMAT Mos_Specific_FmtOsToMos(
5414     MOS_OS_FORMAT   format)
5415 {
5416     switch (static_cast<int>(format))
5417     {
5418         case DDI_FORMAT_A8B8G8R8     : return Format_A8R8G8B8;
5419         case DDI_FORMAT_X8B8G8R8     : return Format_X8R8G8B8;
5420         case DDI_FORMAT_R32F         : return Format_R32F;
5421         case DDI_FORMAT_A8R8G8B8     : return Format_A8R8G8B8;
5422         case DDI_FORMAT_X8R8G8B8     : return Format_X8R8G8B8;
5423         case DDI_FORMAT_R5G6B5       : return Format_R5G6B5;
5424         case DDI_FORMAT_YUY2         : return Format_YUY2;
5425         case DDI_FORMAT_P8           : return Format_P8;
5426         case DDI_FORMAT_A8P8         : return Format_A8P8;
5427         case DDI_FORMAT_A8           : return Format_A8;
5428         case DDI_FORMAT_L8           : return Format_L8;
5429         case DDI_FORMAT_L16          : return Format_L16;
5430         case DDI_FORMAT_A4L4         : return Format_A4L4;
5431         case DDI_FORMAT_A8L8         : return Format_A8L8;
5432         case DDI_FORMAT_V8U8         : return Format_V8U8;
5433         case DDI_FORMAT_A16B16G16R16 : return Format_A16B16G16R16;
5434         case DDI_FORMAT_R32G32B32A32F: return Format_R32G32B32A32F;
5435         case FOURCC_YVYU             : return Format_YVYU;
5436         case FOURCC_UYVY             : return Format_UYVY;
5437         case FOURCC_VYUY             : return Format_VYUY;
5438         case FOURCC_AYUV             : return Format_AYUV;
5439         case FOURCC_NV12             : return Format_NV12;
5440         case FOURCC_NV21             : return Format_NV21;
5441         case FOURCC_NV11             : return Format_NV11;
5442         case FOURCC_P208             : return Format_P208;
5443         case FOURCC_IMC1             : return Format_IMC1;
5444         case FOURCC_IMC2             : return Format_IMC2;
5445         case FOURCC_IMC3             : return Format_IMC3;
5446         case FOURCC_IMC4             : return Format_IMC4;
5447         case FOURCC_I420             : return Format_I420;
5448         case FOURCC_IYUV             : return Format_IYUV;
5449         case FOURCC_YV12             : return Format_YV12;
5450         case FOURCC_YVU9             : return Format_YVU9;
5451         case FOURCC_AI44             : return Format_AI44;
5452         case FOURCC_IA44             : return Format_IA44;
5453         case FOURCC_400P             : return Format_400P;
5454         case FOURCC_411P             : return Format_411P;
5455         case FOURCC_411R             : return Format_411R;
5456         case FOURCC_422H             : return Format_422H;
5457         case FOURCC_422V             : return Format_422V;
5458         case FOURCC_444P             : return Format_444P;
5459         case FOURCC_RGBP             : return Format_RGBP;
5460         case FOURCC_BGRP             : return Format_BGRP;
5461         case FOURCC_P010             : return Format_P010;
5462         case FOURCC_P016             : return Format_P016;
5463         case FOURCC_Y216             : return Format_Y216;
5464         case FOURCC_Y416             : return Format_Y416;
5465         case FOURCC_Y210             : return Format_Y210;
5466         case FOURCC_Y410             : return Format_Y410;
5467         default                      : return Format_Invalid;
5468     }
5469 }
5470 
5471 //!
5472 //! \brief    Convet from MOS OS to OS format
5473 //! \details  need to refactor this function after libva ddi interface done, or after OS format defined
5474 //!          for Linux/Android
5475 //! \param    MOS_FORMAT format
5476 //!           [in] MOS OS surface format
5477 //! \return   MOS_OS_FORMAT
5478 //!           Return OS format
5479 //!
Mos_Specific_FmtMosToOs(MOS_FORMAT format)5480 MOS_OS_FORMAT Mos_Specific_FmtMosToOs(
5481     MOS_FORMAT     format)
5482 {
5483     switch (format)
5484     {
5485     case Format_A8R8G8B8     : return (MOS_OS_FORMAT)DDI_FORMAT_A8R8G8B8;
5486     case Format_X8R8G8B8     : return (MOS_OS_FORMAT)DDI_FORMAT_X8R8G8B8;
5487     case Format_A8B8G8R8     : return (MOS_OS_FORMAT)DDI_FORMAT_A8B8G8R8;
5488     case Format_R32U         : return (MOS_OS_FORMAT)DDI_FORMAT_R32F;
5489     case Format_R32F         : return (MOS_OS_FORMAT)DDI_FORMAT_R32F;
5490     case Format_R5G6B5       : return (MOS_OS_FORMAT)DDI_FORMAT_R5G6B5;
5491     case Format_YUY2         : return (MOS_OS_FORMAT)DDI_FORMAT_YUY2;
5492     case Format_P8           : return (MOS_OS_FORMAT)DDI_FORMAT_P8;
5493     case Format_A8P8         : return (MOS_OS_FORMAT)DDI_FORMAT_A8P8;
5494     case Format_A8           : return (MOS_OS_FORMAT)DDI_FORMAT_A8;
5495     case Format_L8           : return (MOS_OS_FORMAT)DDI_FORMAT_L8;
5496     case Format_L16          : return (MOS_OS_FORMAT)DDI_FORMAT_L16;
5497     case Format_A4L4         : return (MOS_OS_FORMAT)DDI_FORMAT_A4L4;
5498     case Format_A8L8         : return (MOS_OS_FORMAT)DDI_FORMAT_A8L8;
5499     case Format_V8U8         : return (MOS_OS_FORMAT)DDI_FORMAT_V8U8;
5500     case Format_YVYU         : return (MOS_OS_FORMAT)FOURCC_YVYU;
5501     case Format_UYVY         : return (MOS_OS_FORMAT)FOURCC_UYVY;
5502     case Format_VYUY         : return (MOS_OS_FORMAT)FOURCC_VYUY;
5503     case Format_AYUV         : return (MOS_OS_FORMAT)FOURCC_AYUV;
5504     case Format_NV12         : return (MOS_OS_FORMAT)FOURCC_NV12;
5505     case Format_NV21         : return (MOS_OS_FORMAT)FOURCC_NV21;
5506     case Format_NV11         : return (MOS_OS_FORMAT)FOURCC_NV11;
5507     case Format_P208         : return (MOS_OS_FORMAT)FOURCC_P208;
5508     case Format_IMC1         : return (MOS_OS_FORMAT)FOURCC_IMC1;
5509     case Format_IMC2         : return (MOS_OS_FORMAT)FOURCC_IMC2;
5510     case Format_IMC3         : return (MOS_OS_FORMAT)FOURCC_IMC3;
5511     case Format_IMC4         : return (MOS_OS_FORMAT)FOURCC_IMC4;
5512     case Format_I420         : return (MOS_OS_FORMAT)FOURCC_I420;
5513     case Format_IYUV         : return (MOS_OS_FORMAT)FOURCC_IYUV;
5514     case Format_YV12         : return (MOS_OS_FORMAT)FOURCC_YV12;
5515     case Format_YVU9         : return (MOS_OS_FORMAT)FOURCC_YVU9;
5516     case Format_AI44         : return (MOS_OS_FORMAT)FOURCC_AI44;
5517     case Format_IA44         : return (MOS_OS_FORMAT)FOURCC_IA44;
5518     case Format_400P         : return (MOS_OS_FORMAT)FOURCC_400P;
5519     case Format_411P         : return (MOS_OS_FORMAT)FOURCC_411P;
5520     case Format_411R         : return (MOS_OS_FORMAT)FOURCC_411R;
5521     case Format_422H         : return (MOS_OS_FORMAT)FOURCC_422H;
5522     case Format_422V         : return (MOS_OS_FORMAT)FOURCC_422V;
5523     case Format_444P         : return (MOS_OS_FORMAT)FOURCC_444P;
5524     case Format_RGBP         : return (MOS_OS_FORMAT)FOURCC_RGBP;
5525     case Format_BGRP         : return (MOS_OS_FORMAT)FOURCC_BGRP;
5526     case Format_STMM         : return (MOS_OS_FORMAT)DDI_FORMAT_P8;
5527     case Format_P010         : return (MOS_OS_FORMAT)FOURCC_P010;
5528     case Format_P016         : return (MOS_OS_FORMAT)FOURCC_P016;
5529     case Format_Y216         : return (MOS_OS_FORMAT)FOURCC_Y216;
5530     case Format_Y416         : return (MOS_OS_FORMAT)FOURCC_Y416;
5531     case Format_A16B16G16R16 : return (MOS_OS_FORMAT)DDI_FORMAT_A16B16G16R16;
5532     case Format_Y210         : return (MOS_OS_FORMAT)FOURCC_Y216;
5533     case Format_Y410         : return (MOS_OS_FORMAT)FOURCC_Y410;
5534     case Format_R32G32B32A32F: return (MOS_OS_FORMAT)DDI_FORMAT_R32G32B32A32F;
5535     default                  : return (MOS_OS_FORMAT)DDI_FORMAT_UNKNOWN;
5536     }
5537 }
5538 
5539 //!
5540 //! \brief    Check for GPU context valid
5541 //! \details  Always returns MOS_STATUS_SUCCESS on Linux.
5542 //            This interface is implemented for compatibility.
5543 //! \param    PMOS_INTERFACE pOsInterface
5544 //!           [in] pointer to Os interface structure
5545 //! \param    MOS_GPU_CONTEXT GpuContext
5546 //!           [in] Gpu Context
5547 //! \return   MOS_STATUS
5548 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
5549 //!
Mos_Specific_IsGpuContextValid(PMOS_INTERFACE pOsInterface,MOS_GPU_CONTEXT GpuContext)5550 MOS_STATUS Mos_Specific_IsGpuContextValid(
5551     PMOS_INTERFACE         pOsInterface,
5552     MOS_GPU_CONTEXT        GpuContext)
5553 {
5554     MOS_UNUSED(pOsInterface);
5555     MOS_UNUSED(GpuContext);
5556     return MOS_STATUS_SUCCESS;
5557 }
5558 
5559 //!
5560 //! \brief    Unified OS Resources sync
5561 //! \details  Tag based synchronization at the resource level
5562 //! \param    PMOS_INTERFACE pOsInterface
5563 //!           [in] Pointer to OS Interface
5564 //! \param    PMOS_RESOURCE pOsResource
5565 //!           [in] Pointer to OS Resource
5566 //! \param    MOS_GPU_CONTEXT requestorGPUCtx
5567 //!           [in] GPU  Context
5568 //! \param    int32_t bWriteOperation
5569 //!           [in] true if write operation
5570 //! \return   void
5571 //!
Mos_Specific_SyncOnResource(PMOS_INTERFACE pOsInterface,PMOS_RESOURCE pOsResource,MOS_GPU_CONTEXT requestorGPUCtx,int32_t bWriteOperation)5572 void Mos_Specific_SyncOnResource(
5573     PMOS_INTERFACE          pOsInterface,
5574     PMOS_RESOURCE           pOsResource,
5575     MOS_GPU_CONTEXT         requestorGPUCtx,
5576     int32_t                 bWriteOperation)
5577 {
5578     MOS_UNUSED(pOsInterface);
5579     MOS_UNUSED(pOsResource);
5580     MOS_UNUSED(requestorGPUCtx);
5581     MOS_UNUSED(bWriteOperation);
5582 }
5583 
5584 //!
5585 //! \brief    Synchronize GPU context
5586 //! \details  Synchronize GPU context
5587 //! \param    PMOS_INTERFACE pOsInterface
5588 //!           [in] OS Interface
5589 //! \param    MOS_GPU_CONTEXT busyGPUCtx
5590 //!           [in] Busy context id being requested to sync with
5591 //! \param    MOS_GPU_CONTEXT requestorGPUCtx
5592 //!           [in] Requestor context id
5593 //! \return   void
5594 //!
Mos_Specific_SyncGpuContext(PMOS_INTERFACE pOsInterface,MOS_GPU_CONTEXT busyGPUCtx,MOS_GPU_CONTEXT requestorGPUCtx)5595 void Mos_Specific_SyncGpuContext(
5596     PMOS_INTERFACE        pOsInterface,
5597     MOS_GPU_CONTEXT       busyGPUCtx,
5598     MOS_GPU_CONTEXT       requestorGPUCtx)
5599 {
5600     MOS_UNUSED(pOsInterface);
5601     MOS_UNUSED(busyGPUCtx);
5602     MOS_UNUSED(requestorGPUCtx);
5603 }
5604 
5605 //!
5606 //! \brief    Synchronize 3d GPU context
5607 //! \details  Synchronize 3d GPU context
5608 //! \param    PMOS_INTERFACE pOsInterface
5609 //!           [in] OS Interface
5610 //! \param    PMOS_SYNC_PARAMS pSyncParams
5611 //!           [in] Sync parameters
5612 //! \return   void
5613 //!
Mos_Specific_SyncWith3DContext(PMOS_INTERFACE pOsInterface,PMOS_SYNC_PARAMS pSyncParams)5614 void Mos_Specific_SyncWith3DContext(
5615     PMOS_INTERFACE        pOsInterface,
5616     PMOS_SYNC_PARAMS      pSyncParams)
5617 {
5618     MOS_UNUSED(pOsInterface);
5619     MOS_UNUSED(pSyncParams);
5620 }
5621 
5622 //!
5623 //! \brief    Checks for HW enabled
5624 //! \details  Checks for HW enabled
5625 //! \param    PMOS_INTERFACE pOsInterface
5626 //!           [in] pointer to Os interface structure
5627 //! \return   int32_t
5628 //!           Returns true id HW enabled if CP mode
5629 //!
Mos_Specific_IsNullHWEnabled(PMOS_INTERFACE pOsInterface)5630 int32_t Mos_Specific_IsNullHWEnabled(
5631     PMOS_INTERFACE     pOsInterface)
5632 {
5633     MOS_UNUSED(pOsInterface);
5634     return false;
5635 }
5636 
5637 //!
5638 //! \brief    Get GPU status buffer
5639 //! \details  Gets the status buffer for the resource
5640 //! \param    PMOS_INTERFACE pOsInterface
5641 //!           [in] Pointer to OS Interface
5642 //! \param    PMOS_RESOURCE pOsResource
5643 //!           [out] Pointer to OS Resource
5644 //! \return   MOS_STATUS
5645 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
5646 //!
Mos_Specific_GetGpuStatusBufferResource(PMOS_INTERFACE pOsInterface,PMOS_RESOURCE & pOsResource)5647 MOS_STATUS Mos_Specific_GetGpuStatusBufferResource(
5648     PMOS_INTERFACE         pOsInterface,
5649     PMOS_RESOURCE          &pOsResource)
5650 {
5651     MOS_OS_FUNCTION_ENTER;
5652 
5653     MOS_OS_CHK_NULL_RETURN(pOsInterface);
5654 
5655     if (pOsInterface->apoMosEnabled)
5656     {
5657         return MosInterface::GetGpuStatusBufferResource(pOsInterface->osStreamState, pOsResource, pOsInterface->osStreamState->currentGpuContextHandle);
5658     }
5659 
5660     if (pOsInterface->modularizedGpuCtxEnabled && !Mos_Solo_IsEnabled(nullptr))
5661     {
5662         auto gpuContext = Linux_GetGpuContext(pOsInterface, pOsInterface->CurrentGpuContextHandle);
5663         MOS_OS_CHK_NULL_RETURN(gpuContext);
5664 
5665         auto resource = gpuContext->GetStatusBufferResource();
5666         MOS_OS_CHK_NULL_RETURN(resource);
5667 
5668         pOsResource = gpuContext->GetStatusBufferMosResource();
5669         MOS_OS_CHK_NULL_RETURN(pOsResource);
5670         MOS_ZeroMemory(pOsResource, sizeof(MOS_RESOURCE));
5671 
5672         MOS_OS_CHK_STATUS_RETURN(resource->ConvertToMosResource(pOsResource));
5673 
5674         return MOS_STATUS_SUCCESS;
5675     }
5676 
5677     PMOS_CONTEXT pOsContext;
5678 
5679     MOS_OS_ASSERT(pOsInterface);
5680     MOS_OS_ASSERT(pOsInterface->pOsContext);
5681 
5682     pOsContext = pOsInterface->pOsContext;
5683 
5684     pOsResource = pOsContext->pGPUStatusBuffer;
5685     return MOS_STATUS_SUCCESS;
5686 }
5687 
5688 //!
5689 //! \brief    Get GPU status tag offset
5690 //! \details  Gets the status tag offset
5691 //! \param    PMOS_INTERFACE pOsInterface
5692 //!           [in] Pointer to OS Interface
5693 //! \param    MOS_GPU_CONTEXT GpuContext
5694 //!           [in] GPU Context
5695 //! \return   uint32_t
5696 //!           Returns the tag offset
5697 //!
Mos_Specific_GetGpuStatusTagOffset(PMOS_INTERFACE pOsInterface,MOS_GPU_CONTEXT GpuContext)5698 uint32_t Mos_Specific_GetGpuStatusTagOffset(
5699     PMOS_INTERFACE        pOsInterface,
5700     MOS_GPU_CONTEXT       GpuContext)
5701 {
5702     MOS_OS_FUNCTION_ENTER;
5703 
5704     MOS_OS_CHK_NULL_RETURN(pOsInterface);
5705 
5706     uint32_t offset = 0;
5707 
5708     if (pOsInterface->apoMosEnabled)
5709     {
5710         // always 0 in apo
5711         return 0;
5712     }
5713     // A gobal status buffer for all GPU contexts is no longer used when modulized GPU context enabled,
5714     // replace with separate buffer corresponding to each GPU context and the offset will be 0
5715     if (!pOsInterface->modularizedGpuCtxEnabled || Mos_Solo_IsEnabled(nullptr))
5716     {
5717         offset = sizeof(MOS_GPU_STATUS_DATA) * GpuContext;
5718     }
5719 
5720     return offset;
5721 }
5722 
5723 //!
5724 //! \brief    Get GPU status tag
5725 //! \details  Gets the status tag
5726 //! \param    PMOS_INTERFACE pOsInterface
5727 //!           [in] Pointer to OS Interface
5728 //! \param    MOS_GPU_CONTEXT GpuContext
5729 //!           [in] GPU Context
5730 //! \return   uint32_t
5731 //!           Returns the tag
5732 //!
Mos_Specific_GetGpuStatusTag(PMOS_INTERFACE pOsInterface,MOS_GPU_CONTEXT mosGpuCtx)5733 uint32_t Mos_Specific_GetGpuStatusTag(
5734     PMOS_INTERFACE            pOsInterface,
5735     MOS_GPU_CONTEXT           mosGpuCtx)
5736 {
5737     MOS_OS_FUNCTION_ENTER;
5738 
5739     MOS_OS_ASSERT(pOsInterface);
5740 
5741     if (mosGpuCtx == MOS_GPU_CONTEXT_INVALID_HANDLE)
5742     {
5743         MOS_OS_ASSERTMESSAGE("Invalid input parameter GpuContext.");
5744         return -1;
5745     }
5746 
5747     if (pOsInterface->modularizedGpuCtxEnabled && !Mos_Solo_IsEnabled(nullptr))
5748     {
5749         if (pOsInterface->osContextPtr == nullptr)
5750         {
5751             MOS_OS_ASSERTMESSAGE("invalid input parameters!");
5752             return 0;
5753         }
5754 
5755         auto osCxtSpecific = static_cast<OsContextSpecific*>(pOsInterface->osContextPtr);
5756 
5757         auto handle = osCxtSpecific->GetGpuContextHandle(mosGpuCtx);
5758 
5759         if (pOsInterface->apoMosEnabled)
5760         {
5761             return MosInterface::GetGpuStatusTag(pOsInterface->osStreamState, handle);
5762         }
5763 
5764         auto gpuContext = Linux_GetGpuContext(pOsInterface, handle);
5765         MOS_OS_CHK_NULL_RETURN(gpuContext);
5766 
5767         return gpuContext->GetGpuStatusTag();
5768     }
5769 
5770     PMOS_CONTEXT pOsContext;
5771 
5772     MOS_OS_ASSERT(pOsInterface->pOsContext);
5773     //------------------------------------
5774 
5775     pOsContext = pOsInterface->pOsContext;
5776 
5777     return pOsContext->pfnGetGpuCtxBufferTag(pOsContext, mosGpuCtx);
5778 }
5779 
5780 //!
5781 //! \brief    Increment GPU status tag
5782 //! \details  Increment the status tag
5783 //! \param    PMOS_INTERFACE pOsInterface
5784 //!           [in] Pointer to OS Interface
5785 //! \param    MOS_GPU_CONTEXT GpuContext
5786 //!           [in] GPU Context
5787 //! \return   void
5788 //!
Mos_Specific_IncrementGpuStatusTag(PMOS_INTERFACE pOsInterface,MOS_GPU_CONTEXT mosGpuCtx)5789 void Mos_Specific_IncrementGpuStatusTag(
5790     PMOS_INTERFACE        pOsInterface,
5791     MOS_GPU_CONTEXT       mosGpuCtx)
5792 {
5793     MOS_OS_FUNCTION_ENTER;
5794 
5795     MOS_OS_ASSERT(pOsInterface);
5796 
5797     if (mosGpuCtx == MOS_GPU_CONTEXT_INVALID_HANDLE)
5798     {
5799         MOS_OS_ASSERTMESSAGE("Invalid input parameter GpuContext.");
5800         return;
5801     }
5802 
5803     if (pOsInterface->modularizedGpuCtxEnabled && !Mos_Solo_IsEnabled(nullptr))
5804     {
5805         if (pOsInterface->osContextPtr == nullptr)
5806         {
5807             MOS_OS_ASSERTMESSAGE("invalid input parameters!");
5808             return;
5809         }
5810 
5811         auto osCxtSpecific = static_cast<OsContextSpecific*>(pOsInterface->osContextPtr);
5812 
5813         auto handle = osCxtSpecific->GetGpuContextHandle(mosGpuCtx);
5814 
5815         if (pOsInterface->apoMosEnabled)
5816         {
5817             MosInterface::IncrementGpuStatusTag(pOsInterface->osStreamState, handle);
5818             return;
5819         }
5820 
5821         auto gpuContext = Linux_GetGpuContext(pOsInterface, handle);
5822 
5823         if (gpuContext)
5824         {
5825             gpuContext->IncrementGpuStatusTag();
5826         }
5827         else
5828         {
5829             MOS_OS_ASSERTMESSAGE("Cannot get valid Gpu context!");
5830         }
5831     }
5832 
5833     PMOS_CONTEXT pOsContext;
5834 
5835     //------------------------------------
5836     MOS_OS_ASSERT(pOsInterface);
5837     MOS_OS_ASSERT(pOsInterface->pOsContext);
5838     //------------------------------------
5839 
5840     pOsContext = pOsInterface->pOsContext;
5841 
5842     pOsContext->pfnIncGpuCtxBufferTag(pOsContext, mosGpuCtx);
5843 }
5844 
5845 //!
5846 //! \brief    Get GPU status Sync tag
5847 //! \details  This function will return the GPU status tag which is updated when corresponding
5848 //!           GPU packet is done. User can use this flag to check if some GPU packet is done.
5849 //! \param    PMOS_INTERFACE pOsInterface
5850 //!           [in] Pointer to OS Interface
5851 //! \param    MOS_GPU_CONTEXT GpuContext
5852 //!           [in] GPU Context
5853 //! \return   uint32_t
5854 //!           Returns the tag
5855 //!
Mos_Specific_GetGpuStatusSyncTag(PMOS_INTERFACE pOsInterface,MOS_GPU_CONTEXT GpuContext)5856 uint32_t Mos_Specific_GetGpuStatusSyncTag(
5857     PMOS_INTERFACE            pOsInterface,
5858     MOS_GPU_CONTEXT           GpuContext)
5859 {
5860     MOS_UNUSED(pOsInterface);
5861     MOS_UNUSED(GpuContext);
5862     return 0;
5863 }
5864 
5865 //!
5866 //! \brief    Sets the resource sync tag
5867 //! \details  Dummy implementation on Linux for compatibility.
5868 //! \param    PMOS_INTERFACE pOsInterface
5869 //!           [in] Pointer to OS Interface
5870 //! \param    PMOS_SYNC_PARAMS pParams
5871 //!           [in] Pointer to sync params
5872 //! \return   void
5873 //!
Mos_Specific_SetResourceSyncTag(PMOS_INTERFACE pOsInterface,PMOS_SYNC_PARAMS pParams)5874 void Mos_Specific_SetResourceSyncTag(
5875     PMOS_INTERFACE         pOsInterface,
5876     PMOS_SYNC_PARAMS       pParams)
5877 {
5878     MOS_UNUSED(pOsInterface);
5879     MOS_UNUSED(pParams);
5880     return ;
5881 }
5882 
5883 //!
5884 //! \brief    Perform overlay sync
5885 //! \details  Dummy implementation on Linux for compatibility.
5886 //! \param    PMOS_INTERFACE pOsInterface
5887 //!           [in] Pointer to OS Interface
5888 //! \param    PMOS_SYNC_PARAMS pParams
5889 //!           [in] Pointer to sync params
5890 //! \return   MOS_STATUS
5891 //!           Return MOS_STATUS_SUCCESS
5892 //!
Mos_Specific_PerformOverlaySync(PMOS_INTERFACE pOsInterface,PMOS_SYNC_PARAMS pParams)5893 MOS_STATUS Mos_Specific_PerformOverlaySync(
5894     PMOS_INTERFACE         pOsInterface,
5895     PMOS_SYNC_PARAMS       pParams)
5896 {
5897     MOS_UNUSED(pOsInterface);
5898     MOS_UNUSED(pParams);
5899     return MOS_STATUS_SUCCESS;
5900 }
5901 
5902 //!
5903 //! \brief    Signal OS Engine
5904 //! \details  Dummy implementation on Linux for compatibility.
5905 //! \param    PMOS_INTERFACE pOsInterface
5906 //!           [in] Pointer to OS Interface
5907 //! \param    PMOS_SYNC_PARAMS pParams
5908 //!           [in] Pointer to sync params
5909 //! \return   MOS_STATUS
5910 //!           Return MOS_STATUS_SUCCESS
5911 //!
Mos_Specific_EngineSignal(PMOS_INTERFACE pOsInterface,PMOS_SYNC_PARAMS pParams)5912 MOS_STATUS Mos_Specific_EngineSignal(
5913     PMOS_INTERFACE         pOsInterface,
5914     PMOS_SYNC_PARAMS       pParams)
5915 {
5916     MOS_UNUSED(pOsInterface);
5917     MOS_UNUSED(pParams);
5918     return MOS_STATUS_SUCCESS;
5919 }
5920 
5921 //!
5922 //! \brief    Wait on sync
5923 //! \details  Dummy implementation on Linux for compatibility.
5924 //! \param    PMOS_INTERFACE pOsInterface
5925 //!           [in] Pointer to OS Interface
5926 //! \param    PMOS_SYNC_PARAMS pParams
5927 //!           [in] Pointer to sync params
5928 //! \return   MOS_STATUS
5929 //!           Return MOS_STATUS_SUCCESS
5930 //!
Mos_Specific_EngineWait(PMOS_INTERFACE pOsInterface,PMOS_SYNC_PARAMS pParams)5931 MOS_STATUS Mos_Specific_EngineWait(
5932     PMOS_INTERFACE         pOsInterface,
5933     PMOS_SYNC_PARAMS       pParams)
5934 {
5935     MOS_UNUSED(pOsInterface);
5936     MOS_UNUSED(pParams);
5937     return MOS_STATUS_SUCCESS;
5938 }
5939 
5940 //!
5941 //! \brief    Signal on resource
5942 //! \details  Dummy implementation on Linux for compatibility.
5943 //! \param    PMOS_INTERFACE pOsInterface
5944 //!           [in] Pointer to OS Interface
5945 //! \param    PMOS_SYNC_PARAMS pParams
5946 //!           [in] Pointer to sync params
5947 //! \return   MOS_STATUS
5948 //!           Return MOS_STATUS_SUCCESS
5949 //!
Mos_Specific_ResourceSignal(PMOS_INTERFACE pOsInterface,PMOS_SYNC_PARAMS pParams)5950 MOS_STATUS Mos_Specific_ResourceSignal(
5951     PMOS_INTERFACE         pOsInterface,
5952     PMOS_SYNC_PARAMS       pParams)
5953 {
5954     MOS_UNUSED(pOsInterface);
5955     MOS_UNUSED(pParams);
5956     return MOS_STATUS_SUCCESS;
5957 }
5958 
5959 //!
5960 //! \brief    Wait on resource
5961 //! \details  Dummy implementation on Linux for compatibility.
5962 //! \param    PMOS_INTERFACE pOsInterface
5963 //!           [in] Pointer to OS Interface
5964 //! \param    PMOS_SYNC_PARAMS pParams
5965 //!           [in] Pointer to sync params
5966 //! \return   MOS_STATUS
5967 //!           Return MOS_STATUS_SUCCESS
5968 //!
Mos_Specific_ResourceWait(PMOS_INTERFACE pOsInterface,PMOS_SYNC_PARAMS pParams)5969 MOS_STATUS Mos_Specific_ResourceWait(
5970     PMOS_INTERFACE         pOsInterface,
5971     PMOS_SYNC_PARAMS       pParams)
5972 {
5973     MOS_UNUSED(pOsInterface);
5974     MOS_UNUSED(pParams);
5975     return MOS_STATUS_SUCCESS;
5976 }
5977 
5978 //!
5979 //! \brief    Create Sync Resource
5980 //! \details  Dummy implementation on Linux for compatibility.
5981 //! \param    PMOS_INTERFACE pOsInterface
5982 //!           [in] Pointer to OS Interface
5983 //! \param    PMOS_RESOURCE pOsResource
5984 //!           [in] Pointer to OS resource
5985 //! \return   MOS_STATUS
5986 //!           Return MOS_STATUS_SUCCESS
5987 //!
Mos_Specific_CreateSyncResource(PMOS_INTERFACE pOsInterface,PMOS_RESOURCE pOsResource)5988 MOS_STATUS Mos_Specific_CreateSyncResource(
5989     PMOS_INTERFACE        pOsInterface,
5990     PMOS_RESOURCE         pOsResource)
5991 {
5992     MOS_UNUSED(pOsInterface);
5993     MOS_UNUSED(pOsResource);
5994     return MOS_STATUS_SUCCESS;
5995 }
5996 
5997 //!
5998 //! \brief    Destroy Sync resource
5999 //! \details  Dummy implementation on Linux for compatibility.
6000 //! \param    PMOS_INTERFACE pOsInterface
6001 //!           [in] Pointer to OS Interface
6002 //! \param    PMOS_RESOURCE pOsResource
6003 //!           [in] Pointer to OS resource
6004 //! \return   MOS_STATUS
6005 //!           Return MOS_STATUS_SUCCESS
6006 //!
Mos_Specific_DestroySyncResource(PMOS_INTERFACE pOsInterface,PMOS_RESOURCE pOsResource)6007 MOS_STATUS Mos_Specific_DestroySyncResource(
6008     PMOS_INTERFACE      pOsInterface,
6009     PMOS_RESOURCE       pOsResource)
6010 {
6011     MOS_UNUSED(pOsInterface);
6012     MOS_UNUSED(pOsResource);
6013     return MOS_STATUS_SUCCESS;
6014 }
6015 
6016 //!
6017 //! \brief    Initializes the tags for Hybrid Decode multi-threading sync
6018 //! \details  Initializes the tags for Hybrid Decode multi-threading sync
6019 //! \param    PMOS_INTERFACE pOsInterface
6020 //!           [in] OS Interface
6021 //! \param    PMOS_RESOURCE pOsResource
6022 //!           [in] Pointer to OS resource
6023 //! \param    uint8_t ucRenderTargetIndex
6024 //!           [in] Index of render target in pSemHandleList for pOsResource
6025 //! \param    PMOS_SEMAPHORE *pCurFrmSem
6026 //!           [in] List of semaphore handles used for current frame sync
6027 //! \param    PMOS_SEMAPHORE *pRefFrmSem
6028 //!           [in] List of semaphore handles used for reference frame sync
6029 //! \param    PMOS_MUTEX *pFrmMutex
6030 //!           [in] List of mutex handles of frame lock mutex
6031 //! \return   MOS_STATUS
6032 //!
Mos_Specific_InitializeMultiThreadingSyncTags(PMOS_INTERFACE pOsInterface,PMOS_RESOURCE pOsResource,uint8_t ucRenderTargetIndex,PMOS_SEMAPHORE * pCurFrmSem,PMOS_SEMAPHORE * pRefFrmSem,PMOS_MUTEX * pFrmMutex)6033 MOS_STATUS Mos_Specific_InitializeMultiThreadingSyncTags(
6034     PMOS_INTERFACE          pOsInterface,
6035     PMOS_RESOURCE           pOsResource,
6036     uint8_t                 ucRenderTargetIndex,
6037     PMOS_SEMAPHORE          *pCurFrmSem,
6038     PMOS_SEMAPHORE          *pRefFrmSem,
6039     PMOS_MUTEX              *pFrmMutex)
6040 {
6041     MOS_STATUS       eStatus = MOS_STATUS_SUCCESS;
6042 
6043     MOS_OS_CHK_NULL(pOsInterface);
6044     MOS_OS_CHK_NULL(pOsResource);
6045     MOS_OS_CHK_NULL(pCurFrmSem);
6046     MOS_OS_CHK_NULL(pRefFrmSem);
6047 
6048     if(*pOsResource->ppReferenceFrameSemaphore == nullptr)
6049     {
6050         *pOsResource->ppReferenceFrameSemaphore = MosUtilities::MosCreateSemaphore(1, 1);
6051     }
6052 
6053     if(*pOsResource->ppCurrentFrameSemaphore == nullptr)
6054     {
6055         *pOsResource->ppCurrentFrameSemaphore = MosUtilities::MosCreateSemaphore(1, 1);
6056     }
6057 
6058     if((*pOsResource->ppReferenceFrameSemaphore != nullptr) && (*pOsResource->ppCurrentFrameSemaphore != nullptr))
6059     {
6060         pCurFrmSem[ucRenderTargetIndex] = *pOsResource->ppCurrentFrameSemaphore;
6061         pRefFrmSem[ucRenderTargetIndex] = *pOsResource->ppReferenceFrameSemaphore;
6062         pFrmMutex[ucRenderTargetIndex]  = nullptr;
6063     }
6064 
6065 finish:
6066     return eStatus;
6067 }
6068 
6069 //!
6070 //! \brief    Wait current frame's semaphore for Hybrid Decode multi-threading sync
6071 //! \details  Wait current frame's semaphore for Hybrid Decode multi-threading sync
6072 //! \param    PMOS_RESOURCE pOsResource
6073 //!           [in] Pointer to OS resource
6074 //! \return   MOS_STATUS
6075 //!
Mos_Specific_MultiThreadingWaitCurrentFrame(PMOS_RESOURCE pOsResource)6076 MOS_STATUS Mos_Specific_MultiThreadingWaitCurrentFrame(
6077     PMOS_RESOURCE   pOsResource)
6078 {
6079     MOS_STATUS      eStatus = MOS_STATUS_SUCCESS;
6080 
6081     MOS_OS_CHK_NULL(pOsResource);
6082 
6083     MOS_OS_CHK_STATUS(MosUtilities::MosWaitSemaphore(*pOsResource->ppCurrentFrameSemaphore, INFINITE));
6084 
6085 finish:
6086     return eStatus;
6087 }
6088 
6089 //!
6090 //! \brief    Post current frame's semaphore for Hybrid Decode multi-threading sync
6091 //! \details  Post current frame's semaphore for Hybrid Decode multi-threading sync
6092 //! \param    PMOS_RESOURCE pOsResource
6093 //!           [in] Pointer to OS resource
6094 //! \return   MOS_STATUS
6095 //!
Mos_Specific_MultiThreadingPostCurrentFrame(PMOS_RESOURCE pOsResource)6096 MOS_STATUS Mos_Specific_MultiThreadingPostCurrentFrame(
6097     PMOS_RESOURCE   pOsResource)
6098 {
6099     MOS_STATUS      eStatus = MOS_STATUS_SUCCESS;
6100 
6101     MOS_OS_CHK_NULL(pOsResource);
6102 
6103     MOS_OS_CHK_STATUS(MosUtilities::MosPostSemaphore(*pOsResource->ppCurrentFrameSemaphore, 1));
6104 
6105 finish:
6106     return eStatus;
6107 }
6108 
6109 //!
6110 //! \brief    Sets hybrid decoder running flag
6111 //! \details  Sets hybrid decoder running flag to indicate there is a hybrid decoder
6112 //!           is running
6113 //! \param    PMOS_INTERFACE pOsInterface
6114 //!           [in] OS Interface
6115 //! \param    int32_t bFlag
6116 //!           [in] hybrid decoder (HEVC or VP9) running flag
6117 //! \return   MOS_STATUS
6118 //!
Mos_Specific_SetHybridDecoderRunningFlag(PMOS_INTERFACE pOsInterface,int32_t bFlag)6119 MOS_STATUS Mos_Specific_SetHybridDecoderRunningFlag(
6120     PMOS_INTERFACE          pOsInterface,
6121     int32_t                 bFlag)
6122 {
6123     PMOS_CONTEXT          pOsContext;
6124     MOS_STATUS            eStatus = MOS_STATUS_SUCCESS;
6125 
6126     MOS_OS_CHK_NULL(pOsInterface);
6127     MOS_OS_CHK_NULL(pOsInterface->pOsContext);
6128 
6129     pOsContext = pOsInterface->pOsContext;
6130     pOsContext->bHybridDecoderRunningFlag = bFlag;
6131 
6132 finish:
6133     return eStatus;
6134 }
6135 
6136 //!
6137 //! \brief    Gets hybrid decoder running flag
6138 //! \details  Gets hybrid decoder running flag to decide if hybrid decoder is being used
6139 //! \param    PMOS_INTERFACE pOsInterface
6140 //!           [in] OS Interface
6141 //! \param    int32_t bFlag
6142 //!           [in] hybrid decoder (HEVC or VP9) running flag
6143 //! \return   MOS_STATUS
6144 //!
Mos_Specific_GetHybridDecoderRunningFlag(PMOS_INTERFACE pOsInterface,int32_t * pFlag)6145 MOS_STATUS Mos_Specific_GetHybridDecoderRunningFlag(
6146     PMOS_INTERFACE          pOsInterface,
6147     int32_t                 *pFlag)
6148 {
6149     PMOS_CONTEXT          pOsContext;
6150     MOS_STATUS            eStatus = MOS_STATUS_SUCCESS;
6151 
6152     MOS_OS_CHK_NULL(pFlag);
6153     *pFlag = false;
6154 
6155     MOS_OS_CHK_NULL(pOsInterface);
6156     MOS_OS_CHK_NULL(pOsInterface->pOsContext);
6157 
6158     pOsContext = pOsInterface->pOsContext;
6159     *pFlag = pOsContext->bHybridDecoderRunningFlag;
6160 
6161 finish:
6162     return eStatus;
6163 }
6164 
6165 //!
6166 //! \brief    Multi thread resource sync method
6167 //! \details  Dummy implementation on Linux for compatibility.
6168 //! \param    PMOS_INTERFACE pOsInterface
6169 //!           [in] OS Interface
6170 //! \param    PMOS_RESOURCE pOsResource
6171 //!           [in] Pointer to OS resource
6172 //! \return   MOS_STATUS
6173 //!
Mos_Specific_MultiThreadResourceSync(PMOS_INTERFACE pOsInterface,PMOS_RESOURCE pOsResource)6174 MOS_STATUS Mos_Specific_MultiThreadResourceSync(
6175     PMOS_INTERFACE          pOsInterface,
6176     PMOS_RESOURCE           pOsResource)
6177 {
6178     MOS_UNUSED(pOsInterface);
6179     MOS_UNUSED(pOsResource);
6180     return MOS_STATUS_SUCCESS;
6181 }
6182 
6183 //!
6184 //! \brief    Registers a complete notification event
6185 //! \details  Registers a complete notification event
6186 //! \param    PMOS_INTERFACE pOsInterface
6187 //!           [in] Pointer to OS Interface
6188 //! \param    MOS_GPU_CONTEXT GpuContext
6189 //!           [in] GPU Context
6190 //! \return   MOS_STATUS
6191 //!           Return MOS_STATUS_SUCCESS
6192 //!
Mos_Specific_RegisterBBCompleteNotifyEvent(PMOS_INTERFACE pOsInterface,MOS_GPU_CONTEXT GpuContext)6193 MOS_STATUS Mos_Specific_RegisterBBCompleteNotifyEvent(
6194     PMOS_INTERFACE     pOsInterface,
6195     MOS_GPU_CONTEXT    GpuContext)
6196 {
6197     MOS_UNUSED(pOsInterface);
6198     MOS_UNUSED(GpuContext);
6199     return MOS_STATUS_SUCCESS;
6200 }
6201 
6202 //!
6203 //! \brief    Waits on a complete notification event
6204 //! \details  Waits on a complete notification event
6205 //! \param    PMOS_INTERFACE pOsInterface
6206 //!           [in] Pointer to OS Interface
6207 //! \param    uint32_t uiTimeOut
6208 //!           [in] Time to wait
6209 //! \return   MOS_STATUS
6210 //!           Return MOS_STATUS_SUCCESS
6211 //!
Mos_Specific_WaitForBBCompleteNotifyEvent(PMOS_INTERFACE pOsInterface,MOS_GPU_CONTEXT GpuContext,uint32_t uiTimeOut)6212 MOS_STATUS Mos_Specific_WaitForBBCompleteNotifyEvent(
6213     PMOS_INTERFACE     pOsInterface,
6214     MOS_GPU_CONTEXT    GpuContext,
6215     uint32_t           uiTimeOut)
6216 {
6217     MOS_UNUSED(pOsInterface);
6218     MOS_UNUSED(GpuContext);
6219     usleep(uiTimeOut);
6220 
6221     return MOS_STATUS_SUCCESS;
6222 }
6223 
Mos_Specific_WaitAllCmdCompletion_Os(PMOS_INTERFACE pOsInterface)6224 MOS_STATUS Mos_Specific_WaitAllCmdCompletion_Os(
6225     PMOS_INTERFACE pOsInterface)
6226 {
6227     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
6228 
6229     return eStatus;
6230 }
6231 
6232 //!
6233 //! \brief    Get interface version
6234 //! \details  Get interface version
6235 //!
6236 //! \param    PMOS_INTERFACE pOsInterface
6237 //!           [in] OS Interface
6238 //!
6239 //! \return   uint32_t
6240 //!           Read-only OS runtime interface version, it's meaning diff from OS and API
6241 //!
Mos_Specific_GetInterfaceVersion(PMOS_INTERFACE pOsInterface)6242 uint32_t Mos_Specific_GetInterfaceVersion(
6243     PMOS_INTERFACE        pOsInterface)
6244 {
6245     MOS_UNUSED(pOsInterface);
6246     return 0;
6247 }
6248 
6249 //!
6250 //! \brief    Determines if the resource should be CPU cacheable during allocation
6251 //! \param    PMOS_INTERFACE pOsInterface
6252 //!           [in] Pointer to OS Interface
6253 //! \param    PMOS_ALLOC_GFXRES_PARAMS pAllocParams
6254 //!           [in] allocation parameters
6255 //! \return   int32_t
6256 //!           Return if resource should be CPU cacheable
6257 //!
Mos_Specific_SetCpuCacheability(PMOS_INTERFACE pOsInterface,PMOS_ALLOC_GFXRES_PARAMS pAllocParams)6258 int32_t Mos_Specific_SetCpuCacheability(
6259     PMOS_INTERFACE              pOsInterface,
6260     PMOS_ALLOC_GFXRES_PARAMS    pAllocParams)
6261 {
6262     MOS_UNUSED(pOsInterface);
6263     MOS_UNUSED(pAllocParams);
6264     return false;
6265 }
6266 
6267 //!
6268 //! \brief    Sets the flags to skip the sync on a particular resource
6269 //! \details  This is required to avoid updating resource tags/masks for a given resource
6270 //!           This way we dont end up putting unnecessary sync points by syncing on this particular resource
6271 //! \param    PMOS_ALLOC_GFXRES_PARAMS pAllocParams
6272 //!           [in] allocation parameters
6273 //! \return   MOS_STATUS
6274 //!           Return MOS_STATUS_SUCCESS if success else failure reason
6275 //!
Mos_Specific_SkipResourceSync(PMOS_RESOURCE pOsResource)6276 MOS_STATUS Mos_Specific_SkipResourceSync(
6277     PMOS_RESOURCE               pOsResource)
6278 {
6279     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
6280 
6281     //---------------------------------------
6282     MOS_OS_CHK_NULL(pOsResource);
6283     //---------------------------------------
6284 
6285     mos_bo_set_object_async(pOsResource->bo);
6286 
6287 finish:
6288     return eStatus;
6289 }
6290 
6291 //!
6292 //! \brief    Gets the HW rendering flags
6293 //! \details  Gets the HW rendering flags
6294 //! \param    PMOS_INTERFACE pOsInterface
6295 //!           [in] Pointer to OS Interface
6296 //! \return   MOS_NULL_RENDERING_FLAGS
6297 //!           Returns the null rendering flags
6298 //!
Mos_Specific_GetNullHWRenderFlags(PMOS_INTERFACE pOsInterface)6299 MOS_NULL_RENDERING_FLAGS  Mos_Specific_GetNullHWRenderFlags(
6300     PMOS_INTERFACE         pOsInterface)
6301 {
6302     return pOsInterface->NullHWAccelerationEnable;
6303 }
6304 
6305 //!
6306 //! \brief    Debug hook to note type of surface state or sampler state being
6307 //!           used.
6308 //! \details  Sets the Command buffer debug info
6309 //! \param    PMOS_INTERFACE pOsInterface
6310 //!           [in] Pointer to OS Interface
6311 //! \param    int32_t bSamplerState
6312 //!           [in] Sampler state
6313 //! \param    int32_t bSurfaceState
6314 //!           [in] Surface state
6315 //! \param    uint32_t dwStateIndex
6316 //!           [in] State index
6317 //! \param    uint32_t dwType
6318 //!           [in] dword type
6319 //! \return   MOS_STATUS
6320 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
6321 //!
Mos_Specific_SetCmdBufferDebugInfo(PMOS_INTERFACE pOsInterface,int32_t bSamplerState,int32_t bSurfaceState,uint32_t dwStateIndex,uint32_t dwType)6322 MOS_STATUS Mos_Specific_SetCmdBufferDebugInfo(
6323     PMOS_INTERFACE              pOsInterface,
6324     int32_t                     bSamplerState,
6325     int32_t                     bSurfaceState,
6326     uint32_t                    dwStateIndex,
6327     uint32_t                    dwType)
6328 {
6329     MOS_UNUSED(pOsInterface);
6330     MOS_UNUSED(bSamplerState);
6331     MOS_UNUSED(bSurfaceState);
6332     MOS_UNUSED(dwStateIndex);
6333     MOS_UNUSED(dwType);
6334     // stub function. implemented for simulation but not driver.
6335     return MOS_STATUS_SUCCESS;
6336 }
6337 
6338 //!
6339 //! \brief    Command buffer debug
6340 //! \details  Debug hook to get type of surface state or sampler state being
6341 //!           used.
6342 //! \param    PMOS_INTERFACE pOsInterface
6343 //! \param    int32_t bSamplerState
6344 //! \param    int32_t bSurfaceState
6345 //! \param    uint32_t dwStateIndex
6346 //! \return   uint32_t
6347 //!
Mos_Specific_GetCmdBufferDebugInfo(PMOS_INTERFACE pOsInterface,int32_t bSamplerState,int32_t bSurfaceState,uint32_t dwStateIndex)6348 uint32_t Mos_Specific_GetCmdBufferDebugInfo(
6349     PMOS_INTERFACE              pOsInterface,
6350     int32_t                     bSamplerState,
6351     int32_t                     bSurfaceState,
6352     uint32_t                    dwStateIndex)
6353 {
6354     MOS_UNUSED(pOsInterface);
6355     MOS_UNUSED(bSamplerState);
6356     MOS_UNUSED(bSurfaceState);
6357     MOS_UNUSED(dwStateIndex);
6358     // stub function. implemented for simulation but not driver.
6359     return 0;
6360 }
6361 
6362 //!
6363 //! \brief    Set PAK/MFX context for Encoder which can be used for Synchronization
6364 //! \details  On Linux, the synchronization is handled in KMD, no job in UMD
6365 //! \param    PMOS_INTERFACE pOsInterface
6366 //!           [in] pointer to OS interface structure
6367 //! \param    MOS_GPU_CONTEXT GpuContext
6368 //!           [in] GPU context
6369 //! \return   MOS_STATUS
6370 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
6371 //!
Mos_Specific_SetEncodePakContext(PMOS_INTERFACE pOsInterface,MOS_GPU_CONTEXT GpuContext)6372 void Mos_Specific_SetEncodePakContext(
6373     PMOS_INTERFACE        pOsInterface,
6374     MOS_GPU_CONTEXT       GpuContext)
6375 {
6376     MOS_UNUSED(pOsInterface);
6377     MOS_UNUSED(GpuContext);
6378     return;
6379 }
6380 
6381 //!
6382 //! \brief    Set VME/ENC context for Encoder which can be used for Synchronization
6383 //! \details  On Linux, the synchronization is handled in KMD, no job in UMD
6384 //! \param    PMOS_INTERFACE pOsInterface
6385 //!           [in] pointer to OS interface structure
6386 //! \param    MOS_GPU_CONTEXT GpuContext
6387 //!           [in] GPU context
6388 //! \return   MOS_STATUS
6389 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
6390 //!
Mos_Specific_SetEncodeEncContext(PMOS_INTERFACE pOsInterface,MOS_GPU_CONTEXT GpuContext)6391 void Mos_Specific_SetEncodeEncContext(
6392     PMOS_INTERFACE        pOsInterface,
6393     MOS_GPU_CONTEXT       GpuContext)
6394 {
6395     MOS_UNUSED(pOsInterface);
6396     MOS_UNUSED(GpuContext);
6397     return;
6398 }
6399 
6400 //!
6401 //! \brief    Verifys the patch list to be used for rendering GPU commands is large enough
6402 //! \details
6403 //! \param    PMOS_INTERFACE pOsInterface
6404 //!           [in] pointer to OS interface structure
6405 //! \param    uint32_t dwRequestedSize
6406 //!           [in] patch list size to be verified
6407 //! \return   MOS_STATUS
6408 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
6409 //!
Mos_Specific_VerifyPatchListSize(PMOS_INTERFACE pOsInterface,uint32_t dwRequestedSize)6410 MOS_STATUS Mos_Specific_VerifyPatchListSize(
6411     PMOS_INTERFACE          pOsInterface,
6412     uint32_t                dwRequestedSize)
6413 {
6414     MOS_OS_FUNCTION_ENTER;
6415 
6416     MOS_OS_CHK_NULL_RETURN(pOsInterface);
6417 
6418     if (pOsInterface->apoMosEnabled)
6419     {
6420         // No APO MOS interface support for this func, implement in wrapper
6421         auto streamState = pOsInterface->osStreamState;
6422 
6423         MOS_OS_CHK_NULL_RETURN(streamState);
6424         MOS_OS_CHK_NULL_RETURN(streamState->osDeviceContext);
6425 
6426         auto osDeviceContext = streamState->osDeviceContext;
6427 
6428         auto gpuContextMgr = osDeviceContext->GetGpuContextMgr();
6429         if (gpuContextMgr)
6430         {
6431             auto gpuCtx = gpuContextMgr->GetGpuContext(streamState->currentGpuContextHandle);
6432 
6433             auto gpuCtxSpecific = static_cast<GpuContextSpecificNext *>(gpuCtx);
6434             MOS_OS_CHK_NULL_RETURN(gpuCtxSpecific);
6435             return (gpuCtxSpecific->VerifyPatchListSize(dwRequestedSize));
6436         }
6437     }
6438     if (pOsInterface->modularizedGpuCtxEnabled && !Mos_Solo_IsEnabled(nullptr))
6439     {
6440         auto gpuContext = Linux_GetGpuContext(pOsInterface, pOsInterface->CurrentGpuContextHandle);
6441         MOS_OS_CHK_NULL_RETURN(gpuContext);
6442 
6443         return (gpuContext->VerifyPatchListSize(dwRequestedSize));
6444     }
6445 
6446     MOS_STATUS              eStatus;
6447     PMOS_OS_CONTEXT         pOsContext;
6448     PMOS_OS_GPU_CONTEXT     pOsGpuContext;
6449 
6450     MOS_OS_CHK_NULL(pOsInterface);
6451 
6452     eStatus       = MOS_STATUS_SUCCESS;
6453 
6454     pOsContext    = pOsInterface->pOsContext;
6455     MOS_OS_CHK_NULL(pOsContext);
6456 
6457     pOsGpuContext = &(pOsContext->OsGpuContext[pOsInterface->CurrentGpuContextOrdinal]);
6458     if (dwRequestedSize > pOsGpuContext->uiMaxPatchLocationsize)
6459     {
6460         eStatus = MOS_STATUS_UNKNOWN;
6461     }
6462 
6463 finish:
6464     return eStatus;
6465 }
6466 
6467 //!
6468 //! \brief    reset command buffer space
6469 //! \details  resets the command buffer space
6470 //! \param    PMOS_INTERFACE pOsInterface
6471 //!           [in] pointer to OS interface structure
6472 //! \param    PMOS_COMMAND_BUFFER pCmdBuffer
6473 //!           [in] pointer to command buffer structure
6474 //! \return   MOS_STATUS
6475 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
6476 //!
Mos_Specific_ResetCommandBuffer(PMOS_INTERFACE pOsInterface,PMOS_COMMAND_BUFFER pCmdBuffer)6477 MOS_STATUS Mos_Specific_ResetCommandBuffer(
6478     PMOS_INTERFACE          pOsInterface,
6479     PMOS_COMMAND_BUFFER     pCmdBuffer)
6480 {
6481     PMOS_OS_CONTEXT         pOsContext;
6482     PMOS_OS_GPU_CONTEXT     pOsGpuContext;
6483     MOS_UNUSED(pCmdBuffer);
6484     MOS_OS_FUNCTION_ENTER;
6485 
6486     MOS_OS_CHK_NULL_RETURN(pOsInterface);
6487     MOS_OS_CHK_NULL_RETURN(pCmdBuffer);
6488 
6489     if (pOsInterface->apoMosEnabled)
6490     {
6491         return MosInterface::ResetCommandBuffer(pOsInterface->osStreamState, pCmdBuffer);
6492     }
6493 
6494     if (pOsInterface->CurrentGpuContextOrdinal == MOS_GPU_CONTEXT_INVALID_HANDLE)
6495     {
6496         MOS_OS_ASSERTMESSAGE("Invalid input parameter GpuContext.");
6497         return MOS_STATUS_INVALID_PARAMETER;
6498     }
6499 
6500     if (pOsInterface->modularizedGpuCtxEnabled && !Mos_Solo_IsEnabled(nullptr))
6501     {
6502         auto gpuContext = Linux_GetGpuContext(pOsInterface, pOsInterface->CurrentGpuContextHandle);
6503         MOS_OS_CHK_NULL_RETURN(gpuContext);
6504 
6505         return gpuContext->ResetCommandBuffer();
6506     }
6507 
6508     pOsContext    = pOsInterface->pOsContext;
6509     pOsGpuContext = &pOsContext->OsGpuContext[pOsInterface->CurrentGpuContextOrdinal];
6510 
6511     pOsGpuContext->bCBFlushed = true;
6512 
6513 finish:
6514     return MOS_STATUS_SUCCESS;
6515 }
6516 
6517 //!
6518 //! \brief    Get the memory compression mode
6519 //! \details  Gets the memory compression mode from GMM
6520 //! \param    PMOS_INTERFACE pOsInterface
6521 //!           [in] pointer to OS interface structure
6522 //! \param    PMOS_RESOURCE pOsResource
6523 //!           [in] pointer to input OS resource
6524 //! \param    PMOS_MEMCOMP_STATE pResMmcMode
6525 //!           [out] the memory compression mode gotten from OS resource
6526 //! \return   MOS_STATUS
6527 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
6528 //!
Mos_Specific_GetMemoryCompressionMode(PMOS_INTERFACE pOsInterface,PMOS_RESOURCE pOsResource,PMOS_MEMCOMP_STATE pResMmcMode)6529 MOS_STATUS Mos_Specific_GetMemoryCompressionMode(
6530     PMOS_INTERFACE      pOsInterface,
6531     PMOS_RESOURCE       pOsResource,
6532     PMOS_MEMCOMP_STATE  pResMmcMode)
6533 {
6534     PGMM_RESOURCE_INFO      pGmmResourceInfo;
6535     GMM_RESOURCE_FLAG       flags;
6536     MOS_STATUS              eStatus = MOS_STATUS_UNKNOWN;
6537     MOS_OS_FUNCTION_ENTER;
6538 
6539     MOS_OS_CHK_NULL_RETURN(pOsResource);
6540     MOS_OS_CHK_NULL_RETURN(pResMmcMode);
6541     MOS_OS_CHK_NULL_RETURN(pOsInterface);
6542 
6543     MediaFeatureTable* skuTable = nullptr;
6544     skuTable = pOsInterface->pfnGetSkuTable(pOsInterface);
6545     MOS_OS_CHK_NULL_RETURN(skuTable);
6546 
6547     if (pOsInterface->apoMosEnabled)
6548     {
6549         return MosInterface::GetMemoryCompressionMode(pOsInterface->osStreamState, pOsResource, *pResMmcMode);
6550     }
6551 
6552     // Get Gmm resource info
6553     pGmmResourceInfo = (GMM_RESOURCE_INFO*)pOsResource->pGmmResInfo;
6554     MOS_OS_CHK_NULL_RETURN(pGmmResourceInfo);
6555 
6556     flags = pOsResource->pGmmResInfo->GetResFlags();
6557 
6558     if (!flags.Gpu.MMC || !flags.Gpu.CCS)
6559     {
6560         *pResMmcMode = MOS_MEMCOMP_DISABLED;
6561         return MOS_STATUS_SUCCESS;
6562     }
6563 
6564     if (flags.Info.MediaCompressed || flags.Info.RenderCompressed)
6565     {
6566         *pResMmcMode = flags.Info.RenderCompressed ? MOS_MEMCOMP_RC : MOS_MEMCOMP_MC;
6567     }
6568     else
6569     {
6570         switch  (pGmmResourceInfo->GetMmcMode(0))
6571         {
6572             case GMM_MMC_HORIZONTAL:
6573                 *pResMmcMode = MOS_MEMCOMP_HORIZONTAL;
6574                 break;
6575             case GMM_MMC_VERTICAL:
6576                 *pResMmcMode = MOS_MEMCOMP_VERTICAL;
6577                 break;
6578             case GMM_MMC_DISABLED:
6579             default:
6580                 *pResMmcMode = MOS_MEMCOMP_DISABLED;
6581                 break;
6582         }
6583     }
6584 
6585     uint32_t          MmcFormat = 0;
6586     GMM_RESOURCE_FORMAT gmmResFmt;
6587 
6588     gmmResFmt = pGmmResourceInfo->GetResourceFormat();
6589 
6590     if (*pResMmcMode == MOS_MEMCOMP_MC         &&
6591        (!MEDIA_IS_SKU(skuTable, FtrFlatPhysCCS)))
6592     {
6593         MmcFormat = static_cast<uint32_t>(pOsInterface->pfnGetGmmClientContext(pOsInterface)->GetMediaSurfaceStateCompressionFormat(gmmResFmt));
6594         *pResMmcMode = (MmcFormat != 0) ? *pResMmcMode : MOS_MEMCOMP_DISABLED;
6595     }
6596 
6597     eStatus = MOS_STATUS_SUCCESS;
6598 
6599 
6600 finish:
6601     return eStatus;
6602 }
6603 
6604 //!
6605 //! \brief    Set the memory compression mode in GMM
6606 //! \details  Set the memory compression mode
6607 //! \param    PMOS_INTERFACE pOsInterface
6608 //!           [in] pointer to OS interface structure
6609 //! \param    PMOS_RESOURCE pOsResource
6610 //!           [in] pointer to input OS resource
6611 //! \param    MOS_MEMCOMP_STATE ResMmcMode
6612 //!           [in] the memory compression mode to be set into OS resource
6613 //! \return   MOS_STATUS
6614 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
6615 //!
Mos_Specific_SetMemoryCompressionMode(PMOS_INTERFACE pOsInterface,PMOS_RESOURCE pOsResource,MOS_MEMCOMP_STATE ResMmcMode)6616 MOS_STATUS Mos_Specific_SetMemoryCompressionMode(
6617     PMOS_INTERFACE      pOsInterface,
6618     PMOS_RESOURCE       pOsResource,
6619     MOS_MEMCOMP_STATE   ResMmcMode)
6620 {
6621     PGMM_RESOURCE_INFO      pGmmResourceInfo = nullptr;
6622     GMM_RESOURCE_MMC_INFO   GmmResMmcMode = GMM_MMC_DISABLED;
6623     MOS_STATUS              eStatus = MOS_STATUS_UNKNOWN;
6624     MOS_OS_FUNCTION_ENTER;
6625     MOS_OS_CHK_NULL(pOsResource);
6626     MOS_OS_CHK_NULL(pOsInterface);
6627 
6628     if (pOsInterface->apoMosEnabled)
6629     {
6630         return MosInterface::SetMemoryCompressionMode(pOsInterface->osStreamState, pOsResource, ResMmcMode);
6631     }
6632 
6633     // Get Gmm resource info
6634     pGmmResourceInfo = (GMM_RESOURCE_INFO*)pOsResource->pGmmResInfo;
6635     MOS_OS_CHK_NULL(pGmmResourceInfo);
6636 
6637     switch (ResMmcMode)
6638     {
6639         case MOS_MEMCOMP_HORIZONTAL:
6640             GmmResMmcMode = GMM_MMC_HORIZONTAL;
6641             break;
6642         case MOS_MEMCOMP_VERTICAL:
6643             GmmResMmcMode = GMM_MMC_VERTICAL;
6644             break;
6645         case MOS_MEMCOMP_DISABLED:
6646         default:
6647             GmmResMmcMode = GMM_MMC_DISABLED;
6648             break;
6649     }
6650 
6651     pGmmResourceInfo->SetMmcMode(GmmResMmcMode, 0);
6652 
6653     eStatus = MOS_STATUS_SUCCESS;
6654 
6655 finish:
6656     return eStatus;
6657 }
6658 
6659 //!
6660 //! \brief    Set the memory compression hint in GMM on Linux or Gralloc on Android
6661 //! \details  Indicate if the surface is compressible
6662 //! \param    PMOS_INTERFACE pOsInterface
6663 //!           [in] pointer to OS interface structure
6664 //! \param    PMOS_RESOURCE pOsResource
6665 //!           [in] pointer to input OS resource
6666 //! \param    int32_t bHintOn
6667 //!           [in] the memory compression hint to be set
6668 //! \return   MOS_STATUS
6669 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
6670 //!
Mos_Specific_SetMemoryCompressionHint(PMOS_INTERFACE pOsInterface,PMOS_RESOURCE pOsResource,int32_t bHintOn)6671 MOS_STATUS Mos_Specific_SetMemoryCompressionHint(
6672     PMOS_INTERFACE      pOsInterface,
6673     PMOS_RESOURCE       pOsResource,
6674     int32_t             bHintOn)
6675 {
6676     PGMM_RESOURCE_INFO      pGmmResourceInfo = nullptr;
6677     uint32_t                uiArrayIndex = 0;
6678     MOS_STATUS              eStatus;
6679     MOS_OS_FUNCTION_ENTER;
6680     eStatus = MOS_STATUS_UNKNOWN;
6681     MOS_OS_CHK_NULL(pOsResource);
6682     MOS_OS_CHK_NULL(pOsInterface);
6683 
6684      if (pOsInterface->apoMosEnabled)
6685      {
6686          return MosInterface::SetMemoryCompressionHint(pOsInterface->osStreamState, pOsResource, bHintOn);
6687      }
6688 
6689     // Get Gmm resource info
6690     pGmmResourceInfo = (GMM_RESOURCE_INFO*)pOsResource->pGmmResInfo;
6691     MOS_OS_CHK_NULL(pGmmResourceInfo);
6692 
6693     pGmmResourceInfo->SetMmcHint(bHintOn ? GMM_MMC_HINT_ON : GMM_MMC_HINT_OFF, uiArrayIndex);
6694 
6695     eStatus = MOS_STATUS_SUCCESS;
6696 
6697 finish:
6698     return eStatus;
6699 }
6700 
6701 //!
6702 //! \brief    Get the memory compression format
6703 //! \details  Gets the memory compression format from GMM
6704 //! \param    PMOS_INTERFACE pOsInterface
6705 //!           [in] pointer to OS interface structure
6706 //! \param    PMOS_RESOURCE pOsResource
6707 //!           [in] pointer to input OS resource
6708 //! \param    uint32_t *pResMmcFormat
6709 //!           [out] the memory compression format gotten from GMM resource
6710 //! \return   MOS_STATUS
6711 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
6712 //!
Mos_Specific_GetMemoryCompressionFormat(PMOS_INTERFACE pOsInterface,PMOS_RESOURCE pOsResource,uint32_t * pResMmcFormat)6713 MOS_STATUS Mos_Specific_GetMemoryCompressionFormat(
6714     PMOS_INTERFACE      pOsInterface,
6715     PMOS_RESOURCE       pOsResource,
6716     uint32_t            *pResMmcFormat)
6717 {
6718 
6719     PGMM_RESOURCE_INFO      pGmmResourceInfo;
6720     MOS_STATUS              eStatus = MOS_STATUS_UNKNOWN;
6721     MOS_OS_FUNCTION_ENTER;
6722     MOS_OS_CHK_NULL(pOsResource);
6723     MOS_OS_CHK_NULL(pOsInterface);
6724     MOS_OS_CHK_NULL(pResMmcFormat);
6725 
6726     if (pOsInterface->apoMosEnabled)
6727     {
6728         return MosInterface::GetMemoryCompressionFormat(pOsInterface->osStreamState, pOsResource, pResMmcFormat);
6729     }
6730 
6731     // Get Gmm resource info
6732     pGmmResourceInfo = (GMM_RESOURCE_INFO*)pOsResource->pGmmResInfo;
6733     MOS_OS_CHK_NULL(pGmmResourceInfo);
6734 
6735     MOS_OS_CHK_NULL(pOsInterface->pfnGetGmmClientContext(pOsInterface));
6736     // Get compression format from GMM RESOURCE FORMAT
6737     GMM_RESOURCE_FORMAT gmmResFmt;
6738     gmmResFmt = pGmmResourceInfo->GetResourceFormat();
6739     MOS_MEMCOMP_STATE   MmcMode;
6740     uint32_t            MmcFormat;
6741     Mos_Specific_GetMemoryCompressionMode(pOsInterface, pOsResource, &MmcMode);
6742     switch (MmcMode)
6743     {
6744     case MOS_MEMCOMP_MC:
6745         MmcFormat = static_cast<uint32_t>(pOsInterface->pfnGetGmmClientContext(pOsInterface)->GetMediaSurfaceStateCompressionFormat(gmmResFmt));
6746         break;
6747     case MOS_MEMCOMP_RC:
6748         MmcFormat = static_cast<uint32_t>(pOsInterface->pfnGetGmmClientContext(pOsInterface)->GetSurfaceStateCompressionFormat(gmmResFmt));
6749         break;
6750     default:
6751         MmcFormat = 0;
6752     }
6753 
6754     if (MmcFormat > 0x1F)
6755     {
6756         MOS_OS_ASSERTMESSAGE("Get a incorrect Compression format(%d) from GMM", MmcFormat);
6757     }
6758     else
6759     {
6760         *pResMmcFormat = MmcFormat;
6761         MOS_OS_VERBOSEMESSAGE("GMM compression mode %d, compression format %d", MmcMode, MmcFormat);
6762     }
6763 
6764     eStatus = MOS_STATUS_SUCCESS;
6765 
6766 finish:
6767     return eStatus;
6768 
6769 }
6770 
6771 #ifdef ANDROID
6772 //!
6773 //! \brief    Create GPU node association.
6774 //! \details  Create GPU node association.
6775 //! \param    PMOS_INTERFACE pOsInterface
6776 //!           [in] OS Interface
6777 //! \param    MOS_MEDIA_OPERATION MediaOperation
6778 //!           [in] Media operation
6779 //! \param    MOS_GPU_NODE *pVideoNodeOrdinal
6780 //!           [out] VCS node ordinal
6781 //! \return   MOS_STATUS
6782 //!           MOS_STATUS_SUCCESS if success, otherwise error code
6783 //!
Mos_Specific_CreateVideoNodeAssociation(PMOS_INTERFACE pOsInterface,int32_t bSetVideoNode,MOS_GPU_NODE * pVideoNodeOrdinal)6784 MOS_STATUS Mos_Specific_CreateVideoNodeAssociation(
6785     PMOS_INTERFACE      pOsInterface,
6786     int32_t             bSetVideoNode,
6787     MOS_GPU_NODE        *pVideoNodeOrdinal)
6788 {
6789     MOS_UNUSED(pOsInterface);
6790     MOS_UNUSED(bSetVideoNode);
6791     MOS_OS_ASSERT(pVideoNodeOrdinal);
6792 
6793     // return VDBox #1 for now.
6794     *pVideoNodeOrdinal = MOS_GPU_NODE_VIDEO;
6795 
6796     return MOS_STATUS_SUCCESS;
6797 }
6798 
6799 //!
6800 //! \brief    Destroy GPU node association.
6801 //! \details  Destroy GPU node association.
6802 //! \param    PMOS_INTERFACE pOsInterface
6803 //!           [in] OS Interface
6804 //! \param    MOS_GPU_NODE VideoNodeOrdinal
6805 //!           [in] VCS node ordinal
6806 //! \return   MOS_STATUS
6807 //!           MOS_STATUS_SUCCESS if success, otherwise error code
6808 //!
Mos_Specific_DestroyVideoNodeAssociation(PMOS_INTERFACE pOsInterface,MOS_GPU_NODE VideoNodeOrdinal)6809 MOS_STATUS Mos_Specific_DestroyVideoNodeAssociation(
6810     PMOS_INTERFACE     pOsInterface,
6811     MOS_GPU_NODE       VideoNodeOrdinal)
6812 {
6813     MOS_UNUSED(pOsInterface);
6814     MOS_UNUSED(VideoNodeOrdinal);
6815     return MOS_STATUS_SUCCESS;
6816 }
6817 
6818 #else
6819 
6820 //!
6821 //! \brief    Create GPU node association.
6822 //! \details  Create GPU node association.
6823 //! \param    PMOS_INTERFACE pOsInterface
6824 //!           [in] OS Interface
6825 //! \param    MOS_MEDIA_OPERATION MediaOperation
6826 //!           [in] Media operation
6827 //! \param    MOS_GPU_NODE *pVideoNodeOrdinal
6828 //!           [out] VCS node ordinal
6829 //! \return   MOS_STATUS
6830 //!           MOS_STATUS_SUCCESS if success, otherwise error code
6831 //!
Mos_Specific_CreateVideoNodeAssociation(PMOS_INTERFACE pOsInterface,int32_t bSetVideoNode,MOS_GPU_NODE * pVideoNodeOrdinal)6832 MOS_STATUS Mos_Specific_CreateVideoNodeAssociation(
6833     PMOS_INTERFACE      pOsInterface,
6834     int32_t             bSetVideoNode,
6835     MOS_GPU_NODE        *pVideoNodeOrdinal)
6836 {
6837     PMOS_OS_CONTEXT         pOsContext;
6838     PVDBOX_WORKLOAD         pVDBoxWorkLoad = nullptr;
6839     MOS_STATUS              eStatus = MOS_STATUS_SUCCESS;
6840 
6841     MOS_OS_FUNCTION_ENTER;
6842 
6843     MOS_OS_ASSERT(pOsInterface);
6844     MOS_OS_ASSERT(pVideoNodeOrdinal);
6845 
6846     pOsContext = pOsInterface->pOsContext;
6847 
6848     if (false == pOsContext->bKMDHasVCS2)
6849     {
6850         *pVideoNodeOrdinal = MOS_GPU_NODE_VIDEO;
6851         goto finish;
6852     }
6853 
6854     // If node selection is forced or we have only one VDBox, turn balancing off.
6855     // After that check debug flags.
6856     if (pOsInterface->bEnableVdboxBalancing)
6857     {
6858         pOsContext->bPerCmdBufferBalancing = !bSetVideoNode && pOsContext->bKMDHasVCS2 && pOsInterface->pfnGetVdboxNodeId;
6859     }
6860     else
6861     {
6862         pOsContext->bPerCmdBufferBalancing = 0;
6863     }
6864 
6865 #if (_DEBUG || _RELEASE_INTERNAL)
6866     if (pOsInterface->eForceVdbox == MOS_FORCE_VDBOX_1)
6867     {
6868         bSetVideoNode = true;
6869         *pVideoNodeOrdinal = MOS_GPU_NODE_VIDEO;
6870         pOsContext->bPerCmdBufferBalancing = 0;
6871     }
6872     else if (pOsInterface->eForceVdbox == MOS_FORCE_VDBOX_2)
6873     {
6874         bSetVideoNode = true;
6875         *pVideoNodeOrdinal = MOS_GPU_NODE_VIDEO2;
6876         pOsContext->bPerCmdBufferBalancing = 0;
6877     }
6878 #endif // _DEBUG || _RELEASE_INTERNAL
6879 
6880     if (pOsContext->semid == MOS_LINUX_IPC_INVALID_ID)
6881     {
6882         MOS_OS_ASSERTMESSAGE("Invalid semid in OsContext.");
6883         eStatus = MOS_STATUS_UNKNOWN;
6884         goto finish;
6885     }
6886 
6887     LockSemaphore(pOsContext->semid);
6888 
6889     pVDBoxWorkLoad = (PVDBOX_WORKLOAD)pOsContext->pShm;
6890     MOS_OS_ASSERT(pVDBoxWorkLoad);
6891 
6892     if (bSetVideoNode)
6893     {
6894         if (*pVideoNodeOrdinal == MOS_GPU_NODE_VIDEO)
6895         {
6896             pVDBoxWorkLoad->uiVDBoxCount[0]++;
6897         }
6898         else if (*pVideoNodeOrdinal == MOS_GPU_NODE_VIDEO2)
6899         {
6900             pVDBoxWorkLoad->uiVDBoxCount[1]++;
6901         }
6902         else
6903         {
6904             MOS_OS_ASSERTMESSAGE("VDBoxWorkLoad not set.");
6905         }
6906     }
6907     else
6908     {
6909         if (pVDBoxWorkLoad->uiVDBoxCount[0] < pVDBoxWorkLoad->uiVDBoxCount[1])
6910         {
6911             *pVideoNodeOrdinal = MOS_GPU_NODE_VIDEO;
6912             pVDBoxWorkLoad->uiVDBoxCount[0]++;
6913         }
6914         else if (pVDBoxWorkLoad->uiVDBoxCount[0] == pVDBoxWorkLoad->uiVDBoxCount[1])
6915         {
6916             // this ping-pong method improves much performance for multi-session HD to HD xcode
6917             if (pVDBoxWorkLoad->uiRingIndex == 0)
6918             {
6919                 *pVideoNodeOrdinal = MOS_GPU_NODE_VIDEO;
6920                 pVDBoxWorkLoad->uiVDBoxCount[0]++;
6921                 pVDBoxWorkLoad->uiRingIndex = 1;
6922             }
6923             else
6924             {
6925                 *pVideoNodeOrdinal = MOS_GPU_NODE_VIDEO2;
6926                 pVDBoxWorkLoad->uiVDBoxCount[1]++;
6927                 pVDBoxWorkLoad->uiRingIndex = 0;
6928             }
6929         }
6930         else
6931         {
6932             *pVideoNodeOrdinal = MOS_GPU_NODE_VIDEO2;
6933             pVDBoxWorkLoad->uiVDBoxCount[1]++;
6934         }
6935     }
6936 
6937     UnLockSemaphore(pOsContext->semid);
6938 
6939 finish:
6940     return eStatus;
6941 }
6942 
6943 //!
6944 //! \brief    Destroy GPU node association.
6945 //! \details  Destroy GPU node association.
6946 //! \param    PMOS_INTERFACE pOsInterface
6947 //!           [in] OS Interface
6948 //! \param    MOS_GPU_NODE VideoNodeOrdinal
6949 //!           [in] VCS node ordinal
6950 //! \return   MOS_STATUS
6951 //!           MOS_STATUS_SUCCESS if success, otherwise error code
6952 //!
Mos_Specific_DestroyVideoNodeAssociation(PMOS_INTERFACE pOsInterface,MOS_GPU_NODE VideoNodeOrdinal)6953 MOS_STATUS Mos_Specific_DestroyVideoNodeAssociation(
6954     PMOS_INTERFACE     pOsInterface,
6955     MOS_GPU_NODE       VideoNodeOrdinal)
6956 {
6957     PMOS_OS_CONTEXT         pOsContext = nullptr;
6958     PVDBOX_WORKLOAD         pVDBoxWorkLoad = nullptr;
6959 
6960     MOS_OS_FUNCTION_ENTER;
6961     MOS_OS_CHK_NULL_RETURN(pOsInterface);
6962     MOS_OS_CHK_NULL_RETURN(pOsInterface->pOsContext);
6963     pOsContext    = pOsInterface->pOsContext;
6964 
6965     // not do workload balancing in UMD just return;
6966     if (pOsContext->bKMDHasVCS2 == false)
6967     {
6968         return MOS_STATUS_SUCCESS;
6969     }
6970 
6971      if (pOsContext->semid == MOS_LINUX_IPC_INVALID_ID)
6972      {
6973          MOS_OS_ASSERTMESSAGE("Invalid semid in OsContext.");
6974          return MOS_STATUS_UNKNOWN;
6975      }
6976 
6977     LockSemaphore(pOsContext->semid);
6978 
6979     pVDBoxWorkLoad = (PVDBOX_WORKLOAD)pOsContext->pShm;
6980     MOS_OS_ASSERT(pVDBoxWorkLoad);
6981 
6982     if (VideoNodeOrdinal == MOS_GPU_NODE_VIDEO)
6983     {
6984         pVDBoxWorkLoad->uiVDBoxCount[0]--;
6985     }
6986     else
6987     {
6988         pVDBoxWorkLoad->uiVDBoxCount[1]--;
6989     }
6990 
6991     UnLockSemaphore(pOsContext->semid);
6992 
6993     return MOS_STATUS_SUCCESS;
6994 }
6995 #endif
6996 
Mos_Specific_GetVdboxNodeId(PMOS_INTERFACE pOsInterface,PMOS_COMMAND_BUFFER pCmdBuffer)6997 MOS_VDBOX_NODE_IND Mos_Specific_GetVdboxNodeId(
6998     PMOS_INTERFACE pOsInterface,
6999     PMOS_COMMAND_BUFFER pCmdBuffer)
7000 {
7001     MOS_VDBOX_NODE_IND idx = MOS_VDBOX_NODE_INVALID;
7002 
7003     MOS_OS_CHK_NULL_NO_STATUS(pCmdBuffer);
7004     MOS_OS_CHK_NULL_NO_STATUS(pOsInterface);
7005     MOS_OS_CHK_NULL_NO_STATUS(pOsInterface->pOsContext);
7006 
7007     // If we have assigned vdbox index for the given cmdbuf, return it immediately
7008     if (MOS_VDBOX_NODE_INVALID != pCmdBuffer->iVdboxNodeIndex) {
7009         idx = pCmdBuffer->iVdboxNodeIndex;
7010         return idx;
7011     }
7012 
7013 finish:
7014     return idx;
7015 }
7016 
7017 //!
7018 //! \brief    Get the memory object
7019 //! \details  Get the memory object for cache policy
7020 //! \param    MOS_HW_RESOURCE_DEF MosUsage
7021 //!           [in] HW resource
7022 //!           [in] Gmm client context
7023 //! \return   MEMORY_OBJECT_CONTROL_STATE
7024 //!           Return the memory object
7025 //!
Mos_Specific_CachePolicyGetMemoryObject(MOS_HW_RESOURCE_DEF MosUsage,GMM_CLIENT_CONTEXT * pGmmClientContext)7026 MEMORY_OBJECT_CONTROL_STATE Mos_Specific_CachePolicyGetMemoryObject(
7027     MOS_HW_RESOURCE_DEF         MosUsage,
7028     GMM_CLIENT_CONTEXT          *pGmmClientContext)
7029 {
7030    // Force convert to stream handle for wrapper
7031     return MosInterface::GetCachePolicyMemoryObject(pGmmClientContext, MosUsage);
7032 }
7033 
7034 //!
7035 //! \brief    Get the L1 config
7036 //! \details  Get the L1 config for cache policy
7037 //! \param    MOS_HW_RESOURCE_DEF MosUsage
7038 //!           [in] HW resource
7039 //!           [in] Gmm client context
7040 //! \return   uint8_t
7041 //!           L1_CACHE_CONTROL
7042 //!
Mos_Specific_CachePolicyGetL1Config(MOS_HW_RESOURCE_DEF MosUsage,GMM_CLIENT_CONTEXT * pGmmClientContext)7043 uint8_t Mos_Specific_CachePolicyGetL1Config(
7044     MOS_HW_RESOURCE_DEF         MosUsage,
7045     GMM_CLIENT_CONTEXT          *pGmmClientContext)
7046 {
7047     return 0;
7048 }
7049 
7050 
7051 //*-----------------------------------------------------------------------------
7052 //| Purpose   : Loads library
7053 //| Returns   : Instance to handle
7054 //*-----------------------------------------------------------------------------
7055 //!
7056 //! \brief
7057 //! \details
7058 //! \param    const char  *pFileName
7059 //! \return   HINSTANCE
7060 //!
Mos_Specific_LoadLibrary(PMOS_INTERFACE pOsInterface,PCCHAR pFileName,void ** ppvModule)7061 MOS_STATUS Mos_Specific_LoadLibrary(
7062     PMOS_INTERFACE              pOsInterface,
7063     PCCHAR                      pFileName,
7064     void                        **ppvModule)
7065 {
7066     char  *error;
7067     MOS_UNUSED(pOsInterface);
7068     //---------------------------------
7069     MOS_OS_ASSERT(pFileName);
7070     //---------------------------------
7071 
7072     return MosInterface::MosLoadLibrary(nullptr, pFileName, ppvModule);
7073 }
7074 
7075 //*-----------------------------------------------------------------------------
7076 //| Purpose   : Frees library
7077 //| Returns   : Result of the operation
7078 //*-----------------------------------------------------------------------------
7079 //!
7080 //! \brief
7081 //! \details
7082 //! \param    HINSTANCE hInstance
7083 //! \return   MOS_STATUS
7084 //!
Mos_Specific_FreeLibrary(void * hInstance)7085 MOS_STATUS Mos_Specific_FreeLibrary(
7086     void  *hInstance)
7087 {
7088     int32_t bStatus;
7089 
7090     //---------------------------------
7091     MOS_OS_ASSERT(hInstance);
7092     //---------------------------------
7093 
7094     return MosInterface::MosFreeLibrary(hInstance);
7095 }
7096 
7097 //!
7098 //! \brief    Determines if the GPU Hung
7099 //! \param    PMOS_INTERFACE pOsInterface
7100 //!           [in] Pointer to OS Interface
7101 //! \return   int32_t
7102 //!           Return if the GPU Hung
7103 //!
Mos_Specific_IsGPUHung(PMOS_INTERFACE pOsInterface)7104 int32_t Mos_Specific_IsGPUHung(
7105     PMOS_INTERFACE              pOsInterface)
7106 {
7107     uint32_t dwResetCount = 0;
7108     uint32_t dwActiveBatch = 0;
7109     uint32_t dwPendingBatch = 0;
7110     int32_t bResult = false;
7111     int32_t ret = 0;
7112 
7113     if (pOsInterface == nullptr)
7114     {
7115         MOS_OS_ASSERTMESSAGE("Mos_Specific_IsGPUHung: pOsInterface == NULL");
7116         return false;
7117     }
7118 
7119     if (pOsInterface->apoMosEnabled)
7120     {
7121         return MosInterface::IsGPUHung(pOsInterface->osStreamState);
7122     }
7123 
7124     dwResetCount = dwActiveBatch = dwPendingBatch = 0;
7125 
7126     ret = mos_get_reset_stats(pOsInterface->pOsContext->intel_context, &dwResetCount,
7127                                 &dwActiveBatch, &dwPendingBatch);
7128     if (ret)
7129     {
7130         MOS_OS_NORMALMESSAGE("mos_get_reset_stats return error(%d)\n", ret);
7131         goto finish;
7132     }
7133 
7134     if (dwResetCount != pOsInterface->dwGPUResetCount   ||
7135         dwActiveBatch != pOsInterface->dwGPUActiveBatch ||
7136         dwPendingBatch != pOsInterface->dwGPUPendingBatch)
7137     {
7138         pOsInterface->dwGPUResetCount   = dwResetCount;
7139         pOsInterface->dwGPUActiveBatch  = dwActiveBatch;
7140         pOsInterface->dwGPUPendingBatch = dwPendingBatch;
7141         bResult = true;
7142     }
7143 
7144 finish:
7145     return bResult;
7146 }
7147 
Mos_Specific_GetAuxTableBaseAddr(PMOS_INTERFACE osInterface)7148 uint64_t Mos_Specific_GetAuxTableBaseAddr(
7149     PMOS_INTERFACE              osInterface)
7150 {
7151     if (osInterface == nullptr || osInterface->osContextPtr == nullptr)
7152     {
7153         MOS_OS_NORMALMESSAGE("Invalid osInterface");
7154         return 0;
7155     }
7156     auto osCtx = static_cast<OsContextSpecific *>(osInterface->osContextPtr);
7157     AuxTableMgr *auxTableMgr = osCtx->GetAuxTableMgr();
7158 
7159     return auxTableMgr ? auxTableMgr->GetAuxTableBase() : 0;
7160 }
7161 
7162 //!
7163 //! \brief  Get gpu context priority from KMD
7164 //! \param  [in] pOsInterface
7165 //!         Pointer to OS interface
7166 //! \param  [out] pPriority
7167 //!         the priority of the  current context.
7168 //!
Mos_Specific_GetGpuPriority(PMOS_INTERFACE pOsInterface,int32_t * pPriority)7169 void Mos_Specific_GetGpuPriority(
7170         PMOS_INTERFACE              pOsInterface,
7171         int32_t*                    pPriority)
7172 {
7173     MOS_OS_ASSERT(pOsInterface);
7174 
7175     if (pOsInterface->apoMosEnabled)
7176     {
7177         return MosInterface::GetGpuPriority(pOsInterface->osStreamState, pPriority);
7178     }
7179 
7180     if (pOsInterface->osContextPtr)
7181     {
7182         auto osCxtSpecific = static_cast<OsContextSpecific*>(pOsInterface->osContextPtr);
7183         osCxtSpecific->GetGpuPriority(pPriority);
7184     }
7185     else
7186     {
7187         MOS_OS_ASSERTMESSAGE("OS context is nullptr.");
7188     }
7189 }
7190 
7191 //!
7192 //! \brief  Set gpu priority to KMD
7193 //! \param  [in] pOsInterface
7194 //!         Pointer to OS interface
7195 //! \param  [in] priority
7196 //!         the priority set to current context.
7197 //!
Mos_Specific_SetGpuPriority(PMOS_INTERFACE pOsInterface,int32_t priority)7198 void Mos_Specific_SetGpuPriority(
7199         PMOS_INTERFACE              pOsInterface,
7200         int32_t                     priority)
7201 {
7202     MOS_OS_ASSERT(pOsInterface);
7203 
7204     if (pOsInterface->apoMosEnabled)
7205     {
7206         return MosInterface::SetGpuPriority(pOsInterface->osStreamState, priority);
7207     }
7208 
7209     if (pOsInterface->osContextPtr)
7210     {
7211         auto osCxtSpecific = static_cast<OsContextSpecific*>(pOsInterface->osContextPtr);
7212         osCxtSpecific->SetGpuPriority(priority);
7213     }
7214     else
7215     {
7216         MOS_OS_ASSERTMESSAGE("OS context is nullptr.");
7217     }
7218 }
7219 
7220 //!
7221 //! \brief  Set slice count to shared memory and KMD
7222 //! \param  [in] pOsInterface
7223 //!         Pointer to OS interface
7224 //! \param  [in,out] pSliceCount
7225 //!         Pointer to the slice count. Input the slice count for current
7226 //!         context, output the ruling slice count shared by all contexts.
7227 //!
Mos_Specific_SetSliceCount(PMOS_INTERFACE pOsInterface,uint32_t * pSliceCount)7228 void Mos_Specific_SetSliceCount(
7229         PMOS_INTERFACE              pOsInterface,
7230         uint32_t *pSliceCount)
7231 {
7232     MOS_OS_ASSERT(pOsInterface);
7233     MOS_OS_ASSERT(pSliceCount);
7234 
7235     if (pOsInterface->osContextPtr)
7236     {
7237         pOsInterface->osContextPtr->SetSliceCount(pSliceCount);
7238     }
7239     else
7240     {
7241         MOS_OS_ASSERTMESSAGE("OS context is nullptr.");
7242     }
7243 }
7244 
7245 //!
7246 //! \brief
7247 //! \details
7248 //! \param    const char  *pFileName
7249 //! \return   HINSTANCE
7250 //!
Mos_Specific_LogData(char * pData)7251 void Mos_Specific_LogData(
7252     char       *pData)
7253 {
7254     MOS_UNUSED(pData);
7255     return;
7256 }
7257 
Mos_Specific_NotifyStreamIndexSharing(PMOS_INTERFACE pOsInterface)7258 void Mos_Specific_NotifyStreamIndexSharing(
7259     PMOS_INTERFACE              pOsInterface)
7260 {
7261     MOS_UNUSED(pOsInterface);
7262 }
7263 
Mos_Specific_CheckVirtualEngineSupported(PMOS_INTERFACE pOsResource)7264 MOS_STATUS Mos_Specific_CheckVirtualEngineSupported(
7265     PMOS_INTERFACE      pOsResource)
7266 {
7267     auto skuTable = pOsResource->pfnGetSkuTable(pOsResource);
7268     MOS_OS_CHK_NULL_RETURN(skuTable);
7269     if (MEDIA_IS_SKU(skuTable, FtrContextBasedScheduling))
7270     {
7271         pOsResource->bSupportVirtualEngine = true;
7272     }
7273     else
7274     {
7275         pOsResource->bSupportVirtualEngine = false;
7276     }
7277 
7278     return MOS_STATUS_SUCCESS;
7279 }
7280 
Mos_Specific_InitInterface_Ve(PMOS_INTERFACE osInterface)7281 static MOS_STATUS Mos_Specific_InitInterface_Ve(
7282     PMOS_INTERFACE osInterface)
7283 {
7284     PLATFORM                            Platform;
7285     MOS_STATUS                          eStatus;
7286     MOS_USER_FEATURE_VALUE_DATA         userFeatureData;
7287     MOS_STATUS                          eStatusUserFeature;
7288 
7289     MOS_OS_FUNCTION_ENTER;
7290 
7291     eStatus = MOS_STATUS_SUCCESS;
7292     eStatusUserFeature = MOS_STATUS_SUCCESS;
7293 
7294     // Get platform information
7295     memset(&Platform, 0, sizeof(PLATFORM));
7296     if (!Mos_Solo_IsEnabled(nullptr))
7297     {
7298         osInterface->pfnGetPlatform(osInterface, &Platform);
7299     }
7300 
7301     if (GFX_IS_GEN_11_OR_LATER(Platform) || Mos_Solo_IsEnabled(nullptr))
7302     {
7303         //keep this as false until VE is enabled by all media components
7304         osInterface->bSupportVirtualEngine = false;
7305         osInterface->bUseHwSemaForResSyncInVE = false;
7306         osInterface->pVEInterf = nullptr;
7307         osInterface->VEEnable = false;
7308 
7309         auto skuTable = osInterface->pfnGetSkuTable(osInterface);
7310         MOS_OS_CHK_NULL_RETURN(skuTable);
7311         if (MEDIA_IS_SKU(skuTable, FtrGucSubmission))
7312         {
7313             osInterface->bGucSubmission = true;
7314         }
7315 
7316         //Read Scalable/Legacy Decode mode on Gen11+
7317         //1:by default for scalable decode mode
7318         //0:for legacy decode mode
7319         MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
7320         eStatusUserFeature = MOS_UserFeature_ReadValue_ID(
7321             NULL,
7322             __MEDIA_USER_FEATURE_VALUE_ENABLE_HCP_SCALABILITY_DECODE_ID,
7323             &userFeatureData,
7324             (MOS_CONTEXT_HANDLE)osInterface->pOsContext);
7325         osInterface->bHcpDecScalabilityMode = userFeatureData.u32Data ? MOS_SCALABILITY_ENABLE_MODE_DEFAULT : MOS_SCALABILITY_ENABLE_MODE_FALSE;
7326         if(osInterface->bHcpDecScalabilityMode
7327             && (eStatusUserFeature == MOS_STATUS_SUCCESS))
7328         {
7329             //user's value to enable scalability
7330             osInterface->bHcpDecScalabilityMode = MOS_SCALABILITY_ENABLE_MODE_USER_FORCE;
7331         }
7332 
7333 #if (_DEBUG || _RELEASE_INTERNAL)
7334         osInterface->frameSplit                  = false;
7335         MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
7336         MOS_UserFeature_ReadValue_ID(
7337             NULL,
7338             __MEDIA_USER_FEATURE_VALUE_ENABLE_LINUX_FRAME_SPLIT_ID,
7339             &userFeatureData,
7340             (MOS_CONTEXT_HANDLE)osInterface->pOsContext);
7341         osInterface->frameSplit = (uint32_t)userFeatureData.i32Data;
7342 
7343         MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
7344         MOS_UserFeature_ReadValue_ID(
7345             NULL,
7346             __MEDIA_USER_FEATURE_VALUE_ENABLE_GUC_SUBMISSION_ID,
7347             &userFeatureData,
7348             (MOS_CONTEXT_HANDLE)osInterface->pOsContext);
7349         osInterface->bGucSubmission = osInterface->bGucSubmission && ((uint32_t)userFeatureData.i32Data);
7350 
7351         // read the "Force VEBOX" user feature key
7352         // 0: not force
7353         MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
7354         MOS_UserFeature_ReadValue_ID(
7355             NULL,
7356             __MEDIA_USER_FEATURE_VALUE_FORCE_VEBOX_ID,
7357             &userFeatureData,
7358             (MOS_CONTEXT_HANDLE)osInterface->pOsContext);
7359         osInterface->eForceVebox = (MOS_FORCE_VEBOX)userFeatureData.u32Data;
7360 
7361         //KMD Virtual Engine DebugOverride
7362         // 0: not Override
7363         MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
7364         MOS_UserFeature_ReadValue_ID(
7365             NULL,
7366             __MEDIA_USER_FEATURE_VALUE_ENABLE_VE_DEBUG_OVERRIDE_ID,
7367             &userFeatureData,
7368             (MOS_CONTEXT_HANDLE)osInterface->pOsContext);
7369         osInterface->bEnableDbgOvrdInVE = userFeatureData.u32Data ? true : false;
7370 #endif
7371 
7372         // UMD Vebox Virtual Engine Scalability Mode
7373         // 0: disable. can set to 1 only when KMD VE is enabled.
7374         MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
7375         eStatusUserFeature = MOS_UserFeature_ReadValue_ID(
7376             NULL,
7377             __MEDIA_USER_FEATURE_VALUE_ENABLE_VEBOX_SCALABILITY_MODE_ID,
7378             &userFeatureData,
7379             (MOS_CONTEXT_HANDLE)osInterface->pOsContext);
7380         osInterface->bVeboxScalabilityMode = userFeatureData.u32Data ? MOS_SCALABILITY_ENABLE_MODE_DEFAULT : MOS_SCALABILITY_ENABLE_MODE_FALSE;
7381 
7382 #if (_DEBUG || _RELEASE_INTERNAL)
7383         if(osInterface->bVeboxScalabilityMode
7384             && (eStatusUserFeature == MOS_STATUS_SUCCESS))
7385         {
7386             //user's value to enable scalability
7387             osInterface->bVeboxScalabilityMode = MOS_SCALABILITY_ENABLE_MODE_USER_FORCE;
7388 
7389             if (osInterface->eForceVebox == MOS_FORCE_VEBOX_NONE)
7390             {
7391                 osInterface->eForceVebox = MOS_FORCE_VEBOX_1_2;
7392             }
7393         }
7394         else if ((!osInterface->bVeboxScalabilityMode)
7395             && (eStatusUserFeature == MOS_STATUS_SUCCESS))
7396         {
7397             osInterface->eForceVebox        = MOS_FORCE_VEBOX_NONE;
7398         }
7399 
7400         // read the "Force VEBOX" user feature key
7401         // 0: not force
7402         MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
7403         MOS_UserFeature_ReadValue_ID(
7404             NULL,
7405             __MEDIA_USER_FEATURE_VALUE_FORCE_VEBOX_ID,
7406             &userFeatureData,
7407             (MOS_CONTEXT_HANDLE)osInterface->pOsContext);
7408         osInterface->eForceVebox = (MOS_FORCE_VEBOX)userFeatureData.u32Data;
7409 #endif
7410     }
7411 
7412     return eStatus;
7413 }
7414 
7415 //! \brief    Unified OS Initializes OS Linux Interface
7416 //! \details  Linux OS Interface initilization
7417 //! \param    PMOS_INTERFACE pOsInterface
7418 //!           [in] Pointer to OS Interface
7419 //! \param    PMOS_CONTEXT pOsDriverContext
7420 //!           [in] Pointer to Driver context
7421 //! \return   MOS_STATUS
7422 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
7423 //!
Mos_Specific_InitInterface(PMOS_INTERFACE pOsInterface,PMOS_CONTEXT pOsDriverContext)7424 MOS_STATUS Mos_Specific_InitInterface(
7425     PMOS_INTERFACE     pOsInterface,
7426     PMOS_CONTEXT       pOsDriverContext)
7427 {
7428     PMOS_OS_CONTEXT                 pOsContext = nullptr;
7429     PMOS_USER_FEATURE_INTERFACE     pOsUserFeatureInterface = nullptr;
7430     MOS_STATUS                      eStatus;
7431     MediaFeatureTable              *pSkuTable = nullptr;
7432     MOS_USER_FEATURE_VALUE_DATA     UserFeatureData;
7433     uint32_t                        dwResetCount = 0;
7434     int32_t                         ret = 0;
7435     bool                            modularizedGpuCtxEnabled = false;
7436     char *pMediaWatchdog = nullptr;
7437     long int watchdog = 0;
7438 
7439     MOS_OS_FUNCTION_ENTER;
7440 
7441     eStatus                 = MOS_STATUS_UNKNOWN;
7442     MOS_OS_CHK_NULL(pOsInterface);
7443     MOS_OS_CHK_NULL(pOsDriverContext);
7444     pOsContext              = nullptr;
7445     pOsUserFeatureInterface = (PMOS_USER_FEATURE_INTERFACE)&pOsInterface->UserFeatureInterface;
7446     MOS_OS_CHK_NULL(pOsUserFeatureInterface);
7447 
7448     MOS_OS_NORMALMESSAGE("mm:Mos_Specific_InitInterface called.");
7449 
7450     pOsInterface->modularizedGpuCtxEnabled  = true;
7451     pOsInterface->veDefaultEnable           = true;
7452     pOsInterface->phasedSubmission          = true;
7453 
7454     pOsInterface->apoMosEnabled             = pOsDriverContext->m_apoMosEnabled;
7455     if (pOsInterface->apoMosEnabled)
7456     {
7457         pOsInterface->streamStateIniter = true;
7458         MOS_OS_CHK_STATUS(MosInterface::CreateOsStreamState(
7459             &pOsInterface->osStreamState,
7460             (MOS_DEVICE_HANDLE)pOsDriverContext->m_osDeviceContext,
7461             (MOS_INTERFACE_HANDLE)pOsInterface,
7462             pOsInterface->Component,
7463             pOsDriverContext));
7464 
7465         // Set interface functions for legacy HAL
7466         pOsContext                          = (PMOS_OS_CONTEXT)pOsInterface->osStreamState->perStreamParameters;
7467         MOS_OS_CHK_NULL_RETURN(pOsContext);
7468 
7469         pOsContext->GetGPUTag                  = Linux_GetGPUTag;
7470     }
7471     else
7472     {
7473         // Create Linux OS Context
7474         pOsContext = (PMOS_OS_CONTEXT)MOS_AllocAndZeroMemory(sizeof(MOS_OS_CONTEXT));
7475         MOS_OS_CHK_NULL_RETURN(pOsContext);
7476     }
7477 
7478     if (pOsInterface->modulizedMosEnabled && !Mos_Solo_IsEnabled(nullptr))
7479     {
7480         OsContext *osContextPtr = OsContext::GetOsContextObject();
7481         if (osContextPtr == nullptr)
7482         {
7483             MOS_OS_ASSERTMESSAGE("Unable to get the active OS context.");
7484             eStatus = MOS_STATUS_INVALID_PARAMETER;
7485             goto finish;
7486         }
7487 
7488         pOsInterface->osContextPtr = osContextPtr;
7489 
7490         if (pOsInterface->osContextPtr->GetOsContextValid() == false)
7491         {
7492             eStatus = pOsInterface->osContextPtr->Init(pOsDriverContext);
7493             if (MOS_STATUS_SUCCESS != eStatus)
7494             {
7495                 MOS_OS_ASSERTMESSAGE("Unable to initialize MODS context.");
7496                 eStatus = MOS_STATUS_INVALID_PARAMETER;
7497                 goto finish;
7498             }
7499         }
7500 
7501         //ApoMos do it in CreateOsStreamState
7502         if (!pOsInterface->apoMosEnabled)
7503         {
7504             OsContextSpecific *pOsContextSpecific = static_cast<OsContextSpecific *>(pOsInterface->osContextPtr);
7505             pOsContext->intel_context             = pOsContextSpecific->GetDrmContext();
7506             pOsContext->pGmmClientContext         = pOsDriverContext->pGmmClientContext;
7507         }
7508     }
7509     else
7510     {
7511         pOsContext->pGmmClientContext = pOsDriverContext->pGmmClientContext;
7512     }
7513 
7514     MOS_ZeroMemory(&UserFeatureData, sizeof(UserFeatureData));
7515 #if MOS_MEDIASOLO_SUPPORTED
7516     if (pOsInterface->bSoloInUse)
7517     {
7518         UserFeatureData.i32Data = pOsInterface->bSimIsActive;
7519         UserFeatureData.i32DataFlag = MOS_USER_FEATURE_VALUE_DATA_FLAG_CUSTOM_DEFAULT_VALUE_TYPE;
7520     }
7521 #endif
7522 #if (_DEBUG || _RELEASE_INTERNAL)
7523     MOS_UserFeature_ReadValue_ID(
7524         nullptr,
7525         __MEDIA_USER_FEATURE_VALUE_SIM_ENABLE_ID,
7526         &UserFeatureData,
7527         (MOS_CONTEXT_HANDLE)pOsContext);
7528 #endif
7529     pOsInterface->bSimIsActive = (int32_t)UserFeatureData.i32Data;
7530     if (!pOsInterface->apoMosEnabled)
7531     {
7532         pOsContext->bSimIsActive = pOsInterface->bSimIsActive;
7533     }
7534 
7535     // Initialize
7536     if (!pOsInterface->apoMosEnabled)
7537     {
7538         modularizedGpuCtxEnabled = pOsInterface->modularizedGpuCtxEnabled && !Mos_Solo_IsEnabled(pOsContext);
7539         eStatus = Linux_InitContext(pOsContext, pOsDriverContext, pOsInterface->modulizedMosEnabled && !Mos_Solo_IsEnabled(pOsContext), modularizedGpuCtxEnabled);
7540         if( MOS_STATUS_SUCCESS != eStatus )
7541         {
7542             MOS_OS_ASSERTMESSAGE("Unable to initialize context.");
7543             goto finish;
7544         }
7545 
7546         pOsContext->bFreeContext = true;
7547 
7548         //Added by Ben for video memory allocation
7549         pOsContext->bufmgr = pOsDriverContext->bufmgr;
7550         mos_bufmgr_gem_enable_reuse(pOsDriverContext->bufmgr);
7551     }
7552 
7553     pOsInterface->pOsContext                  = pOsContext;
7554 
7555     pOsInterface->bUsesPatchList              = true;
7556     pOsInterface->bUsesGfxAddress             = false;
7557     pOsInterface->bNoParsingAssistanceInKmd   = true;
7558     pOsInterface->bUsesCmdBufHeaderInResize   = false;
7559     pOsInterface->bUsesCmdBufHeader           = false;
7560     pOsInterface->dwNumNalUnitBytesIncluded   = MOS_NAL_UNIT_LENGTH - MOS_NAL_UNIT_STARTCODE_LENGTH;
7561 
7562     pOsInterface->bInlineCodecStatusUpdate    = true;
7563     pOsInterface->bAllowExtraPatchToSameLoc   = false;
7564 
7565     // Initialize OS interface functions
7566     pOsInterface->pfnSetGpuContext                          = Mos_Specific_SetGpuContext;
7567     pOsInterface->pfnSetGpuContextFromHandle                = Mos_Specific_SetGpuContextFromHandle;
7568     pOsInterface->pfnGetGpuContext                          = Mos_Specific_GetGpuContext;
7569     pOsInterface->pfnSetEncodePakContext                    = Mos_Specific_SetEncodePakContext;
7570     pOsInterface->pfnSetEncodeEncContext                    = Mos_Specific_SetEncodeEncContext;
7571     pOsInterface->pfnGetGmmClientContext                    = Mos_Specific_GetGmmClientContext;
7572 
7573     pOsInterface->pfnGetPlatform                            = Mos_Specific_GetPlatform;
7574     pOsInterface->pfnDestroy                                = Mos_Specific_Destroy;
7575     pOsInterface->pfnGetSkuTable                            = Mos_Specific_GetSkuTable;
7576     pOsInterface->pfnGetWaTable                             = Mos_Specific_GetWaTable;
7577     pOsInterface->pfnGetGtSystemInfo                        = Mos_Specific_GetGtSystemInfo;
7578     pOsInterface->pfnGetMediaEngineInfo                     = Mos_Specific_GetMediaEngineInfo;
7579     pOsInterface->pfnResetOsStates                          = Mos_Specific_ResetOsStates;
7580     pOsInterface->pfnAllocateResource                       = Mos_Specific_AllocateResource;
7581     pOsInterface->pfnGetResourceInfo                        = Mos_Specific_GetResourceInfo;
7582     pOsInterface->pfnFreeResource                           = Mos_Specific_FreeResource;
7583     pOsInterface->pfnFreeResourceWithFlag                   = Mos_Specific_FreeResourceWithFlag;
7584     pOsInterface->pfnLockSyncRequest                        = Mos_Specific_LockSyncRequest;
7585     pOsInterface->pfnLockResource                           = Mos_Specific_LockResource;
7586     pOsInterface->pfnUnlockResource                         = Mos_Specific_UnlockResource;
7587     pOsInterface->pfnDecompResource                         = Mos_Specific_DecompResource;
7588     pOsInterface->pfnDoubleBufferCopyResource               = Mos_Specific_DoubleBufferCopyResource;
7589     pOsInterface->pfnMediaCopyResource2D                    = Mos_Specific_MediaCopyResource2D;
7590     pOsInterface->pfnGetMosContext                          = Mos_Specific_GetMosContext;
7591     pOsInterface->pfnUpdateResourceUsageType                = Mos_Specific_UpdateResourceUsageType;
7592     pOsInterface->pfnRegisterResource                       = Mos_Specific_RegisterResource;
7593     pOsInterface->pfnResetResourceAllocationIndex           = Mos_Specific_ResetResourceAllocationIndex;
7594     pOsInterface->pfnGetResourceAllocationIndex             = Mos_Specific_GetResourceAllocationIndex;
7595     pOsInterface->pfnGetResourceGfxAddress                  = Mos_Specific_GetResourceGfxAddress;
7596     pOsInterface->pfnGetCommandBuffer                       = Mos_Specific_GetCommandBuffer;
7597     pOsInterface->pfnResetCommandBuffer                     = Mos_Specific_ResetCommandBuffer;
7598     pOsInterface->pfnReturnCommandBuffer                    = Mos_Specific_ReturnCommandBuffer;
7599     pOsInterface->pfnSubmitCommandBuffer                    = Mos_Specific_SubmitCommandBuffer;
7600     pOsInterface->pfnWaitAndReleaseCmdBuffer                = Mos_Specific_WaitAndReleaseCmdBuffer;
7601     pOsInterface->pfnVerifyCommandBufferSize                = Mos_Specific_VerifyCommandBufferSize;
7602     pOsInterface->pfnResizeCommandBufferAndPatchList        = Mos_Specific_ResizeCommandBufferAndPatchList;
7603     pOsInterface->pfnFmt_OsToMos                            = Mos_Specific_FmtOsToMos;
7604     pOsInterface->pfnFmt_MosToOs                            = Mos_Specific_FmtMosToOs;
7605     pOsInterface->pfnFmt_MosToGmm                           = Mos_Specific_ConvertMosFmtToGmmFmt;
7606     pOsInterface->pfnSetPerfTag                             = Mos_Specific_SetPerfTag;
7607     pOsInterface->pfnResetPerfBufferID                      = Mos_Specific_ResetPerfBufferID;
7608     pOsInterface->pfnIncPerfFrameID                         = Mos_Specific_IncPerfFrameID;
7609     pOsInterface->pfnIncPerfBufferID                        = Mos_Specific_IncPerfBufferID;
7610     pOsInterface->pfnGetPerfTag                             = Mos_Specific_GetPerfTag;
7611     pOsInterface->pfnSetPerfHybridKernelID                  = Mos_Specific_SetPerfHybridKernelID;
7612     pOsInterface->pfnIsPerfTagSet                           = Mos_Specific_IsPerfTagSet;
7613     pOsInterface->pfnSetIndirectStateSize                   = Mos_Specific_SetIndirectStateSize;
7614     pOsInterface->pfnGetIndirectState                       = Mos_Specific_GetIndirectState;
7615     pOsInterface->pfnGetIndirectStatePointer                = Mos_Specific_GetIndirectStatePointer;
7616     pOsInterface->pfnSetPatchEntry                          = Mos_Specific_SetPatchEntry;
7617     pOsInterface->pfnGetInterfaceVersion                    = Mos_Specific_GetInterfaceVersion;
7618 
7619     pOsInterface->pfnLoadLibrary                            = Mos_Specific_LoadLibrary;
7620     pOsInterface->pfnFreeLibrary                            = Mos_Specific_FreeLibrary;
7621     pOsInterface->pfnLogData                                = Mos_Specific_LogData;
7622     pOsInterface->pfnCheckVirtualEngineSupported            = Mos_Specific_CheckVirtualEngineSupported;
7623 
7624     //GPU context and synchronization functions
7625     pOsInterface->pfnCreateGpuContext                       = Mos_Specific_CreateGpuContext;
7626     pOsInterface->pfnCreateGpuComputeContext                = Mos_Specific_CreateGpuComputeContext;
7627     pOsInterface->pfnDestroyGpuContext                      = Mos_Specific_DestroyGpuContext;
7628     pOsInterface->pfnDestroyGpuComputeContext               = Mos_Specific_DestroyGpuComputeContext;
7629     pOsInterface->pfnIsGpuContextValid                      = Mos_Specific_IsGpuContextValid;
7630     pOsInterface->pfnSyncOnResource                         = Mos_Specific_SyncOnResource;
7631     pOsInterface->pfnSyncGpuContext                         = Mos_Specific_SyncGpuContext;
7632     pOsInterface->pfnSyncWith3DContext                      = Mos_Specific_SyncWith3DContext;
7633     pOsInterface->pfnGetGpuStatusBufferResource             = Mos_Specific_GetGpuStatusBufferResource;
7634     pOsInterface->pfnGetGpuStatusTagOffset                  = Mos_Specific_GetGpuStatusTagOffset;
7635     pOsInterface->pfnGetGpuStatusTag                        = Mos_Specific_GetGpuStatusTag;
7636     pOsInterface->pfnIncrementGpuStatusTag                  = Mos_Specific_IncrementGpuStatusTag;
7637     pOsInterface->pfnGetGpuStatusSyncTag                    = Mos_Specific_GetGpuStatusSyncTag;
7638     pOsInterface->pfnSetResourceSyncTag                     = Mos_Specific_SetResourceSyncTag;
7639     pOsInterface->pfnPerformOverlaySync                     = Mos_Specific_PerformOverlaySync;
7640     pOsInterface->pfnEngineSignal                           = Mos_Specific_EngineSignal;
7641     pOsInterface->pfnEngineWait                             = Mos_Specific_EngineWait;
7642     pOsInterface->pfnWaitAllCmdCompletion                   = Mos_Specific_WaitAllCmdCompletion_Os;
7643     pOsInterface->pfnResourceSignal                         = Mos_Specific_ResourceSignal;
7644     pOsInterface->pfnResourceWait                           = Mos_Specific_ResourceWait;
7645     pOsInterface->pfnCreateSyncResource                     = Mos_Specific_CreateSyncResource;
7646     pOsInterface->pfnDestroySyncResource                    = Mos_Specific_DestroySyncResource;
7647     pOsInterface->pfnInitializeMultiThreadingSyncTags       = Mos_Specific_InitializeMultiThreadingSyncTags;
7648     pOsInterface->pfnMultiThreadingWaitCurrentFrame         = Mos_Specific_MultiThreadingWaitCurrentFrame;
7649     pOsInterface->pfnMultiThreadingPostCurrentFrame         = Mos_Specific_MultiThreadingPostCurrentFrame;
7650     pOsInterface->pfnSetHybridDecoderRunningFlag            = Mos_Specific_SetHybridDecoderRunningFlag;
7651     pOsInterface->pfnGetHybridDecoderRunningFlag            = Mos_Specific_GetHybridDecoderRunningFlag;
7652     pOsInterface->pfnMultiThreadResourceSync                = Mos_Specific_MultiThreadResourceSync;
7653 
7654     pOsInterface->pfnCachePolicyGetMemoryObject             = Mos_Specific_CachePolicyGetMemoryObject;
7655     pOsInterface->pfnVerifyPatchListSize                    = Mos_Specific_VerifyPatchListSize;
7656     pOsInterface->pfnGetMemoryCompressionMode               = Mos_Specific_GetMemoryCompressionMode;
7657     pOsInterface->pfnSetMemoryCompressionMode               = Mos_Specific_SetMemoryCompressionMode;
7658     pOsInterface->pfnSetMemoryCompressionHint               = Mos_Specific_SetMemoryCompressionHint;
7659     pOsInterface->pfnGetMemoryCompressionFormat             = Mos_Specific_GetMemoryCompressionFormat;
7660     pOsInterface->pfnCreateVideoNodeAssociation             = Mos_Specific_CreateVideoNodeAssociation;
7661     pOsInterface->pfnDestroyVideoNodeAssociation            = Mos_Specific_DestroyVideoNodeAssociation;
7662     pOsInterface->pfnGetVdboxNodeId                         = Mos_Specific_GetVdboxNodeId;
7663 
7664     pOsInterface->pfnGetNullHWRenderFlags                   = Mos_Specific_GetNullHWRenderFlags;
7665     pOsInterface->pfnSetCmdBufferDebugInfo                  = Mos_Specific_SetCmdBufferDebugInfo;
7666     pOsInterface->pfnGetCmdBufferDebugInfo                  = Mos_Specific_GetCmdBufferDebugInfo;
7667 
7668     pOsInterface->pfnRegisterBBCompleteNotifyEvent          = Mos_Specific_RegisterBBCompleteNotifyEvent;
7669     pOsInterface->pfnWaitForBBCompleteNotifyEvent           = Mos_Specific_WaitForBBCompleteNotifyEvent;
7670     pOsInterface->pfnCachePolicyGetMemoryObject             = Mos_Specific_CachePolicyGetMemoryObject;
7671     pOsInterface->pfnCachePolicyGetL1Config                 = Mos_Specific_CachePolicyGetL1Config;
7672     pOsInterface->pfnSetCpuCacheability                     = Mos_Specific_SetCpuCacheability;
7673     pOsInterface->pfnSkipResourceSync                       = Mos_Specific_SkipResourceSync;
7674     pOsInterface->pfnIsGPUHung                              = Mos_Specific_IsGPUHung;
7675     pOsInterface->pfnGetAuxTableBaseAddr                    = Mos_Specific_GetAuxTableBaseAddr;
7676     pOsInterface->pfnSetSliceCount                          = Mos_Specific_SetSliceCount;
7677     pOsInterface->pfnGetResourceIndex                       = Mos_Specific_GetResourceIndex;
7678     pOsInterface->pfnSetSliceCount                          = Mos_Specific_SetSliceCount;
7679     pOsInterface->pfnGetGpuPriority                         = Mos_Specific_GetGpuPriority;
7680     pOsInterface->pfnSetGpuPriority                         = Mos_Specific_SetGpuPriority;
7681     pOsInterface->pfnIsSetMarkerEnabled                     = Mos_Specific_IsSetMarkerEnabled;
7682     pOsInterface->pfnGetMarkerResource                      = Mos_Specific_GetMarkerResource;
7683     pOsInterface->pfnNotifyStreamIndexSharing               = Mos_Specific_NotifyStreamIndexSharing;
7684 
7685     pOsInterface->pfnSetGpuContextHandle                    = Mos_Specific_SetGpuContextHandle;
7686     pOsInterface->pfnGetGpuContextMgr                       = Mos_Specific_GetGpuContextMgr;
7687     pOsInterface->pfnGetGpuContextbyHandle                  = Mos_Specific_GetGpuContextbyHandle;
7688 
7689     pOsUserFeatureInterface->bIsNotificationSupported   = false;
7690     pOsUserFeatureInterface->pOsInterface               = pOsInterface;
7691 
7692     pOsUserFeatureInterface->pfnEnableNotification      = MosUtilities::MosUserFeatureEnableNotification;
7693     pOsUserFeatureInterface->pfnDisableNotification     = MosUtilities::MosUserFeatureDisableNotification;
7694     pOsUserFeatureInterface->pfnParsePath               = MosUtilities::MosUserFeatureParsePath;
7695 
7696     // Init reset count for the context
7697     ret = mos_get_reset_stats(pOsInterface->pOsContext->intel_context, &dwResetCount, nullptr, nullptr);
7698     if (ret)
7699     {
7700         MOS_OS_NORMALMESSAGE("mos_get_reset_stats return error(%d)\n", ret);
7701         dwResetCount = 0;
7702     }
7703     pOsInterface->dwGPUResetCount   = dwResetCount;
7704     pOsInterface->dwGPUActiveBatch  = 0;
7705     pOsInterface->dwGPUPendingBatch = 0;
7706 
7707     // enable it on Linux
7708     pOsInterface->bMediaReset         = true;
7709     pOsInterface->umdMediaResetEnable = true;
7710 
7711     pMediaWatchdog = getenv("INTEL_MEDIA_RESET_WATCHDOG");
7712     if (pMediaWatchdog != nullptr)
7713     {
7714         watchdog = strtol(pMediaWatchdog, nullptr, 0);
7715         if (watchdog == 0)
7716         {
7717             pOsInterface->bMediaReset         = false;
7718             pOsInterface->umdMediaResetEnable = false;
7719         }
7720     }
7721 
7722     // initialize MOS_CP interface
7723     pOsInterface->osCpInterface = Create_MosCpInterface(pOsInterface);
7724     if (pOsInterface->osCpInterface == nullptr)
7725     {
7726         MOS_OS_ASSERTMESSAGE("fail to create osCpInterface.");
7727         return MOS_STATUS_UNKNOWN;
7728     }
7729 
7730     // Check SKU table to detect if simulation environment (HAS) is enabled
7731     pSkuTable = pOsInterface->pfnGetSkuTable(pOsInterface);
7732     MOS_OS_CHK_NULL(pSkuTable);
7733 
7734 #if (_DEBUG || _RELEASE_INTERNAL)
7735     // read the "Force VDBOX" user feature key
7736     // 0: not force
7737     MOS_ZeroMemory(&UserFeatureData, sizeof(UserFeatureData));
7738     MOS_UserFeature_ReadValue_ID(
7739         nullptr,
7740         __MEDIA_USER_FEATURE_VALUE_FORCE_VDBOX_ID,
7741         &UserFeatureData,
7742         (MOS_CONTEXT_HANDLE)pOsContext);
7743     pOsInterface->eForceVdbox = UserFeatureData.u32Data;
7744 
7745     // Force TileYf/Ys
7746     // 0: Tile Y  1: Tile Yf   2 Tile Ys
7747     MOS_ZeroMemory(&UserFeatureData, sizeof(UserFeatureData));
7748     MOS_UserFeature_ReadValue_ID(
7749         nullptr,
7750         __MEDIA_USER_FEATURE_VALUE_FORCE_YFYS_ID,
7751         &UserFeatureData,
7752         (MOS_CONTEXT_HANDLE)pOsContext);
7753     pOsInterface->dwForceTileYfYs = (uint32_t)UserFeatureData.i32Data;
7754 
7755     // Null HW Driver
7756     // 0: Disable
7757     MOS_ZeroMemory(&UserFeatureData, sizeof(UserFeatureData));
7758     MOS_USER_FEATURE_INVALID_KEY_ASSERT(MOS_UserFeature_ReadValue_ID(
7759         nullptr,
7760         __MEDIA_USER_FEATURE_VALUE_NULL_HW_ACCELERATION_ENABLE_ID,
7761         &UserFeatureData,
7762         (MOS_CONTEXT_HANDLE)pOsContext));
7763     pOsInterface->NullHWAccelerationEnable.Value = UserFeatureData.u32Data;
7764 #endif // (_DEBUG || _RELEASE_INTERNAL)
7765 
7766 #if MOS_MEDIASOLO_SUPPORTED
7767     Mos_Solo_Initialize(pOsInterface);
7768 #endif // MOS_MEDIASOLO_SUPPORTED
7769     if (!pOsInterface->apoMosEnabled)
7770     {
7771         // read the "Disable KMD Watchdog" user feature key
7772         MOS_ZeroMemory(&UserFeatureData, sizeof(UserFeatureData));
7773         MOS_UserFeature_ReadValue_ID(
7774             nullptr,
7775             __MEDIA_USER_FEATURE_VALUE_DISABLE_KMD_WATCHDOG_ID,
7776             &UserFeatureData,
7777             (MOS_CONTEXT_HANDLE)pOsContext);
7778         pOsContext->bDisableKmdWatchdog = (UserFeatureData.i32Data) ? true : false;
7779 
7780         // read "Linux PerformanceTag Enable" user feature key
7781         MOS_ZeroMemory(&UserFeatureData, sizeof(UserFeatureData));
7782         MOS_UserFeature_ReadValue_ID(
7783             nullptr,
7784             __MEDIA_USER_FEATURE_VALUE_LINUX_PERFORMANCETAG_ENABLE_ID,
7785             &UserFeatureData,
7786             (MOS_CONTEXT_HANDLE)pOsContext);
7787         pOsContext->uEnablePerfTag = UserFeatureData.i32Data;
7788     }
7789     eStatus = Mos_Specific_InitInterface_Ve(pOsInterface);
7790     if(eStatus != MOS_STATUS_SUCCESS)
7791     {
7792         goto finish;
7793     }
7794 
7795     eStatus = MOS_STATUS_SUCCESS;
7796 
7797 finish:
7798     if( MOS_STATUS_SUCCESS != eStatus && nullptr != pOsContext )
7799     {
7800         MOS_FreeMemAndSetNull(pOsContext);
7801     }
7802     return eStatus;
7803 }
7804 
7805 //!
7806 //! \brief    Check if OS resource is nullptr
7807 //! \details  Check if OS resource is nullptr
7808 //! \param    PMOS_RESOURCE pOsResource
7809 //!           [in] Pointer to OS Resource
7810 //! \return   int32_t
7811 //!           Return true if nullptr, otherwise false
7812 //!
Mos_ResourceIsNull(PMOS_RESOURCE pOsResource)7813 int32_t Mos_ResourceIsNull(
7814     PMOS_RESOURCE   pOsResource)
7815 {
7816     //---------------------
7817     if( nullptr == pOsResource )
7818     {
7819         MOS_OS_ASSERTMESSAGE("found pOsResource nullptr\n");
7820         return true;
7821     }
7822     //---------------------
7823 
7824     return ((pOsResource->bo == nullptr)
7825 #if (_DEBUG || _RELEASE_INTERNAL)
7826          && ((pOsResource->pData == nullptr) )
7827 #endif // (_DEBUG || _RELEASE_INTERNAL)
7828     );
7829 
7830 }
7831 
7832 //!
7833 //! \brief    OS reset resource
7834 //! \details  Resets the OS resource
7835 //! \param    PMOS_RESOURCE pOsResource
7836 //!           [in] Pointer to OS Resource
7837 //! \return   void
7838 //!           Return NONE
7839 //!
Mos_ResetResource(PMOS_RESOURCE pOsResource)7840 void Mos_ResetResource(
7841     PMOS_RESOURCE   pOsResource)
7842 {
7843     int32_t i;
7844 
7845     MOS_OS_FUNCTION_ENTER;
7846 
7847     MOS_OS_ASSERT(pOsResource);
7848 
7849     MOS_ZeroMemory(pOsResource, sizeof(MOS_RESOURCE));
7850     pOsResource->Format  = Format_None;
7851     for (i = 0; i < MOS_GPU_CONTEXT_MAX; i++)
7852     {
7853         pOsResource->iAllocationIndex[i] = MOS_INVALID_ALLOC_INDEX;
7854     }
7855 }
7856 
7857 //!
7858 //! \brief    Convert to MOS tile type
7859 //! \details  Convert from Linux to MOS tile type
7860 //! \param    uint32_t type
7861 //!           [in] tile type
7862 //! \return   MOS_TILE_TYPE
7863 //!           Return MOS tile type
7864 //!
LinuxToMosTileType(uint32_t type)7865 MOS_TILE_TYPE LinuxToMosTileType(uint32_t type)
7866 {
7867     switch (type) {
7868         case I915_TILING_NONE:
7869             return MOS_TILE_LINEAR;
7870         case I915_TILING_X:
7871             return MOS_TILE_X;
7872         case I915_TILING_Y:
7873             return MOS_TILE_Y;
7874         default:
7875             return MOS_TILE_INVALID;
7876     }
7877 };
7878 
7879 //!
7880 //! \brief    Get resource index
7881 //! \details  Get resource index of MOS_RESOURCE
7882 //! \param    PMOS_RESOURCE osResource
7883 //!           [in] Pointer to OS resource
7884 //! \return   uint32_t
7885 //!           Resource index
7886 //!
Mos_Specific_GetResourceIndex(PMOS_RESOURCE osResource)7887 uint32_t Mos_Specific_GetResourceIndex(
7888     PMOS_RESOURCE           osResource)
7889 {
7890     return 0;
7891 }
7892 
Mos_Specific_GetResourcePitch(PMOS_RESOURCE pOsResource)7893 uint32_t Mos_Specific_GetResourcePitch(
7894     PMOS_RESOURCE               pOsResource)
7895 {
7896     MOS_OS_FUNCTION_ENTER;
7897 
7898     MOS_OS_ASSERT(pOsResource);
7899 
7900     return pOsResource->iPitch;
7901 }
7902 
Mos_Specific_SetResourceWidth(PMOS_RESOURCE pOsResource,uint32_t dwWidth)7903 void Mos_Specific_SetResourceWidth(
7904     PMOS_RESOURCE               pOsResource,
7905     uint32_t                    dwWidth)
7906 {
7907     MOS_OS_FUNCTION_ENTER;
7908 
7909     MOS_OS_ASSERT(pOsResource);
7910 
7911     pOsResource->iWidth = dwWidth;
7912 }
7913 
Mos_Specific_SetResourceFormat(PMOS_RESOURCE pOsResource,MOS_FORMAT mosFormat)7914 void Mos_Specific_SetResourceFormat(
7915     PMOS_RESOURCE               pOsResource,
7916     MOS_FORMAT                  mosFormat)
7917 {
7918     MOS_OS_FUNCTION_ENTER;
7919 
7920     MOS_OS_ASSERT(pOsResource);
7921 
7922     pOsResource->Format = mosFormat;
7923 }
7924 
7925 //!
7926 //! \brief    Get SetMarker enabled flag
7927 //! \details  Get SetMarker enabled flag from OsInterface
7928 //! \param    PMOS_INTERFACE pOsInterface
7929 //!           [in] OS Interface
7930 //! \return   bool
7931 //!           SetMarker enabled flag
7932 //!
Mos_Specific_IsSetMarkerEnabled(PMOS_INTERFACE pOsInterface)7933 bool Mos_Specific_IsSetMarkerEnabled(
7934     PMOS_INTERFACE         pOsInterface)
7935 {
7936     return false;
7937 }
7938 
7939 //!
7940 //! \brief    Get SetMarker resource address
7941 //! \details  Get SetMarker resource address from OsInterface
7942 //! \param    PMOS_INTERFACE pOsInterface
7943 //!           [in] OS Interface
7944 //! \return   PMOS_RESOURCE
7945 //!           SetMarker resource address
7946 //!
Mos_Specific_GetMarkerResource(PMOS_INTERFACE pOsInterface)7947 PMOS_RESOURCE Mos_Specific_GetMarkerResource(
7948     PMOS_INTERFACE         pOsInterface)
7949 {
7950     return 0;
7951 }
7952 
7953 //!
7954 //! \brief    Get TimeStamp frequency base
7955 //! \details  Get TimeStamp frequency base from OsInterface
7956 //! \param    PMOS_INTERFACE pOsInterface
7957 //!           [in] OS Interface
7958 //! \return   uint32_t
7959 //!           time stamp frequency base
7960 //!
Mos_Specific_GetTsFrequency(PMOS_INTERFACE osInterface)7961 uint32_t Mos_Specific_GetTsFrequency(PMOS_INTERFACE osInterface)
7962 {
7963     int32_t freq = 0;
7964     drm_i915_getparam_t gp;
7965     MOS_ZeroMemory(&gp, sizeof(gp));
7966     gp.param = I915_PARAM_CS_TIMESTAMP_FREQUENCY;
7967     gp.value = &freq;
7968     int ret = drmIoctl(osInterface->pOsContext->fd, DRM_IOCTL_I915_GETPARAM, &gp);
7969     if(ret == 0)
7970     {
7971         return freq;
7972     }
7973     else
7974     {
7975         // fail to query it from KMD
7976         return 0;
7977     }
7978 }
7979 
7980 //!
7981 //! \brief    Checks whether the requested resource is releasable
7982 //! \param    PMOS_INTERFACE pOsInterface
7983 //!           [in] OS Interface
7984 //! \param    PMOS_RESOURCE pOsResource
7985 //!           [in] Pointer to OS Resource
7986 //! \return   MOS_STATUS
7987 //!           MOS_STATUS_SUCCESS if requested can be released, otherwise MOS_STATUS_UNKNOWN
7988 //!
Mos_Specific_IsResourceReleasable(PMOS_INTERFACE pOsInterface,PMOS_RESOURCE pOsResource)7989 MOS_STATUS Mos_Specific_IsResourceReleasable(
7990     PMOS_INTERFACE         pOsInterface,
7991     PMOS_RESOURCE          pOsResource)
7992 {
7993     return MOS_STATUS_SUCCESS;
7994 }
7995 
Mos_GetDeviceUfPathInfo(PMOS_CONTEXT mosContext)7996 MOS_USER_FEATURE_KEY_PATH_INFO *Mos_GetDeviceUfPathInfo(
7997     PMOS_CONTEXT mosContext)
7998 {
7999     MOS_UNUSED(mosContext);
8000     //NOT IMPLEMENTED
8001     return nullptr;
8002 }
8003 
8004 #if MOS_COMMAND_RESINFO_DUMP_SUPPORTED
8005 struct GpuCmdResInfoDump::GpuCmdResInfo
8006 {
8007     int32_t             iWidth;
8008     int32_t             iHeight;
8009     int32_t             iSize;
8010     int32_t             iPitch;
8011     int32_t             iDepth;
8012     MOS_FORMAT          Format;
8013     int32_t             iCount;
8014     int32_t             iAllocationIndex[MOS_GPU_CONTEXT_MAX];
8015     uint32_t            dwGfxAddress;
8016     const char          *bufname;
8017     uint32_t            isTiled;
8018     MOS_TILE_TYPE       TileType;
8019     uint32_t            bMapped;
8020     uint32_t            name;
8021     uint64_t            user_provided_va;
8022     bool                bConvertedFromDDIResource;
8023 };
8024 
StoreCmdResPtr(PMOS_INTERFACE pOsInterface,const void * pRes)8025 void GpuCmdResInfoDump::StoreCmdResPtr(PMOS_INTERFACE pOsInterface, const void *pRes) const
8026 {
8027     if (!m_dumpEnabled)
8028     {
8029         return;
8030     }
8031     auto gpuContext = Linux_GetGpuContext(pOsInterface, pOsInterface->CurrentGpuContextHandle);
8032     MOS_OS_ASSERT(gpuContext != nullptr);
8033 
8034     auto pResTmp1 = (const MOS_RESOURCE *)(pRes);
8035     auto pResTmp2 = (GpuCmdResInfo *)MOS_AllocMemory(sizeof(GpuCmdResInfo));
8036 
8037     pResTmp2->iWidth                    = pResTmp1->iWidth;
8038     pResTmp2->iHeight                   = pResTmp1->iHeight;
8039     pResTmp2->iSize                     = pResTmp1->iSize;
8040     pResTmp2->iPitch                    = pResTmp1->iPitch;
8041     pResTmp2->iDepth                    = pResTmp1->iDepth;
8042     pResTmp2->Format                    = pResTmp1->Format;
8043     pResTmp2->iCount                    = pResTmp1->iCount;
8044     for (auto i = 0; i < MOS_GPU_CONTEXT_MAX; i++)
8045     {
8046         pResTmp2->iAllocationIndex[i] = pResTmp1->iAllocationIndex[i];
8047     }
8048     pResTmp2->dwGfxAddress              = pResTmp1->dwGfxAddress;
8049     pResTmp2->bufname                   = pResTmp1->bufname;
8050     pResTmp2->isTiled                   = pResTmp1->isTiled;
8051     pResTmp2->TileType                  = pResTmp1->TileType;
8052     pResTmp2->bMapped                   = pResTmp1->bMapped;
8053     pResTmp2->name                      = pResTmp1->name;
8054     pResTmp2->user_provided_va          = pResTmp1->user_provided_va;
8055     pResTmp2->bConvertedFromDDIResource = pResTmp1->bConvertedFromDDIResource;
8056 
8057     gpuContext->PushCmdResPtr((const void *)pResTmp2);
8058 }
8059 
ClearCmdResPtrs(PMOS_INTERFACE pOsInterface)8060 void GpuCmdResInfoDump::ClearCmdResPtrs(PMOS_INTERFACE pOsInterface) const
8061 {
8062     if (!m_dumpEnabled)
8063     {
8064         return;
8065     }
8066 
8067     auto gpuContext = Linux_GetGpuContext(pOsInterface, pOsInterface->CurrentGpuContextHandle);
8068     MOS_OS_ASSERT(gpuContext != nullptr);
8069 
8070     auto &cmdResInfoPtrs = gpuContext->GetCmdResPtrs();
8071 
8072     for (auto e : cmdResInfoPtrs)
8073     {
8074         MOS_FreeMemory((void *)e);
8075     }
8076 
8077     gpuContext->ClearCmdResPtrs();
8078 }
8079 
Dump(const void * cmdResInfoPtr,std::ofstream & outputFile)8080 void GpuCmdResInfoDump::Dump(const void *cmdResInfoPtr, std::ofstream &outputFile) const
8081 {
8082     using std::endl;
8083 
8084     auto pRes = (const GpuCmdResInfo *)(cmdResInfoPtr);
8085 
8086     outputFile << "Gpu Resource Pointer      : " << pRes << endl;
8087     outputFile << "iWidth                    : " << pRes->iWidth << endl;
8088     outputFile << "iHeight                   : " << pRes->iHeight << endl;
8089     outputFile << "iSize                     : " << pRes->iSize << endl;
8090     outputFile << "iPitch                    : " << pRes->iPitch << endl;
8091     outputFile << "iDepth                    : " << pRes->iDepth << endl;
8092     outputFile << "Format                    : " << (int32_t)pRes->Format << endl;
8093     outputFile << "iCount                    : " << pRes->iCount << endl;
8094     outputFile << "iAllocationIndex          : ";
8095     for (auto i = 0; i < MOS_GPU_CONTEXT_MAX; i++)
8096     {
8097         outputFile << pRes->iAllocationIndex[i] << " ";
8098     }
8099     outputFile << endl;
8100     outputFile << "dwGfxAddress              : " << pRes->dwGfxAddress << endl;
8101     outputFile << "bufname                   : " << pRes->bufname << endl;
8102     outputFile << "isTiled                   : " << pRes->isTiled << endl;
8103     outputFile << "TileType                  : " << GetTileType(pRes->TileType) << endl;
8104     outputFile << "bMapped                   : " << pRes->bMapped << endl;
8105     outputFile << "name                      : " << pRes->name << endl;
8106     outputFile << "user_provided_va          : " << pRes->user_provided_va << endl;
8107     outputFile << "bConvertedFromDDIResource : " << pRes->bConvertedFromDDIResource << endl;
8108     outputFile << endl;
8109 }
8110 
GetCmdResPtrs(PMOS_INTERFACE pOsInterface)8111 const std::vector<const void *> &GpuCmdResInfoDump::GetCmdResPtrs(PMOS_INTERFACE pOsInterface) const
8112 {
8113     const auto *gpuContext = Linux_GetGpuContext(pOsInterface, pOsInterface->CurrentGpuContextHandle);
8114     MOS_OS_ASSERT(gpuContext != nullptr);
8115 
8116     return gpuContext->GetCmdResPtrs();
8117 }
8118 #endif // MOS_COMMAND_RESINFO_DUMP_SUPPORTED
8119