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