1 /*
2 * Copyright (c) 2016-2020, 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     codechal_decode_scalability.cpp
24 //! \brief    Implements the decode interface extension for decode scalability.
25 //! \details  Implements all functions required by CodecHal for scalability decoding.
26 //!
27 
28 #include "codechal_decoder.h"
29 #include "codechal_decode_scalability.h"
30 #include "mos_util_user_interface.h"
31 #include "mos_solo_generic.h"
32 #include "mos_os_virtualengine_next.h"
33 
34 //!
35 //! \brief    calculate secondary cmd buffer index
36 //! \details  calculate secondary cmd buffer index to get or return secondary cmd buffer
37 //! \param    [in]  pScalabilityState
38 //!                pointer to scalability decode state
39 //! \param    [in]  pdwBufIdxPlus1
40 //!                pointer to buf index, will contain the returned buf index value.
41 //! \return   MOS_STATUS
42 //!           MOS_STATUS_SUCCESS if success, else fail reason
43 //!
CodecHalDecodeScalability_CalculateScdryCmdBufIndex(PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityState,uint32_t * pdwBufIdxPlus1)44 static MOS_STATUS CodecHalDecodeScalability_CalculateScdryCmdBufIndex(
45     PCODECHAL_DECODE_SCALABILITY_STATE  pScalabilityState,
46     uint32_t                           *pdwBufIdxPlus1)
47 {
48     uint32_t                        HcpDecPhaseForBufIdx;
49     MOS_STATUS                      eStatus = MOS_STATUS_SUCCESS;
50 
51     CODECHAL_DECODE_FUNCTION_ENTER;
52 
53     CODECHAL_DECODE_CHK_NULL_RETURN(pScalabilityState);
54     CODECHAL_DECODE_CHK_NULL_RETURN(pdwBufIdxPlus1);
55 
56     HcpDecPhaseForBufIdx = pScalabilityState->HcpDecPhase;
57     if (pScalabilityState->HcpDecPhase == CodechalDecode::CodechalHcpDecodePhaseLegacyS2L)
58     {
59         //S2L commands put in the FE secondary command buffer.
60         CODECHAL_DECODE_ASSERT(pScalabilityState->bShortFormatInUse);
61         HcpDecPhaseForBufIdx = CODECHAL_HCP_DECODE_PHASE_FE;
62     }
63 
64     //buffer index order is same as the buffer order in resScalableBatchBufs[] of MOS_VIRTUALENGINE_HINT_PARAMS
65     *pdwBufIdxPlus1 = HcpDecPhaseForBufIdx - (pScalabilityState->bFESeparateSubmission ?
66         CODECHAL_HCP_DECODE_PHASE_BE0 : CODECHAL_HCP_DECODE_PHASE_FE) + 1;
67 
68     return eStatus;
69 }
70 
71 //!
72 //! \brief    check if valid decode phase
73 //! \param    [in]  pScalabilityState
74 //!                pointer to scalability decode state
75 //! \param    [in]  HcpDecPhase
76 //!                Hcp Decode Phase
77 //! \return   MOS_STATUS
78 //!           MOS_STATUS_SUCCESS if valid decode phase, else fail reason
79 //!
CodecHalDecodeScalability_CheckDecPhaseValidity(PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityState,uint32_t HcpDecPhase)80 static MOS_STATUS CodecHalDecodeScalability_CheckDecPhaseValidity(
81     PCODECHAL_DECODE_SCALABILITY_STATE  pScalabilityState,
82     uint32_t                            HcpDecPhase)
83 {
84     bool                bInValidPhase = false;
85     MOS_STATUS          eStatus = MOS_STATUS_SUCCESS;
86 
87     CODECHAL_DECODE_FUNCTION_ENTER;
88 
89     CODECHAL_DECODE_CHK_NULL_RETURN(pScalabilityState);
90 
91     switch (HcpDecPhase)
92     {
93         case CodechalDecode::CodechalHcpDecodePhaseInitialized:
94             break;
95         case CodechalDecode::CodechalHcpDecodePhaseLegacyS2L:
96             if (!pScalabilityState->bShortFormatInUse)
97             {
98                 bInValidPhase = true;
99             }
100             break;
101         case CodechalDecode::CodechalHcpDecodePhaseLegacyLong:
102             if (pScalabilityState->bScalableDecodeMode)
103             {
104                 bInValidPhase = true;
105             }
106             break;
107         case CODECHAL_HCP_DECODE_PHASE_FE:
108         case CODECHAL_HCP_DECODE_PHASE_BE0:
109             if (!pScalabilityState->bScalableDecodeMode)
110             {
111                 bInValidPhase = true;
112             }
113             else if (pScalabilityState->ucScalablePipeNum < 2)
114             {
115                 //at least 2 pipe
116                 bInValidPhase = true;
117             }
118             break;
119         case CODECHAL_HCP_DECODE_PHASE_BE1:
120         case CODECHAL_HCP_DECODE_PHASE_RESERVED:
121             if (!pScalabilityState->bScalableDecodeMode)
122             {
123                 bInValidPhase = true;
124             }
125             else if (pScalabilityState->ucScalablePipeNum < (HcpDecPhase - CODECHAL_HCP_DECODE_PHASE_BE0 + 1))
126             {
127                 bInValidPhase = true;
128             }
129             break;
130         default:
131             bInValidPhase = true;
132             break;
133     }
134 
135     if (bInValidPhase)
136     {
137         eStatus = MOS_STATUS_INVALID_PARAMETER;
138         CODECHAL_DECODE_ASSERTMESSAGE("invalid decode phase : %d !", HcpDecPhase);
139     }
140 
141     return eStatus;
142 }
143 
144 //!
145 //! \brief    Allocate fixed size resources for scalability decode
146 //! \details  Allocate fixed size resources for scalability decode
147 //! \param    [in]  pScalabilityState
148 //!                pointer to scalability decode state
149 //! \return   MOS_STATUS
150 //!           MOS_STATUS_SUCCESS if success, else fail reason
151 //!
CodecHalDecodeScalability_AllocateResources_FixedSizes(PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityState)152 MOS_STATUS CodecHalDecodeScalability_AllocateResources_FixedSizes(
153     PCODECHAL_DECODE_SCALABILITY_STATE  pScalabilityState)
154 {
155     PMOS_INTERFACE          pOsInterface;
156     MOS_ALLOC_GFXRES_PARAMS AllocParamsForBufferLinear;
157     MOS_LOCK_PARAMS         LockFlagsWriteOnly;
158     uint8_t                *pData;
159     MOS_STATUS              eStatus = MOS_STATUS_SUCCESS;
160 
161     CODECHAL_DECODE_FUNCTION_ENTER;
162 
163     CODECHAL_DECODE_CHK_NULL_RETURN(pScalabilityState);
164     CODECHAL_DECODE_CHK_NULL_RETURN(pScalabilityState->pHwInterface);
165     CODECHAL_DECODE_CHK_NULL_RETURN(pScalabilityState->pHwInterface->GetOsInterface());
166 
167     pOsInterface = pScalabilityState->pHwInterface->GetOsInterface();
168 
169     MOS_ZeroMemory(&LockFlagsWriteOnly, sizeof(MOS_LOCK_PARAMS));
170     LockFlagsWriteOnly.WriteOnly = 1;
171 
172     // initiate allocation paramters
173     MOS_ZeroMemory(&AllocParamsForBufferLinear, sizeof(MOS_ALLOC_GFXRES_PARAMS));
174     AllocParamsForBufferLinear.Type = MOS_GFXRES_BUFFER;
175     AllocParamsForBufferLinear.TileType = MOS_TILE_LINEAR;
176     AllocParamsForBufferLinear.Format = Format_Buffer;
177 
178     if (pScalabilityState->Standard == CODECHAL_HEVC)//Confirmed by HW that VP9 does not need this buffer
179     {
180         //for Scalability --- Slice State Stream Out Buffer
181         AllocParamsForBufferLinear.dwBytes = CODECHAL_HEVC_MAX_NUM_SLICES_LVL_6 * pScalabilityState->sliceStateCLs * CODECHAL_CACHELINE_SIZE;
182         AllocParamsForBufferLinear.pBufName = "SliceStateStreamOut";
183 
184         eStatus = (MOS_STATUS)pOsInterface->pfnAllocateResource(
185             pOsInterface,
186             &AllocParamsForBufferLinear,
187             &pScalabilityState->resSliceStateStreamOutBuffer);
188 
189         if (eStatus != MOS_STATUS_SUCCESS)
190         {
191             CODECHAL_DECODE_ASSERTMESSAGE("Failed to allocate SliceState StreamOut Buffer.");
192             return eStatus;
193         }
194     }
195 
196     //Semaphore memory for BEs to start at the same time
197     AllocParamsForBufferLinear.dwBytes = sizeof(uint32_t);
198     AllocParamsForBufferLinear.pBufName = "BESemaphoreMemory";
199 
200     eStatus = (MOS_STATUS)pOsInterface->pfnAllocateResource(
201         pOsInterface,
202         &AllocParamsForBufferLinear,
203         &pScalabilityState->resSemaMemBEs);
204 
205     if (eStatus != MOS_STATUS_SUCCESS)
206     {
207         CODECHAL_DECODE_ASSERTMESSAGE("Failed to allocate BE Semaphore memory.");
208         return eStatus;
209     }
210 
211     pData = (uint8_t*)pOsInterface->pfnLockResource(
212         pOsInterface,
213         &pScalabilityState->resSemaMemBEs,
214         &LockFlagsWriteOnly);
215 
216     CODECHAL_DECODE_CHK_NULL_RETURN(pData);
217 
218     MOS_ZeroMemory(pData, sizeof(uint32_t));
219 
220     CODECHAL_DECODE_CHK_STATUS_RETURN(pOsInterface->pfnUnlockResource(
221         pOsInterface,
222         &pScalabilityState->resSemaMemBEs));
223 
224     AllocParamsForBufferLinear.dwBytes = sizeof(uint32_t);
225     AllocParamsForBufferLinear.pBufName = "DelayMinusMemory";
226 
227     eStatus = (MOS_STATUS)pOsInterface->pfnAllocateResource(
228         pOsInterface,
229         &AllocParamsForBufferLinear,
230         &pScalabilityState->resDelayMinus);
231 
232     if (eStatus != MOS_STATUS_SUCCESS)
233     {
234         CODECHAL_DECODE_ASSERTMESSAGE("Failed to allocate delay minus memory.");
235         return eStatus;
236     }
237 
238     pData = (uint8_t*)pOsInterface->pfnLockResource(
239         pOsInterface,
240         &pScalabilityState->resDelayMinus,
241         &LockFlagsWriteOnly);
242 
243     CODECHAL_DECODE_CHK_NULL_RETURN(pData);
244 
245     MOS_ZeroMemory(pData, sizeof(uint32_t));
246 
247     CODECHAL_DECODE_CHK_STATUS_RETURN(pOsInterface->pfnUnlockResource(
248         pOsInterface,
249         &pScalabilityState->resDelayMinus));
250 
251     if (pScalabilityState->pHwInterface->GetMfxInterface()->GetNumVdbox() > 2)
252     {
253         if (pScalabilityState->bFESeparateSubmission)
254         {
255             //SW Semaphore sync object for FE/BE synchronization
256             CODECHAL_DECODE_CHK_STATUS_RETURN(pOsInterface->pfnCreateSyncResource(pOsInterface, &pScalabilityState->resFeBeSyncObject));
257         }
258         else if (pOsInterface->bUseHwSemaForResSyncInVE)
259         {
260             //Semaphore memory for FE /BE synchronization
261             AllocParamsForBufferLinear.dwBytes = sizeof(uint32_t);
262             AllocParamsForBufferLinear.pBufName = "FEBESemaphMemory";
263 
264             eStatus = (MOS_STATUS)pOsInterface->pfnAllocateResource(
265                 pOsInterface,
266                 &AllocParamsForBufferLinear,
267                 &pScalabilityState->resSemaMemFEBE);
268 
269             if (eStatus != MOS_STATUS_SUCCESS)
270             {
271                 CODECHAL_DECODE_ASSERTMESSAGE("Failed to allocate FEBE Semaph memory.");
272                 return eStatus;
273             }
274 
275             pData = (uint8_t*)pOsInterface->pfnLockResource(
276                 pOsInterface,
277                 &pScalabilityState->resSemaMemFEBE,
278                 &LockFlagsWriteOnly);
279 
280             CODECHAL_DECODE_CHK_NULL_RETURN(pData);
281 
282             MOS_ZeroMemory(pData, sizeof(uint32_t));
283 
284             CODECHAL_DECODE_CHK_STATUS_RETURN(pOsInterface->pfnUnlockResource(
285                 pOsInterface,
286                 &pScalabilityState->resSemaMemFEBE));
287         }
288     }
289 
290     AllocParamsForBufferLinear.dwBytes = sizeof(CODECHAL_DECODE_SCALABILITY_FE_STATUS);
291     AllocParamsForBufferLinear.pBufName = "FEStatusBuffer";
292     eStatus = (MOS_STATUS)pOsInterface->pfnAllocateResource(
293         pOsInterface,
294         &AllocParamsForBufferLinear,
295         &pScalabilityState->resFEStatusBuffer);
296 
297     if (eStatus != MOS_STATUS_SUCCESS)
298     {
299         CODECHAL_DECODE_ASSERTMESSAGE("Failed to allocate FE status Buffer.");
300         return eStatus;
301     }
302 
303     //Semaphore memory for frame decode completion synchronization
304     AllocParamsForBufferLinear.dwBytes = sizeof(uint32_t);
305     AllocParamsForBufferLinear.pBufName = "CompletionSemaphMemory";
306 
307     eStatus = (MOS_STATUS)pOsInterface->pfnAllocateResource(
308         pOsInterface,
309         &AllocParamsForBufferLinear,
310         &pScalabilityState->resSemaMemCompletion);
311 
312     if (eStatus != MOS_STATUS_SUCCESS)
313     {
314         CODECHAL_DECODE_ASSERTMESSAGE("Failed to allocate Completion Semaph memory.");
315         return eStatus;
316     }
317 
318     pData = (uint8_t*)pOsInterface->pfnLockResource(
319         pOsInterface,
320         &pScalabilityState->resSemaMemCompletion,
321         &LockFlagsWriteOnly);
322 
323     CODECHAL_DECODE_CHK_NULL_RETURN(pData);
324 
325     MOS_ZeroMemory(pData, sizeof(uint32_t));
326 
327     CODECHAL_DECODE_CHK_STATUS_RETURN(pOsInterface->pfnUnlockResource(
328         pOsInterface,
329         &pScalabilityState->resSemaMemCompletion));
330 
331     return eStatus;
332 }
333 
334 //!
335 //! \brief    Get secondary cmd buffer
336 //! \param    [in]  pScalabilityState
337 //!                Scalability decode state
338 //! \param    [in] pSdryCmdBuf
339 //!                secondary cmd buffer address
340 //! \return   MOS_STATUS
341 //!           MOS_STATUS_SUCCESS if success, else fail reason
342 //!
CodecHalDecodeScalability_GetVESecondaryCmdBuffer(PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityState,PMOS_COMMAND_BUFFER pSdryCmdBuf)343 static MOS_STATUS CodecHalDecodeScalability_GetVESecondaryCmdBuffer(
344     PCODECHAL_DECODE_SCALABILITY_STATE  pScalabilityState,
345     PMOS_COMMAND_BUFFER                 pSdryCmdBuf)
346 {
347     PMOS_INTERFACE                  pOsInterface;
348     uint32_t                        HcpDecPhase;
349     uint32_t                        dwBufIdxPlus1 = 0;
350     MOS_STATUS                      eStatus = MOS_STATUS_SUCCESS;
351 
352     CODECHAL_DECODE_FUNCTION_ENTER;
353 
354     CODECHAL_DECODE_CHK_NULL_RETURN(pScalabilityState);
355     CODECHAL_DECODE_CHK_NULL_RETURN(pSdryCmdBuf);
356     CODECHAL_DECODE_CHK_NULL_RETURN(pScalabilityState->pHwInterface);
357     CODECHAL_DECODE_CHK_NULL_RETURN(pScalabilityState->pHwInterface->GetOsInterface());
358 
359     pOsInterface        = pScalabilityState->pHwInterface->GetOsInterface();
360     HcpDecPhase         = pScalabilityState->HcpDecPhase;
361 
362     //calculate bufidx for getting secondary cmd buffer.
363     CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalDecodeScalability_CalculateScdryCmdBufIndex(pScalabilityState, &dwBufIdxPlus1));
364     //Check if valid decode phase
365     CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalDecodeScalability_CheckDecPhaseValidity(pScalabilityState, HcpDecPhase));
366 
367     //Get batch buffer according to current decode phase
368     switch (HcpDecPhase)
369     {
370         case CodechalDecode::CodechalHcpDecodePhaseLegacyS2L:
371             //Note: no break here, S2L and FE commands put in one secondary command buffer.
372         case CODECHAL_HCP_DECODE_PHASE_FE:
373             if(!pScalabilityState->bFESeparateSubmission)
374             {
375                 CODECHAL_DECODE_CHK_STATUS_RETURN(pOsInterface->pfnGetCommandBuffer(pOsInterface, pSdryCmdBuf, dwBufIdxPlus1));
376                 CODECHAL_DECODE_CHK_NULL_RETURN(pSdryCmdBuf);
377             }
378             else
379             {
380                 //if FE separate submission, S2L and FE cmd buffer are in primary cmd buffer, shall not call this function to get secondary cmd buffer
381                 eStatus = MOS_STATUS_INVALID_PARAMETER;
382                 CODECHAL_DECODE_ASSERTMESSAGE("S2L or FE does not need secondary cmd buffer in FE separate submission!");
383             }
384             break;
385         case CODECHAL_HCP_DECODE_PHASE_BE0:
386         case CODECHAL_HCP_DECODE_PHASE_BE1:
387         case CODECHAL_HCP_DECODE_PHASE_RESERVED:
388             CODECHAL_DECODE_CHK_STATUS_RETURN(pOsInterface->pfnGetCommandBuffer(pOsInterface, pSdryCmdBuf, dwBufIdxPlus1));
389             CODECHAL_DECODE_CHK_NULL_RETURN(pSdryCmdBuf);
390             break;
391         default:
392             //never comes here because other decode phase already checked invalid in function CodecHalDecodeScalability_CheckDecPhaseValidity,
393             eStatus = MOS_STATUS_INVALID_PARAMETER;
394             break;
395     }
396 
397     return eStatus;
398 }
399 
CodecHalDecodeScalability_AllocateResources_VariableSizes(PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityState,PMHW_VDBOX_HCP_BUFFER_SIZE_PARAMS pHcpBufSizeParam,PMHW_VDBOX_HCP_BUFFER_REALLOC_PARAMS pAllocParam)400 MOS_STATUS CodecHalDecodeScalability_AllocateResources_VariableSizes(
401     PCODECHAL_DECODE_SCALABILITY_STATE   pScalabilityState,
402     PMHW_VDBOX_HCP_BUFFER_SIZE_PARAMS    pHcpBufSizeParam,
403     PMHW_VDBOX_HCP_BUFFER_REALLOC_PARAMS pAllocParam)
404 {
405     MOS_ALLOC_GFXRES_PARAMS AllocParamsForBufferLinear;
406     PMOS_INTERFACE          pOsInterface;
407     MOS_STATUS              eStatus = MOS_STATUS_SUCCESS;
408 
409     CODECHAL_DECODE_FUNCTION_ENTER;
410 
411     CODECHAL_DECODE_CHK_NULL_RETURN(pScalabilityState);
412     CODECHAL_DECODE_CHK_NULL_RETURN(pScalabilityState->pHwInterface);
413     CODECHAL_DECODE_CHK_NULL_RETURN(pScalabilityState->pHwInterface->GetOsInterface());
414     CODECHAL_DECODE_CHK_NULL_RETURN(pHcpBufSizeParam);
415     CODECHAL_DECODE_CHK_NULL_RETURN(pAllocParam);
416 
417     pOsInterface = pScalabilityState->pHwInterface->GetOsInterface();
418 
419     // initiate allocation paramters
420     MOS_ZeroMemory(&AllocParamsForBufferLinear, sizeof(MOS_ALLOC_GFXRES_PARAMS));
421     AllocParamsForBufferLinear.Type     = MOS_GFXRES_BUFFER;
422     AllocParamsForBufferLinear.TileType = MOS_TILE_LINEAR;
423     AllocParamsForBufferLinear.Format   = Format_Buffer;
424 
425     if (pScalabilityState->Standard == CODECHAL_HEVC)//Confirmed by HW that this buffer is not used in VP9 decoding
426     {
427         CODECHAL_DECODE_CHK_STATUS_RETURN(pScalabilityState->pfnIsHcpBufferReallocNeeded(pScalabilityState->pHwInterface,
428                                                                                  MHW_VDBOX_HCP_INTERNAL_BUFFER_MV_UP_RT_COL,
429                                                                                  pAllocParam));
430         if (pAllocParam->bNeedBiggerSize || Mos_ResourceIsNull(&pScalabilityState->resMvUpRightColStoreBuffer))
431         {
432             if (!Mos_ResourceIsNull(&pScalabilityState->resMvUpRightColStoreBuffer))
433             {
434                 pOsInterface->pfnFreeResource(
435                     pOsInterface,
436                     &pScalabilityState->resMvUpRightColStoreBuffer);
437             }
438             // MV UpperRight Column Store Buffer
439             CODECHAL_DECODE_CHK_STATUS_RETURN(pScalabilityState->pfnGetHcpBufferSize(pScalabilityState->pHwInterface,
440                                                                              MHW_VDBOX_HCP_INTERNAL_BUFFER_MV_UP_RT_COL,
441                                                                              pHcpBufSizeParam));
442             AllocParamsForBufferLinear.dwBytes  = pHcpBufSizeParam->dwBufferSize;
443             AllocParamsForBufferLinear.pBufName = "MVUpperRightColumnStore";
444 
445             eStatus = (MOS_STATUS)pOsInterface->pfnAllocateResource(
446                 pOsInterface,
447                 &AllocParamsForBufferLinear,
448                 &pScalabilityState->resMvUpRightColStoreBuffer);
449 
450             if (eStatus != MOS_STATUS_SUCCESS)
451             {
452                 CODECHAL_DECODE_ASSERTMESSAGE("Failed to allocate MV UpperRight Column Store Buffer.");
453                 return eStatus;
454             }
455         }
456     }
457 
458     CODECHAL_DECODE_CHK_STATUS_RETURN(pScalabilityState->pfnIsHcpBufferReallocNeeded(pScalabilityState->pHwInterface,
459                                                                              MHW_VDBOX_HCP_INTERNAL_BUFFER_INTRA_PRED_UP_RIGHT_COL,
460                                                                              pAllocParam));
461     if (pAllocParam->bNeedBiggerSize || Mos_ResourceIsNull(&pScalabilityState->resIntraPredUpRightColStoreBuffer))
462     {
463         if (!Mos_ResourceIsNull(&pScalabilityState->resIntraPredUpRightColStoreBuffer))
464         {
465             pOsInterface->pfnFreeResource(
466                 pOsInterface,
467                 &pScalabilityState->resIntraPredUpRightColStoreBuffer);
468         }
469         // IntraPred UpperRight Column Store Buffer
470         CODECHAL_DECODE_CHK_STATUS_RETURN(pScalabilityState->pfnGetHcpBufferSize(pScalabilityState->pHwInterface,
471                                                                          MHW_VDBOX_HCP_INTERNAL_BUFFER_INTRA_PRED_UP_RIGHT_COL,
472                                                                          pHcpBufSizeParam));
473         AllocParamsForBufferLinear.dwBytes  = pHcpBufSizeParam->dwBufferSize;
474          AllocParamsForBufferLinear.pBufName = "IntraPredUpperRightColumnStore";
475 
476         eStatus = (MOS_STATUS)pOsInterface->pfnAllocateResource(
477             pOsInterface,
478             &AllocParamsForBufferLinear,
479             &pScalabilityState->resIntraPredUpRightColStoreBuffer);
480 
481         if (eStatus != MOS_STATUS_SUCCESS)
482         {
483             CODECHAL_DECODE_ASSERTMESSAGE("Failed to allocate IntraPred UpperRight Column Store Buffer.");
484             return eStatus;
485         }
486     }
487 
488     CODECHAL_DECODE_CHK_STATUS_RETURN(pScalabilityState->pfnIsHcpBufferReallocNeeded(pScalabilityState->pHwInterface,
489                                                                              MHW_VDBOX_HCP_INTERNAL_BUFFER_INTRA_PRED_LFT_RECON_COL,
490                                                                              pAllocParam));
491     if (pAllocParam->bNeedBiggerSize || Mos_ResourceIsNull(&pScalabilityState->resIntraPredLeftReconColStoreBuffer))
492     {
493         if (!Mos_ResourceIsNull(&pScalabilityState->resIntraPredLeftReconColStoreBuffer))
494         {
495             pOsInterface->pfnFreeResource(
496                 pOsInterface,
497                 &pScalabilityState->resIntraPredLeftReconColStoreBuffer);
498         }
499         // IntraPred Left Recon Column Store Buffer
500         CODECHAL_DECODE_CHK_STATUS_RETURN(pScalabilityState->pfnGetHcpBufferSize(pScalabilityState->pHwInterface,
501                                                                          MHW_VDBOX_HCP_INTERNAL_BUFFER_INTRA_PRED_LFT_RECON_COL,
502                                                                          pHcpBufSizeParam));
503         AllocParamsForBufferLinear.dwBytes  = pHcpBufSizeParam->dwBufferSize;
504         AllocParamsForBufferLinear.pBufName = "IntraPredLeftReconColumnStore";
505 
506         eStatus = (MOS_STATUS)pOsInterface->pfnAllocateResource(
507             pOsInterface,
508             &AllocParamsForBufferLinear,
509             &pScalabilityState->resIntraPredLeftReconColStoreBuffer);
510 
511         if (eStatus != MOS_STATUS_SUCCESS)
512         {
513             CODECHAL_DECODE_ASSERTMESSAGE("Failed to allocate IntraPred Left Recon Column Store Buffer.");
514             return eStatus;
515         }
516     }
517 
518     CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalDecodeScalability_AllocateCABACStreamOutBuffer(pScalabilityState,
519                                                                             pHcpBufSizeParam,
520                                                                             pAllocParam,
521                                                                             &pScalabilityState->resCABACSyntaxStreamOutBuffer[0]));
522 
523     pScalabilityState->presCABACStreamOutBuffer = &pScalabilityState->resCABACSyntaxStreamOutBuffer[0];
524 
525     return eStatus;
526 }
527 
CodecHalDecodeScalability_AllocateCABACStreamOutBuffer(PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityState,PMHW_VDBOX_HCP_BUFFER_SIZE_PARAMS pHcpBufSizeParam,PMHW_VDBOX_HCP_BUFFER_REALLOC_PARAMS pAllocParam,PMOS_RESOURCE presCABACStreamOutBuffer)528 MOS_STATUS CodecHalDecodeScalability_AllocateCABACStreamOutBuffer(
529     PCODECHAL_DECODE_SCALABILITY_STATE   pScalabilityState,
530     PMHW_VDBOX_HCP_BUFFER_SIZE_PARAMS    pHcpBufSizeParam,
531     PMHW_VDBOX_HCP_BUFFER_REALLOC_PARAMS pAllocParam,
532     PMOS_RESOURCE                        presCABACStreamOutBuffer)
533 {
534     PMOS_INTERFACE          pOsInterface;
535     MOS_ALLOC_GFXRES_PARAMS AllocParamsForBufferLinear;
536     MOS_STATUS              eStatus = MOS_STATUS_SUCCESS;
537 
538     CODECHAL_DECODE_FUNCTION_ENTER;
539 
540     CODECHAL_DECODE_CHK_NULL_RETURN(pScalabilityState);
541     CODECHAL_DECODE_CHK_NULL_RETURN(pScalabilityState->pHwInterface);
542     CODECHAL_DECODE_CHK_NULL_RETURN(pScalabilityState->pHwInterface->GetOsInterface());
543     CODECHAL_DECODE_CHK_NULL_RETURN(pHcpBufSizeParam);
544     CODECHAL_DECODE_CHK_NULL_RETURN(pAllocParam);
545     CODECHAL_DECODE_CHK_NULL_RETURN(presCABACStreamOutBuffer);
546 
547     pOsInterface = pScalabilityState->pHwInterface->GetOsInterface();
548 
549     // initiate allocation paramters
550     MOS_ZeroMemory(&AllocParamsForBufferLinear, sizeof(MOS_ALLOC_GFXRES_PARAMS));
551     AllocParamsForBufferLinear.Type     = MOS_GFXRES_BUFFER;
552     AllocParamsForBufferLinear.TileType = MOS_TILE_LINEAR;
553     AllocParamsForBufferLinear.Format   = Format_Buffer;
554 
555     CODECHAL_DECODE_CHK_STATUS_RETURN(pScalabilityState->pfnIsHcpBufferReallocNeeded(pScalabilityState->pHwInterface,
556                                                                              MHW_VDBOX_HCP_INTERNAL_BUFFER_CABAC_STREAMOUT,
557                                                                              pAllocParam));
558     if (pAllocParam->bNeedBiggerSize || Mos_ResourceIsNull(presCABACStreamOutBuffer))
559     {
560         if (!Mos_ResourceIsNull(presCABACStreamOutBuffer))
561         {
562             pOsInterface->pfnFreeResource(
563                 pOsInterface,
564                 presCABACStreamOutBuffer);
565         }
566 
567         CODECHAL_DECODE_CHK_STATUS_RETURN(pScalabilityState->pfnGetHcpBufferSize(pScalabilityState->pHwInterface,
568                                                                          MHW_VDBOX_HCP_INTERNAL_BUFFER_CABAC_STREAMOUT,
569                                                                          pHcpBufSizeParam));
570 
571         pScalabilityState->dwCABACSyntaxStreamOutBufferSize = pHcpBufSizeParam->dwBufferSize;
572 
573         AllocParamsForBufferLinear.dwBytes = pHcpBufSizeParam->dwBufferSize;
574         AllocParamsForBufferLinear.pBufName = "CABACStreamOutBuffer";
575 
576         eStatus = (MOS_STATUS)pOsInterface->pfnAllocateResource(
577             pOsInterface,
578             &AllocParamsForBufferLinear,
579             presCABACStreamOutBuffer);
580 
581         if (eStatus != MOS_STATUS_SUCCESS)
582         {
583             CODECHAL_DECODE_ASSERTMESSAGE("Failed to allocate CABAC StreamOut Buffer.");
584             return eStatus;
585         }
586     }
587 
588     return eStatus;
589 }
590 
CodecHalDecodeScalability_Destroy(PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityState)591 void CodecHalDecodeScalability_Destroy (
592     PCODECHAL_DECODE_SCALABILITY_STATE  pScalabilityState)
593 {
594     PMOS_INTERFACE      pOsInterface;
595 
596     CODECHAL_DECODE_FUNCTION_ENTER;
597 
598     CODECHAL_DECODE_CHK_NULL_NO_STATUS_RETURN(pScalabilityState);
599     CODECHAL_DECODE_CHK_NULL_NO_STATUS_RETURN(pScalabilityState->pHwInterface);
600     CODECHAL_DECODE_CHK_NULL_NO_STATUS_RETURN(pScalabilityState->pHwInterface->GetOsInterface());
601     pOsInterface = pScalabilityState->pHwInterface->GetOsInterface();
602 
603     pOsInterface->pfnFreeResource(
604         pOsInterface,
605         &pScalabilityState->resSliceStateStreamOutBuffer);
606     pOsInterface->pfnFreeResource(
607         pOsInterface,
608         &pScalabilityState->resMvUpRightColStoreBuffer);
609     pOsInterface->pfnFreeResource(
610         pOsInterface,
611         &pScalabilityState->resIntraPredLeftReconColStoreBuffer);
612     pOsInterface->pfnFreeResource(
613         pOsInterface,
614         &pScalabilityState->resIntraPredUpRightColStoreBuffer);
615     for (int i = 0; i < CODECHAL_HCP_STREAMOUT_BUFFER_MAX_NUM; i++)
616     {
617         pOsInterface->pfnFreeResource(
618             pOsInterface,
619             &pScalabilityState->resCABACSyntaxStreamOutBuffer[i]);
620     }
621     pOsInterface->pfnFreeResource(
622         pOsInterface,
623         &pScalabilityState->resSemaMemBEs);
624     pOsInterface->pfnFreeResource(
625         pOsInterface,
626         &pScalabilityState->resDelayMinus);
627     if (pOsInterface->bUseHwSemaForResSyncInVE)
628     {
629         pOsInterface->pfnFreeResource(
630             pOsInterface,
631             &pScalabilityState->resSemaMemFEBE);
632     }
633     pOsInterface->pfnFreeResource(
634         pOsInterface,
635         &pScalabilityState->resFEStatusBuffer);
636     pOsInterface->pfnDestroySyncResource(pOsInterface, &pScalabilityState->resFeBeSyncObject);
637 
638     pOsInterface->pfnFreeResource(
639         pOsInterface,
640         &pScalabilityState->resSemaMemCompletion);
641 
642     return;
643 }
644 
CodecHalDecodeScalability_GetCmdBufferToUse(PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityState,PMOS_COMMAND_BUFFER pScdryCmdBuf,PMOS_COMMAND_BUFFER * ppCmdBufToUse)645 MOS_STATUS CodecHalDecodeScalability_GetCmdBufferToUse(
646     PCODECHAL_DECODE_SCALABILITY_STATE  pScalabilityState,
647     PMOS_COMMAND_BUFFER                 pScdryCmdBuf,
648     PMOS_COMMAND_BUFFER                 *ppCmdBufToUse)
649 {
650     MOS_STATUS                      eStatus = MOS_STATUS_SUCCESS;
651 
652     CODECHAL_DECODE_FUNCTION_ENTER;
653 
654     CODECHAL_DECODE_CHK_NULL_RETURN(pScalabilityState);
655     CODECHAL_DECODE_CHK_NULL_RETURN(ppCmdBufToUse);
656 
657     if (!CodecHalDecodeScalabilityIsFESeparateSubmission(pScalabilityState) ||
658         CodecHalDecodeScalabilityIsBEPhase(pScalabilityState))
659     {
660         pScalabilityState->bUseSecdryCmdBuffer = true;
661         CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalDecodeScalability_GetVESecondaryCmdBuffer(pScalabilityState, pScdryCmdBuf));
662         *ppCmdBufToUse = pScdryCmdBuf;
663     }
664     else
665     {
666         pScalabilityState->bUseSecdryCmdBuffer = false;
667     }
668 
669     return eStatus;
670 }
671 
CodecHalDecodeScalability_ReturnSdryCmdBuffer(PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityState,PMOS_COMMAND_BUFFER pSdryCmdBuf)672 MOS_STATUS CodecHalDecodeScalability_ReturnSdryCmdBuffer(
673     PCODECHAL_DECODE_SCALABILITY_STATE  pScalabilityState,
674     PMOS_COMMAND_BUFFER                 pSdryCmdBuf)
675 {
676     PMOS_INTERFACE                  pOsInterface;
677     uint32_t                        HcpDecPhase;
678     uint32_t                        dwBufIdxPlus1;
679     MOS_STATUS                      eStatus = MOS_STATUS_SUCCESS;
680 
681     CODECHAL_DECODE_FUNCTION_ENTER;
682 
683     CODECHAL_DECODE_CHK_NULL_RETURN(pScalabilityState);
684     CODECHAL_DECODE_CHK_NULL_RETURN(pSdryCmdBuf);
685     CODECHAL_DECODE_CHK_NULL_RETURN(pScalabilityState->pHwInterface);
686     CODECHAL_DECODE_CHK_NULL_RETURN(pScalabilityState->pHwInterface->GetOsInterface());
687 
688     pOsInterface = pScalabilityState->pHwInterface->GetOsInterface();
689 
690     if (!pScalabilityState->bUseSecdryCmdBuffer)
691     {
692         return eStatus;
693     }
694 
695     HcpDecPhase         = pScalabilityState->HcpDecPhase;
696 
697     //calculate bufidx for getting secondary cmd buffer.
698     CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalDecodeScalability_CalculateScdryCmdBufIndex(pScalabilityState, &dwBufIdxPlus1));
699     //Check if valid decode phase
700     CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalDecodeScalability_CheckDecPhaseValidity(pScalabilityState, HcpDecPhase));
701 
702     //Get batch buffer according to current decode phase
703     switch (HcpDecPhase)
704     {
705         case CodechalDecode::CodechalHcpDecodePhaseLegacyS2L:
706             //Note: no break here, S2L and FE commands put in one secondary command buffer.
707         case CODECHAL_HCP_DECODE_PHASE_FE:
708             if(!pScalabilityState->bFESeparateSubmission)
709             {
710                 pOsInterface->pfnReturnCommandBuffer(pOsInterface, pSdryCmdBuf, dwBufIdxPlus1);
711             }
712             else
713             {
714                 //if FE separate submission, S2L and FE cmd buffer are in primary cmd buffer, shall not call this function to get secondary cmd buffer
715                 eStatus = MOS_STATUS_INVALID_PARAMETER;
716                 CODECHAL_DECODE_ASSERTMESSAGE("S2L or FE does not need secondary cmd buffer in FE separate submission!");
717             }
718             break;
719         case CODECHAL_HCP_DECODE_PHASE_BE0:
720         case CODECHAL_HCP_DECODE_PHASE_BE1:
721         case CODECHAL_HCP_DECODE_PHASE_RESERVED:
722             pOsInterface->pfnReturnCommandBuffer(pOsInterface, pSdryCmdBuf, dwBufIdxPlus1);
723             break;
724         default:
725             //never comes here because other decode phase already checked invalid in function CodecHalDecodeScalability_CheckDecPhaseValidity,
726             eStatus = MOS_STATUS_INVALID_PARAMETER;
727             break;
728     }
729 
730     return eStatus;
731 }
732 
CodecHalDecodeScalablity_SetFECabacStreamoutOverflowStatus(PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityState,PMOS_COMMAND_BUFFER pCmdBufferInUse)733 MOS_STATUS CodecHalDecodeScalablity_SetFECabacStreamoutOverflowStatus(
734     PCODECHAL_DECODE_SCALABILITY_STATE  pScalabilityState,
735     PMOS_COMMAND_BUFFER                 pCmdBufferInUse)
736 {
737     MhwMiInterface                      *pMiInterface;
738     CodechalHwInterface                 *pHwInterface;
739     MmioRegistersMfx                    *pMmioRegistersMfx;
740     MmioRegistersHcp                    *pMmioRegistersHcp;
741     MHW_MI_STORE_REGISTER_MEM_PARAMS    StoreRegParams;
742     MHW_MI_STORE_DATA_PARAMS            StoreDataParams;
743     MHW_MI_LOAD_REGISTER_REG_PARAMS     LoadRegRegParams;
744     MHW_MI_LOAD_REGISTER_IMM_PARAMS     LoadRegisterImmParams;
745     MHW_MI_FLUSH_DW_PARAMS              FlushDwParams;
746     MHW_MI_MATH_PARAMS                  MiMathParams;
747     MHW_MI_ALU_PARAMS                   MiAluParams[4];
748     MOS_STATUS                          eStatus = MOS_STATUS_SUCCESS;
749 
750     CODECHAL_DECODE_FUNCTION_ENTER;
751 
752     CODECHAL_DECODE_CHK_NULL_RETURN(pCmdBufferInUse);
753     CODECHAL_DECODE_CHK_NULL_RETURN(pScalabilityState);
754 
755     CODECHAL_DECODE_CHK_NULL_RETURN(pScalabilityState->pHwInterface);
756     CODECHAL_DECODE_CHK_NULL_RETURN(pScalabilityState->pHwInterface->GetMiInterface());
757     pMiInterface  = pScalabilityState->pHwInterface->GetMiInterface();
758     pHwInterface = pScalabilityState->pHwInterface;
759 
760     //relative MMIO addressing
761     pMmioRegistersMfx   = pHwInterface->GetMfxInterface()->GetMmioRegisters(MHW_VDBOX_NODE_1);
762     pMmioRegistersHcp   = pHwInterface->GetHcpInterface()->GetMmioRegisters(MHW_VDBOX_NODE_1);
763 
764     MOS_ZeroMemory(&FlushDwParams, sizeof(FlushDwParams));
765     CODECHAL_DECODE_CHK_STATUS_RETURN(pMiInterface->AddMiFlushDwCmd(pCmdBufferInUse, &FlushDwParams));
766 
767     // store stream out size register to general purpose register0 - Hi=0, Lo=FE stream out size
768     MOS_ZeroMemory(&LoadRegRegParams, sizeof(LoadRegRegParams));
769     LoadRegRegParams.dwSrcRegister = pMmioRegistersHcp->hcpDebugFEStreamOutSizeRegOffset;
770     LoadRegRegParams.dwDstRegister = pMmioRegistersMfx->generalPurposeRegister0LoOffset;
771     CODECHAL_DECODE_CHK_STATUS_RETURN(pMiInterface->AddMiLoadRegisterRegCmd(
772         pCmdBufferInUse,
773         &LoadRegRegParams));
774     MOS_ZeroMemory(&LoadRegisterImmParams, sizeof(LoadRegisterImmParams));
775     LoadRegisterImmParams.dwData        = 0;
776     LoadRegisterImmParams.dwRegister    = pMmioRegistersMfx->generalPurposeRegister0HiOffset;
777     CODECHAL_DECODE_CHK_STATUS_RETURN(pMiInterface->AddMiLoadRegisterImmCmd(
778         pCmdBufferInUse,
779         &LoadRegisterImmParams));
780 
781     // load allocated size to general purpose register4 - Hi = 0
782     MOS_ZeroMemory(&LoadRegisterImmParams, sizeof(LoadRegisterImmParams));
783     LoadRegisterImmParams.dwData        = pScalabilityState->dwCABACSyntaxStreamOutBufferSize;
784     LoadRegisterImmParams.dwRegister    = pMmioRegistersMfx->generalPurposeRegister4LoOffset;
785     CODECHAL_DECODE_CHK_STATUS_RETURN(pMiInterface->AddMiLoadRegisterImmCmd(
786         pCmdBufferInUse,
787         &LoadRegisterImmParams));
788     MOS_ZeroMemory(&LoadRegisterImmParams, sizeof(LoadRegisterImmParams));
789     LoadRegisterImmParams.dwData        = 0;
790     LoadRegisterImmParams.dwRegister    = pMmioRegistersMfx->generalPurposeRegister4HiOffset;
791     CODECHAL_DECODE_CHK_STATUS_RETURN(pMiInterface->AddMiLoadRegisterImmCmd(
792         pCmdBufferInUse,
793         &LoadRegisterImmParams));
794 
795     //perform the sub operation(reported size - allocated size)
796     MOS_ZeroMemory(&MiMathParams, sizeof(MiMathParams));
797     MOS_ZeroMemory(&MiAluParams, sizeof(MiAluParams));
798     // load     srcA, reg0
799     MiAluParams[0].AluOpcode    = MHW_MI_ALU_LOAD;
800     MiAluParams[0].Operand1     = MHW_MI_ALU_SRCA;
801     MiAluParams[0].Operand2     = MHW_MI_ALU_GPREG0;
802     // load     srcB, reg4
803     MiAluParams[1].AluOpcode    = MHW_MI_ALU_LOAD;
804     MiAluParams[1].Operand1     = MHW_MI_ALU_SRCB;
805     MiAluParams[1].Operand2     = MHW_MI_ALU_GPREG4;
806     // sub      srcA, srcB
807     MiAluParams[2].AluOpcode    = MHW_MI_ALU_SUB;
808     MiAluParams[2].Operand1     = MHW_MI_ALU_SRCB;
809     MiAluParams[2].Operand2     = MHW_MI_ALU_GPREG4;
810     // store      reg0, CF
811     MiAluParams[3].AluOpcode    = MHW_MI_ALU_STORE;
812     MiAluParams[3].Operand1     = MHW_MI_ALU_GPREG0;
813     MiAluParams[3].Operand2     = MHW_MI_ALU_CF;
814     MiMathParams.pAluPayload    = MiAluParams;
815     MiMathParams.dwNumAluParams = 4; // four ALU commands needed for this substract opertaion. see following ALU commands.
816     CODECHAL_DECODE_CHK_STATUS_RETURN(pMiInterface->AddMiMathCmd(
817         pCmdBufferInUse,
818         &MiMathParams));
819     // store the carry flag of (reported size - allocated size),
820     // if reported size < allocated size,  the carry flag will be 0xFFFFFFFF, else carry flag will be 0x0.
821     MOS_ZeroMemory(&StoreRegParams, sizeof(StoreRegParams));
822     StoreRegParams.presStoreBuffer      = &pScalabilityState->resFEStatusBuffer;
823     StoreRegParams.dwOffset             = CODECHAL_OFFSETOF(CODECHAL_DECODE_SCALABILITY_FE_STATUS, dwCarryFlagOfReportedSizeMinusAllocSize);
824     StoreRegParams.dwRegister           = pMmioRegistersMfx->generalPurposeRegister0LoOffset;
825     CODECHAL_DECODE_CHK_STATUS_RETURN(pMiInterface->AddMiStoreRegisterMemCmd(pCmdBufferInUse, &StoreRegParams));
826 
827     return eStatus;
828 }
829 
CodecHalDecodeScalablity_GetFEReportedCabacStreamoutBufferSize(PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityState,PMOS_COMMAND_BUFFER pCmdBufferInUse)830 MOS_STATUS CodecHalDecodeScalablity_GetFEReportedCabacStreamoutBufferSize(
831     PCODECHAL_DECODE_SCALABILITY_STATE  pScalabilityState,
832     PMOS_COMMAND_BUFFER                 pCmdBufferInUse)
833 {
834     MhwMiInterface                      *pMiInterface;
835     CodechalHwInterface                 *pHwInterface;
836     MmioRegistersHcp                    *pMmioRegistersHcp;
837     MHW_MI_STORE_REGISTER_MEM_PARAMS    StoreRegParams;
838     MHW_MI_FLUSH_DW_PARAMS              FlushDwParams;
839     MOS_STATUS                          eStatus = MOS_STATUS_SUCCESS;
840 
841     CODECHAL_DECODE_FUNCTION_ENTER;
842 
843     CODECHAL_DECODE_CHK_NULL_RETURN(pCmdBufferInUse);
844     CODECHAL_DECODE_CHK_NULL_RETURN(pScalabilityState);
845 
846     CODECHAL_DECODE_CHK_NULL_RETURN(pScalabilityState->pHwInterface);
847     pMiInterface = pScalabilityState->pHwInterface->GetMiInterface();
848     pHwInterface = pScalabilityState->pHwInterface;
849 
850     //relative MMIO addressing
851     pMmioRegistersHcp = pHwInterface->GetHcpInterface()->GetMmioRegisters(MHW_VDBOX_NODE_1);
852 
853     MOS_ZeroMemory(&FlushDwParams, sizeof(FlushDwParams));
854     CODECHAL_DECODE_CHK_STATUS_RETURN(pMiInterface->AddMiFlushDwCmd(pCmdBufferInUse, &FlushDwParams));
855 
856     //store the cabac streamout buff size in register into mem
857     MOS_ZeroMemory(&StoreRegParams, sizeof(StoreRegParams));
858     StoreRegParams.presStoreBuffer = &pScalabilityState->resFEStatusBuffer;
859     StoreRegParams.dwOffset = CODECHAL_OFFSETOF(CODECHAL_DECODE_SCALABILITY_FE_CABAC_STREAMOUT_BUFF_SIZE, dwCabacStreamoutBuffSize);
860     StoreRegParams.dwRegister = pMmioRegistersHcp->hcpDebugFEStreamOutSizeRegOffset;
861     CODECHAL_DECODE_CHK_STATUS_RETURN(pMiInterface->AddMiStoreRegisterMemCmd(pCmdBufferInUse, &StoreRegParams));
862 
863     return eStatus;
864 }
865 
CodecHalDecodeScalability_DetermineDecodePhase(PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityState,uint32_t * pHcpDecPhase)866 MOS_STATUS CodecHalDecodeScalability_DetermineDecodePhase(
867     PCODECHAL_DECODE_SCALABILITY_STATE  pScalabilityState,
868     uint32_t                            *pHcpDecPhase)
869 {
870     uint32_t                        CurPhase;
871     MOS_STATUS                      eStatus = MOS_STATUS_SUCCESS;
872 
873     CODECHAL_DECODE_FUNCTION_ENTER;
874 
875     CODECHAL_DECODE_CHK_NULL_RETURN(pScalabilityState);
876     CODECHAL_DECODE_CHK_NULL_RETURN(pHcpDecPhase);
877 
878     CurPhase = *pHcpDecPhase;
879     //Check if valid decode phase
880     CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalDecodeScalability_CheckDecPhaseValidity(pScalabilityState, CurPhase));
881 
882     if (CodecHalDecodeScalabilityIsScalableMode(pScalabilityState))
883     {
884         switch (CurPhase)
885         {
886             case CodechalDecode::CodechalHcpDecodePhaseInitialized:
887                 if (pScalabilityState->bShortFormatInUse)
888                 {
889                     *pHcpDecPhase = CodechalDecode::CodechalHcpDecodePhaseLegacyS2L;
890                 }
891                 else
892                 {
893                     *pHcpDecPhase = CODECHAL_HCP_DECODE_PHASE_FE;
894                 }
895                 break;
896             case CodechalDecode::CodechalHcpDecodePhaseLegacyS2L:
897                 *pHcpDecPhase = CODECHAL_HCP_DECODE_PHASE_FE;
898                 break;
899             case CODECHAL_HCP_DECODE_PHASE_FE:
900                 *pHcpDecPhase = CODECHAL_HCP_DECODE_PHASE_BE0;
901                 break;
902             case CODECHAL_HCP_DECODE_PHASE_BE0:
903                 *pHcpDecPhase = CODECHAL_HCP_DECODE_PHASE_BE1;
904                 break;
905             case CODECHAL_HCP_DECODE_PHASE_BE1:
906                 *pHcpDecPhase = CODECHAL_HCP_DECODE_PHASE_RESERVED;
907                 break;
908             default:
909                 //never comes here because other decode phase already checked invalid in function CodecHalDecodeScalability_CheckDecPhaseValidity,
910                 eStatus = MOS_STATUS_INVALID_PARAMETER;
911                 break;
912         }
913     }
914     else
915     {
916         switch (CurPhase)
917         {
918             case CodechalDecode::CodechalHcpDecodePhaseInitialized:
919                 if (pScalabilityState->bShortFormatInUse)
920                 {
921                     *pHcpDecPhase = CodechalDecode::CodechalHcpDecodePhaseLegacyS2L;
922                 }
923                 else
924                 {
925                     *pHcpDecPhase = CodechalDecode::CodechalHcpDecodePhaseLegacyLong;
926                 }
927                 break;
928             case CodechalDecode::CodechalHcpDecodePhaseLegacyS2L:
929                 *pHcpDecPhase = CodechalDecode::CodechalHcpDecodePhaseLegacyLong;
930                 break;
931             default:
932                 //never comes here because other decode phase already checked invalid in function CodecHalDecodeScalability_CheckDecPhaseValidity,
933                 eStatus = MOS_STATUS_INVALID_PARAMETER;
934                 break;
935         }
936     }
937 
938     pScalabilityState->HcpDecPhase = *pHcpDecPhase;
939 
940     return eStatus;
941 }
942 
CodecHalDecodeScalability_DetermineSendWatchdogTimerStart(PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityState,bool * pbSend)943 MOS_STATUS CodecHalDecodeScalability_DetermineSendWatchdogTimerStart(
944     PCODECHAL_DECODE_SCALABILITY_STATE  pScalabilityState,
945     bool                                *pbSend)
946 {
947     uint32_t                        HcpDecPhase;
948     MOS_STATUS                      eStatus = MOS_STATUS_SUCCESS;
949 
950     CODECHAL_DECODE_FUNCTION_ENTER;
951 
952     CODECHAL_DECODE_CHK_NULL_RETURN(pScalabilityState);
953     HcpDecPhase  = pScalabilityState->HcpDecPhase;
954 
955     //Check if valid decode phase
956     CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalDecodeScalability_CheckDecPhaseValidity(pScalabilityState, HcpDecPhase));
957 
958     switch (HcpDecPhase)
959     {
960         case CodechalDecode::CodechalHcpDecodePhaseLegacyS2L:
961             *pbSend = true;
962             break;
963         case CODECHAL_HCP_DECODE_PHASE_FE:
964             *pbSend = !pScalabilityState->bShortFormatInUse;
965             break;
966         case CODECHAL_HCP_DECODE_PHASE_BE0:
967         case CODECHAL_HCP_DECODE_PHASE_BE1:
968         case CODECHAL_HCP_DECODE_PHASE_RESERVED:
969             *pbSend = true;
970             break;
971         default:
972             //never comes here because other decode phase already checked invalid in function CodecHalDecodeScalability_CheckDecPhaseValidity,
973             eStatus = MOS_STATUS_INVALID_PARAMETER;
974             break;
975     }
976 
977     return eStatus;
978 }
979 
CodecHalDecodeScalability_SwitchGpuContext(PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityState)980 MOS_STATUS CodecHalDecodeScalability_SwitchGpuContext(
981     PCODECHAL_DECODE_SCALABILITY_STATE  pScalabilityState)
982 {
983     PMOS_INTERFACE                  pOsInterface;
984     MOS_GPU_CONTEXT                 GpuContext;
985     uint32_t                        HcpDecPhase;
986     bool                            bFESepSwitchContextFlag = false;
987     MOS_STATUS                      eStatus = MOS_STATUS_SUCCESS;
988 
989     CODECHAL_DECODE_FUNCTION_ENTER;
990 
991     CODECHAL_DECODE_CHK_NULL_RETURN(pScalabilityState);
992     CODECHAL_DECODE_CHK_NULL_RETURN(pScalabilityState->pHwInterface);
993     CODECHAL_DECODE_CHK_NULL_RETURN(pScalabilityState->pHwInterface->GetOsInterface());
994 
995     pOsInterface = pScalabilityState->pHwInterface->GetOsInterface();
996     HcpDecPhase  = pScalabilityState->HcpDecPhase;
997 
998     if (pScalabilityState->bFESeparateSubmission)
999     {
1000         if (CodecHalDecodeScalability1stPhaseofSubmission(pScalabilityState))
1001         {
1002             bFESepSwitchContextFlag = true;
1003             if (pScalabilityState->bFESeparateSubmission && HcpDecPhase == CODECHAL_HCP_DECODE_PHASE_BE0)
1004             {
1005                 GpuContext = pScalabilityState->VideoContext;
1006             }
1007             else
1008             {
1009                 GpuContext = pScalabilityState->VideoContextForFE;
1010             }
1011         }
1012     }
1013 
1014 #if (_DEBUG || _RELEASE_INTERNAL)
1015     if (CodecHalDecodeScalability1stDecPhase(pScalabilityState))
1016     {
1017         // report in-use
1018         MOS_USER_FEATURE_VALUE_WRITE_DATA UserFeatureWriteData;
1019         MOS_ZeroMemory(&UserFeatureWriteData, sizeof(UserFeatureWriteData));
1020         UserFeatureWriteData.Value.i32Data = pScalabilityState->bFESeparateSubmission;
1021         UserFeatureWriteData.ValueID = __MEDIA_USER_FEATURE_VALUE_SCALABILITY_FE_SEPARATE_SUBMISSION_IN_USE_ID;
1022         MOS_UserFeature_WriteValues_ID(nullptr, &UserFeatureWriteData, 1, pOsInterface->pOsContext);
1023     }
1024 #endif
1025 
1026     if (bFESepSwitchContextFlag)
1027     {
1028         CODECHAL_DECODE_VERBOSEMESSAGE("Change Decode GPU Ctxt to %d.", GpuContext);
1029 
1030         // Switch GPU context
1031         CODECHAL_DECODE_CHK_STATUS_RETURN(pOsInterface->pfnSetGpuContext(pOsInterface, GpuContext));
1032         // Reset allocation list and house keeping
1033         pOsInterface->pfnResetOsStates(pOsInterface);
1034     }
1035 
1036     return eStatus;
1037 }
1038 
CodecHalDecodeScalability_InitSemaMemResources(PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityState,PMOS_COMMAND_BUFFER pCmdBuffer)1039 MOS_STATUS CodecHalDecodeScalability_InitSemaMemResources(
1040     PCODECHAL_DECODE_SCALABILITY_STATE  pScalabilityState,
1041     PMOS_COMMAND_BUFFER                 pCmdBuffer)
1042 {
1043     CodechalHwInterface      *pHwInterface;
1044     MhwMiInterface           *pMiInterface;
1045     MOS_STATUS               eStatus = MOS_STATUS_SUCCESS;
1046 
1047     CODECHAL_DECODE_FUNCTION_ENTER;
1048 
1049     CODECHAL_DECODE_CHK_NULL_RETURN(pScalabilityState);
1050     CODECHAL_DECODE_CHK_NULL_RETURN(pScalabilityState->pHwInterface);
1051     CODECHAL_DECODE_CHK_NULL_RETURN(pScalabilityState->pHwInterface->GetMiInterface());
1052     pHwInterface       = pScalabilityState->pHwInterface;
1053     pMiInterface = pHwInterface->GetMiInterface();
1054 
1055     MHW_MI_STORE_DATA_PARAMS StoreDataParams;
1056     MOS_ZeroMemory(&StoreDataParams, sizeof(StoreDataParams));
1057 
1058     if (!Mos_ResourceIsNull(&pScalabilityState->resSemaMemCompletion))
1059     {
1060         StoreDataParams.pOsResource       = &pScalabilityState->resSemaMemCompletion;
1061         StoreDataParams.dwResourceOffset  = 0;
1062         StoreDataParams.dwValue           = 0;
1063         CODECHAL_DECODE_CHK_STATUS_RETURN(pMiInterface->AddMiStoreDataImmCmd(
1064             pCmdBuffer,
1065             &StoreDataParams));
1066     }
1067 
1068     return eStatus;
1069 
1070 }
1071 
CodecHalDecodeScalability_DecidePipeNum(PCODECHAL_DECODE_SCALABILITY_STATE pScalState,PCODECHAL_DECODE_SCALABILITY_INIT_PARAMS pInitParams)1072 MOS_STATUS CodecHalDecodeScalability_DecidePipeNum(
1073     PCODECHAL_DECODE_SCALABILITY_STATE         pScalState,
1074     PCODECHAL_DECODE_SCALABILITY_INIT_PARAMS   pInitParams)
1075 {
1076     PMOS_VIRTUALENGINE_INTERFACE pVEInterface;
1077     MOS_STATUS                   eStatus = MOS_STATUS_SUCCESS;
1078 
1079     CODECHAL_DECODE_FUNCTION_ENTER;
1080 
1081     CODECHAL_DECODE_CHK_NULL_RETURN(pScalState);
1082     CODECHAL_DECODE_CHK_NULL_RETURN(pScalState->pVEInterface);
1083     CODECHAL_DECODE_CHK_NULL_RETURN(pInitParams);
1084 
1085     pVEInterface = pScalState->pVEInterface;
1086 
1087     pScalState->ucScalablePipeNum = CODECHAL_DECODE_HCP_Legacy_PIPE_NUM_1;
1088     if (pInitParams->usingSFC)
1089     {
1090         //using SFC can only work in single pipe mode.
1091         return MOS_STATUS_SUCCESS;
1092     }
1093 
1094 #if (_DEBUG || _RELEASE_INTERNAL)
1095     if (pScalState->bAlwaysFrameSplit)
1096     {
1097         if (pScalState->ucNumVdbox != 1)
1098         {
1099             if (pScalState->ucNumVdbox == 2)
1100             {
1101                 pScalState->ucScalablePipeNum = CODECHAL_DECODE_HCP_SCALABLE_PIPE_NUM_2;
1102             }
1103             else
1104             {
1105                 pScalState->ucScalablePipeNum = CODECHAL_DECODE_HCP_SCALABLE_PIPE_NUM_RESERVED;
1106             }
1107         }
1108     }
1109     else
1110 #endif
1111     {
1112         if (pScalState->ucNumVdbox != 1)
1113         {
1114             if (pScalState->ucNumVdbox == 2)
1115             {
1116                 if (pScalState->dwHcpDecModeSwtichTh1Width != 0)
1117                 {
1118                     if (pInitParams->u32PicWidthInPixel >= pScalState->dwHcpDecModeSwtichTh1Width)
1119                     {
1120                         pScalState->ucScalablePipeNum = CODECHAL_DECODE_HCP_SCALABLE_PIPE_NUM_2;
1121                     }
1122                 }
1123                 else if ((!CodechalDecodeNonRextFormat(pInitParams->format)
1124                                 && CodechalDecodeResolutionEqualLargerThan4k(pInitParams->u32PicWidthInPixel, pInitParams->u32PicHeightInPixel))
1125                             || (CodechalDecodeNonRextFormat(pInitParams->format)
1126                                 && CodechalDecodeResolutionEqualLargerThan5k(pInitParams->u32PicWidthInPixel, pInitParams->u32PicHeightInPixel)))
1127                 {
1128                     pScalState->ucScalablePipeNum = CODECHAL_DECODE_HCP_SCALABLE_PIPE_NUM_2;
1129                 }
1130 
1131                 if (pScalState->bIsEvenSplit == false)
1132                 {
1133                     // disable scalability for clips with width less than split condition when MMC is on
1134                     if (pInitParams->u32PicWidthInPixel <= CODEC_SCALABILITY_FIRST_TILE_WIDTH_4K)
1135                     {
1136                         pScalState->ucScalablePipeNum = CODECHAL_DECODE_HCP_Legacy_PIPE_NUM_1;
1137                     }
1138                 }
1139             }
1140             else
1141             {
1142                 if (pScalState->dwHcpDecModeSwtichTh1Width != 0 &&
1143                     pScalState->dwHcpDecModeSwtichTh2Width != 0)
1144                 {
1145                     if (pInitParams->u32PicWidthInPixel >= pScalState->dwHcpDecModeSwtichTh2Width)
1146                     {
1147                         pScalState->ucScalablePipeNum = CODECHAL_DECODE_HCP_SCALABLE_PIPE_NUM_RESERVED;
1148                     }
1149                     else if (pInitParams->u32PicWidthInPixel >= pScalState->dwHcpDecModeSwtichTh1Width)
1150                     {
1151                         pScalState->ucScalablePipeNum = CODECHAL_DECODE_HCP_SCALABLE_PIPE_NUM_2;
1152                     }
1153                 }
1154                 else
1155                 {
1156                     if ((pInitParams->u32PicWidthInPixel * pInitParams->u32PicHeightInPixel) >= (CODECHAL_HCP_DECODE_SCALABLE_THRESHOLD4_WIDTH * CODECHAL_HCP_DECODE_SCALABLE_THRESHOLD4_HEIGHT))
1157                     {
1158                         pScalState->ucScalablePipeNum = CODECHAL_DECODE_HCP_SCALABLE_PIPE_NUM_RESERVED;
1159                     }
1160                     else if ((!CodechalDecodeNonRextFormat(pInitParams->format)
1161                                 && CodechalDecodeResolutionEqualLargerThan4k(pInitParams->u32PicWidthInPixel, pInitParams->u32PicHeightInPixel))
1162                             || (CodechalDecodeNonRextFormat(pInitParams->format)
1163                                 && CodechalDecodeResolutionEqualLargerThan5k(pInitParams->u32PicWidthInPixel, pInitParams->u32PicHeightInPixel)))
1164                     {
1165                         pScalState->ucScalablePipeNum = CODECHAL_DECODE_HCP_SCALABLE_PIPE_NUM_2;
1166                     }
1167                 }
1168             }
1169         }
1170     }
1171 
1172     return eStatus;
1173 }
1174 
CodechalDecodeScalability_MapPipeNumToLRCACount(PCODECHAL_DECODE_SCALABILITY_STATE pScalState,uint32_t * LRCACount)1175 MOS_STATUS CodechalDecodeScalability_MapPipeNumToLRCACount(
1176     PCODECHAL_DECODE_SCALABILITY_STATE   pScalState,
1177     uint32_t                             *LRCACount)
1178 {
1179     MOS_STATUS    eStatus = MOS_STATUS_SUCCESS;
1180 
1181     CODECHAL_DECODE_FUNCTION_ENTER;
1182 
1183     CODECHAL_DECODE_CHK_NULL_RETURN(pScalState);
1184     CODECHAL_DECODE_CHK_NULL_RETURN(LRCACount);
1185 
1186     *LRCACount = 1; // initialzed to 1.
1187 
1188     switch (pScalState->ucScalablePipeNum)
1189     {
1190     case CODECHAL_DECODE_HCP_SCALABLE_PIPE_NUM_RESERVED:
1191         *LRCACount = pScalState->bFESeparateSubmission ? 3 : 4;
1192         break;
1193     case CODECHAL_DECODE_HCP_SCALABLE_PIPE_NUM_2:
1194         // on GT2 or debug override enabled, FE separate submission = false, FE run on the same engine of BEs;
1195         // on GT3, FE separate submission = true, scalability submission includes only BEs.
1196         *LRCACount = 2;
1197         break;
1198     case CODECHAL_DECODE_HCP_Legacy_PIPE_NUM_1:
1199         *LRCACount = 1;
1200         break;
1201     default:
1202         CODECHAL_DECODE_ASSERTMESSAGE("invalid pipe number.")
1203             return MOS_STATUS_INVALID_PARAMETER;
1204     }
1205 
1206     if (*LRCACount > pScalState->ucNumVdbox)
1207     {
1208         CODECHAL_DECODE_ASSERTMESSAGE("LRCA count can not exceed vdbox number.");
1209         return MOS_STATUS_INVALID_PARAMETER;
1210     }
1211 
1212     return eStatus;
1213 }
1214 
CodechalDecodeScalability_ChkGpuCtxReCreation(PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityState,PMOS_GPUCTX_CREATOPTIONS_ENHANCED CurgpuCtxCreatOpts)1215 MOS_STATUS CodechalDecodeScalability_ChkGpuCtxReCreation(
1216     PCODECHAL_DECODE_SCALABILITY_STATE         pScalabilityState,
1217     PMOS_GPUCTX_CREATOPTIONS_ENHANCED          CurgpuCtxCreatOpts)
1218 {
1219     PMOS_INTERFACE      pOsInterface;
1220     bool                changed = false;
1221     uint32_t            NewLRCACount = 0, PreLRCACount = 0;
1222     MOS_STATUS          eStatus = MOS_STATUS_SUCCESS;
1223 
1224     CODECHAL_DECODE_FUNCTION_ENTER;
1225 
1226     CODECHAL_DECODE_CHK_NULL_RETURN(pScalabilityState);
1227     CODECHAL_DECODE_CHK_NULL_RETURN(CurgpuCtxCreatOpts);
1228 
1229     pOsInterface    = pScalabilityState->pHwInterface->GetOsInterface();
1230 
1231 #if (_DEBUG || _RELEASE_INTERNAL)
1232     if (pOsInterface->bEnableDbgOvrdInVE)
1233     {
1234         changed = false;
1235     }
1236     else
1237 #endif
1238     {
1239         CODECHAL_DECODE_CHK_STATUS_RETURN(pScalabilityState->pfnMapPipeNumToLRCACount(
1240             pScalabilityState,
1241             &NewLRCACount));
1242 
1243         if (CurgpuCtxCreatOpts->LRCACount != NewLRCACount)
1244         {
1245             changed = true;
1246             PreLRCACount = CurgpuCtxCreatOpts->LRCACount;
1247             CurgpuCtxCreatOpts->LRCACount = NewLRCACount;
1248         }
1249         else
1250         {
1251             changed = false;
1252         }
1253     }
1254 
1255     if (changed)
1256     {
1257          auto contextToCreate = MOS_GPU_CONTEXT_VIDEO;
1258 
1259          switch (NewLRCACount)
1260          {
1261          case 2:
1262              contextToCreate = pScalabilityState->VideoContextForMP;
1263              break;
1264          case 3:
1265              contextToCreate = pScalabilityState->VideoContextFor3P;
1266              break;
1267          default:
1268              contextToCreate = pScalabilityState->VideoContextForSP;
1269              break;
1270          }
1271 
1272          CODECHAL_DECODE_CHK_STATUS_RETURN(pOsInterface->pfnCreateGpuContext(
1273              pOsInterface,
1274              contextToCreate,
1275              MOS_GPU_NODE_VIDEO,
1276              CurgpuCtxCreatOpts));
1277          CODECHAL_DECODE_CHK_STATUS_RETURN(pOsInterface->pfnRegisterBBCompleteNotifyEvent(
1278              pOsInterface,
1279              contextToCreate));
1280 
1281         // Switch across single pipe/ scalable mode gpu contexts
1282         MOS_GPU_CONTEXT GpuContext = contextToCreate;
1283         CODECHAL_DECODE_VERBOSEMESSAGE("Change Decode GPU Ctxt to %d.", GpuContext);
1284         CODECHAL_DECODE_CHK_STATUS_RETURN(pOsInterface->pfnSetGpuContext(pOsInterface, GpuContext));
1285         // Reset allocation list and house keeping
1286         pOsInterface->pfnResetOsStates(pOsInterface);
1287         // Gpu context re-use
1288         pScalabilityState->VideoContext = GpuContext;
1289     }
1290 
1291     return eStatus;
1292 }
1293 
1294 #if (_DEBUG || _RELEASE_INTERNAL)
CodechalDecodeScalability_DebugOvrdDecidePipeNum(PCODECHAL_DECODE_SCALABILITY_STATE pScalState)1295 MOS_STATUS CodechalDecodeScalability_DebugOvrdDecidePipeNum(
1296     PCODECHAL_DECODE_SCALABILITY_STATE         pScalState)
1297 {
1298     PMOS_VIRTUALENGINE_INTERFACE pVEInterface;
1299     MOS_STATUS                   eStatus = MOS_STATUS_SUCCESS;
1300 
1301     CODECHAL_DECODE_CHK_NULL_RETURN(pScalState);
1302     CODECHAL_DECODE_CHK_NULL_RETURN(pScalState->pVEInterface);
1303     CODECHAL_DECODE_CHK_NULL_RETURN(pScalState->pHwInterface);
1304 
1305     pVEInterface = pScalState->pVEInterface;
1306     PMOS_INTERFACE pOsInterface = pScalState->pHwInterface->GetOsInterface();
1307     CODECHAL_DECODE_CHK_NULL_RETURN(pOsInterface);
1308 
1309     if (pOsInterface->apoMosEnabled)
1310     {
1311         CODECHAL_DECODE_CHK_NULL_RETURN(pVEInterface->veInterface);
1312         auto veInterface = pVEInterface->veInterface;
1313         if (veInterface->GetEngineCount() == 1)
1314         {
1315             pScalState->ucScalablePipeNum = CODECHAL_DECODE_HCP_Legacy_PIPE_NUM_1;
1316         }
1317         else if (veInterface->GetEngineCount() == 2)
1318         {
1319             //engine count = 2, only support FE run on the same engine as one of BE for now.
1320             pScalState->ucScalablePipeNum = CODECHAL_DECODE_HCP_SCALABLE_PIPE_NUM_2;
1321         }
1322         else if (veInterface->GetEngineCount() == 4 &&
1323                  veInterface->GetEngineLogicId(3) != veInterface->GetEngineLogicId(0) &&
1324                  veInterface->GetEngineLogicId(3) != veInterface->GetEngineLogicId(1) &&
1325                  veInterface->GetEngineLogicId(3) != veInterface->GetEngineLogicId(2))
1326         {
1327             pScalState->ucScalablePipeNum = CODECHAL_DECODE_HCP_SCALABLE_PIPE_NUM_RESERVED;
1328         }
1329         else
1330         {
1331             CODECHAL_DECODE_ASSERTMESSAGE("invalid parameter settings in debug override.");
1332             return MOS_STATUS_INVALID_PARAMETER;
1333         }
1334 
1335         return eStatus;
1336     }
1337 
1338     // debug override for virtual tile
1339     if (pVEInterface->ucEngineCount == 1)
1340     {
1341         pScalState->ucScalablePipeNum = CODECHAL_DECODE_HCP_Legacy_PIPE_NUM_1;
1342     }
1343     else if (pVEInterface->ucEngineCount == 2)
1344     {
1345         //engine count = 2, only support FE run on the same engine as one of BE for now.
1346         pScalState->ucScalablePipeNum = CODECHAL_DECODE_HCP_SCALABLE_PIPE_NUM_2;
1347     }
1348     else if (pVEInterface->ucEngineCount == 4 &&
1349         pVEInterface->EngineLogicId[3] != pVEInterface->EngineLogicId[0] &&
1350         pVEInterface->EngineLogicId[3] != pVEInterface->EngineLogicId[1] &&
1351         pVEInterface->EngineLogicId[3] != pVEInterface->EngineLogicId[2])
1352     {
1353         pScalState->ucScalablePipeNum = CODECHAL_DECODE_HCP_SCALABLE_PIPE_NUM_RESERVED;
1354     }
1355     else
1356     {
1357         CODECHAL_DECODE_ASSERTMESSAGE("invalid parameter settings in debug override.");
1358         return MOS_STATUS_INVALID_PARAMETER;
1359     }
1360 
1361     return eStatus;
1362 }
1363 #endif
1364 
CodechalDecodeScalability_ConstructParmsForGpuCtxCreation(PCODECHAL_DECODE_SCALABILITY_STATE pScalState,PMOS_GPUCTX_CREATOPTIONS_ENHANCED gpuCtxCreatOpts,CodechalSetting * codecHalSetting)1365 MOS_STATUS CodechalDecodeScalability_ConstructParmsForGpuCtxCreation(
1366     PCODECHAL_DECODE_SCALABILITY_STATE         pScalState,
1367     PMOS_GPUCTX_CREATOPTIONS_ENHANCED          gpuCtxCreatOpts,
1368     CodechalSetting *                          codecHalSetting)
1369 {
1370     PMOS_INTERFACE                           pOsInterface;
1371     CODECHAL_DECODE_SCALABILITY_INIT_PARAMS  initParams;
1372     MOS_STATUS                               eStatus = MOS_STATUS_SUCCESS;
1373 
1374     CODECHAL_DECODE_FUNCTION_ENTER;
1375 
1376     CODECHAL_DECODE_CHK_NULL_RETURN(pScalState);
1377     CODECHAL_DECODE_CHK_NULL_RETURN(pScalState->pHwInterface);
1378     CODECHAL_DECODE_CHK_NULL_RETURN(gpuCtxCreatOpts);
1379     CODECHAL_DECODE_CHK_NULL_RETURN(codecHalSetting);
1380     bool sfcInUse = codecHalSetting->sfcInUseHinted && codecHalSetting->downsamplingHinted
1381                        && (MEDIA_IS_SKU(pScalState->pHwInterface->GetSkuTable(), FtrSFCPipe)
1382                        && !MEDIA_IS_SKU(pScalState->pHwInterface->GetSkuTable(), FtrDisableVDBox2SFC));
1383     pOsInterface    = pScalState->pHwInterface->GetOsInterface();
1384     MEDIA_FEATURE_TABLE *m_skuTable = pOsInterface->pfnGetSkuTable(pOsInterface);
1385 #if (_DEBUG || _RELEASE_INTERNAL)
1386     if (pOsInterface->bEnableDbgOvrdInVE)
1387     {
1388         PMOS_VIRTUALENGINE_INTERFACE pVEInterface = pScalState->pVEInterface;
1389         CODECHAL_DECODE_CHK_NULL_RETURN(pVEInterface);
1390         gpuCtxCreatOpts->DebugOverride      = true;
1391         if (MEDIA_IS_SKU(m_skuTable, FtrSfcScalability))
1392         {
1393             gpuCtxCreatOpts->UsingSFC = false;// this param ignored when dbgoverride enabled
1394         }
1395         else
1396         {
1397             gpuCtxCreatOpts->UsingSFC = sfcInUse;  // this param ignored when dbgoverride enabled
1398         }
1399         CODECHAL_DECODE_CHK_STATUS_RETURN(pScalState->pfnDebugOvrdDecidePipeNum(pScalState));
1400 
1401         if (pOsInterface->apoMosEnabled)
1402         {
1403             CODECHAL_DECODE_CHK_NULL_RETURN(pVEInterface->veInterface);
1404             for (uint32_t i = 0; i < pVEInterface->veInterface->GetEngineCount(); i++)
1405             {
1406                 gpuCtxCreatOpts->EngineInstance[i] = pVEInterface->veInterface->GetEngineLogicId(i);
1407             }
1408         }
1409         else
1410         {
1411             for (uint32_t i = 0; i < pVEInterface->ucEngineCount; i++)
1412             {
1413                 gpuCtxCreatOpts->EngineInstance[i] = pVEInterface->EngineLogicId[i];
1414             }
1415         }
1416     }
1417     else
1418 #endif
1419     {
1420         if (MEDIA_IS_SKU(m_skuTable, FtrSfcScalability))
1421         {
1422             gpuCtxCreatOpts->UsingSFC = false;
1423         }
1424         else
1425         {
1426             gpuCtxCreatOpts->UsingSFC = sfcInUse;
1427         }
1428 
1429         MOS_ZeroMemory(&initParams, sizeof(initParams));
1430         initParams.u32PicWidthInPixel   = MOS_ALIGN_CEIL(codecHalSetting->width, 8);
1431         initParams.u32PicHeightInPixel  = MOS_ALIGN_CEIL(codecHalSetting->height, 8);
1432         if (((codecHalSetting->standard == CODECHAL_VP9) || (codecHalSetting->standard == CODECHAL_HEVC))
1433                 && (codecHalSetting->chromaFormat == HCP_CHROMA_FORMAT_YUV420))
1434         {
1435             initParams.format = Format_NV12;
1436             if (codecHalSetting->lumaChromaDepth == CODECHAL_LUMA_CHROMA_DEPTH_10_BITS)
1437             {
1438                 initParams.format = Format_P010;
1439             }
1440         }
1441         initParams.usingSFC             = sfcInUse;
1442         initParams.usingSecureDecode    = codecHalSetting->secureMode;
1443         CODECHAL_DECODE_CHK_STATUS_RETURN(pScalState->pfnDecidePipeNum(
1444             pScalState,
1445             &initParams));
1446     }
1447 
1448     CODECHAL_DECODE_CHK_STATUS_RETURN(pScalState->pfnMapPipeNumToLRCACount(
1449         pScalState,
1450         &gpuCtxCreatOpts->LRCACount));
1451 
1452     return eStatus;
1453 }
1454 
CodecHalDecodeScalability_InitScalableParams(PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityState,PCODECHAL_DECODE_SCALABILITY_INIT_PARAMS pInitParams,uint16_t * pucDecPassNum)1455 MOS_STATUS CodecHalDecodeScalability_InitScalableParams(
1456     PCODECHAL_DECODE_SCALABILITY_STATE         pScalabilityState,
1457     PCODECHAL_DECODE_SCALABILITY_INIT_PARAMS   pInitParams,
1458     uint16_t                                   *pucDecPassNum)
1459 {
1460     PMOS_INTERFACE                  pOsInterface;
1461     PMOS_VIRTUALENGINE_INTERFACE    pVEInterface;
1462     MOS_STATUS                      eStatus = MOS_STATUS_SUCCESS;
1463 
1464     CODECHAL_DECODE_FUNCTION_ENTER;
1465 
1466     CODECHAL_DECODE_CHK_NULL_RETURN(pScalabilityState);
1467     CODECHAL_DECODE_CHK_NULL_RETURN(pScalabilityState->pHwInterface);
1468     CODECHAL_DECODE_CHK_NULL_RETURN(pScalabilityState->pHwInterface->GetOsInterface());
1469 
1470     pOsInterface    = pScalabilityState->pHwInterface->GetOsInterface();
1471     pVEInterface    = pScalabilityState->pVEInterface;
1472 
1473     if (!pOsInterface->bSupportVirtualEngine)
1474     {
1475         eStatus = MOS_STATUS_INVALID_PARAMETER;
1476         CODECHAL_DECODE_ASSERTMESSAGE("Scalability decode must run with virtual engine interface.\n");
1477         return eStatus;
1478     }
1479 
1480     pScalabilityState->bScalableDecodeMode = false; // initialized to false
1481 
1482 #if (_DEBUG || _RELEASE_INTERNAL)
1483     if (pOsInterface->bEnableDbgOvrdInVE)
1484     {
1485         if (!MOS_VE_CTXBASEDSCHEDULING_SUPPORTED(pOsInterface))
1486         {
1487             if (pOsInterface->apoMosEnabled)
1488             {
1489                 CODECHAL_DECODE_CHK_NULL_RETURN(pVEInterface->veInterface);
1490                 pScalabilityState->ucScalablePipeNum = pVEInterface->veInterface->GetEngineCount() - 1;
1491             }
1492             else
1493             {
1494                 pScalabilityState->ucScalablePipeNum = pVEInterface->ucEngineCount - 1;
1495             }
1496             pScalabilityState->bScalableDecodeMode = true;
1497         }
1498         else
1499         {
1500             // do nothing since pipe number already decided at the gpu context creation.
1501         }
1502     }
1503     else
1504 #endif
1505     {
1506         // Decide pipe number
1507         CODECHAL_DECODE_CHK_STATUS_RETURN(pScalabilityState->pfnDecidePipeNum(pScalabilityState, pInitParams));
1508     }
1509 
1510     // Decide scalable mode or single pipe mode
1511     if (pScalabilityState->ucScalablePipeNum > 1 && pOsInterface->frameSplit)
1512     {
1513         pScalabilityState->bScalableDecodeMode = true;
1514     }
1515 
1516     CODECHAL_DECODE_CHK_NULL_RETURN(pucDecPassNum);
1517     // Decide Decode pass number - pucDecPassNum
1518     if (pScalabilityState->bScalableDecodeMode)
1519     {
1520         *pucDecPassNum = pScalabilityState->ucScalablePipeNum + 1; // FE + all BEs
1521     }
1522     else
1523     {
1524         *pucDecPassNum = 1;
1525     }
1526 
1527     // Add one pass for S2L conversion in short format.
1528     if (pScalabilityState->bShortFormatInUse)
1529     {
1530         *pucDecPassNum = *pucDecPassNum + 1;
1531     }
1532 
1533     pScalabilityState->VideoContext = pInitParams->gpuCtxInUse;
1534 
1535     return eStatus;
1536 }
1537 
CodecHalDecodeScalability_SetHintParams(PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityState,PCODECHAL_DECODE_SCALABILITY_SETHINT_PARMS pSetHintParms)1538 MOS_STATUS CodecHalDecodeScalability_SetHintParams(
1539     PCODECHAL_DECODE_SCALABILITY_STATE         pScalabilityState,
1540     PCODECHAL_DECODE_SCALABILITY_SETHINT_PARMS pSetHintParms)
1541 {
1542     PMOS_VIRTUALENGINE_INTERFACE    pVEInterface;
1543     MOS_VIRTUALENGINE_SET_PARAMS    VEParams;
1544     PMOS_INTERFACE                  pOsInterface;
1545     MOS_STATUS                      eStatus = MOS_STATUS_SUCCESS;
1546 
1547     CODECHAL_DECODE_FUNCTION_ENTER;
1548 
1549     CODECHAL_DECODE_CHK_NULL_RETURN(pScalabilityState);
1550     CODECHAL_DECODE_CHK_NULL_RETURN(pSetHintParms);
1551     CODECHAL_DECODE_CHK_NULL_RETURN(pScalabilityState->pHwInterface);
1552     CODECHAL_DECODE_CHK_NULL_RETURN(pScalabilityState->pHwInterface->GetOsInterface());
1553 
1554     pOsInterface    = pScalabilityState->pHwInterface->GetOsInterface();
1555     pVEInterface    = pScalabilityState->pVEInterface;
1556 
1557     MOS_ZeroMemory(&VEParams, sizeof(VEParams));
1558     if(!MOS_VE_CTXBASEDSCHEDULING_SUPPORTED(pOsInterface))
1559     {
1560         //not used by VE2.0
1561         VEParams.bNeedSyncWithPrevious       = pSetHintParms->bNeedSyncWithPrevious;
1562         VEParams.bSameEngineAsLastSubmission = pSetHintParms->bSameEngineAsLastSubmission;
1563         VEParams.bSFCInUse                   = pSetHintParms->bSFCInUse;
1564     }
1565 
1566     VEParams.ucScalablePipeNum  = pScalabilityState->ucScalablePipeNum;
1567 
1568     if (pScalabilityState->bScalableDecodeMode)
1569     {
1570         if (pScalabilityState->bFESeparateSubmission)
1571         {
1572             //set Hint parameter for FE submission
1573             VEParams.bScalableMode = false;
1574             if (pVEInterface->pfnVESetHintParams)
1575             {
1576                 CODECHAL_DECODE_CHK_STATUS_RETURN(pVEInterface->pfnVESetHintParams(pVEInterface, &VEParams));
1577             }
1578         }
1579 
1580         VEParams.bScalableMode = true;
1581         VEParams.bHaveFrontEndCmds = (pScalabilityState->bFESeparateSubmission ? false : true);
1582         if (pVEInterface->pfnVESetHintParams)
1583         {
1584             CODECHAL_DECODE_CHK_STATUS_RETURN(pVEInterface->pfnVESetHintParams(pVEInterface, &VEParams));
1585         }
1586     }
1587     else
1588     {
1589         VEParams.bScalableMode = false;
1590         if (pVEInterface->pfnVESetHintParams)
1591         {
1592             CODECHAL_DECODE_CHK_STATUS_RETURN(pVEInterface->pfnVESetHintParams(pVEInterface, &VEParams));
1593         }
1594     }
1595 
1596     return eStatus;
1597 }
1598 
1599 #if (_DEBUG || _RELEASE_INTERNAL)
CodecHalDecodeScalability_DbgDumpCmdBuffer(CodechalDecode * pDecoder,PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityState,CodechalDebugInterface * debugInterface,PMOS_COMMAND_BUFFER pPrimCmdBuf)1600 MOS_STATUS CodecHalDecodeScalability_DbgDumpCmdBuffer(
1601     CodechalDecode                      *pDecoder,
1602     PCODECHAL_DECODE_SCALABILITY_STATE  pScalabilityState,
1603     CodechalDebugInterface              *debugInterface,
1604     PMOS_COMMAND_BUFFER                 pPrimCmdBuf)
1605 {
1606     MOS_STATUS                      eStatus = MOS_STATUS_SUCCESS;
1607     MOS_COMMAND_BUFFER              ScdryCmdBuffer;
1608     PMOS_COMMAND_BUFFER             pCmdBufferInUse;
1609 
1610     CODECHAL_DECODE_FUNCTION_ENTER;
1611 
1612     CODECHAL_DECODE_CHK_NULL_RETURN(pDecoder);
1613     CODECHAL_DECODE_CHK_NULL_RETURN(pScalabilityState);
1614     CODECHAL_DECODE_CHK_NULL_RETURN(pPrimCmdBuf);
1615 
1616     if (!pScalabilityState->bScalableDecodeMode)
1617     {
1618         eStatus = MOS_STATUS_INVALID_PARAMETER;
1619         CODECHAL_DECODE_ASSERTMESSAGE("Invalid decode parameters!");
1620         return eStatus;
1621     }
1622 
1623     if (CodecHalDecodeScalabilityIsFESeparateSubmission(pScalabilityState)
1624         && CodecHalDecodeScalabilityIsFEPhase(pScalabilityState))
1625     {
1626         pCmdBufferInUse = pPrimCmdBuf;
1627     }
1628     else
1629     {
1630         CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalDecodeScalability_GetVESecondaryCmdBuffer(pScalabilityState, &ScdryCmdBuffer));
1631         pCmdBufferInUse = &ScdryCmdBuffer;
1632     }
1633 
1634     CODECHAL_DECODE_CHK_STATUS_RETURN(debugInterface->DumpCmdBuffer(
1635         pCmdBufferInUse,
1636         CODECHAL_NUM_MEDIA_STATES,
1637         "_DEC"));
1638 
1639     return eStatus;
1640 }
1641 #endif
1642 
CodecHalDecodeScalability_PopulateHintParams(PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityState,PMOS_COMMAND_BUFFER pPrimCmdBuf)1643 MOS_STATUS CodecHalDecodeScalability_PopulateHintParams(
1644     PCODECHAL_DECODE_SCALABILITY_STATE  pScalabilityState,
1645     PMOS_COMMAND_BUFFER                 pPrimCmdBuf)
1646 {
1647     MOS_STATUS                      eStatus = MOS_STATUS_SUCCESS;
1648     PMOS_CMD_BUF_ATTRI_VE          pAttriVe;
1649 
1650     CODECHAL_DECODE_FUNCTION_ENTER;
1651 
1652     CODECHAL_DECODE_CHK_NULL_RETURN(pScalabilityState);
1653     CODECHAL_DECODE_CHK_NULL_RETURN(pPrimCmdBuf);
1654     pAttriVe = (PMOS_CMD_BUF_ATTRI_VE)(pPrimCmdBuf->Attributes.pAttriVe);
1655 
1656     if (pAttriVe)
1657     {
1658         if ((CodecHalDecodeScalabilityIsScalableMode(pScalabilityState) &&
1659              !CodecHalDecodeScalabilityIsFESeparateSubmission(pScalabilityState)) ||
1660             (CodecHalDecodeScalabilityIsFESeparateSubmission(pScalabilityState) &&
1661              CodecHalDecodeScalabilityIsBEPhase(pScalabilityState)))
1662         {
1663             CODECHAL_DECODE_CHK_NULL_RETURN(pScalabilityState->pScalHintParms);
1664             pAttriVe->VEngineHintParams = *(pScalabilityState->pScalHintParms);
1665         }
1666         else
1667         {
1668             CODECHAL_DECODE_CHK_NULL_RETURN(pScalabilityState->pSingleHintParms);
1669             pAttriVe->VEngineHintParams = *(pScalabilityState->pSingleHintParms);
1670         }
1671 
1672         pAttriVe->bUseVirtualEngineHint = true;
1673     }
1674 
1675     return eStatus;
1676 }
1677 
CodecHalDecodeScalability_SignalFE2BESemaphore(PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityState,PMOS_COMMAND_BUFFER pCmdBufferInUse)1678 MOS_STATUS CodecHalDecodeScalability_SignalFE2BESemaphore(
1679     PCODECHAL_DECODE_SCALABILITY_STATE  pScalabilityState,
1680     PMOS_COMMAND_BUFFER                 pCmdBufferInUse)
1681 {
1682     PMOS_INTERFACE                      pOsInterface;
1683     MhwMiInterface                      *pMiInterface;
1684     MOS_SYNC_PARAMS                     SyncParams;
1685     MOS_STATUS                          eStatus = MOS_STATUS_SUCCESS;
1686 
1687     CODECHAL_DECODE_FUNCTION_ENTER;
1688 
1689     CODECHAL_DECODE_CHK_NULL_RETURN(pScalabilityState);
1690     CODECHAL_DECODE_CHK_NULL_RETURN(pScalabilityState->pHwInterface);
1691     CODECHAL_DECODE_CHK_NULL_RETURN(pScalabilityState->pHwInterface->GetOsInterface());
1692     CODECHAL_DECODE_CHK_NULL_RETURN(pScalabilityState->pHwInterface->GetMiInterface());
1693     CODECHAL_DECODE_CHK_NULL_RETURN(pCmdBufferInUse);
1694 
1695     pOsInterface  = pScalabilityState->pHwInterface->GetOsInterface();
1696     pMiInterface  = pScalabilityState->pHwInterface->GetMiInterface();
1697 
1698     // FE semaphore to BE0 for FE/BE Sync.
1699     if (pScalabilityState->bScalableDecodeMode && pScalabilityState->ucNumVdbox > 2)
1700     {
1701         // When FE separate submission enabled, use SW semaphore between FE/BE0. Otherwise use HW semaphore
1702         if (pScalabilityState->bFESeparateSubmission)
1703         {
1704             SyncParams = g_cInitSyncParams;
1705             SyncParams.GpuContext = pScalabilityState->VideoContextForFE;
1706             SyncParams.presSyncResource = &pScalabilityState->resFeBeSyncObject;
1707             CODECHAL_DECODE_CHK_STATUS_RETURN(pOsInterface->pfnEngineSignal(pOsInterface, &SyncParams));
1708         }
1709         else
1710         {
1711             //post HW semaphore (FE-BE) after FE completion , mi atomic increase 1
1712             CODECHAL_DECODE_CHK_STATUS_RETURN(pScalabilityState->pHwInterface->SendMiAtomicDwordCmd(&pScalabilityState->resSemaMemFEBE, 1, MHW_MI_ATOMIC_INC, pCmdBufferInUse));
1713         }
1714     }
1715 
1716     return eStatus;
1717 }
1718 
CodecHalDecodeScalability_FEBESync(PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityState,PMOS_COMMAND_BUFFER pCmdBufferInUse)1719 MOS_STATUS CodecHalDecodeScalability_FEBESync(
1720     PCODECHAL_DECODE_SCALABILITY_STATE  pScalabilityState,
1721     PMOS_COMMAND_BUFFER                 pCmdBufferInUse)
1722 {
1723     PMOS_INTERFACE                      pOsInterface;
1724     MhwMiInterface                      *pMiInterface;
1725     uint32_t                            HcpDecPhase;
1726     MOS_STATUS                          eStatus = MOS_STATUS_SUCCESS;
1727 
1728     CODECHAL_DECODE_FUNCTION_ENTER;
1729 
1730     CODECHAL_DECODE_CHK_NULL_RETURN(pScalabilityState);
1731     CODECHAL_DECODE_CHK_NULL_RETURN(pScalabilityState->pHwInterface);
1732     CODECHAL_DECODE_CHK_NULL_RETURN(pScalabilityState->pHwInterface->GetOsInterface());
1733     CODECHAL_DECODE_CHK_NULL_RETURN(pScalabilityState->pHwInterface->GetMiInterface());
1734     CODECHAL_DECODE_CHK_NULL_RETURN(pCmdBufferInUse);
1735 
1736     pOsInterface        = pScalabilityState->pHwInterface->GetOsInterface();
1737     pMiInterface        = pScalabilityState->pHwInterface->GetMiInterface();
1738     HcpDecPhase         = pScalabilityState->HcpDecPhase;
1739 
1740     //FE& BE0 Sync.
1741     if (HcpDecPhase == CODECHAL_HCP_DECODE_PHASE_BE0 && pScalabilityState->pHwInterface->GetMfxInterface()->GetNumVdbox() > 2)
1742     {
1743         if (pScalabilityState->bFESeparateSubmission)
1744         {
1745             MOS_SYNC_PARAMS SyncParams;
1746 
1747             SyncParams = g_cInitSyncParams;
1748             SyncParams.GpuContext = pScalabilityState->VideoContext;
1749             SyncParams.presSyncResource = &pScalabilityState->resFeBeSyncObject;
1750 
1751             CODECHAL_DECODE_CHK_STATUS_RETURN(pOsInterface->pfnEngineWait(pOsInterface, &SyncParams));
1752         }
1753         else
1754         {
1755             pMiInterface->AddWatchdogTimerStopCmd(pCmdBufferInUse);
1756 
1757             CODECHAL_DECODE_CHK_STATUS_RETURN(pScalabilityState->pHwInterface->SendHwSemaphoreWaitCmd(&pScalabilityState->resSemaMemFEBE, 1, MHW_MI_SAD_EQUAL_SDD, pCmdBufferInUse));
1758             //reset semaphore. mi atomic decrease 1
1759             CODECHAL_DECODE_CHK_STATUS_RETURN(pScalabilityState->pHwInterface->SendMiAtomicDwordCmd(&pScalabilityState->resSemaMemFEBE, 1, MHW_MI_ATOMIC_DEC, pCmdBufferInUse));
1760         }
1761     }
1762 
1763     if (CodecHalDecodeScalabilityIsBEPhase(pScalabilityState))
1764     {
1765         // Stop Watchdog before BEs wait
1766         pMiInterface->AddWatchdogTimerStopCmd(pCmdBufferInUse);
1767 
1768         //HW Semaphore for BEs Starting at the same time
1769         CODECHAL_DECODE_CHK_STATUS_RETURN(pScalabilityState->pHwInterface->SendMiAtomicDwordCmd(&pScalabilityState->resSemaMemBEs, 1, MHW_MI_ATOMIC_INC, pCmdBufferInUse));
1770         CODECHAL_DECODE_CHK_STATUS_RETURN(pScalabilityState->pHwInterface->SendHwSemaphoreWaitCmd(
1771             &pScalabilityState->resSemaMemBEs,
1772             pScalabilityState->ucScalablePipeNum,
1773             MHW_MI_SAD_EQUAL_SDD,
1774             pCmdBufferInUse));
1775 
1776         // Program some placeholder cmds to resolve the hazard between BEs sync
1777         MHW_MI_STORE_DATA_PARAMS dataParams;
1778         dataParams.pOsResource = &pScalabilityState->resDelayMinus;
1779         dataParams.dwResourceOffset = 0;
1780         dataParams.dwValue = 0xDE1A;
1781         for (uint32_t i = 0; i < pScalabilityState->numDelay; i++)
1782         {
1783             CODECHAL_DECODE_CHK_STATUS_RETURN(pScalabilityState->pHwInterface->GetMiInterface()->AddMiStoreDataImmCmd(
1784                 pCmdBufferInUse,
1785                 &dataParams));
1786         }
1787 
1788         //reset HW semaphore
1789         CODECHAL_DECODE_CHK_STATUS_RETURN(pScalabilityState->pHwInterface->SendMiAtomicDwordCmd(&pScalabilityState->resSemaMemBEs, 1, MHW_MI_ATOMIC_DEC, pCmdBufferInUse));
1790 
1791         // Condidtional BB END for streamout buffer writing over allocated size
1792         CODECHAL_DECODE_CHK_STATUS_RETURN(pScalabilityState->pHwInterface->SendCondBbEndCmd(
1793             &pScalabilityState->resFEStatusBuffer,
1794             CODECHAL_OFFSETOF(CODECHAL_DECODE_SCALABILITY_FE_STATUS, dwCarryFlagOfReportedSizeMinusAllocSize),
1795             0,
1796             true,
1797             pCmdBufferInUse));
1798 
1799     }
1800 
1801     return eStatus;
1802 }
1803 
CodecHalDecodeScalability_BEsCompletionSync(PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityState,PMOS_COMMAND_BUFFER pCmdBufferInUse)1804 MOS_STATUS CodecHalDecodeScalability_BEsCompletionSync(
1805     PCODECHAL_DECODE_SCALABILITY_STATE  pScalabilityState,
1806     PMOS_COMMAND_BUFFER                 pCmdBufferInUse)
1807 {
1808     MhwMiInterface             *pMiInterface;
1809     uint32_t                   HcpDecPhase;
1810     MOS_STATUS                 eStatus = MOS_STATUS_SUCCESS;
1811 
1812     CODECHAL_DECODE_FUNCTION_ENTER;
1813 
1814     CODECHAL_DECODE_CHK_NULL_RETURN(pScalabilityState);
1815     CODECHAL_DECODE_CHK_NULL_RETURN(pScalabilityState->pHwInterface);
1816     CODECHAL_DECODE_CHK_NULL_RETURN(pScalabilityState->pHwInterface->GetMiInterface());
1817     CODECHAL_DECODE_CHK_NULL_RETURN(pCmdBufferInUse);
1818     HcpDecPhase        = pScalabilityState->HcpDecPhase;
1819 
1820     if (CodecHalDecodeScalabilityIsLastCompletePhase(pScalabilityState))
1821     {
1822         CODECHAL_DECODE_CHK_STATUS_RETURN(pScalabilityState->pHwInterface->SendHwSemaphoreWaitCmd(
1823             &pScalabilityState->resSemaMemCompletion,
1824             pScalabilityState->ucScalablePipeNum - 1,
1825             MHW_MI_SAD_EQUAL_SDD,
1826             pCmdBufferInUse));
1827 
1828         for (int i = 0; i < pScalabilityState->ucScalablePipeNum - 1; i++)
1829         {
1830             CODECHAL_DECODE_CHK_STATUS_RETURN(pScalabilityState->pHwInterface->SendMiAtomicDwordCmd(
1831                 &pScalabilityState->resSemaMemCompletion,
1832                 1,
1833                 MHW_MI_ATOMIC_DEC,
1834                 pCmdBufferInUse));
1835         }
1836     }
1837     else
1838     {
1839         CODECHAL_DECODE_CHK_STATUS_RETURN(pScalabilityState->pHwInterface->SendMiAtomicDwordCmd(
1840             &pScalabilityState->resSemaMemCompletion,
1841             1,
1842             MHW_MI_ATOMIC_INC,
1843             pCmdBufferInUse));
1844     }
1845 
1846     return eStatus;
1847 }
1848 
CodecHalDecodeScalability_ReadCSEngineIDReg(PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityState,CodechalDecodeStatusBuffer * pDecodeStatusBuf,PMOS_COMMAND_BUFFER pCmdBufferInUse)1849 MOS_STATUS CodecHalDecodeScalability_ReadCSEngineIDReg(
1850     PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityState,
1851     CodechalDecodeStatusBuffer        *pDecodeStatusBuf,
1852     PMOS_COMMAND_BUFFER                pCmdBufferInUse)
1853 {
1854     MHW_MI_STORE_REGISTER_MEM_PARAMS  StoreRegParams;
1855     MhwMiInterface                    *pMiInterface;
1856     MmioRegistersHcp                  *pMmioRegisters;
1857     uint8_t                           ucPhaseIndex = 0;
1858     uint32_t                          dwOffset = 0;
1859     uint32_t                          dwCurrIndex = 0;
1860     uint32_t                          dwPreIndex = 0;
1861     MOS_STATUS                        eStatus = MOS_STATUS_SUCCESS;
1862 
1863     CODECHAL_DECODE_FUNCTION_ENTER;
1864 
1865     CODECHAL_DECODE_CHK_NULL_RETURN(pDecodeStatusBuf);
1866     CODECHAL_DECODE_CHK_NULL_RETURN(pScalabilityState);
1867     CODECHAL_DECODE_CHK_NULL_RETURN(pScalabilityState->pHwInterface);
1868     CODECHAL_DECODE_CHK_NULL_RETURN(pScalabilityState->pHwInterface->GetMiInterface());
1869 
1870     pMiInterface = pScalabilityState->pHwInterface->GetMiInterface();
1871     pMmioRegisters = pScalabilityState->pHwInterface->GetHcpInterface()->GetMmioRegisters(MHW_VDBOX_NODE_1); //relative mmio addressing.
1872 
1873     ucPhaseIndex = (pScalabilityState->HcpDecPhase < CODECHAL_HCP_DECODE_PHASE_FE) ?
1874         0 : (pScalabilityState->HcpDecPhase - CODECHAL_HCP_DECODE_PHASE_FE);
1875 
1876     if (ucPhaseIndex >= CODECHAL_HCP_DECODE_SCALABLE_MAX_PHASE_NUM)
1877     {
1878         eStatus = MOS_STATUS_INVALID_PARAMETER;
1879         CODECHAL_DECODE_ASSERTMESSAGE("Invalid HCP decode phase!");
1880         return eStatus;
1881     }
1882 
1883     if (CodecHalDecodeScalabilityIsScalableMode(pScalabilityState) &&
1884         pScalabilityState->HcpDecPhase > CODECHAL_HCP_DECODE_PHASE_BE0)
1885     {
1886         if (pDecodeStatusBuf->m_currIndex == 0)
1887         {
1888             dwPreIndex = CODECHAL_DECODE_STATUS_NUM - 1;
1889         }
1890         else
1891         {
1892             dwPreIndex = pDecodeStatusBuf->m_currIndex - 1;
1893         }
1894     }
1895 
1896     dwCurrIndex = (CodecHalDecodeScalabilityIsScalableMode(pScalabilityState) &&
1897         pScalabilityState->HcpDecPhase > CODECHAL_HCP_DECODE_PHASE_BE0) ?
1898         dwPreIndex : pDecodeStatusBuf->m_currIndex;
1899 
1900     dwOffset = (dwCurrIndex * sizeof(CodechalDecodeStatus)) +
1901         pDecodeStatusBuf->m_csEngineIdOffset + sizeof(uint32_t)* ucPhaseIndex +
1902         sizeof(uint32_t)* 2;
1903 
1904     MOS_ZeroMemory(&StoreRegParams, sizeof(StoreRegParams));
1905     StoreRegParams.presStoreBuffer  = &pDecodeStatusBuf->m_statusBuffer;
1906     StoreRegParams.dwOffset         = dwOffset;
1907     StoreRegParams.dwRegister       = pMmioRegisters->csEngineIdOffset;
1908     CODECHAL_DECODE_CHK_STATUS_RETURN(pMiInterface->AddMiStoreRegisterMemCmd(pCmdBufferInUse, &StoreRegParams));
1909 
1910     return eStatus;
1911 }
1912 
IsHevcBufferReallocNeeded(CodechalHwInterface * hwInterface,MHW_VDBOX_HCP_INTERNAL_BUFFER_TYPE bufferType,PMHW_VDBOX_HCP_BUFFER_REALLOC_PARAMS reallocParam)1913 MOS_STATUS IsHevcBufferReallocNeeded(
1914     CodechalHwInterface                  *hwInterface,
1915     MHW_VDBOX_HCP_INTERNAL_BUFFER_TYPE   bufferType,
1916     PMHW_VDBOX_HCP_BUFFER_REALLOC_PARAMS reallocParam)
1917 {
1918     return hwInterface->GetHcpInterface()->IsHevcBufferReallocNeeded(bufferType, reallocParam);
1919 }
1920 
GetHevcBufferSize(CodechalHwInterface * hwInterface,MHW_VDBOX_HCP_INTERNAL_BUFFER_TYPE bufferType,PMHW_VDBOX_HCP_BUFFER_SIZE_PARAMS hcpBufSizeParam)1921 MOS_STATUS GetHevcBufferSize(
1922     CodechalHwInterface                 *hwInterface,
1923     MHW_VDBOX_HCP_INTERNAL_BUFFER_TYPE  bufferType,
1924     PMHW_VDBOX_HCP_BUFFER_SIZE_PARAMS   hcpBufSizeParam)
1925 {
1926     return hwInterface->GetHcpInterface()->GetHevcBufferSize(bufferType, hcpBufSizeParam);
1927 }
1928 
IsVp9BufferReallocNeeded(CodechalHwInterface * hwInterface,MHW_VDBOX_HCP_INTERNAL_BUFFER_TYPE bufferType,PMHW_VDBOX_HCP_BUFFER_REALLOC_PARAMS reallocParam)1929 MOS_STATUS IsVp9BufferReallocNeeded(
1930     CodechalHwInterface                  *hwInterface,
1931     MHW_VDBOX_HCP_INTERNAL_BUFFER_TYPE   bufferType,
1932     PMHW_VDBOX_HCP_BUFFER_REALLOC_PARAMS reallocParam)
1933 {
1934     return hwInterface->GetHcpInterface()->IsVp9BufferReallocNeeded(bufferType, reallocParam);
1935 }
1936 
GetVp9BufferSize(CodechalHwInterface * hwInterface,MHW_VDBOX_HCP_INTERNAL_BUFFER_TYPE bufferType,PMHW_VDBOX_HCP_BUFFER_SIZE_PARAMS hcpBufSizeParam)1937 MOS_STATUS GetVp9BufferSize(
1938     CodechalHwInterface                 *hwInterface,
1939     MHW_VDBOX_HCP_INTERNAL_BUFFER_TYPE  bufferType,
1940     PMHW_VDBOX_HCP_BUFFER_SIZE_PARAMS   hcpBufSizeParam)
1941 {
1942     return hwInterface->GetHcpInterface()->GetVp9BufferSize(bufferType, hcpBufSizeParam);
1943 }
1944 
CodecHalDecodeScalability_InitializeState(CodechalDecode * pDecoder,PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityState,CodechalHwInterface * hwInterface,bool bShortFormat)1945 MOS_STATUS CodecHalDecodeScalability_InitializeState (
1946     CodechalDecode                     *pDecoder,
1947     PCODECHAL_DECODE_SCALABILITY_STATE  pScalabilityState,
1948     CodechalHwInterface                *hwInterface,
1949     bool                                bShortFormat)
1950 {
1951     PMOS_VIRTUALENGINE_INTERFACE   pVEInterface;
1952     MOS_VIRTUALENGINE_INIT_PARAMS  VEInitParms;
1953     MOS_USER_FEATURE_VALUE_DATA    UserFeatureData;
1954     PMOS_INTERFACE                 osInterface;
1955     MhwVdboxMfxInterface           *vdboxMfxInterface;
1956     uint8_t                        vdboxNum;
1957     MOS_STATUS                     eStatus = MOS_STATUS_SUCCESS;
1958 
1959     CODECHAL_DECODE_FUNCTION_ENTER;
1960 
1961     CODECHAL_DECODE_CHK_NULL_RETURN(pDecoder);
1962     CODECHAL_DECODE_CHK_NULL_RETURN(pScalabilityState);
1963     CODECHAL_DECODE_CHK_NULL_RETURN(hwInterface);
1964     osInterface = hwInterface->GetOsInterface();
1965     CODECHAL_DECODE_CHK_NULL_RETURN(osInterface);
1966 
1967     vdboxMfxInterface = hwInterface->GetMfxInterface();
1968     CODECHAL_DECODE_CHK_NULL_RETURN(vdboxMfxInterface);
1969     vdboxNum = vdboxMfxInterface->GetNumVdbox();
1970 
1971     if (vdboxNum < 2
1972         || !osInterface->bHcpDecScalabilityMode)
1973    {
1974         eStatus = MOS_STATUS_INVALID_PARAMETER;
1975         CODECHAL_DECODE_ASSERTMESSAGE("not support scalability on this platform.");
1976         return eStatus;
1977     }
1978 
1979     pScalabilityState->VideoContextForSP = MOS_GPU_CONTEXT_VIDEO;
1980     pScalabilityState->VideoContextForMP = MOS_VE_MULTINODESCALING_SUPPORTED(osInterface) ? MOS_GPU_CONTEXT_VIDEO5 : MOS_GPU_CONTEXT_VDBOX2_VIDEO;
1981     pScalabilityState->VideoContextFor3P = MOS_VE_MULTINODESCALING_SUPPORTED(osInterface) ? MOS_GPU_CONTEXT_VIDEO7 : MOS_GPU_CONTEXT_VDBOX2_VIDEO2;
1982 
1983     pScalabilityState->numDelay = 15;
1984 
1985 #if (_DEBUG || _RELEASE_INTERNAL)
1986     // Reg key of the threshold for mode switch single pipe <-> 2 pipe. Using pic width value to control mode switch for now
1987     MOS_ZeroMemory(&UserFeatureData, sizeof(UserFeatureData));
1988     MOS_UserFeature_ReadValue_ID(
1989         nullptr,
1990         __MEDIA_USER_FEATURE_VALUE_HCP_DECODE_MODE_SWITCH_THRESHOLD1_ID,
1991         &UserFeatureData,
1992         osInterface->pOsContext);
1993     pScalabilityState->dwHcpDecModeSwtichTh1Width = UserFeatureData.u32Data;
1994 
1995     MOS_ZeroMemory(&UserFeatureData, sizeof(UserFeatureData));
1996     MOS_UserFeature_ReadValue_ID(
1997         nullptr,
1998         __MEDIA_USER_FEATURE_VALUE_HCP_DECODE_MODE_SWITCH_THRESHOLD2_ID,
1999         &UserFeatureData,
2000         osInterface->pOsContext);
2001     pScalabilityState->dwHcpDecModeSwtichTh2Width = UserFeatureData.u32Data;
2002 
2003     MOS_ZeroMemory(&UserFeatureData, sizeof(UserFeatureData));
2004     MOS_UserFeature_ReadValue_ID(
2005         nullptr,
2006         __MEDIA_USER_FEATURE_VALUE_SCALABILITY_OVERRIDE_SPLIT_WIDTH_IN_MINCB,
2007         &UserFeatureData,
2008         osInterface->pOsContext);
2009     pScalabilityState->dbgOvrdWidthInMinCb = UserFeatureData.u32Data;
2010 #endif
2011 
2012     // enable FE separate submission by default in multi-pipe mode
2013     if (hwInterface->GetMfxInterface()->GetNumVdbox() > 2)
2014     {
2015         pScalabilityState->bFESeparateSubmission = true;
2016     }
2017     else
2018     {
2019         // no benefit to enable FE separate submission on 2 vdbox config.
2020         pScalabilityState->bFESeparateSubmission = false;
2021     }
2022 
2023 #if (_DEBUG || _RELEASE_INTERNAL)
2024     if (osInterface->bEnableDbgOvrdInVE || Mos_Solo_IsInUse(osInterface))
2025     {
2026         //if DbgOverride is enabled, FE separate submission is not supported
2027         pScalabilityState->bFESeparateSubmission = false;
2028     }
2029 #endif
2030 
2031     if (pScalabilityState->bFESeparateSubmission)
2032     {
2033         MOS_GPU_CONTEXT         GpuContext = MOS_VE_CTXBASEDSCHEDULING_SUPPORTED(osInterface) ? MOS_GPU_CONTEXT_VIDEO : MOS_GPU_CONTEXT_VIDEO4;
2034         GpuContext = MOS_VE_MULTINODESCALING_SUPPORTED(osInterface) ? MOS_GPU_CONTEXT_VIDEO4 : GpuContext;
2035 
2036         MHW_VDBOX_GPUNODE_LIMIT gpuNodeLimit;
2037         MOS_ZeroMemory(&gpuNodeLimit, sizeof(MHW_VDBOX_GPUNODE_LIMIT));
2038         CODECHAL_DECODE_CHK_STATUS_RETURN(vdboxMfxInterface->FindGpuNodeToUse(
2039             &gpuNodeLimit));
2040         MOS_GPU_NODE videoGpuNode = (MOS_GPU_NODE)(gpuNodeLimit.dwGpuNodeToUse);
2041 
2042         MOS_GPUCTX_CREATOPTIONS createOpts;
2043         CODECHAL_DECODE_CHK_STATUS_RETURN(osInterface->pfnCreateGpuContext(
2044             osInterface,
2045             GpuContext,
2046             videoGpuNode,
2047             &createOpts));
2048         pScalabilityState->VideoContextForFE = GpuContext;
2049     }
2050 
2051     pScalabilityState->Standard              = pDecoder->GetStandard();
2052     pScalabilityState->VideoContext          = pDecoder->GetVideoContext();
2053     pScalabilityState->bShortFormatInUse     = bShortFormat;
2054     pScalabilityState->ucNumVdbox            = vdboxNum;
2055     pScalabilityState->pHwInterface          = hwInterface;
2056 
2057     //virtual engine init with scalability
2058     MOS_ZeroMemory(&VEInitParms, sizeof(VEInitParms));
2059     VEInitParms.bScalabilitySupported     = true;
2060     VEInitParms.bFESeparateSubmit         = pScalabilityState->bFESeparateSubmission;
2061     VEInitParms.ucMaxNumPipesInUse        = (vdboxNum == 2) ? 2 : 3;
2062     VEInitParms.ucNumOfSdryCmdBufSets     = CODECHAL_SCALABILITY_DECODE_SECONDARY_CMDBUFSET_NUM;
2063     VEInitParms.ucMaxNumOfSdryCmdBufInOneFrame = (pScalabilityState->bFESeparateSubmission) ? VEInitParms.ucMaxNumPipesInUse : (VEInitParms.ucMaxNumPipesInUse + 1);
2064     CODECHAL_DECODE_CHK_STATUS_RETURN(osInterface->pfnVirtualEngineInterfaceInitialize(osInterface, &VEInitParms));
2065     pScalabilityState->pVEInterface = pVEInterface = osInterface->pVEInterf;
2066 
2067     if (pVEInterface->pfnVEGetHintParams)
2068     {
2069         CODECHAL_DECODE_CHK_STATUS_RETURN(pVEInterface->pfnVEGetHintParams(pVEInterface, true, &pScalabilityState->pScalHintParms));
2070     }
2071     if (pVEInterface->pfnVEGetHintParams)
2072     {
2073         CODECHAL_DECODE_CHK_STATUS_RETURN(pVEInterface->pfnVEGetHintParams(pVEInterface, false, &pScalabilityState->pSingleHintParms));
2074     }
2075 
2076 #if (_DEBUG || _RELEASE_INTERNAL)
2077     MOS_ZeroMemory(&UserFeatureData, sizeof(UserFeatureData));
2078     MOS_UserFeature_ReadValue_ID(
2079         nullptr,
2080         __MEDIA_USER_FEATURE_VALUE_HCP_DECODE_ALWAYS_FRAME_SPLIT_ID,
2081         &UserFeatureData,
2082         osInterface->pOsContext);
2083     pScalabilityState->bAlwaysFrameSplit = UserFeatureData.u32Data ? true : false;
2084 #endif
2085 
2086     pScalabilityState->bIsEvenSplit = true;
2087 
2088     if (pDecoder->GetStandard() == CODECHAL_HEVC)
2089     {
2090         pScalabilityState->pfnGetHcpBufferSize         = GetHevcBufferSize;
2091         pScalabilityState->pfnIsHcpBufferReallocNeeded = IsHevcBufferReallocNeeded;
2092     }
2093     else if (pDecoder->GetStandard() == CODECHAL_VP9)
2094     {
2095         pScalabilityState->pfnGetHcpBufferSize         = GetVp9BufferSize;
2096         pScalabilityState->pfnIsHcpBufferReallocNeeded = IsVp9BufferReallocNeeded;
2097     }
2098     else
2099     {
2100         eStatus = MOS_STATUS_INVALID_PARAMETER;
2101         CODECHAL_DECODE_ASSERTMESSAGE("unsupported decode format for scalability mode.");
2102         return eStatus;
2103     }
2104 
2105     pScalabilityState->bToggleCABACStreamOutBuffer = false;
2106     pScalabilityState->sliceStateCLs = CODECHAL_SCALABILITY_SLICE_STATE_CACHELINES_PER_SLICE;
2107     pScalabilityState->pfnDecidePipeNum = CodecHalDecodeScalability_DecidePipeNum;
2108     pScalabilityState->pfnMapPipeNumToLRCACount = CodechalDecodeScalability_MapPipeNumToLRCACount;
2109 #if (_DEBUG || _RELEASE_INTERNAL)
2110     pScalabilityState->pfnDebugOvrdDecidePipeNum = CodechalDecodeScalability_DebugOvrdDecidePipeNum;
2111 #endif
2112 
2113     CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalDecodeScalability_AllocateResources_FixedSizes(pScalabilityState));
2114 
2115     return eStatus;
2116 }
2117 
CodecHalDecodeScalabilityIsToSubmitCmdBuffer(PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityState)2118 bool CodecHalDecodeScalabilityIsToSubmitCmdBuffer(
2119     PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityState)
2120 {
2121     if (pScalabilityState == nullptr)
2122     {
2123         return false;
2124     }
2125     else
2126     {
2127         return (CodecHalDecodeScalabilityIsFinalBEPhase(pScalabilityState) ||
2128             (pScalabilityState->HcpDecPhase == CODECHAL_HCP_DECODE_PHASE_FE && pScalabilityState->bFESeparateSubmission));
2129     }
2130 }
2131 
CodecHalDecodeScalability_DecPhaseToSubmissionType(PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityState,PMOS_COMMAND_BUFFER pCmdBuffer)2132 void CodecHalDecodeScalability_DecPhaseToSubmissionType(
2133     PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityState,
2134     PMOS_COMMAND_BUFFER pCmdBuffer)
2135 {
2136     switch (pScalabilityState->HcpDecPhase)
2137     {
2138         case CodechalDecode::CodechalHcpDecodePhaseLegacyS2L:
2139             //Note: no break here, S2L and FE commands put in one secondary command buffer.
2140         case CODECHAL_HCP_DECODE_PHASE_FE:
2141             pCmdBuffer->iSubmissionType = SUBMISSION_TYPE_MULTI_PIPE_ALONE;
2142             break;
2143         case CODECHAL_HCP_DECODE_PHASE_BE0:
2144             pCmdBuffer->iSubmissionType = SUBMISSION_TYPE_MULTI_PIPE_MASTER;
2145             break;
2146         case CODECHAL_HCP_DECODE_PHASE_BE1:
2147             pCmdBuffer->iSubmissionType = SUBMISSION_TYPE_MULTI_PIPE_SLAVE | SUBMISSION_TYPE_MULTI_PIPE_FLAGS_LAST_PIPE;
2148             break;
2149         case CODECHAL_HCP_DECODE_PHASE_RESERVED:
2150         default:
2151             pCmdBuffer->iSubmissionType = SUBMISSION_TYPE_MULTI_PIPE_ALONE;
2152             break;
2153     }
2154 }