1 /*
2 * Copyright (c) 2017-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_g12.cpp
24 //! \brief    Impelements the public interface for Gen12 Scalability Decode
25 //!
26 #include "codechal_decoder.h"
27 #include "codechal_decode_scalability_g12.h"
28 #include "media_user_settings_mgr_g12.h"
29 #include "mos_os_virtualengine_next.h"
30 
31 //==<Functions>=======================================================
32 //!
33 //! \brief    calculate secondary cmd buffer index
34 //! \details  calculate secondary cmd buffer index to get or return secondary cmd buffer
35 //! \param    [in]  pScalabilityState
36 //!                pointer to scalability decode state
37 //! \param    [in]  pdwBufIdxPlus1
38 //!                pointer to buf index, will contain the returned buf index value.
39 //! \return   MOS_STATUS
40 //!           MOS_STATUS_SUCCESS if success, else fail reason
41 //!
CodecHalDecodeScalability_CalculateScdryCmdBufIndex_G12(PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityStateBase,uint32_t * pdwBufIdxPlus1)42 static MOS_STATUS CodecHalDecodeScalability_CalculateScdryCmdBufIndex_G12(
43     PCODECHAL_DECODE_SCALABILITY_STATE  pScalabilityStateBase,
44     uint32_t                           *pdwBufIdxPlus1)
45 {
46     uint32_t                        HcpDecPhaseForBufIdx;
47     MOS_STATUS                      eStatus = MOS_STATUS_SUCCESS;
48 
49     CODECHAL_DECODE_FUNCTION_ENTER;
50 
51     PCODECHAL_DECODE_SCALABILITY_STATE_G12 pScalabilityState = static_cast<PCODECHAL_DECODE_SCALABILITY_STATE_G12>(pScalabilityStateBase);
52 
53     CODECHAL_DECODE_CHK_NULL(pScalabilityStateBase);
54     CODECHAL_DECODE_CHK_NULL(pdwBufIdxPlus1);
55     CODECHAL_DECODE_CHK_NULL(pScalabilityStateBase->pHwInterface);
56     CODECHAL_DECODE_CHK_NULL(pScalabilityStateBase->pHwInterface->GetOsInterface());
57 
58     if (pScalabilityState->HcpDecPhase == CODECHAL_HCP_DECODE_PHASE_REAL_TILE)
59     {
60         *pdwBufIdxPlus1 = pScalabilityState->u8RtCurPipe + 1;
61         if(pScalabilityStateBase->pHwInterface->GetOsInterface()->phasedSubmission
62         && !pScalabilityStateBase->pHwInterface->GetOsInterface()->bGucSubmission)
63         {
64             /*  3 tiles 2 pipe for example:
65                 cur phase               cur pip
66                 0                       0, 1                2 cmd buffer needed
67                 1                       0                   1 cmd buffer needed
68                 all of 3 tiles cmd ready, submit 3 cmd togather
69              */
70             *pdwBufIdxPlus1 += (pScalabilityState->u8RtCurPhase * pScalabilityState->u8RtPhaseNum);
71         }
72     }
73     else
74     {
75         HcpDecPhaseForBufIdx = pScalabilityState->HcpDecPhase;
76         if (pScalabilityState->HcpDecPhase == CodechalDecode::CodechalHcpDecodePhaseLegacyS2L)
77         {
78             //S2L commands put in the FE secondary command buffer.
79             CODECHAL_DECODE_ASSERT(pScalabilityState->bShortFormatInUse);
80             HcpDecPhaseForBufIdx = CODECHAL_HCP_DECODE_PHASE_FE;
81         }
82 
83         //buffer index order is same as the buffer order in resScalableBatchBufs[] of MOS_VIRTUALENGINE_HINT_PARAMS
84         *pdwBufIdxPlus1 = HcpDecPhaseForBufIdx - (pScalabilityState->bFESeparateSubmission ?
85             CODECHAL_HCP_DECODE_PHASE_BE0 : CODECHAL_HCP_DECODE_PHASE_FE) + 1;
86     }
87 
88 finish:
89     return eStatus;
90 }
91 
92 //!
93 //! \brief    check if valid decode phase
94 //! \param    [in]  pScalabilityState
95 //!                pointer to scalability decode state
96 //! \param    [in]  HcpDecPhase
97 //!                Hcp Decode Phase
98 //! \return   MOS_STATUS
99 //!           MOS_STATUS_SUCCESS if valid decode phase, else fail reason
100 //!
CodecHalDecodeScalability_CheckDecPhaseValidity_G12(PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityStateBase,uint32_t HcpDecPhase)101 static MOS_STATUS CodecHalDecodeScalability_CheckDecPhaseValidity_G12(
102     PCODECHAL_DECODE_SCALABILITY_STATE  pScalabilityStateBase,
103     uint32_t                            HcpDecPhase)
104 {
105     bool                bInValidPhase = false;
106     MOS_STATUS          eStatus = MOS_STATUS_SUCCESS;
107 
108     CODECHAL_DECODE_FUNCTION_ENTER;
109 
110     PCODECHAL_DECODE_SCALABILITY_STATE_G12 pScalabilityState = static_cast<PCODECHAL_DECODE_SCALABILITY_STATE_G12>(pScalabilityStateBase);
111 
112     CODECHAL_DECODE_CHK_NULL(pScalabilityStateBase);
113 
114     switch (HcpDecPhase)
115     {
116     case CodechalDecode::CodechalHcpDecodePhaseInitialized:
117         break;
118     case CodechalDecode::CodechalHcpDecodePhaseLegacyS2L:
119         if (!pScalabilityState->bShortFormatInUse)
120         {
121             bInValidPhase = true;
122         }
123         break;
124     case CodechalDecode::CodechalHcpDecodePhaseLegacyLong:
125         if (pScalabilityState->bScalableDecodeMode)
126         {
127             bInValidPhase = true;
128         }
129         break;
130     case CODECHAL_HCP_DECODE_PHASE_FE:
131     case CODECHAL_HCP_DECODE_PHASE_BE0:
132         if (!pScalabilityState->bScalableDecodeMode)
133         {
134             bInValidPhase = true;
135         }
136         else if (pScalabilityState->ucScalablePipeNum < 2)
137         {
138             //at least 2 pipe
139             bInValidPhase = true;
140         }
141         break;
142     case CODECHAL_HCP_DECODE_PHASE_REAL_TILE:
143         if (pScalabilityState->ucScalablePipeNum <= pScalabilityState->u8RtCurPipe)
144         {
145             bInValidPhase = true;
146         }
147         break;
148     default:
149         if(HcpDecPhase > CODECHAL_HCP_DECODE_PHASE_BE0 &&
150             HcpDecPhase != CODECHAL_HCP_DECODE_PHASE_REAL_TILE)
151         {
152             if (!pScalabilityState->bScalableDecodeMode)
153             {
154                 bInValidPhase = true;
155             }
156             else if (pScalabilityState->ucScalablePipeNum < (HcpDecPhase - CODECHAL_HCP_DECODE_PHASE_BE0 + 1))
157             {
158                 bInValidPhase = true;
159             }
160         }
161         else
162         {
163             bInValidPhase = true;
164         }
165         break;
166     }
167 
168     if (bInValidPhase)
169     {
170         eStatus = MOS_STATUS_INVALID_PARAMETER;
171         CODECHAL_DECODE_ASSERTMESSAGE("invalid decode phase : %d !", HcpDecPhase);
172     }
173 
174 finish:
175     return eStatus;
176 }
177 
CodecHalDecodeScalability_GetVESecondaryCmdBuffer_G12(PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityState,PMOS_COMMAND_BUFFER pSdryCmdBuf)178  MOS_STATUS CodecHalDecodeScalability_GetVESecondaryCmdBuffer_G12(
179     PCODECHAL_DECODE_SCALABILITY_STATE  pScalabilityState,
180     PMOS_COMMAND_BUFFER                 pSdryCmdBuf)
181 {
182     PMOS_INTERFACE                  pOsInterface;
183     uint32_t                        HcpDecPhase;
184     uint32_t                        dwBufIdxPlus1 = 0;
185     MOS_STATUS                      eStatus = MOS_STATUS_SUCCESS;
186 
187     CODECHAL_DECODE_FUNCTION_ENTER;
188 
189     CODECHAL_DECODE_CHK_NULL(pScalabilityState);
190     CODECHAL_DECODE_CHK_NULL(pSdryCmdBuf);
191     CODECHAL_DECODE_CHK_NULL(pScalabilityState->pHwInterface);
192     CODECHAL_DECODE_CHK_NULL(pScalabilityState->pHwInterface->GetOsInterface());
193 
194     pOsInterface = pScalabilityState->pHwInterface->GetOsInterface();
195     HcpDecPhase = pScalabilityState->HcpDecPhase;
196 
197     //calculate bufidx for getting secondary cmd buffer.
198     CODECHAL_DECODE_CHK_STATUS(CodecHalDecodeScalability_CalculateScdryCmdBufIndex_G12(pScalabilityState, &dwBufIdxPlus1));
199     //Check if valid decode phase
200     CODECHAL_DECODE_CHK_STATUS(CodecHalDecodeScalability_CheckDecPhaseValidity_G12(pScalabilityState, HcpDecPhase));
201 
202     //Get batch buffer according to current decode phase
203     switch (HcpDecPhase)
204     {
205     case CodechalDecode::CodechalHcpDecodePhaseLegacyS2L:
206         //Note: no break here, S2L and FE commands put in one secondary command buffer.
207     case CODECHAL_HCP_DECODE_PHASE_FE:
208         if (!pScalabilityState->bFESeparateSubmission)
209         {
210             CODECHAL_DECODE_CHK_STATUS(pOsInterface->pfnGetCommandBuffer(pOsInterface, pSdryCmdBuf, dwBufIdxPlus1));
211             CODECHAL_DECODE_CHK_NULL(pSdryCmdBuf);
212         }
213         else
214         {
215             //if FE separate submission, S2L and FE cmd buffer are in primary cmd buffer, shall not call this function to get secondary cmd buffer
216             eStatus = MOS_STATUS_INVALID_PARAMETER;
217             CODECHAL_DECODE_ASSERTMESSAGE("S2L or FE does not need secondary cmd buffer in FE separate submission!");
218         }
219         break;
220     default:
221         if(((HcpDecPhase >= CODECHAL_HCP_DECODE_PHASE_BE0) && ((HcpDecPhase-CODECHAL_HCP_DECODE_PHASE_FE) <= pScalabilityState->ucScalablePipeNum)) ||
222             (HcpDecPhase == CODECHAL_HCP_DECODE_PHASE_REAL_TILE))
223         {
224             CODECHAL_DECODE_CHK_STATUS(pOsInterface->pfnGetCommandBuffer(pOsInterface, pSdryCmdBuf, dwBufIdxPlus1));
225             CODECHAL_DECODE_CHK_NULL(pSdryCmdBuf);
226         }
227         else
228         {
229             eStatus = MOS_STATUS_INVALID_PARAMETER;
230         }
231         break;
232     }
233 
234 finish:
235     return eStatus;
236 }
237 
CodecHalDecodeScalability_GetCmdBufferToUse_G12(PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityStateBase,PMOS_COMMAND_BUFFER pScdryCmdBuf,PMOS_COMMAND_BUFFER * ppCmdBufToUse)238 MOS_STATUS CodecHalDecodeScalability_GetCmdBufferToUse_G12(
239     PCODECHAL_DECODE_SCALABILITY_STATE  pScalabilityStateBase,
240     PMOS_COMMAND_BUFFER                 pScdryCmdBuf,
241     PMOS_COMMAND_BUFFER                 *ppCmdBufToUse)
242 {
243     MOS_STATUS                      eStatus = MOS_STATUS_SUCCESS;
244 
245     CODECHAL_DECODE_FUNCTION_ENTER;
246 
247     PCODECHAL_DECODE_SCALABILITY_STATE_G12 pScalabilityState = static_cast<PCODECHAL_DECODE_SCALABILITY_STATE_G12>(pScalabilityStateBase);
248 
249     CODECHAL_DECODE_CHK_NULL(pScalabilityStateBase);
250     CODECHAL_DECODE_CHK_NULL(ppCmdBufToUse);
251     CODECHAL_DECODE_CHK_NULL(pScalabilityStateBase->pHwInterface);
252     CODECHAL_DECODE_CHK_NULL(pScalabilityStateBase->pHwInterface->GetOsInterface());
253 
254     if (!CodecHalDecodeScalabilityIsFESeparateSubmission(pScalabilityState) ||
255         CodecHalDecodeScalabilityIsBEPhaseG12(pScalabilityState) ||
256         pScalabilityStateBase->pHwInterface->GetOsInterface()->bGucSubmission)
257     {
258         pScalabilityState->bUseSecdryCmdBuffer = true;
259         CODECHAL_DECODE_CHK_STATUS(CodecHalDecodeScalability_GetVESecondaryCmdBuffer_G12(pScalabilityState, pScdryCmdBuf));
260         *ppCmdBufToUse = pScdryCmdBuf;
261     }
262     else
263     {
264         pScalabilityState->bUseSecdryCmdBuffer = false;
265     }
266 
267 finish:
268     return eStatus;
269 }
270 
CodecHalDecodeScalability_ReturnSdryCmdBuffer_G12(PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityState,PMOS_COMMAND_BUFFER pSdryCmdBuf)271 MOS_STATUS CodecHalDecodeScalability_ReturnSdryCmdBuffer_G12(
272     PCODECHAL_DECODE_SCALABILITY_STATE  pScalabilityState,
273     PMOS_COMMAND_BUFFER                 pSdryCmdBuf)
274 {
275     PMOS_INTERFACE                  pOsInterface;
276     uint32_t                        HcpDecPhase;
277     uint32_t                        dwBufIdxPlus1;
278     MOS_STATUS                      eStatus = MOS_STATUS_SUCCESS;
279 
280     CODECHAL_DECODE_FUNCTION_ENTER;
281 
282     CODECHAL_DECODE_CHK_NULL(pScalabilityState);
283     CODECHAL_DECODE_CHK_NULL(pSdryCmdBuf);
284     CODECHAL_DECODE_CHK_NULL(pScalabilityState->pHwInterface);
285     CODECHAL_DECODE_CHK_NULL(pScalabilityState->pHwInterface->GetOsInterface());
286 
287     pOsInterface = pScalabilityState->pHwInterface->GetOsInterface();
288 
289     if (!pScalabilityState->bUseSecdryCmdBuffer)
290     {
291         goto finish;
292     }
293 
294     HcpDecPhase = pScalabilityState->HcpDecPhase;
295 
296     //calculate bufidx for getting secondary cmd buffer.
297     CODECHAL_DECODE_CHK_STATUS(CodecHalDecodeScalability_CalculateScdryCmdBufIndex_G12(pScalabilityState, &dwBufIdxPlus1));
298     //Check if valid decode phase
299     CODECHAL_DECODE_CHK_STATUS(CodecHalDecodeScalability_CheckDecPhaseValidity_G12(pScalabilityState, HcpDecPhase));
300 
301     //Get batch buffer according to current decode phase
302     switch (HcpDecPhase)
303     {
304     case CodechalDecode::CodechalHcpDecodePhaseLegacyS2L:
305         //Note: no break here, S2L and FE commands put in one secondary command buffer.
306     case CODECHAL_HCP_DECODE_PHASE_FE:
307         if (!pScalabilityState->bFESeparateSubmission)
308         {
309             pOsInterface->pfnReturnCommandBuffer(pOsInterface, pSdryCmdBuf, dwBufIdxPlus1);
310         }
311         else
312         {
313             //if FE separate submission, S2L and FE cmd buffer are in primary cmd buffer, shall not call this function to get secondary cmd buffer
314             eStatus = MOS_STATUS_INVALID_PARAMETER;
315             CODECHAL_DECODE_ASSERTMESSAGE("S2L or FE does not need secondary cmd buffer in FE separate submission!");
316         }
317         break;
318     default:
319         if(((HcpDecPhase >= CODECHAL_HCP_DECODE_PHASE_BE0) && ((HcpDecPhase-CODECHAL_HCP_DECODE_PHASE_FE) <= pScalabilityState->ucScalablePipeNum)) ||
320           (HcpDecPhase == CODECHAL_HCP_DECODE_PHASE_REAL_TILE))
321         {
322             pOsInterface->pfnReturnCommandBuffer(pOsInterface, pSdryCmdBuf, dwBufIdxPlus1);
323         }
324         else
325         {
326             eStatus = MOS_STATUS_INVALID_PARAMETER;
327         }
328         break;
329     }
330 
331 finish:
332     return eStatus;
333 }
334 
CodecHalDecodeScalability_DetermineDecodePhase_G12(PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityStateBase,uint32_t * pHcpDecPhase)335 MOS_STATUS CodecHalDecodeScalability_DetermineDecodePhase_G12(
336     PCODECHAL_DECODE_SCALABILITY_STATE  pScalabilityStateBase,
337     uint32_t                            *pHcpDecPhase)
338 {
339     uint32_t                        CurPhase;
340     MOS_STATUS                      eStatus = MOS_STATUS_SUCCESS;
341 
342     CODECHAL_DECODE_FUNCTION_ENTER;
343 
344     PCODECHAL_DECODE_SCALABILITY_STATE_G12 pScalabilityState = static_cast<PCODECHAL_DECODE_SCALABILITY_STATE_G12>(pScalabilityStateBase);
345 
346     CODECHAL_DECODE_CHK_NULL(pScalabilityStateBase);
347     CODECHAL_DECODE_CHK_NULL(pHcpDecPhase);
348 
349     CurPhase = *pHcpDecPhase;
350     //Check if valid decode phase
351     CODECHAL_DECODE_CHK_STATUS(CodecHalDecodeScalability_CheckDecPhaseValidity_G12(pScalabilityState, CurPhase));
352 
353     if (pScalabilityState->bIsRtMode)
354     {
355         switch (CurPhase)
356         {
357         case CodechalDecode::CodechalHcpDecodePhaseInitialized:
358             if (pScalabilityState->bShortFormatInUse)
359             {
360                 *pHcpDecPhase = CodechalDecode::CodechalHcpDecodePhaseLegacyS2L;
361             }
362             else
363             {
364                 *pHcpDecPhase = CODECHAL_HCP_DECODE_PHASE_REAL_TILE;
365             }
366             break;
367         case CodechalDecode::CodechalHcpDecodePhaseLegacyS2L:
368         case CODECHAL_HCP_DECODE_PHASE_REAL_TILE:
369             *pHcpDecPhase = CODECHAL_HCP_DECODE_PHASE_REAL_TILE;
370             break;
371         default:
372             eStatus = MOS_STATUS_INVALID_PARAMETER;
373             break;
374         }
375     }
376     else if (CodecHalDecodeScalabilityIsScalableMode(pScalabilityState))
377     {
378         switch (CurPhase)
379         {
380         case CodechalDecode::CodechalHcpDecodePhaseInitialized:
381             if (pScalabilityState->bShortFormatInUse)
382             {
383                 *pHcpDecPhase = CodechalDecode::CodechalHcpDecodePhaseLegacyS2L;
384             }
385             else
386             {
387                 *pHcpDecPhase = CODECHAL_HCP_DECODE_PHASE_FE;
388             }
389             break;
390         case CodechalDecode::CodechalHcpDecodePhaseLegacyS2L:
391             *pHcpDecPhase = CODECHAL_HCP_DECODE_PHASE_FE;
392             break;
393         case CODECHAL_HCP_DECODE_PHASE_FE:
394             *pHcpDecPhase = CODECHAL_HCP_DECODE_PHASE_BE0;
395             break;
396         default:
397             if(CurPhase >= CODECHAL_HCP_DECODE_PHASE_BE0 && ((CurPhase-CODECHAL_HCP_DECODE_PHASE_FE) <= pScalabilityState->ucScalablePipeNum))
398             {
399                 *pHcpDecPhase = CurPhase + 1;
400             }
401             else
402             {
403                 eStatus = MOS_STATUS_INVALID_PARAMETER;
404             }
405             break;
406         }
407     }
408     else
409     {
410         switch (CurPhase)
411         {
412         case CodechalDecode::CodechalHcpDecodePhaseInitialized:
413             if (pScalabilityState->bShortFormatInUse)
414             {
415                 *pHcpDecPhase = CodechalDecode::CodechalHcpDecodePhaseLegacyS2L;
416             }
417             else
418             {
419                 *pHcpDecPhase = CodechalDecode::CodechalHcpDecodePhaseLegacyLong;
420             }
421             break;
422         case CodechalDecode::CodechalHcpDecodePhaseLegacyS2L:
423         case CodechalDecode::CodechalHcpDecodePhaseLegacyLong:
424             *pHcpDecPhase = CodechalDecode::CodechalHcpDecodePhaseLegacyLong;
425             break;
426         default:
427             //never comes here because other decode phase already checked invalid in function CodecHalDecodeScalability_CheckDecPhaseValidity,
428             eStatus = MOS_STATUS_INVALID_PARAMETER;
429             break;
430         }
431     }
432 
433     pScalabilityState->HcpDecPhase = *pHcpDecPhase;
434 
435 finish:
436     return eStatus;
437 }
438 
CodecHalDecodeScalability_InitScalableParams_G12(PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityStateBase,PCODECHAL_DECODE_SCALABILITY_INIT_PARAMS pInitParamsBase,uint16_t * pucDecPassNum)439 MOS_STATUS CodecHalDecodeScalability_InitScalableParams_G12(
440     PCODECHAL_DECODE_SCALABILITY_STATE         pScalabilityStateBase,
441     PCODECHAL_DECODE_SCALABILITY_INIT_PARAMS   pInitParamsBase,
442     uint16_t                                   *pucDecPassNum)
443 {
444     PMOS_INTERFACE                  pOsInterface;
445     PMOS_VIRTUALENGINE_INTERFACE    pVEInterface;
446     MOS_STATUS                      eStatus = MOS_STATUS_SUCCESS;
447 
448     CODECHAL_DECODE_FUNCTION_ENTER;
449 
450     PCODECHAL_DECODE_SCALABILITY_STATE_G12 pScalabilityState = static_cast<PCODECHAL_DECODE_SCALABILITY_STATE_G12>(pScalabilityStateBase);
451     PCODECHAL_DECODE_SCALABILITY_INIT_PARAMS_G12 pInitParams = static_cast<PCODECHAL_DECODE_SCALABILITY_INIT_PARAMS_G12>(pInitParamsBase);
452 
453     CODECHAL_DECODE_CHK_NULL(pScalabilityStateBase);
454     CODECHAL_DECODE_CHK_NULL(pScalabilityStateBase->pHwInterface);
455     CODECHAL_DECODE_CHK_NULL(pScalabilityStateBase->pHwInterface->GetOsInterface());
456 
457     pOsInterface = pScalabilityStateBase->pHwInterface->GetOsInterface();
458     pVEInterface = pScalabilityStateBase->pVEInterface;
459 
460     if (!pOsInterface->bSupportVirtualEngine)
461     {
462         eStatus = MOS_STATUS_INVALID_PARAMETER;
463         CODECHAL_DECODE_ASSERTMESSAGE("Scalability decode must run with virtual engine interface.\n");
464         goto finish;
465     }
466 
467     pScalabilityState->bScalableDecodeMode = false; // initialized to false
468     pScalabilityState->bIsRtMode = false;
469 
470 #if (_DEBUG || _RELEASE_INTERNAL)
471     if (pOsInterface->bEnableDbgOvrdInVE)
472     {
473         if (!MOS_VE_CTXBASEDSCHEDULING_SUPPORTED(pOsInterface))
474         {
475             if (pOsInterface->apoMosEnabled)
476             {
477                 CODECHAL_DECODE_CHK_NULL(pVEInterface->veInterface);
478                 pScalabilityState->ucScalablePipeNum = pVEInterface->veInterface->GetEngineCount() - 1;
479             }
480             else
481             {
482                 pScalabilityState->ucScalablePipeNum = pVEInterface->ucEngineCount - 1;
483             }
484             pScalabilityState->bScalableDecodeMode = true;
485         }
486         else
487         {
488             // do nothing since pipe number already decided at the gpu context creation.
489         }
490     }
491     else
492 #endif
493     {
494         // Decide pipe number
495         CODECHAL_DECODE_CHK_STATUS(pScalabilityState->pfnDecidePipeNum(pScalabilityState, pInitParams));
496     }
497 
498     // Decide scalable mode or single pipe mode
499     if (pScalabilityState->ucScalablePipeNum > 1)
500     {
501         pScalabilityState->bScalableDecodeMode = true;
502     }
503 
504     CODECHAL_DECODE_CHK_NULL(pucDecPassNum);
505     // Decide Decode pass number - pucDecPassNum
506     if (pScalabilityState->bScalableDecodeMode)
507     {
508         bool        bCanEnableRealTile = true;
509         uint8_t     u8MaxTileColumn = HEVC_NUM_MAX_TILE_COLUMN;
510 
511 #if (_DEBUG || _RELEASE_INTERNAL)
512         bCanEnableRealTile = !pScalabilityState->bDisableRtMode;
513         if (!pScalabilityState->bEnableRtMultiPhase)
514             u8MaxTileColumn = pScalabilityState->ucScalablePipeNum;
515 #endif
516         bCanEnableRealTile = bCanEnableRealTile && pInitParams->bIsTileEnabled && (pInitParams->u8NumTileColumns > 1) &&
517             (pInitParams->u8NumTileColumns <= u8MaxTileColumn) && (pInitParams->u8NumTileRows <= HEVC_NUM_MAX_TILE_ROW) &&
518             pInitParams->bHasSubsetParams;
519         if (bCanEnableRealTile)
520         {
521             pScalabilityState->bIsRtMode = true;
522             //WA: No FE for real tile decoding and need to disable FE separate submission
523             pScalabilityState->bFESeparateSubmission = false;
524             pScalabilityState->u8RtPhaseNum =
525                 (pInitParams->u8NumTileColumns + pScalabilityState->ucScalablePipeNum - 1) / pScalabilityState->ucScalablePipeNum;
526             pScalabilityState->u8RtPipeInLastPhase = pInitParams->u8NumTileColumns - pScalabilityState->ucScalablePipeNum * (pScalabilityState->u8RtPhaseNum - 1);
527             pScalabilityState->u8RtCurPipe = 0;
528             pScalabilityState->u8RtCurPhase = 0;
529 
530             *pucDecPassNum = pInitParams->u8NumTileColumns;
531         }
532         else if (pInitParams->bIsSccDecoding) // No virtual tile support for SCC, fallback to legacy mode
533         {
534             pScalabilityState->bScalableDecodeMode = false;
535             *pucDecPassNum = 1;
536         }
537         else
538         {
539             *pucDecPassNum = pScalabilityState->ucScalablePipeNum + 1; // FE + all BEs
540             pScalabilityState->bFESeparateSubmission = pScalabilityState->bFESeparateSubmissionVT;
541         }
542     }
543     else
544     {
545         *pucDecPassNum = 1;
546     }
547 
548     // Add one pass for S2L conversion in short format.
549     if (pScalabilityState->bShortFormatInUse)
550     {
551         *pucDecPassNum = *pucDecPassNum + 1;
552     }
553 
554     pScalabilityState->VideoContext = pInitParams->gpuCtxInUse;
555 
556 finish:
557     return eStatus;
558 }
559 
CodecHalDecodeScalability_SetHintParams_G12(PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityStateBase,PCODECHAL_DECODE_SCALABILITY_SETHINT_PARMS pSetHintParms)560 MOS_STATUS CodecHalDecodeScalability_SetHintParams_G12(
561     PCODECHAL_DECODE_SCALABILITY_STATE         pScalabilityStateBase,
562     PCODECHAL_DECODE_SCALABILITY_SETHINT_PARMS pSetHintParms)
563 {
564     PMOS_VIRTUALENGINE_INTERFACE    pVEInterface;
565     MOS_VIRTUALENGINE_SET_PARAMS    VEParams;
566     PMOS_INTERFACE                  pOsInterface;
567     MOS_STATUS                      eStatus = MOS_STATUS_SUCCESS;
568 
569     CODECHAL_DECODE_FUNCTION_ENTER;
570 
571     PCODECHAL_DECODE_SCALABILITY_STATE_G12 pScalabilityState = static_cast<PCODECHAL_DECODE_SCALABILITY_STATE_G12>(pScalabilityStateBase);
572 
573     CODECHAL_DECODE_CHK_NULL(pScalabilityStateBase);
574     CODECHAL_DECODE_CHK_NULL(pSetHintParms);
575     CODECHAL_DECODE_CHK_NULL(pScalabilityStateBase->pHwInterface);
576     CODECHAL_DECODE_CHK_NULL(pScalabilityStateBase->pHwInterface->GetOsInterface());
577 
578     pOsInterface = pScalabilityStateBase->pHwInterface->GetOsInterface();
579     pVEInterface = pScalabilityStateBase->pVEInterface;
580 
581     MOS_ZeroMemory(&VEParams, sizeof(VEParams));
582     if (!MOS_VE_CTXBASEDSCHEDULING_SUPPORTED(pOsInterface))
583     {
584         //not used by VE2.0
585         VEParams.bNeedSyncWithPrevious = pSetHintParms->bNeedSyncWithPrevious;
586         VEParams.bSameEngineAsLastSubmission = pSetHintParms->bSameEngineAsLastSubmission;
587         VEParams.bSFCInUse = pSetHintParms->bSFCInUse;
588     }
589 
590     VEParams.ucScalablePipeNum = pScalabilityState->ucScalablePipeNum;
591 
592     if (pScalabilityState->bScalableDecodeMode)
593     {
594         if (pScalabilityState->bFESeparateSubmission)
595         {
596             //set Hint parameter for FE submission
597             VEParams.bScalableMode = false;
598             if (pVEInterface->pfnVESetHintParams)
599             {
600                 CODECHAL_DECODE_CHK_STATUS(pVEInterface->pfnVESetHintParams(pVEInterface, &VEParams));
601             }
602         }
603 
604         VEParams.bScalableMode = true;
605         VEParams.bHaveFrontEndCmds = pScalabilityState->bIsRtMode ? false : (pScalabilityState->bFESeparateSubmission ? false : true);
606         if (pVEInterface->pfnVESetHintParams)
607         {
608             CODECHAL_DECODE_CHK_STATUS(pVEInterface->pfnVESetHintParams(pVEInterface, &VEParams));
609         }
610     }
611     else
612     {
613         VEParams.bScalableMode = false;
614         if (pVEInterface->pfnVESetHintParams)
615         {
616             CODECHAL_DECODE_CHK_STATUS(pVEInterface->pfnVESetHintParams(pVEInterface, &VEParams));
617         }
618     }
619 
620 finish:
621     return eStatus;
622 }
623 
624 #if (_DEBUG || _RELEASE_INTERNAL)
CodecHalDecodeScalability_DbgDumpCmdBuffer_G12(CodechalDecode * pDecoder,PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityState,CodechalDebugInterface * debugInterface,PMOS_COMMAND_BUFFER pPrimCmdBuf)625 MOS_STATUS CodecHalDecodeScalability_DbgDumpCmdBuffer_G12(
626     CodechalDecode                      *pDecoder,
627     PCODECHAL_DECODE_SCALABILITY_STATE  pScalabilityState,
628     CodechalDebugInterface              *debugInterface,
629     PMOS_COMMAND_BUFFER                 pPrimCmdBuf)
630 {
631     MOS_STATUS                      eStatus = MOS_STATUS_SUCCESS;
632     MOS_COMMAND_BUFFER              ScdryCmdBuffer;
633     PMOS_COMMAND_BUFFER             pCmdBufferInUse;
634     std::string                     cmdName = "DEC";
635 
636     CODECHAL_DECODE_FUNCTION_ENTER;
637 
638     CODECHAL_DECODE_CHK_NULL(pDecoder);
639     CODECHAL_DECODE_CHK_NULL(pScalabilityState);
640     CODECHAL_DECODE_CHK_NULL(pPrimCmdBuf);
641 
642     if (!pScalabilityState->bScalableDecodeMode)
643     {
644         eStatus = MOS_STATUS_INVALID_PARAMETER;
645         CODECHAL_DECODE_ASSERTMESSAGE("Invalid decode parameters!");
646         goto finish;
647     }
648 
649     if (CodecHalDecodeScalabilityIsFESeparateSubmission(pScalabilityState)
650         && CodecHalDecodeScalabilityIsFEPhase(pScalabilityState))
651     {
652         pCmdBufferInUse = pPrimCmdBuf;
653     }
654     else
655     {
656         //calculate bufidx for getting secondary cmd buffer.
657         uint32_t dwBufIdxPlus1 = 0;
658         CODECHAL_DECODE_CHK_STATUS(CodecHalDecodeScalability_CalculateScdryCmdBufIndex_G12(pScalabilityState, &dwBufIdxPlus1));
659         cmdName = cmdName + "_secondary_" + std::to_string(dwBufIdxPlus1);
660         CODECHAL_DECODE_CHK_STATUS(CodecHalDecodeScalability_GetVESecondaryCmdBuffer_G12(pScalabilityState, &ScdryCmdBuffer));
661         pCmdBufferInUse = &ScdryCmdBuffer;
662     }
663 
664     CODECHAL_DECODE_CHK_STATUS_RETURN(debugInterface->DumpCmdBuffer(
665         pCmdBufferInUse,
666         CODECHAL_NUM_MEDIA_STATES,
667         cmdName.c_str()));
668 
669 finish:
670     return eStatus;
671 }
672 #endif
673 
CodecHalDecodeScalability_FEBESync_G12(PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityStateBase,PMOS_COMMAND_BUFFER pCmdBufferInUse,bool phasedSubmission)674 MOS_STATUS CodecHalDecodeScalability_FEBESync_G12(
675     PCODECHAL_DECODE_SCALABILITY_STATE  pScalabilityStateBase,
676     PMOS_COMMAND_BUFFER                 pCmdBufferInUse,
677     bool phasedSubmission)
678 {
679     PMOS_INTERFACE                      pOsInterface;
680     MhwMiInterface                      *pMiInterface;
681     uint32_t                            HcpDecPhase;
682     uint32_t                            curPipeInUse = 0;
683     MOS_STATUS                          eStatus = MOS_STATUS_SUCCESS;
684 
685     CODECHAL_DECODE_FUNCTION_ENTER;
686 
687     PCODECHAL_DECODE_SCALABILITY_STATE_G12 pScalabilityState = static_cast<PCODECHAL_DECODE_SCALABILITY_STATE_G12>(pScalabilityStateBase);
688 
689     CODECHAL_DECODE_CHK_NULL(pScalabilityStateBase);
690     CODECHAL_DECODE_CHK_NULL(pScalabilityStateBase->pHwInterface);
691     CODECHAL_DECODE_CHK_NULL(pScalabilityStateBase->pHwInterface->GetOsInterface());
692     CODECHAL_DECODE_CHK_NULL(pScalabilityStateBase->pHwInterface->GetMiInterface());
693     CODECHAL_DECODE_CHK_NULL(pCmdBufferInUse);
694 
695     pOsInterface = pScalabilityStateBase->pHwInterface->GetOsInterface();
696     pMiInterface = pScalabilityState->pHwInterface->GetMiInterface();
697     HcpDecPhase = pScalabilityStateBase->HcpDecPhase;
698 
699     //FE& BE0 Sync. to refine (ucNumVdbox > )for GT3
700     if (HcpDecPhase == CODECHAL_HCP_DECODE_PHASE_BE0
701         && pScalabilityState->pHwInterface->GetMfxInterface()->GetNumVdbox() > 2
702         && !pOsInterface->bGucSubmission)
703     {
704         if (pScalabilityState->bFESeparateSubmission)
705         {
706             MOS_SYNC_PARAMS SyncParams;
707 
708             SyncParams = g_cInitSyncParams;
709             SyncParams.GpuContext = pScalabilityState->VideoContext;
710             SyncParams.presSyncResource = &pScalabilityState->resFeBeSyncObject;
711 
712             CODECHAL_DECODE_CHK_STATUS(pOsInterface->pfnEngineWait(pOsInterface, &SyncParams));
713         }
714         else
715         {
716             CODECHAL_DECODE_CHK_STATUS(pScalabilityState->pHwInterface->SendHwSemaphoreWaitCmd(&pScalabilityState->resSemaMemFEBE, 1, MHW_MI_SAD_EQUAL_SDD, pCmdBufferInUse));
717             //reset semaphore. mi atomic decrease 1
718             CODECHAL_DECODE_CHK_STATUS(pScalabilityState->pHwInterface->SendMiAtomicDwordCmd(&pScalabilityState->resSemaMemFEBE, 1, MHW_MI_ATOMIC_DEC, pCmdBufferInUse));
719         }
720     }
721 
722     if (CodecHalDecodeScalabilityIsBEPhaseG12(pScalabilityState) ||
723         (CodecHalDecodeScalabilityIsFirstRealTilePhase(pScalabilityState)))
724     {
725         // Stop Watchdog before BEs wait
726         pMiInterface->AddWatchdogTimerStopCmd(pCmdBufferInUse);
727 
728         //HW Semaphore for BEs Starting at the same time
729         CODECHAL_DECODE_CHK_STATUS(pScalabilityState->pHwInterface->SendMiAtomicDwordCmd(&pScalabilityState->resSemaMemBEs, 1, MHW_MI_ATOMIC_INC, pCmdBufferInUse));
730         uint8_t u8PipeNum = pScalabilityState->ucScalablePipeNum;
731 
732         if (phasedSubmission && pScalabilityState->bIsRtMode)
733         {
734             if (pScalabilityState->u8RtCurPhase == pScalabilityState->u8RtPhaseNum - 1)
735             {
736                 u8PipeNum = pScalabilityState->u8RtPipeInLastPhase;
737             }
738         }
739 
740         CODECHAL_DECODE_CHK_STATUS(pScalabilityState->pHwInterface->SendHwSemaphoreWaitCmd(
741             &pScalabilityState->resSemaMemBEs,
742             u8PipeNum,
743             MHW_MI_SAD_EQUAL_SDD,
744             pCmdBufferInUse));
745 
746         //add additional BEs Sync for two pipes
747         if (u8PipeNum == 2 && !phasedSubmission)
748         {
749             if (pScalabilityState->bIsRtMode)
750             {
751                 curPipeInUse = pScalabilityState->u8RtCurPipe;
752             }
753             else
754             {
755                 curPipeInUse = HcpDecPhase == CODECHAL_HCP_DECODE_PHASE_BE0 ? 0 : 1;
756             }
757             //pipe 0: resSemaMemBEsAdditional[0] + 1, pipe 1: resSemaMemBEsAdditional[1] + 1
758             CODECHAL_DECODE_CHK_STATUS(pScalabilityState->pHwInterface->SendMiAtomicDwordCmd(&pScalabilityState->resSemaMemBEsAdditional[curPipeInUse],
759                 1,
760                 MHW_MI_ATOMIC_INC,
761                 pCmdBufferInUse));
762         }
763 
764         // Program some placeholder cmds to resolve the hazard between BEs sync
765         MHW_MI_STORE_DATA_PARAMS dataParams;
766         dataParams.pOsResource = &pScalabilityState->resDelayMinus;
767         dataParams.dwResourceOffset = 0;
768         dataParams.dwValue = 0xDE1A;
769         for (uint32_t i = 0; i < pScalabilityState->numDelay; i++)
770         {
771             CODECHAL_DECODE_CHK_STATUS_RETURN(pScalabilityState->pHwInterface->GetMiInterface()->AddMiStoreDataImmCmd(
772                 pCmdBufferInUse,
773                 &dataParams));
774         }
775         //additional Semaphore Wait: pipe 0 wait resSemaMemBEsAdditional[1] == 1, pipe 1 wait resSemaMemBEsAdditional[0] == 1
776         if (u8PipeNum == 2 && !phasedSubmission)
777         {
778             CODECHAL_DECODE_CHK_STATUS(pScalabilityState->pHwInterface->SendHwSemaphoreWaitCmd(
779                 &pScalabilityState->resSemaMemBEsAdditional[CODECHAL_SCALABILITY_MAX_PIPE_INDEX_OF_TWO_PIPE - curPipeInUse],
780                 1,
781                 MHW_MI_SAD_EQUAL_SDD,
782                 pCmdBufferInUse));
783         }
784         //reset HW semaphore
785         CODECHAL_DECODE_CHK_STATUS(pScalabilityState->pHwInterface->SendMiAtomicDwordCmd(&pScalabilityState->resSemaMemBEs, 1, MHW_MI_ATOMIC_DEC, pCmdBufferInUse));
786         //pipe 0 reset resSemaMemBEsAdditional[1], pipe 1 reset resSemaMemBEsAdditional[0]
787         if (u8PipeNum == 2 && !phasedSubmission)
788         {
789             CODECHAL_DECODE_CHK_STATUS(pScalabilityState->pHwInterface->SendMiAtomicDwordCmd(
790                 &pScalabilityState->resSemaMemBEsAdditional[CODECHAL_SCALABILITY_MAX_PIPE_INDEX_OF_TWO_PIPE - curPipeInUse],
791                 1,
792                 MHW_MI_ATOMIC_DEC,
793                 pCmdBufferInUse));
794         }
795 
796         if (!pScalabilityState->bIsRtMode)
797         {
798             if (pScalabilityState->bIsEnableEndCurrentBatchBuffLevel)
799             {
800                 // Enhanced Condidtional BB END for streamout buffer writing over allocated size
801                 CODECHAL_DECODE_CHK_STATUS(static_cast<CodechalHwInterfaceG12*>(pScalabilityState->pHwInterface)->SendCondBbEndCmd(
802                     &pScalabilityState->resFEStatusBuffer,
803                     CODECHAL_OFFSETOF(CODECHAL_DECODE_SCALABILITY_FE_CABAC_STREAMOUT_BUFF_SIZE, dwCabacStreamoutBuffSize),
804                     pScalabilityState->dwCABACSyntaxStreamOutBufferSize,
805                     true,
806                     pScalabilityState->bIsEnableEndCurrentBatchBuffLevel,
807                     mhw_mi_g12_X::MI_CONDITIONAL_BATCH_BUFFER_END_CMD::COMPARE_OPERATION_MADLESSTHANIDD,
808                     pCmdBufferInUse));
809                 CODECHAL_DECODE_NORMALMESSAGE("pScalabilityState->bIsEnableEndCurrentBatchBuffLevel: %s\n", "true");
810             }
811             else
812             {
813                 // Condidtional BB END for streamout buffer writing over allocated size
814                 CODECHAL_DECODE_CHK_STATUS(pScalabilityState->pHwInterface->SendCondBbEndCmd(
815                     &pScalabilityState->resFEStatusBuffer,
816                     CODECHAL_OFFSETOF(CODECHAL_DECODE_SCALABILITY_FE_STATUS, dwCarryFlagOfReportedSizeMinusAllocSize),
817                     0,
818                     true,
819                     pCmdBufferInUse));
820             }
821         }
822     }
823 
824 finish:
825     return eStatus;
826 }
827 
CodecHalDecodeScalability_ReadCSEngineIDReg_G12(PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityStateBase,CodechalDecodeStatusBuffer * pDecodeStatusBuf,PMOS_COMMAND_BUFFER pCmdBufferInUse)828 MOS_STATUS CodecHalDecodeScalability_ReadCSEngineIDReg_G12(
829     PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityStateBase,
830     CodechalDecodeStatusBuffer        *pDecodeStatusBuf,
831     PMOS_COMMAND_BUFFER                pCmdBufferInUse)
832 {
833     MHW_MI_STORE_REGISTER_MEM_PARAMS  StoreRegParams;
834     MhwMiInterface                    *pMiInterface;
835     MhwVdboxMfxInterface              *vdboxMfxInterface;
836     MmioRegistersHcp                  *pMmioRegisters;
837     uint8_t                           ucPhaseIndex;
838     uint8_t                           hcpDecMaxPhaseNum;
839     uint32_t                          dwOffset, dwCurrIndex, dwPreIndex;
840     MOS_STATUS                        eStatus = MOS_STATUS_SUCCESS;
841 
842     CODECHAL_DECODE_FUNCTION_ENTER;
843 
844     PCODECHAL_DECODE_SCALABILITY_STATE_G12 pScalabilityState = static_cast<PCODECHAL_DECODE_SCALABILITY_STATE_G12>(pScalabilityStateBase);
845 
846     CODECHAL_DECODE_CHK_NULL(pDecodeStatusBuf);
847     CODECHAL_DECODE_CHK_NULL(pScalabilityStateBase);
848     CODECHAL_DECODE_CHK_NULL(pScalabilityStateBase->pHwInterface);
849     CODECHAL_DECODE_CHK_NULL(pScalabilityStateBase->pHwInterface->GetMiInterface());
850 
851     pMiInterface = pScalabilityStateBase->pHwInterface->GetMiInterface();
852     pMmioRegisters = pScalabilityStateBase->pHwInterface->GetHcpInterface()->GetMmioRegisters(MHW_VDBOX_NODE_1); //relative mmio addressing.
853 
854     vdboxMfxInterface = pScalabilityStateBase->pHwInterface->GetMfxInterface();
855     CODECHAL_DECODE_CHK_NULL(vdboxMfxInterface);
856     hcpDecMaxPhaseNum = vdboxMfxInterface->GetNumVdbox();
857 
858     if (pScalabilityState->HcpDecPhase == CODECHAL_HCP_DECODE_PHASE_REAL_TILE)
859     {
860         ucPhaseIndex = pScalabilityState->u8RtCurPipe;
861         dwCurrIndex = pDecodeStatusBuf->m_currIndex;
862     }
863     else
864     {
865         ucPhaseIndex = (pScalabilityState->HcpDecPhase < CODECHAL_HCP_DECODE_PHASE_FE) ?
866             0 : (pScalabilityState->HcpDecPhase - CODECHAL_HCP_DECODE_PHASE_FE);
867 
868         if (ucPhaseIndex > hcpDecMaxPhaseNum)
869         {
870             eStatus = MOS_STATUS_INVALID_PARAMETER;
871             CODECHAL_DECODE_ASSERTMESSAGE("Invalid HCP decode phase!");
872             goto finish;
873         }
874 
875         if (CodecHalDecodeScalabilityIsScalableMode(pScalabilityState) &&
876             pScalabilityState->HcpDecPhase > CODECHAL_HCP_DECODE_PHASE_BE0)
877         {
878             if (pDecodeStatusBuf->m_currIndex == 0)
879             {
880                 dwPreIndex = CODECHAL_DECODE_STATUS_NUM - 1;
881             }
882             else
883             {
884                 dwPreIndex = pDecodeStatusBuf->m_currIndex - 1;
885             }
886         }
887 
888         dwCurrIndex = (CodecHalDecodeScalabilityIsScalableMode(pScalabilityState) &&
889             pScalabilityState->HcpDecPhase > CODECHAL_HCP_DECODE_PHASE_BE0) ?
890             dwPreIndex : pDecodeStatusBuf->m_currIndex;
891     }
892 
893     dwOffset = (dwCurrIndex * sizeof(CodechalDecodeStatus)) +
894         pDecodeStatusBuf->m_csEngineIdOffset + sizeof(uint32_t)* ucPhaseIndex +
895         sizeof(uint32_t) * 2;
896 
897     StoreRegParams.presStoreBuffer = &pDecodeStatusBuf->m_statusBuffer;
898     StoreRegParams.dwOffset = dwOffset;
899     StoreRegParams.dwRegister = pMmioRegisters->csEngineIdOffset;
900     CODECHAL_DECODE_CHK_STATUS(pMiInterface->AddMiStoreRegisterMemCmd(pCmdBufferInUse, &StoreRegParams));
901 
902 finish:
903     return eStatus;
904 }
905 
CodecHalDecodeScalability_InitializeState_G12(CodechalDecode * pDecoder,PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityStateBase,CodechalHwInterface * hwInterface,bool bShortFormat,CodechalSetting * settings)906 MOS_STATUS CodecHalDecodeScalability_InitializeState_G12(
907     CodechalDecode                     *pDecoder,
908     PCODECHAL_DECODE_SCALABILITY_STATE  pScalabilityStateBase,
909     CodechalHwInterface                *hwInterface,
910     bool                                bShortFormat,
911     CodechalSetting                    *settings)
912 {
913     PMOS_VIRTUALENGINE_INTERFACE   pVEInterface;
914     MOS_VIRTUALENGINE_INIT_PARAMS  VEInitParms;
915     MOS_USER_FEATURE_VALUE_DATA    UserFeatureData;
916     PMOS_INTERFACE                 osInterface;
917     MhwVdboxMfxInterface           *vdboxMfxInterface;
918     uint8_t                        vdboxNum;
919     MOS_STATUS                     eStatus = MOS_STATUS_SUCCESS;
920 
921     CODECHAL_DECODE_FUNCTION_ENTER;
922 
923     PCODECHAL_DECODE_SCALABILITY_STATE_G12 pScalabilityState = static_cast<PCODECHAL_DECODE_SCALABILITY_STATE_G12>(pScalabilityStateBase);
924 
925     CODECHAL_DECODE_CHK_NULL(pDecoder);
926     CODECHAL_DECODE_CHK_NULL(pScalabilityState);
927     CODECHAL_DECODE_CHK_NULL(hwInterface);
928     osInterface = hwInterface->GetOsInterface();
929     CODECHAL_DECODE_CHK_NULL(osInterface);
930 
931     vdboxMfxInterface = hwInterface->GetMfxInterface();
932     CODECHAL_DECODE_CHK_NULL(vdboxMfxInterface);
933     vdboxNum = vdboxMfxInterface->GetNumVdbox();
934 
935     if (vdboxNum < 2
936         || !osInterface->bHcpDecScalabilityMode)
937     {
938         eStatus = MOS_STATUS_INVALID_PARAMETER;
939         CODECHAL_DECODE_ASSERTMESSAGE("not support scalability on this platform.");
940         goto finish;
941     }
942 
943     pScalabilityState->VideoContextForSP = MOS_GPU_CONTEXT_VIDEO;
944     pScalabilityState->VideoContextForMP = MOS_VE_MULTINODESCALING_SUPPORTED(osInterface) ? MOS_GPU_CONTEXT_VIDEO5 : MOS_GPU_CONTEXT_VDBOX2_VIDEO;
945     pScalabilityState->VideoContextFor3P = MOS_VE_MULTINODESCALING_SUPPORTED(osInterface) ? MOS_GPU_CONTEXT_VIDEO7 : MOS_GPU_CONTEXT_VDBOX2_VIDEO2;
946 
947     pScalabilityState->numDelay = 15;
948 
949 #if (_DEBUG || _RELEASE_INTERNAL)
950     // Reg key of the threshold for mode switch single pipe <-> 2 pipe. Using pic width value to control mode switch for now
951     MOS_ZeroMemory(&UserFeatureData, sizeof(UserFeatureData));
952     MOS_UserFeature_ReadValue_ID(
953         nullptr,
954         __MEDIA_USER_FEATURE_VALUE_HCP_DECODE_MODE_SWITCH_THRESHOLD1_ID,
955         &UserFeatureData,
956         osInterface->pOsContext);
957     pScalabilityState->dwHcpDecModeSwtichTh1Width = UserFeatureData.u32Data;
958 
959     MOS_ZeroMemory(&UserFeatureData, sizeof(UserFeatureData));
960     MOS_UserFeature_ReadValue_ID(
961         nullptr,
962         __MEDIA_USER_FEATURE_VALUE_HCP_DECODE_MODE_SWITCH_THRESHOLD2_ID,
963         &UserFeatureData,
964         osInterface->pOsContext);
965     pScalabilityState->dwHcpDecModeSwtichTh2Width = UserFeatureData.u32Data;
966 
967     // Reg key to control hevc real tile decoding
968     MOS_ZeroMemory(&UserFeatureData, sizeof(UserFeatureData));
969     MOS_UserFeature_ReadValue_ID(
970         nullptr,
971         __MEDIA_USER_FEATURE_VALUE_DISABLE_HEVC_REALTILE_DECODE_ID,
972         &UserFeatureData,
973         osInterface->pOsContext);
974     pScalabilityState->bDisableRtMode = (UserFeatureData.u32Data != 0);
975 
976     // Reg key to control hevc real tile multi-phase decoding
977     MOS_ZeroMemory(&UserFeatureData, sizeof(UserFeatureData));
978     MOS_UserFeature_ReadValue_ID(
979         nullptr,
980         __MEDIA_USER_FEATURE_VALUE_ENABLE_HEVC_REALTILE_MULTI_PHASE_DECODE_ID,
981         &UserFeatureData,
982         osInterface->pOsContext);
983     pScalabilityState->bEnableRtMultiPhase = (UserFeatureData.u32Data != 0);
984 
985     MOS_ZeroMemory(&UserFeatureData, sizeof(UserFeatureData));
986     MOS_UserFeature_ReadValue_ID(
987         nullptr,
988         __MEDIA_USER_FEATURE_VALUE_SCALABILITY_OVERRIDE_SPLIT_WIDTH_IN_MINCB,
989         &UserFeatureData,
990         osInterface->pOsContext);
991     pScalabilityState->dbgOvrdWidthInMinCb = UserFeatureData.u32Data;
992 
993     MOS_ZeroMemory(&UserFeatureData, sizeof(UserFeatureData));
994     MOS_UserFeature_ReadValue_ID(
995         nullptr,
996         __MEDIA_USER_FEATURE_VALUE_HCP_DECODE_USER_PIPE_NUM_ID,
997         &UserFeatureData,
998         osInterface->pOsContext);
999     pScalabilityState->dbgOverUserPipeNum = (uint8_t)UserFeatureData.u32Data;
1000 #endif
1001 
1002     // enable FE separate submission by default in multi-pipe mode
1003     if((vdboxNum > 2) && osInterface->phasedSubmission)
1004     {
1005         pScalabilityState->bFESeparateSubmission = true;
1006     }
1007     else if ((vdboxNum > 2)
1008 #if (_DEBUG || _RELEASE_INTERNAL)
1009         && (((pScalabilityState->dbgOverUserPipeNum >= 3)
1010         && (pScalabilityState->dbgOverUserPipeNum <= vdboxNum)))
1011 #endif
1012         )
1013     {
1014         pScalabilityState->bFESeparateSubmission = true;
1015     }
1016     else
1017     {
1018         pScalabilityState->bFESeparateSubmission = false;
1019     }
1020 
1021     if(osInterface->bGucSubmission)
1022     {
1023         pScalabilityState->bFESeparateSubmission = false;
1024     }
1025 
1026 #if (_DEBUG || _RELEASE_INTERNAL)
1027     if (osInterface->bEnableDbgOvrdInVE)
1028     {
1029         //if DbgOverride is enabled, FE separate submission is not supported
1030         pScalabilityState->bFESeparateSubmission = false;
1031     }
1032 #endif
1033 
1034     pScalabilityState->bFESeparateSubmissionVT = pScalabilityState->bFESeparateSubmission;
1035 
1036     if (pScalabilityState->bFESeparateSubmission)
1037     {
1038         MOS_GPU_CONTEXT         GpuContext = MOS_VE_CTXBASEDSCHEDULING_SUPPORTED(osInterface) ? MOS_GPU_CONTEXT_VIDEO : MOS_GPU_CONTEXT_VIDEO4;
1039         GpuContext                         = MOS_VE_MULTINODESCALING_SUPPORTED(osInterface) ? MOS_GPU_CONTEXT_VIDEO4 : GpuContext;
1040 
1041         MOS_GPUCTX_CREATOPTIONS_ENHANCED createOpts;
1042         createOpts.UsingSFC = settings->sfcInUseHinted && settings->downsamplingHinted
1043                               && (MEDIA_IS_SKU(hwInterface->GetSkuTable(), FtrSFCPipe)
1044                               && !MEDIA_IS_SKU(hwInterface->GetSkuTable(), FtrDisableVDBox2SFC));
1045         CODECHAL_DECODE_CHK_STATUS(osInterface->pfnCreateGpuContext(
1046               osInterface,
1047               GpuContext,
1048               MOS_GPU_NODE_VIDEO,
1049               &createOpts));
1050 
1051         pScalabilityState->VideoContextForFE = GpuContext;
1052     }
1053 
1054     pScalabilityState->Standard = pDecoder->GetStandard();
1055     pScalabilityState->VideoContext = pDecoder->GetVideoContext();
1056     pScalabilityState->bShortFormatInUse = bShortFormat;
1057     pScalabilityState->ucNumVdbox = vdboxNum;
1058     pScalabilityState->pHwInterface = hwInterface;
1059 
1060     //virtual engine init with scalability
1061     MOS_ZeroMemory(&VEInitParms, sizeof(VEInitParms));
1062     VEInitParms.bScalabilitySupported = true;
1063     VEInitParms.bFESeparateSubmit = pScalabilityState->bFESeparateSubmission;
1064     VEInitParms.ucMaxNumPipesInUse = CodecHalDecodeMaxNumPipesInUseG12(vdboxNum);
1065     VEInitParms.ucNumOfSdryCmdBufSets = CODECHAL_SCALABILITY_DECODE_SECONDARY_CMDBUFSET_NUM;
1066     VEInitParms.ucMaxNumOfSdryCmdBufInOneFrame = pScalabilityState->bFESeparateSubmission ? VEInitParms.ucMaxNumPipesInUse : (VEInitParms.ucMaxNumPipesInUse + 1);
1067     CODECHAL_DECODE_CHK_STATUS(Mos_VirtualEngineInterface_Initialize(osInterface, &VEInitParms));
1068     pScalabilityState->pVEInterface = pVEInterface = osInterface->pVEInterf;
1069 
1070     if (pVEInterface->pfnVEGetHintParams)
1071     {
1072         CODECHAL_DECODE_CHK_STATUS(pVEInterface->pfnVEGetHintParams(pVEInterface, true, &pScalabilityState->pScalHintParms));
1073     }
1074     if (pVEInterface->pfnVEGetHintParams)
1075     {
1076         CODECHAL_DECODE_CHK_STATUS(pVEInterface->pfnVEGetHintParams(pVEInterface, false, &pScalabilityState->pSingleHintParms));
1077     }
1078 
1079 #if (_DEBUG || _RELEASE_INTERNAL)
1080     MOS_ZeroMemory(&UserFeatureData, sizeof(UserFeatureData));
1081     MOS_UserFeature_ReadValue_ID(
1082         nullptr,
1083         __MEDIA_USER_FEATURE_VALUE_HCP_DECODE_ALWAYS_FRAME_SPLIT_ID,
1084         &UserFeatureData,
1085         osInterface->pOsContext);
1086     pScalabilityState->bAlwaysFrameSplit = UserFeatureData.u32Data ? true : false;
1087 #endif
1088 
1089     pScalabilityState->bIsEvenSplit = true;
1090 
1091     pScalabilityState->bIsEnableEndCurrentBatchBuffLevel = MEDIA_IS_SKU(hwInterface->GetSkuTable(), FtrConditionalBatchBuffEnd);
1092 
1093     if (pDecoder->GetStandard() == CODECHAL_HEVC)
1094     {
1095         pScalabilityState->pfnGetHcpBufferSize = GetHevcBufferSize;
1096         pScalabilityState->pfnIsHcpBufferReallocNeeded = IsHevcBufferReallocNeeded;
1097     }
1098     else if (pDecoder->GetStandard() == CODECHAL_VP9)
1099     {
1100         pScalabilityState->pfnGetHcpBufferSize = GetVp9BufferSize;
1101         pScalabilityState->pfnIsHcpBufferReallocNeeded = IsVp9BufferReallocNeeded;
1102     }
1103     else
1104     {
1105         eStatus = MOS_STATUS_INVALID_PARAMETER;
1106         CODECHAL_DECODE_ASSERTMESSAGE("unsupported decode format for scalability mode.");
1107         goto finish;
1108     }
1109 
1110     pScalabilityState->bToggleCABACStreamOutBuffer = false;
1111     pScalabilityState->pfnDecidePipeNum = CodecHalDecodeScalability_DecidePipeNum_G12;
1112     pScalabilityState->pfnMapPipeNumToLRCACount = CodechalDecodeScalability_MapPipeNumToLRCACount_G12;
1113 #if (_DEBUG || _RELEASE_INTERNAL)
1114     pScalabilityState->pfnDebugOvrdDecidePipeNum = CodechalDecodeScalability_DebugOvrdDecidePipeNum_G12;
1115 #endif
1116 
1117     pScalabilityState->sliceStateCLs = CODECHAL_SCALABILITY_SLICE_STATE_CACHELINES_PER_SLICE_TGL;
1118     CODECHAL_DECODE_CHK_STATUS(CodecHalDecodeScalability_AllocateResources_FixedSizes_G12(pScalabilityState));
1119 
1120 finish:
1121     return eStatus;
1122 }
1123 
CodecHalDecodeScalability_AdvanceRealTilePass(PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityStateBase)1124 MOS_STATUS CodecHalDecodeScalability_AdvanceRealTilePass(
1125     PCODECHAL_DECODE_SCALABILITY_STATE  pScalabilityStateBase)
1126 {
1127     auto eStatus = MOS_STATUS_SUCCESS;
1128 
1129     PCODECHAL_DECODE_SCALABILITY_STATE_G12 pScalabilityState = static_cast<PCODECHAL_DECODE_SCALABILITY_STATE_G12>(pScalabilityStateBase);
1130 
1131     CODECHAL_DECODE_CHK_NULL_RETURN(pScalabilityStateBase);
1132     CODECHAL_DECODE_ASSERT(pScalabilityState->bIsRtMode);
1133     CODECHAL_DECODE_ASSERT(pScalabilityState->u8RtCurPhase < pScalabilityState->u8RtPhaseNum);
1134 
1135     pScalabilityState->u8RtCurPipe++;
1136     if (pScalabilityState->u8RtCurPipe >= pScalabilityState->ucScalablePipeNum)
1137     {
1138         pScalabilityState->u8RtCurPipe = 0;
1139         pScalabilityState->u8RtCurPhase++;
1140     }
1141 
1142     return eStatus;
1143 }
1144 
CodecHalDecodeScalability_GetCurrentRealTileColumnId(PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityStateBase,uint8_t & col)1145 MOS_STATUS CodecHalDecodeScalability_GetCurrentRealTileColumnId(
1146     PCODECHAL_DECODE_SCALABILITY_STATE  pScalabilityStateBase,
1147     uint8_t                             &col)
1148 {
1149     auto eStatus = MOS_STATUS_SUCCESS;
1150 
1151     PCODECHAL_DECODE_SCALABILITY_STATE_G12 pScalabilityState = static_cast<PCODECHAL_DECODE_SCALABILITY_STATE_G12>(pScalabilityStateBase);
1152 
1153     CODECHAL_DECODE_CHK_NULL_RETURN(pScalabilityStateBase);
1154 
1155     col = pScalabilityState->u8RtCurPipe + pScalabilityState->u8RtCurPhase * pScalabilityState->ucScalablePipeNum;
1156     return eStatus;
1157 }
1158 
CodecHalDecodeScalability_SetSfcState(PCODECHAL_DECODE_SCALABILITY_STATE scalabilityStateBase,void * picParams,CodecRectangle * srcRegion,CodecRectangle * dstRegion,PCODECHAL_DECODE_SFC_SCALABILITY_PARAMS sfcScalabilityParams)1159 MOS_STATUS CodecHalDecodeScalability_SetSfcState(
1160     PCODECHAL_DECODE_SCALABILITY_STATE          scalabilityStateBase,
1161     void                                       *picParams,
1162     CodecRectangle                             *srcRegion,
1163     CodecRectangle                             *dstRegion,
1164     PCODECHAL_DECODE_SFC_SCALABILITY_PARAMS     sfcScalabilityParams)
1165 {
1166     MOS_STATUS  eStatus = MOS_STATUS_SUCCESS;
1167     uint32_t    minCbSize, maxCbSize, widthInPixel, widthInMaxCb;
1168     uint32_t    srcStartX = 0, srcEndX = 0;
1169     uint32_t    engMode, tileType;
1170     uint32_t    tileColumnIndex = 0;
1171     uint32_t    tileColumnCount = 0;
1172     bool        isInput444;
1173     uint32_t    ildbXOffset;
1174     uint64_t    oneBySf;
1175     double      xLandingPoint;
1176     uint32_t    srcEndXTemp;
1177     uint32_t    xOffset;
1178     uint32_t    tileEndX;
1179     uint32_t    dstStartX, dstEndX;
1180 
1181     PCODECHAL_DECODE_SCALABILITY_STATE_G12 scalabilityState = static_cast<PCODECHAL_DECODE_SCALABILITY_STATE_G12>(scalabilityStateBase);
1182 
1183     CODECHAL_DECODE_CHK_NULL_RETURN(scalabilityStateBase);
1184     CODECHAL_DECODE_CHK_NULL_RETURN(sfcScalabilityParams);
1185     CODECHAL_DECODE_CHK_NULL_RETURN(srcRegion);
1186     CODECHAL_DECODE_CHK_NULL_RETURN(dstRegion);
1187     CODECHAL_DECODE_CHK_NULL_RETURN(picParams);
1188 
1189     if (!CodecHalDecodeScalabilityIsScalableMode(scalabilityState))
1190     {
1191         return MOS_STATUS_SUCCESS;
1192     }
1193 
1194     if (scalabilityState->Standard == CODECHAL_HEVC)
1195     {
1196         PCODEC_HEVC_PIC_PARAMS  hevcPicParams = (PCODEC_HEVC_PIC_PARAMS)picParams;
1197 
1198         minCbSize = 1 << (hevcPicParams->log2_min_luma_coding_block_size_minus3 + 3);
1199         maxCbSize = (minCbSize << hevcPicParams->log2_diff_max_min_luma_coding_block_size);
1200         widthInPixel = hevcPicParams->PicWidthInMinCbsY * minCbSize;
1201         widthInMaxCb = MOS_ROUNDUP_DIVIDE(widthInPixel, maxCbSize);
1202         isInput444 = (hevcPicParams->chroma_format_idc == HCP_CHROMA_FORMAT_YUV444);
1203     }
1204     else if (scalabilityState->Standard == CODECHAL_VP9)
1205     {
1206         PCODEC_VP9_PIC_PARAMS vp9PicParams = (PCODEC_VP9_PIC_PARAMS)picParams;
1207 
1208         minCbSize = CODEC_VP9_MIN_BLOCK_WIDTH;
1209         maxCbSize = CODEC_VP9_SUPER_BLOCK_WIDTH;
1210         widthInPixel = vp9PicParams->FrameWidthMinus1 + 1;
1211         widthInMaxCb = MOS_ROUNDUP_DIVIDE(widthInPixel, maxCbSize);
1212         isInput444 = (vp9PicParams->subsampling_x == 0 && vp9PicParams->subsampling_y == 0);
1213     }
1214     else
1215     {
1216         eStatus = MOS_STATUS_INVALID_PARAMETER;
1217         CODECHAL_DECODE_ASSERTMESSAGE("invalid codec type, only HEVC/VP9 are supported in scalability mode.");
1218         return eStatus;
1219     }
1220 
1221     if (scalabilityState->bIsRtMode)
1222     {
1223         PCODEC_HEVC_PIC_PARAMS  hevcPicParams = (PCODEC_HEVC_PIC_PARAMS)picParams;
1224         uint8_t col = scalabilityState->u8RtCurPipe + scalabilityState->u8RtCurPhase * scalabilityState->ucScalablePipeNum;
1225 
1226         if (scalabilityState->u8RtCurPipe == 0)
1227         {
1228             engMode = 1;
1229         }
1230         else if (scalabilityState->u8RtCurPipe == scalabilityState->ucScalablePipeNum - 1)
1231         {
1232             engMode = 2;
1233         }
1234         else
1235         {
1236             engMode = 3;
1237         }
1238 
1239         if (hevcPicParams->uniform_spacing_flag == 1)
1240         {
1241             srcStartX = (col * widthInMaxCb) / (hevcPicParams->num_tile_columns_minus1 + 1) * maxCbSize;
1242             srcEndX = ((col + 1) * widthInMaxCb) / (hevcPicParams->num_tile_columns_minus1 + 1) * maxCbSize - 1;
1243         }
1244         else
1245         {
1246             for (uint8_t i = 0; i < col; i++)
1247             {
1248                 srcStartX += (hevcPicParams->column_width_minus1[i] + 1) * maxCbSize;
1249             }
1250             if (col == hevcPicParams->num_tile_columns_minus1)
1251             {
1252                 srcEndX = srcRegion->m_x + srcRegion->m_width - 1;
1253             }
1254             else
1255             {
1256                 srcEndX = srcStartX + (hevcPicParams->column_width_minus1[col] + 1) * maxCbSize - 1;
1257             }
1258         }
1259 
1260         tileType = 0;
1261         tileColumnIndex = col;
1262         tileColumnCount = hevcPicParams->num_tile_columns_minus1 + 1;
1263     }
1264     else if (CodecHalDecodeScalabilityIsBEPhaseG12(scalabilityState))
1265     {
1266         uint8_t pipeIndex = scalabilityState->HcpDecPhase - CODECHAL_HCP_DECODE_PHASE_BE0;
1267 
1268         if (pipeIndex == 0)
1269         {
1270             engMode = 1;
1271         }
1272         else if (pipeIndex == scalabilityState->ucScalablePipeNum - 1)
1273         {
1274             engMode = 2;
1275         }
1276         else
1277         {
1278             engMode = 3;
1279         }
1280 
1281         srcStartX = pipeIndex * widthInMaxCb / scalabilityState->ucScalablePipeNum;
1282         srcStartX *= maxCbSize;
1283         if (pipeIndex == scalabilityState->ucScalablePipeNum - 1)
1284         {
1285             srcEndX = srcRegion->m_x + srcRegion->m_width - 1;
1286         }
1287         else
1288         {
1289             srcEndX = (pipeIndex + 1) * widthInMaxCb / scalabilityState->ucScalablePipeNum;
1290             srcEndX = srcEndX * maxCbSize - 1;
1291         }
1292 #if (_DEBUG || _RELEASE_INTERNAL)
1293         if (scalabilityState->dbgOvrdWidthInMinCb && scalabilityState->ucScalablePipeNum == 2)
1294         {
1295             if (pipeIndex == 1)
1296             {
1297                 srcStartX = scalabilityState->dbgOvrdWidthInMinCb * minCbSize;
1298                 srcEndX = srcRegion->m_x + srcRegion->m_width - 1;
1299             }
1300             else
1301             {
1302                 srcStartX = 0;
1303                 srcEndX = scalabilityState->dbgOvrdWidthInMinCb * minCbSize - 1;
1304             }
1305         }
1306 #endif
1307 
1308         tileType = 1;
1309         tileColumnIndex = pipeIndex;
1310         tileColumnCount = scalabilityState->ucScalablePipeNum;
1311     }
1312     else
1313     {
1314         engMode = 0;
1315         tileType = 0;
1316         srcStartX = 0;
1317         srcEndX = srcRegion->m_x + srcRegion->m_width - 1;
1318     }
1319 
1320     // Clamp srcStartX, srcEndX into source region
1321     if (srcStartX < srcRegion->m_x)
1322         srcStartX = srcRegion->m_x;
1323     if (srcEndX > srcRegion->m_x + srcRegion->m_width - 1)
1324         srcEndX = srcRegion->m_x + srcRegion->m_width - 1;
1325 
1326     if (tileColumnIndex == 0)
1327     {
1328         scalabilityState->fistValidTileIndex = 0;
1329         scalabilityState->lastValidTileIndex = tileColumnCount - 1;
1330         scalabilityState->dstXLandingCount = 0;
1331     }
1332 
1333     ildbXOffset = (scalabilityState->Standard == CODECHAL_HEVC) ? 5 : 8;  // 1 : HEVC; 0 : VP9
1334     oneBySf = (uint64_t)((double)((uint64_t)(srcRegion->m_width) * 524288 / (dstRegion->m_width)));
1335 
1336     //------------------ start ildb offset correction -----------------------------//
1337     srcEndXTemp = srcEndX - ildbXOffset;
1338 
1339     //---------------------- destination startX determination logic ---------------//
1340     if ((srcRegion->m_x + srcRegion->m_width - 1) <= srcEndXTemp)
1341     {
1342         xOffset = 0;
1343         tileEndX = (srcRegion->m_x + srcRegion->m_width);
1344     }
1345     else
1346     {
1347         xOffset = isInput444 ? 3 : (scalabilityState->Standard == CODECHAL_HEVC) ? 8 : 11;
1348         tileEndX = srcEndXTemp;
1349     }
1350 
1351     while (true)
1352     {
1353         if (srcEndXTemp - srcRegion->m_x < (xOffset + 1))
1354         {
1355             dstEndX = 0;
1356             break;
1357         }
1358         if (scalabilityState->dstXLandingCount == 0)
1359         {
1360             scalabilityState->fistValidTileIndex = tileColumnIndex;
1361         }
1362 
1363         // xLandingpoint = (float)(((max(0, (((float)dest_cntX * (float)one_by_sf) + Xphaseshift)) + ((float)1 << (one_by sf_fraction_precision - beta_precision - 1))) / 524288) + SourceRegionHorizontalOffset)
1364         //
1365         {
1366             const uint32_t one_by_sf_fraction_precision = 19;
1367             const uint32_t beta_precision = 5;
1368             uint32_t xPhaseShift = MOS_CLAMP_MIN_MAX(MOS_F_ROUND((((double)srcRegion->m_width / dstRegion->m_width - 1.0) / 2.0) * 524288.0F), -(1 << (4 + 19)), ((1 << (4 + 19)) - 1));
1369 
1370             double tempDestCntx = (((double)scalabilityState->dstXLandingCount * (double)oneBySf) + xPhaseShift);
1371             if (tempDestCntx < 0)
1372             {
1373                 tempDestCntx = 0;
1374             }
1375             xLandingPoint = (double)(((tempDestCntx + ((double)(1 << (one_by_sf_fraction_precision - beta_precision - 1)))) / 524288) + srcRegion->m_x);
1376         }
1377 
1378         if (xLandingPoint >= (double)(tileEndX - xOffset))
1379         {
1380             dstEndX = scalabilityState->dstXLandingCount - 1;
1381             break;
1382         }
1383         else
1384         {
1385             scalabilityState->dstXLandingCount++;
1386         }
1387     }
1388 
1389     if (xOffset == 0)
1390     {
1391         scalabilityState->lastValidTileIndex = tileColumnIndex;
1392     }
1393 
1394     // Last column end at destination region right border.
1395     if (tileColumnIndex == scalabilityState->lastValidTileIndex)
1396     {
1397         dstEndX = dstRegion->m_x + dstRegion->m_width - 1;
1398     }
1399 
1400     if (tileColumnIndex <= scalabilityState->fistValidTileIndex)
1401         dstStartX = 0;
1402     else if (tileColumnIndex <= scalabilityState->lastValidTileIndex)
1403     {
1404         dstStartX = scalabilityState->lastDstEndX + 1;
1405     }
1406     else
1407     {
1408         dstStartX = 0;
1409         dstEndX = 0;
1410     }
1411     scalabilityState->lastDstEndX = dstEndX;
1412 
1413     sfcScalabilityParams->engineMode = engMode;
1414     sfcScalabilityParams->tileType = tileType;
1415     sfcScalabilityParams->srcStartX = srcStartX;
1416     sfcScalabilityParams->srcEndX = srcEndX;
1417     sfcScalabilityParams->dstStartX = dstStartX;
1418     sfcScalabilityParams->dstEndX = dstEndX;
1419 
1420     return eStatus;
1421 }
1422 
CodecHalDecodeScalabilityIsToSubmitCmdBuffer_G12(PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityStateBase)1423 bool CodecHalDecodeScalabilityIsToSubmitCmdBuffer_G12(
1424     PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityStateBase)
1425 {
1426     PCODECHAL_DECODE_SCALABILITY_STATE_G12 pScalabilityState = static_cast<PCODECHAL_DECODE_SCALABILITY_STATE_G12>(pScalabilityStateBase);
1427 
1428     if (pScalabilityState == nullptr)
1429     {
1430         return false;
1431     }
1432     else
1433     {
1434         return (CodecHalDecodeScalabilityIsFinalBEPhaseG12(pScalabilityState) ||
1435             (pScalabilityState->HcpDecPhase == CODECHAL_HCP_DECODE_PHASE_FE && pScalabilityState->bFESeparateSubmission) ||
1436             CodecHalDecodeScalabilityIsLastRealTilePass(pScalabilityState));
1437     }
1438 }
1439 
CodecHalDecodeScalability_AllocateResources_VariableSizes_G12(PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityState,PMHW_VDBOX_HCP_BUFFER_SIZE_PARAMS pHcpBufSizeParam,PMHW_VDBOX_HCP_BUFFER_REALLOC_PARAMS pAllocParam)1440 MOS_STATUS CodecHalDecodeScalability_AllocateResources_VariableSizes_G12(
1441     PCODECHAL_DECODE_SCALABILITY_STATE   pScalabilityState,
1442     PMHW_VDBOX_HCP_BUFFER_SIZE_PARAMS    pHcpBufSizeParam,
1443     PMHW_VDBOX_HCP_BUFFER_REALLOC_PARAMS pAllocParam)
1444 {
1445     MOS_ALLOC_GFXRES_PARAMS AllocParamsForBufferLinear;
1446     PMOS_INTERFACE          pOsInterface;
1447     MOS_STATUS              eStatus = MOS_STATUS_SUCCESS;
1448 
1449     CODECHAL_DECODE_FUNCTION_ENTER;
1450 
1451     CODECHAL_DECODE_CHK_NULL_RETURN(pScalabilityState);
1452     CODECHAL_DECODE_CHK_NULL_RETURN(pScalabilityState->pHwInterface);
1453     CODECHAL_DECODE_CHK_NULL_RETURN(pScalabilityState->pHwInterface->GetOsInterface());
1454     CODECHAL_DECODE_CHK_NULL_RETURN(pHcpBufSizeParam);
1455     CODECHAL_DECODE_CHK_NULL_RETURN(pAllocParam);
1456     pOsInterface = pScalabilityState->pHwInterface->GetOsInterface();
1457 
1458     CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalDecodeScalability_AllocateResources_VariableSizes(pScalabilityState, pHcpBufSizeParam, pAllocParam));
1459 
1460     // for multi-pipe scalability mode
1461     if (pScalabilityState->ucNumVdbox > 2)
1462     {
1463         if (pScalabilityState->bFESeparateSubmission && pOsInterface->bGucSubmission)
1464         {
1465             for (int i = 1; i < CODECHAL_HCP_STREAMOUT_BUFFER_MAX_NUM; i++)
1466             {
1467                 CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalDecodeScalability_AllocateCABACStreamOutBuffer(pScalabilityState,
1468                     pHcpBufSizeParam,
1469                     pAllocParam,
1470                     &pScalabilityState->resCABACSyntaxStreamOutBuffer[i]));
1471             }
1472 
1473             pScalabilityState->presCABACStreamOutBuffer =
1474                 pScalabilityState->bToggleCABACStreamOutBuffer ? &pScalabilityState->resCABACSyntaxStreamOutBuffer[1] : &pScalabilityState->resCABACSyntaxStreamOutBuffer[0];
1475 
1476             pScalabilityState->bToggleCABACStreamOutBuffer = !pScalabilityState->bToggleCABACStreamOutBuffer;
1477         }
1478     }
1479 
1480     return eStatus;
1481 }
1482 
CodecHalDecodeScalability_AllocateResources_FixedSizes_G12(PCODECHAL_DECODE_SCALABILITY_STATE_G12 pScalabilityState)1483 MOS_STATUS CodecHalDecodeScalability_AllocateResources_FixedSizes_G12(
1484     PCODECHAL_DECODE_SCALABILITY_STATE_G12 pScalabilityState)
1485 {
1486     PMOS_INTERFACE          pOsInterface;
1487     MOS_ALLOC_GFXRES_PARAMS AllocParamsForBufferLinear;
1488     MOS_LOCK_PARAMS         LockFlagsWriteOnly;
1489     uint8_t *               pData = nullptr;
1490     MOS_STATUS              eStatus = MOS_STATUS_SUCCESS;
1491 
1492     CODECHAL_DECODE_FUNCTION_ENTER;
1493 
1494     CODECHAL_DECODE_CHK_NULL_RETURN(pScalabilityState);
1495     CODECHAL_DECODE_CHK_NULL_RETURN(pScalabilityState->pHwInterface);
1496     CODECHAL_DECODE_CHK_NULL_RETURN(pScalabilityState->pHwInterface->GetOsInterface());
1497 
1498     pOsInterface = pScalabilityState->pHwInterface->GetOsInterface();
1499 
1500     MOS_ZeroMemory(&LockFlagsWriteOnly, sizeof(MOS_LOCK_PARAMS));
1501     LockFlagsWriteOnly.WriteOnly = 1;
1502 
1503     // initiate allocation paramters
1504     MOS_ZeroMemory(&AllocParamsForBufferLinear, sizeof(MOS_ALLOC_GFXRES_PARAMS));
1505     AllocParamsForBufferLinear.Type     = MOS_GFXRES_BUFFER;
1506     AllocParamsForBufferLinear.TileType = MOS_TILE_LINEAR;
1507     AllocParamsForBufferLinear.Format   = Format_Buffer;
1508 
1509     CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalDecodeScalability_AllocateResources_FixedSizes(pScalabilityState));
1510 
1511     //Allocate additional BEs Semaphore memory for two pipes to avoid race condition
1512     if (!pOsInterface->phasedSubmission)
1513     {
1514         AllocParamsForBufferLinear.pBufName = "AdditionalBESemaphoreMemory";
1515         AllocParamsForBufferLinear.dwBytes  = sizeof(uint32_t);
1516         for (uint32_t i = 0; i < 2; i++)
1517         {
1518             eStatus = (MOS_STATUS)pOsInterface->pfnAllocateResource(
1519                 pOsInterface,
1520                 &AllocParamsForBufferLinear,
1521                 &pScalabilityState->resSemaMemBEsAdditional[i]);
1522 
1523             if (eStatus != MOS_STATUS_SUCCESS)
1524             {
1525                 CODECHAL_DECODE_ASSERTMESSAGE("Failed to allocate Additional BE Semaphore memory.");
1526                 return eStatus;
1527             }
1528 
1529             pData = (uint8_t *)pOsInterface->pfnLockResource(
1530                 pOsInterface,
1531                 &pScalabilityState->resSemaMemBEsAdditional[i],
1532                 &LockFlagsWriteOnly);
1533 
1534             CODECHAL_DECODE_CHK_NULL_RETURN(pData);
1535 
1536             MOS_ZeroMemory(pData, sizeof(uint32_t));
1537 
1538             CODECHAL_DECODE_CHK_STATUS_RETURN(pOsInterface->pfnUnlockResource(
1539                 pOsInterface,
1540                 &pScalabilityState->resSemaMemBEsAdditional[i]));
1541         }
1542     }
1543 
1544     return eStatus;
1545 }
1546 
CodecHalDecodeScalability_Destroy_G12(PCODECHAL_DECODE_SCALABILITY_STATE_G12 pScalabilityState)1547 void CodecHalDecodeScalability_Destroy_G12(
1548     PCODECHAL_DECODE_SCALABILITY_STATE_G12 pScalabilityState)
1549 {
1550     PMOS_INTERFACE pOsInterface;
1551 
1552     CODECHAL_DECODE_FUNCTION_ENTER;
1553 
1554     CODECHAL_DECODE_CHK_NULL_NO_STATUS_RETURN(pScalabilityState);
1555     CODECHAL_DECODE_CHK_NULL_NO_STATUS_RETURN(pScalabilityState->pHwInterface);
1556     CODECHAL_DECODE_CHK_NULL_NO_STATUS_RETURN(pScalabilityState->pHwInterface->GetOsInterface());
1557     pOsInterface = pScalabilityState->pHwInterface->GetOsInterface();
1558 
1559     CodecHalDecodeScalability_Destroy(pScalabilityState);
1560 
1561     for (int i = 0; i < 2; i++)
1562     {
1563         pOsInterface->pfnFreeResource(
1564             pOsInterface,
1565             &pScalabilityState->resSemaMemBEsAdditional[i]);
1566     }
1567 
1568     return;
1569 }
1570 
CodecHalDecodeScalability_DecidePipeNum_G12(PCODECHAL_DECODE_SCALABILITY_STATE pScalState,PCODECHAL_DECODE_SCALABILITY_INIT_PARAMS pInitParams)1571 MOS_STATUS CodecHalDecodeScalability_DecidePipeNum_G12(
1572     PCODECHAL_DECODE_SCALABILITY_STATE         pScalState,
1573     PCODECHAL_DECODE_SCALABILITY_INIT_PARAMS   pInitParams)
1574 {
1575     PMOS_VIRTUALENGINE_INTERFACE pVEInterface;
1576     MOS_STATUS                   eStatus = MOS_STATUS_SUCCESS;
1577 
1578     CODECHAL_DECODE_FUNCTION_ENTER;
1579 
1580     CODECHAL_DECODE_CHK_NULL_RETURN(pScalState);
1581     CODECHAL_DECODE_CHK_NULL_RETURN(pScalState->pVEInterface);
1582     CODECHAL_DECODE_CHK_NULL_RETURN(pInitParams);
1583     CODECHAL_DECODE_CHK_NULL_RETURN(pScalState->pHwInterface);
1584     CODECHAL_DECODE_CHK_NULL_RETURN(pScalState->pHwInterface->GetOsInterface());
1585 
1586     pVEInterface                                                     = pScalState->pVEInterface;
1587     pScalState->ucScalablePipeNum                                    = CODECHAL_DECODE_HCP_Legacy_PIPE_NUM_1;
1588     PCODECHAL_DECODE_SCALABILITY_STATE_G12       pScalStateG12        = static_cast<PCODECHAL_DECODE_SCALABILITY_STATE_G12>(pScalState);
1589     PCODECHAL_DECODE_SCALABILITY_INIT_PARAMS_G12 pInitParamsG12       = static_cast<PCODECHAL_DECODE_SCALABILITY_INIT_PARAMS_G12>(pInitParams);
1590     uint8_t                                      u8MaxTileColumn      = HEVC_NUM_MAX_TILE_COLUMN;
1591     bool                                         bCanEnableRealTile   = true;
1592     bool                                         bCanEnableScalability = !pScalState->pHwInterface->IsDisableScalability();
1593     PMOS_INTERFACE pOsInterface                                        = pScalState->pHwInterface->GetOsInterface();
1594 
1595 #if (_DEBUG || _RELEASE_INTERNAL)
1596     bCanEnableRealTile = !(static_cast<PCODECHAL_DECODE_SCALABILITY_STATE_G12>(pScalState))->bDisableRtMode;
1597     if (!pScalStateG12->bEnableRtMultiPhase)
1598         u8MaxTileColumn = 2;
1599 #endif
1600     if(!bCanEnableScalability
1601         && pOsInterface
1602         && (pOsInterface->bHcpDecScalabilityMode == MOS_SCALABILITY_ENABLE_MODE_USER_FORCE))
1603     {
1604         bCanEnableScalability = true;
1605     }
1606 
1607     bCanEnableRealTile = bCanEnableRealTile && pInitParamsG12->bIsTileEnabled && (pInitParams->u8NumTileColumns > 1) &&
1608                          (pInitParams->u8NumTileColumns <= u8MaxTileColumn) && (pInitParams->u8NumTileRows <= HEVC_NUM_MAX_TILE_ROW) &&
1609                          pInitParamsG12->bHasSubsetParams;
1610 
1611     if (pInitParams->usingSFC || !bCanEnableScalability)
1612     {
1613         return MOS_STATUS_SUCCESS;
1614     }
1615 
1616 #if (_DEBUG || _RELEASE_INTERNAL)
1617     if (pScalState->bAlwaysFrameSplit)
1618     {
1619         if (pScalState->ucNumVdbox != 1)
1620         {
1621             if (pScalState->ucNumVdbox == 2)
1622             {
1623                 pScalState->ucScalablePipeNum = CODECHAL_DECODE_HCP_SCALABLE_PIPE_NUM_2;
1624             }
1625             else
1626             {
1627                 uint8_t dbgOverUserPipeNum    = pScalStateG12->dbgOverUserPipeNum;
1628                 pScalState->ucScalablePipeNum = CODECHAL_DECODE_HCP_SCALABLE_PIPE_NUM_2;
1629                 if ((dbgOverUserPipeNum >= CODECHAL_DECODE_HCP_SCALABLE_PIPE_NUM_2) && (dbgOverUserPipeNum <= pScalState->ucNumVdbox))
1630                 {
1631                     pScalState->ucScalablePipeNum = dbgOverUserPipeNum;
1632                 }
1633             }
1634         }
1635     }
1636     else
1637 #endif
1638     {
1639         if (pScalState->ucNumVdbox != 1)
1640         {
1641             if (pScalState->ucNumVdbox == 2)
1642             {
1643                 if (pScalState->dwHcpDecModeSwtichTh1Width != 0)
1644                 {
1645                     if (pInitParams->u32PicWidthInPixel >= pScalState->dwHcpDecModeSwtichTh1Width)
1646                     {
1647                         pScalState->ucScalablePipeNum = CODECHAL_DECODE_HCP_SCALABLE_PIPE_NUM_2;
1648                     }
1649                 }
1650                 else if ((!pInitParams->usingHistogram) && ((!CodechalDecodeNonRextFormat(pInitParams->format)
1651                                     && CodechalDecodeResolutionEqualLargerThan4k(pInitParams->u32PicWidthInPixel, pInitParams->u32PicHeightInPixel))
1652                                 || (CodechalDecodeNonRextFormat(pInitParams->format)
1653                                     && CodechalDecodeResolutionEqualLargerThan5k(pInitParams->u32PicWidthInPixel, pInitParams->u32PicHeightInPixel))
1654                                 || (bCanEnableRealTile && (!pOsInterface->osCpInterface->IsCpEnabled() || pOsInterface->bCanEnableSecureRt))))
1655                 {
1656                     pScalState->ucScalablePipeNum = CODECHAL_DECODE_HCP_SCALABLE_PIPE_NUM_2;
1657                 }
1658 
1659                 if (pScalState->bIsEvenSplit == false)
1660                 {
1661                     // disable scalability for clips with width less than split condition when MMC is on
1662                     if (pInitParams->u32PicWidthInPixel <= CODEC_SCALABILITY_FIRST_TILE_WIDTH_4K)
1663                     {
1664                         pScalState->ucScalablePipeNum = CODECHAL_DECODE_HCP_Legacy_PIPE_NUM_1;
1665                     }
1666                 }
1667             }
1668             else
1669             {
1670                 pScalState->ucScalablePipeNum = CODECHAL_DECODE_HCP_Legacy_PIPE_NUM_1;
1671             }
1672         }
1673     }
1674 
1675     return eStatus;
1676 }
1677 
1678 
CodechalDecodeScalability_ConstructParmsForGpuCtxCreation_g12(PCODECHAL_DECODE_SCALABILITY_STATE pScalState,PMOS_GPUCTX_CREATOPTIONS_ENHANCED gpuCtxCreatOpts,CodechalSetting * codecHalSetting)1679 MOS_STATUS CodechalDecodeScalability_ConstructParmsForGpuCtxCreation_g12(
1680     PCODECHAL_DECODE_SCALABILITY_STATE         pScalState,
1681     PMOS_GPUCTX_CREATOPTIONS_ENHANCED          gpuCtxCreatOpts,
1682     CodechalSetting *                          codecHalSetting)
1683 {
1684     PMOS_INTERFACE                           pOsInterface;
1685     CODECHAL_DECODE_SCALABILITY_INIT_PARAMS_G12  initParams;
1686     MOS_STATUS                               eStatus = MOS_STATUS_SUCCESS;
1687 
1688     CODECHAL_DECODE_FUNCTION_ENTER;
1689 
1690     CODECHAL_DECODE_CHK_NULL_RETURN(pScalState);
1691     CODECHAL_DECODE_CHK_NULL_RETURN(pScalState->pHwInterface);
1692     CODECHAL_DECODE_CHK_NULL_RETURN(gpuCtxCreatOpts);
1693     CODECHAL_DECODE_CHK_NULL_RETURN(codecHalSetting);
1694     bool sfcInUse = codecHalSetting->sfcInUseHinted && codecHalSetting->downsamplingHinted
1695                        && (MEDIA_IS_SKU(pScalState->pHwInterface->GetSkuTable(), FtrSFCPipe)
1696                        && !MEDIA_IS_SKU(pScalState->pHwInterface->GetSkuTable(), FtrDisableVDBox2SFC));
1697     pOsInterface    = pScalState->pHwInterface->GetOsInterface();
1698     MEDIA_FEATURE_TABLE *m_skuTable = pOsInterface->pfnGetSkuTable(pOsInterface);
1699 #if (_DEBUG || _RELEASE_INTERNAL)
1700     if (pOsInterface->bEnableDbgOvrdInVE)
1701     {
1702         PMOS_VIRTUALENGINE_INTERFACE pVEInterface = pScalState->pVEInterface;
1703         CODECHAL_DECODE_CHK_NULL_RETURN(pVEInterface);
1704         gpuCtxCreatOpts->DebugOverride      = true;
1705         if (MEDIA_IS_SKU(m_skuTable, FtrSfcScalability))
1706         {
1707             gpuCtxCreatOpts->UsingSFC = false;// this param ignored when dbgoverride enabled
1708         }
1709         else
1710         {
1711             gpuCtxCreatOpts->UsingSFC = sfcInUse;  // this param ignored when dbgoverride enabled
1712         }
1713         CODECHAL_DECODE_CHK_STATUS_RETURN(pScalState->pfnDebugOvrdDecidePipeNum(pScalState));
1714 
1715         if (pOsInterface->apoMosEnabled)
1716         {
1717             CODECHAL_DECODE_CHK_NULL_RETURN(pVEInterface->veInterface);
1718             for (uint32_t i = 0; i < pVEInterface->veInterface->GetEngineCount(); i++)
1719             {
1720                 gpuCtxCreatOpts->EngineInstance[i] = pVEInterface->veInterface->GetEngineLogicId(i);
1721             }
1722         }
1723         else
1724         {
1725             for (uint32_t i = 0; i < pVEInterface->ucEngineCount; i++)
1726             {
1727                 gpuCtxCreatOpts->EngineInstance[i] = pVEInterface->EngineLogicId[i];
1728             }
1729         }
1730     }
1731     else
1732 #endif
1733     {
1734         if (MEDIA_IS_SKU(m_skuTable, FtrSfcScalability))
1735         {
1736             gpuCtxCreatOpts->UsingSFC = false;
1737         }
1738         else
1739         {
1740             gpuCtxCreatOpts->UsingSFC = sfcInUse;
1741         }
1742 
1743         MOS_ZeroMemory(&initParams, sizeof(initParams));
1744         initParams.u32PicWidthInPixel   = MOS_ALIGN_CEIL(codecHalSetting->width, 8);
1745         initParams.u32PicHeightInPixel  = MOS_ALIGN_CEIL(codecHalSetting->height, 8);
1746         if (((codecHalSetting->standard == CODECHAL_VP9) || (codecHalSetting->standard == CODECHAL_HEVC))
1747                 && (codecHalSetting->chromaFormat == HCP_CHROMA_FORMAT_YUV420))
1748         {
1749             initParams.format = Format_NV12;
1750             if (codecHalSetting->lumaChromaDepth == CODECHAL_LUMA_CHROMA_DEPTH_10_BITS)
1751             {
1752                 initParams.format = Format_P010;
1753             }
1754         }
1755         initParams.usingSFC             = sfcInUse;
1756         initParams.usingSecureDecode    = codecHalSetting->secureMode;
1757         CODECHAL_DECODE_CHK_STATUS_RETURN(pScalState->pfnDecidePipeNum(
1758             pScalState,
1759             &initParams));
1760     }
1761 
1762     CODECHAL_DECODE_CHK_STATUS_RETURN(pScalState->pfnMapPipeNumToLRCACount(
1763         pScalState,
1764         &gpuCtxCreatOpts->LRCACount));
1765 
1766     return eStatus;
1767 }
1768 
1769 
CodechalDecodeScalability_MapPipeNumToLRCACount_G12(PCODECHAL_DECODE_SCALABILITY_STATE pScalState,uint32_t * LRCACount)1770 MOS_STATUS CodechalDecodeScalability_MapPipeNumToLRCACount_G12(
1771     PCODECHAL_DECODE_SCALABILITY_STATE   pScalState,
1772     uint32_t                             *LRCACount)
1773 {
1774     MOS_STATUS    eStatus = MOS_STATUS_SUCCESS;
1775 
1776     CODECHAL_DECODE_FUNCTION_ENTER;
1777 
1778     CODECHAL_DECODE_CHK_NULL_RETURN(pScalState);
1779     CODECHAL_DECODE_CHK_NULL_RETURN(LRCACount);
1780 
1781     *LRCACount = 1; // initialzed to 1.
1782 
1783     switch (pScalState->ucScalablePipeNum)
1784     {
1785     case CODECHAL_DECODE_HCP_SCALABLE_PIPE_NUM_2:
1786         // on GT2 or debug override enabled, FE separate submission = false, FE run on the same engine of BEs;
1787         // on GT3, FE separate submission = true, scalability submission includes only BEs.
1788         *LRCACount = 2;
1789         break;
1790     case CODECHAL_DECODE_HCP_Legacy_PIPE_NUM_1:
1791         *LRCACount = 1;
1792         break;
1793     default:
1794         // in release driver bFESeparateSubmission is always false since this is on GT3 or GT4.
1795         // bFESeparateSubmission could be false if debug override enabled.
1796         if (pScalState->bFESeparateSubmission || (static_cast<PCODECHAL_DECODE_SCALABILITY_STATE_G12>(pScalState))->bIsRtMode)
1797         {
1798             *LRCACount = pScalState->ucScalablePipeNum;
1799         }
1800         else
1801         {
1802             *LRCACount = pScalState->ucScalablePipeNum + 1;
1803         }
1804     }
1805 
1806     if (*LRCACount > pScalState->ucNumVdbox)
1807     {
1808         CODECHAL_DECODE_ASSERTMESSAGE("LRCA count can not exceed vdbox number.");
1809         return MOS_STATUS_INVALID_PARAMETER;
1810     }
1811 
1812     return eStatus;
1813 }
1814 
1815 #if (_DEBUG || _RELEASE_INTERNAL)
CodechalDecodeScalability_DebugOvrdDecidePipeNum_G12(PCODECHAL_DECODE_SCALABILITY_STATE pScalState)1816 MOS_STATUS CodechalDecodeScalability_DebugOvrdDecidePipeNum_G12(
1817     PCODECHAL_DECODE_SCALABILITY_STATE         pScalState)
1818 {
1819     PMOS_VIRTUALENGINE_INTERFACE pVEInterface;
1820     MOS_STATUS                   eStatus        = MOS_STATUS_SUCCESS;
1821     PMOS_INTERFACE               pOsInterface   = nullptr;
1822     CODECHAL_DECODE_CHK_NULL_RETURN(pScalState);
1823     CODECHAL_DECODE_CHK_NULL_RETURN(pScalState->pVEInterface);
1824 
1825     pVEInterface = pScalState->pVEInterface;
1826     pOsInterface = pVEInterface->pOsInterface;
1827     CODECHAL_DECODE_CHK_NULL_RETURN(pOsInterface);
1828 
1829     if (pOsInterface->apoMosEnabled)
1830     {
1831         CODECHAL_DECODE_CHK_NULL_RETURN(pVEInterface->veInterface);
1832         auto veInterface = pVEInterface->veInterface;
1833         if (veInterface->GetEngineCount() > pScalState->ucNumVdbox)
1834         {
1835             CODECHAL_DECODE_ASSERTMESSAGE("invalid parameter settings in debug override.");
1836             return MOS_STATUS_INVALID_PARAMETER;
1837         }
1838         else if (veInterface->GetEngineCount() == 1)
1839         {
1840             pScalState->ucScalablePipeNum = CODECHAL_DECODE_HCP_Legacy_PIPE_NUM_1;
1841         }
1842         else if (veInterface->GetEngineCount() == 2)
1843         {
1844             //engine count = 2, only support FE run on the same engine as one of BE for now.
1845             pScalState->ucScalablePipeNum = CODECHAL_DECODE_HCP_SCALABLE_PIPE_NUM_2;
1846         }
1847         else
1848         {
1849             bool bEngineLogicIdValid = false;
1850             for (uint8_t i = 0; i < veInterface->GetEngineCount() - 1; i++)
1851             {
1852                 if (veInterface->GetEngineLogicId(veInterface->GetEngineCount() - 1) !=
1853                     veInterface->GetEngineLogicId(i))
1854                 {
1855                     bEngineLogicIdValid = true;
1856                 }
1857                 else
1858                 {
1859                     bEngineLogicIdValid = false;
1860                     break;
1861                 }
1862             }
1863             if (bEngineLogicIdValid)
1864             {
1865                 pScalState->ucScalablePipeNum = pScalState->ucNumVdbox - 1;
1866             }
1867         }
1868 
1869         return eStatus;
1870     }
1871 
1872     // debug override for virtual tile
1873     if (pVEInterface->ucEngineCount > pScalState->ucNumVdbox)
1874     {
1875         CODECHAL_DECODE_ASSERTMESSAGE("invalid parameter settings in debug override.");
1876         return MOS_STATUS_INVALID_PARAMETER;
1877     }
1878     else if (pVEInterface->ucEngineCount == 1)
1879     {
1880         pScalState->ucScalablePipeNum = CODECHAL_DECODE_HCP_Legacy_PIPE_NUM_1;
1881     }
1882     else if (pVEInterface->ucEngineCount == 2)
1883     {
1884         //engine count = 2, only support FE run on the same engine as one of BE for now.
1885         pScalState->ucScalablePipeNum = CODECHAL_DECODE_HCP_SCALABLE_PIPE_NUM_2;
1886     }
1887     else
1888     {
1889         bool bEngineLogicIdValid = false;
1890         for (uint8_t i = 0; i < pVEInterface->ucEngineCount - 1; i++)
1891         {
1892             if (pVEInterface->EngineLogicId[pVEInterface->ucEngineCount - 1] != pVEInterface->EngineLogicId[i])
1893             {
1894                 bEngineLogicIdValid = true;
1895             }
1896             else
1897             {
1898                 bEngineLogicIdValid = false;
1899                 break;
1900             }
1901         }
1902         if (bEngineLogicIdValid)
1903         {
1904             pScalState->ucScalablePipeNum = pScalState->ucNumVdbox - 1;
1905         }
1906     }
1907 
1908     return eStatus;
1909 }
1910 #endif
1911 
CodecHalDecodeScalability_DecPhaseToSubmissionType_G12(PCODECHAL_DECODE_SCALABILITY_STATE_G12 pScalabilityState,PMOS_COMMAND_BUFFER pCmdBuffer)1912 void CodecHalDecodeScalability_DecPhaseToSubmissionType_G12(
1913     PCODECHAL_DECODE_SCALABILITY_STATE_G12 pScalabilityState,
1914     PMOS_COMMAND_BUFFER pCmdBuffer)
1915 {
1916     switch (pScalabilityState->HcpDecPhase)
1917     {
1918         case CodechalDecode::CodechalHcpDecodePhaseLegacyS2L:
1919             //Note: no break here, S2L and FE commands put in one secondary command buffer.
1920         case CODECHAL_HCP_DECODE_PHASE_FE:
1921             pCmdBuffer->iSubmissionType = SUBMISSION_TYPE_MULTI_PIPE_ALONE;
1922             break;
1923         case CODECHAL_HCP_DECODE_PHASE_BE0:
1924             pCmdBuffer->iSubmissionType = SUBMISSION_TYPE_MULTI_PIPE_MASTER;
1925             break;
1926         case CODECHAL_HCP_DECODE_PHASE_REAL_TILE:
1927             if (pScalabilityState->u8RtCurPipe == 0)
1928             {
1929                 pCmdBuffer->iSubmissionType = SUBMISSION_TYPE_MULTI_PIPE_MASTER;
1930             }
1931             else
1932             {
1933                 pCmdBuffer->iSubmissionType = SUBMISSION_TYPE_MULTI_PIPE_SLAVE;
1934                 pCmdBuffer->iSubmissionType |= ((pScalabilityState->u8RtCurPipe - 1) << SUBMISSION_TYPE_MULTI_PIPE_SLAVE_INDEX_SHIFT);
1935             }
1936 
1937             if (!(pScalabilityState->pHwInterface->GetOsInterface()->bGucSubmission)
1938             && (pScalabilityState->u8RtCurPhase == pScalabilityState->u8RtPhaseNum - 1))
1939             {
1940                 if (pScalabilityState->u8RtCurPipe == pScalabilityState->u8RtPipeInLastPhase - 1)
1941                 {
1942                     pCmdBuffer->iSubmissionType |= SUBMISSION_TYPE_MULTI_PIPE_FLAGS_LAST_PIPE;
1943                 }
1944             }
1945             else
1946             {
1947                 if (pScalabilityState->u8RtCurPipe == pScalabilityState->ucScalablePipeNum-1)
1948                 {
1949                     pCmdBuffer->iSubmissionType |= SUBMISSION_TYPE_MULTI_PIPE_FLAGS_LAST_PIPE;
1950                 }
1951             }
1952             break;
1953         default:
1954             if((pScalabilityState->HcpDecPhase > CODECHAL_HCP_DECODE_PHASE_BE0) &&
1955                 ((pScalabilityState->HcpDecPhase - CODECHAL_HCP_DECODE_PHASE_FE) <= pScalabilityState->ucScalablePipeNum))
1956             {
1957                 pCmdBuffer->iSubmissionType = SUBMISSION_TYPE_MULTI_PIPE_SLAVE;
1958                 pCmdBuffer->iSubmissionType |= ((pScalabilityState->HcpDecPhase - CODECHAL_HCP_DECODE_PHASE_BE1) << SUBMISSION_TYPE_MULTI_PIPE_SLAVE_INDEX_SHIFT);
1959                 if ((pScalabilityState->HcpDecPhase - CODECHAL_HCP_DECODE_PHASE_FE) == pScalabilityState->ucScalablePipeNum)
1960                 {
1961                     pCmdBuffer->iSubmissionType |= SUBMISSION_TYPE_MULTI_PIPE_FLAGS_LAST_PIPE;
1962                 }
1963             }
1964             else
1965             {
1966                 pCmdBuffer->iSubmissionType = SUBMISSION_TYPE_MULTI_PIPE_ALONE;
1967             }
1968     }
1969 }
1970