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 }