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_vp9_g12.cpp
24 //! \brief    Implements the decode interface extension for Gen12 VP9.
25 //! \details  Implements all functions required by CodecHal for Gen12 VP9 decoding.
26 //!
27 
28 #include "codechal_decoder.h"
29 #include "codechal_secure_decode_interface.h"
30 #include "codechal_decode_vp9_g12.h"
31 #include "codechal_decode_sfc_vp9_g12.h"
32 #include "codechal_mmc_decode_vp9_g12.h"
33 #include "mhw_vdbox_hcp_g12_X.h"
34 #include "mhw_vdbox_mfx_g12_X.h"
35 #include "mhw_vdbox_g12_X.h"
36 #include "codechal_hw_g12_X.h"
37 #include "codechal_decode_histogram.h"
38 #include "mhw_mi_g12_X.h"
39 #include "hal_oca_interface.h"
40 
~CodechalDecodeVp9G12()41 CodechalDecodeVp9G12 ::  ~CodechalDecodeVp9G12()
42 {
43     CODECHAL_DECODE_FUNCTION_ENTER;
44 
45     if (m_sinlgePipeVeState)
46     {
47         MOS_FreeMemAndSetNull(m_sinlgePipeVeState);
48      }
49      if (m_scalabilityState)
50      {
51          CodecHalDecodeScalability_Destroy_G12(m_scalabilityState);
52          MOS_FreeMemAndSetNull(m_scalabilityState);
53      }
54      //Note: virtual engine interface destroy is done in MOS layer
55   #ifdef _DECODE_PROCESSING_SUPPORTED
56      if (m_sfcState)
57      {
58          MOS_Delete(m_sfcState);
59          m_sfcState = nullptr;
60      }
61   #endif
62 
63      if (m_histogramSurface)
64      {
65          if (!Mos_ResourceIsNull(&m_histogramSurface->OsResource))
66          {
67              m_osInterface->pfnFreeResource(
68                  m_osInterface,
69                  &m_histogramSurface->OsResource);
70          }
71          MOS_FreeMemory(m_histogramSurface);
72          m_histogramSurface = nullptr;
73      }
74 }
75 
CodechalDecodeVp9G12(CodechalHwInterface * hwInterface,CodechalDebugInterface * debugInterface,PCODECHAL_STANDARD_INFO standardInfo)76 CodechalDecodeVp9G12::CodechalDecodeVp9G12(
77     CodechalHwInterface *   hwInterface,
78     CodechalDebugInterface *debugInterface,
79     PCODECHAL_STANDARD_INFO standardInfo) : CodechalDecodeVp9(hwInterface, debugInterface, standardInfo),
80                                             m_frameSizeMaxAlloced(0),
81                                             m_sinlgePipeVeState(nullptr),
82                                             m_scalabilityState(nullptr)
83 {
84     CODECHAL_DECODE_FUNCTION_ENTER;
85 
86     CODECHAL_DECODE_CHK_NULL_NO_STATUS_RETURN(m_osInterface);
87 
88     m_osInterface->pfnVirtualEngineSupported(m_osInterface, true, true);
89 
90 #if (_DEBUG || _RELEASE_INTERNAL)
91     MOS_USER_FEATURE_VALUE_DATA userFeatureData;
92     MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
93     MOS_UserFeature_ReadValue_ID(
94         nullptr,
95         __MEDIA_USER_FEATURE_VALUE_DECODE_HISTOGRAM_DEBUG_ID,
96         &userFeatureData,
97         m_osInterface->pOsContext);
98     m_histogramDebug = userFeatureData.u32Data ? true : false;
99 #endif
100 }
101 
SetGpuCtxCreatOption(CodechalSetting * codecHalSetting)102 MOS_STATUS CodechalDecodeVp9G12::SetGpuCtxCreatOption(
103     CodechalSetting *codecHalSetting)
104 {
105     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
106 
107     CODECHAL_DECODE_FUNCTION_ENTER;
108 
109     if (!MOS_VE_CTXBASEDSCHEDULING_SUPPORTED(m_osInterface))
110     {
111         CodechalDecode::SetGpuCtxCreatOption(codecHalSetting);
112     }
113     else
114     {
115         m_gpuCtxCreatOpt = MOS_New(MOS_GPUCTX_CREATOPTIONS_ENHANCED);
116         CODECHAL_DECODE_CHK_NULL_RETURN(m_gpuCtxCreatOpt);
117 
118         if (static_cast<MhwVdboxMfxInterfaceG12 *>(m_mfxInterface)->IsScalabilitySupported())
119         {
120             CODECHAL_DECODE_CHK_STATUS_RETURN(CodechalDecodeScalability_ConstructParmsForGpuCtxCreation_g12(
121                 m_scalabilityState,
122                 (PMOS_GPUCTX_CREATOPTIONS_ENHANCED)m_gpuCtxCreatOpt,
123                 codecHalSetting));
124 
125             if (((PMOS_GPUCTX_CREATOPTIONS_ENHANCED)m_gpuCtxCreatOpt)->LRCACount == 2)
126             {
127                 m_videoContext = MOS_VE_MULTINODESCALING_SUPPORTED(m_osInterface) ? MOS_GPU_CONTEXT_VIDEO5 : MOS_GPU_CONTEXT_VDBOX2_VIDEO;
128 
129                 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnCreateGpuContext(
130                     m_osInterface,
131                     m_videoContext,
132                     MOS_GPU_NODE_VIDEO,
133                     m_gpuCtxCreatOpt));
134 
135                 MOS_GPUCTX_CREATOPTIONS createOption;
136                 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnCreateGpuContext(
137                     m_osInterface,
138                     MOS_GPU_CONTEXT_VIDEO,
139                     m_videoGpuNode,
140                     &createOption));
141             }
142             else if (((PMOS_GPUCTX_CREATOPTIONS_ENHANCED)m_gpuCtxCreatOpt)->LRCACount == 3)
143             {
144                 m_videoContext = MOS_VE_MULTINODESCALING_SUPPORTED(m_osInterface) ? MOS_GPU_CONTEXT_VIDEO7 : MOS_GPU_CONTEXT_VDBOX2_VIDEO2;
145 
146                 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnCreateGpuContext(
147                     m_osInterface,
148                     m_videoContext,
149                     MOS_GPU_NODE_VIDEO,
150                     m_gpuCtxCreatOpt));
151 
152                 MOS_GPUCTX_CREATOPTIONS createOption;
153                 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnCreateGpuContext(
154                     m_osInterface,
155                     MOS_GPU_CONTEXT_VIDEO,
156                     m_videoGpuNode,
157                     &createOption));
158             }
159             else
160             {
161                 m_videoContext = MOS_GPU_CONTEXT_VIDEO;
162             }
163         }
164         else
165         {
166             bool sfcInUse = (codecHalSetting->sfcInUseHinted && codecHalSetting->downsamplingHinted
167                                 && (MEDIA_IS_SKU(m_skuTable, FtrSFCPipe) && !MEDIA_IS_SKU(m_skuTable, FtrDisableVDBox2SFC)));
168             CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalDecodeSinglePipeVE_ConstructParmsForGpuCtxCreation(
169                 m_sinlgePipeVeState,
170                 (PMOS_GPUCTX_CREATOPTIONS_ENHANCED)m_gpuCtxCreatOpt,
171                 sfcInUse));
172 
173             m_videoContext = MOS_GPU_CONTEXT_VIDEO;
174         }
175     }
176 
177     return eStatus;
178 }
179 
AllocateResourcesVariableSizes()180 MOS_STATUS CodechalDecodeVp9G12 :: AllocateResourcesVariableSizes()
181 {
182     MOS_STATUS              eStatus = MOS_STATUS_SUCCESS;
183 
184     CODECHAL_DECODE_FUNCTION_ENTER;
185 
186 #ifdef _MMC_SUPPORTED
187     // To WA invalid aux data caused HW issue when MMC on
188     if (m_mmc && m_mmc->IsMmcEnabled() && MEDIA_IS_WA(m_waTable, Wa_1408785368) &&
189         !Mos_ResourceIsNull(&m_destSurface.OsResource) &&
190         m_destSurface.OsResource.bConvertedFromDDIResource)
191     {
192         if (m_secureDecoder && m_secureDecoder->IsAuxDataInvalid(&m_destSurface.OsResource))
193         {
194             CODECHAL_DECODE_CHK_STATUS_RETURN(m_secureDecoder->InitAuxSurface(&m_destSurface.OsResource, false, true));
195         }
196         else
197         {
198             CODECHAL_DECODE_VERBOSEMESSAGE("Clear CCS by VE resolve before frame %d submission", m_frameNum);
199             CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnDecompResource(m_osInterface, &m_destSurface.OsResource));
200             CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSetGpuContext(m_osInterface, m_videoContext));
201         }
202     }
203 #endif
204 
205     if (CodecHalDecodeScalabilityIsScalableMode(m_scalabilityState))
206     {
207         uint32_t widthInSb  = MOS_ROUNDUP_DIVIDE(m_width, CODEC_VP9_SUPER_BLOCK_WIDTH);
208         uint32_t heightInSb = MOS_ROUNDUP_DIVIDE(m_height, CODEC_VP9_SUPER_BLOCK_HEIGHT);
209         uint32_t frameSizeMax = MOS_MAX((m_copyDataBufferInUse ? m_copyDataBufferSize : m_dataSize), m_frameSizeMaxAlloced);
210         uint8_t  maxBitDepth  = 8 + m_vp9DepthIndicator * 2;
211         uint8_t  chromaFormat = m_chromaFormatinProfile;
212 
213         MHW_VDBOX_HCP_BUFFER_SIZE_PARAMS    hcpBufSizeParam;
214         MOS_ZeroMemory(&hcpBufSizeParam, sizeof(hcpBufSizeParam));
215         hcpBufSizeParam.ucMaxBitDepth  = maxBitDepth;
216         hcpBufSizeParam.ucChromaFormat = chromaFormat;
217         hcpBufSizeParam.dwPicWidth     = widthInSb;
218         hcpBufSizeParam.dwPicHeight    = heightInSb;
219         hcpBufSizeParam.dwMaxFrameSize = frameSizeMax;
220 
221         MHW_VDBOX_HCP_BUFFER_REALLOC_PARAMS reallocParam;
222         MOS_ZeroMemory(&reallocParam, sizeof(reallocParam));
223         reallocParam.ucMaxBitDepth       = maxBitDepth;
224         reallocParam.ucChromaFormat      = chromaFormat;
225         reallocParam.dwPicWidth          = widthInSb;
226         reallocParam.dwPicWidthAlloced   = m_allocatedWidthInSb;
227         reallocParam.dwPicHeight         = heightInSb;
228         reallocParam.dwPicHeightAlloced  = m_allocatedHeightInSb;
229         reallocParam.dwFrameSize         = frameSizeMax;
230         reallocParam.dwFrameSizeAlloced  = m_frameSizeMaxAlloced;
231         CODECHAL_DECODE_CHK_STATUS_RETURN(
232             CodecHalDecodeScalability_AllocateResources_VariableSizes_G12(
233                 m_scalabilityState,
234                 &hcpBufSizeParam,
235                 &reallocParam));
236 
237         m_frameSizeMaxAlloced = frameSizeMax;
238     }
239 
240     CODECHAL_DECODE_CHK_STATUS_RETURN(CodechalDecodeVp9 ::AllocateResourcesVariableSizes());
241 
242     return eStatus;
243 }
244 
InitSfcState()245 MOS_STATUS CodechalDecodeVp9G12::InitSfcState()
246 {
247     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
248 #ifdef _DECODE_PROCESSING_SUPPORTED
249     // Check if SFC can be supported
250     CODECHAL_DECODE_CHK_STATUS_RETURN(m_sfcState->CheckAndInitialize(
251         (DecodeProcessingParams *)m_decodeParams.m_procParams,
252         m_vp9PicParams,
253         m_scalabilityState));
254 #endif
255     return eStatus;
256 }
257 
CalcDownsamplingParams(void * picParams,uint32_t * refSurfWidth,uint32_t * refSurfHeight,MOS_FORMAT * format,uint8_t * frameIdx)258 MOS_STATUS CodechalDecodeVp9G12::CalcDownsamplingParams(
259     void                        *picParams,
260     uint32_t                    *refSurfWidth,
261     uint32_t                    *refSurfHeight,
262     MOS_FORMAT                  *format,
263     uint8_t                     *frameIdx)
264 {
265     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
266 
267     CODECHAL_DECODE_CHK_NULL_RETURN(picParams);
268     CODECHAL_DECODE_CHK_NULL_RETURN(refSurfWidth);
269     CODECHAL_DECODE_CHK_NULL_RETURN(refSurfHeight);
270     CODECHAL_DECODE_CHK_NULL_RETURN(format);
271     CODECHAL_DECODE_CHK_NULL_RETURN(frameIdx);
272 
273     PCODEC_VP9_PIC_PARAMS vp9PicParams = (PCODEC_VP9_PIC_PARAMS)picParams;
274 
275     *refSurfWidth = 0;
276     *refSurfHeight = 0;
277     *format = Format_NV12;
278     *frameIdx = vp9PicParams->CurrPic.FrameIdx;
279 
280 
281     *refSurfWidth = MOS_ALIGN_CEIL(vp9PicParams->FrameWidthMinus1 + 1, CODEC_VP9_SUPER_BLOCK_WIDTH);
282     *refSurfHeight = MOS_ALIGN_CEIL(vp9PicParams->FrameHeightMinus1 + 1, CODEC_VP9_SUPER_BLOCK_HEIGHT);
283 
284     if (vp9PicParams->subsampling_x == 1 && vp9PicParams->subsampling_y == 1) //HCP_CHROMA_FORMAT_YUV420
285     {
286         if (vp9PicParams->BitDepthMinus8 > 2)
287         {
288             *format = Format_P016;
289         }
290         else if (vp9PicParams->BitDepthMinus8 > 0)
291         {
292             *format = Format_P010;
293         }
294         else
295         {
296             *format = Format_NV12;
297         }
298     }
299     else if (vp9PicParams->subsampling_x == 0 && vp9PicParams->subsampling_y == 0) //HCP_CHROMA_FORMAT_YUV444
300     {
301         if (vp9PicParams->BitDepthMinus8 > 2)
302         {
303             *format = Format_Y416;
304         }
305         else if (vp9PicParams->BitDepthMinus8 > 0)
306         {
307             *format = Format_Y410;
308         }
309         else
310         {
311             *format = Format_AYUV;
312         }
313     }
314     else
315     {
316         CODECHAL_DECODE_ASSERTMESSAGE("Invalid Chroma sampling format!");
317         eStatus = MOS_STATUS_INVALID_PARAMETER;
318         return eStatus;
319     }
320     return eStatus;
321 }
322 
InitializeDecodeMode()323 MOS_STATUS CodechalDecodeVp9G12 :: InitializeDecodeMode ()
324 {
325     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
326 
327     CODECHAL_DECODE_FUNCTION_ENTER;
328 
329     if ( MOS_VE_SUPPORTED(m_osInterface) && static_cast<MhwVdboxMfxInterfaceG12*>(m_mfxInterface)->IsScalabilitySupported())
330     {
331         CODECHAL_DECODE_SCALABILITY_INIT_PARAMS_G12  initParams;
332 
333         MOS_ZeroMemory(&initParams, sizeof(initParams));
334         initParams.u32PicWidthInPixel  = m_usFrameWidthAlignedMinBlk;
335         initParams.u32PicHeightInPixel = m_usFrameHeightAlignedMinBlk;
336         initParams.format              = m_decodeParams.m_destSurface->Format;
337         initParams.gpuCtxInUse         = GetVideoContext();
338         initParams.usingSecureDecode   = (m_secureDecoder != nullptr);
339         if (m_decodeHistogram == nullptr)
340         {
341             initParams.usingHistogram = false;
342 #if (_DEBUG || _RELEASE_INTERNAL)
343             if (m_histogramDebug)
344             {
345                 initParams.usingHistogram = true;
346             }
347 #endif
348         }
349         else
350         {
351             initParams.usingHistogram = true;
352         }
353         CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalDecodeScalability_InitScalableParams_G12(
354             m_scalabilityState,
355             &initParams,
356             &m_decodePassNum));
357 
358         if (MOS_VE_CTXBASEDSCHEDULING_SUPPORTED(m_osInterface))
359         {
360             CODECHAL_DECODE_CHK_STATUS_RETURN(CodechalDecodeScalability_ChkGpuCtxReCreation(
361                 m_scalabilityState,
362                 (PMOS_GPUCTX_CREATOPTIONS_ENHANCED)m_gpuCtxCreatOpt));
363             SetVideoContext(m_scalabilityState->VideoContext);
364         }
365 
366     }
367 
368     return eStatus;
369 }
370 
DetermineDecodePhase()371 MOS_STATUS CodechalDecodeVp9G12::DetermineDecodePhase()
372 {
373     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
374 
375     CODECHAL_DECODE_FUNCTION_ENTER;
376 
377     if (static_cast<MhwVdboxMfxInterfaceG12*>(m_mfxInterface)->IsScalabilitySupported())
378     {
379         CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalDecodeScalability_DetermineDecodePhase_G12(
380             m_scalabilityState,
381             &m_hcpDecPhase));
382     }
383     else
384     {
385         CODECHAL_DECODE_CHK_STATUS_RETURN(CodechalDecodeVp9 :: DetermineDecodePhase());
386     }
387 
388     return eStatus;
389 }
390 
SetAndPopulateVEHintParams(PMOS_COMMAND_BUFFER primCmdBuf)391 MOS_STATUS CodechalDecodeVp9G12::SetAndPopulateVEHintParams(
392     PMOS_COMMAND_BUFFER       primCmdBuf)
393 {
394     MOS_STATUS                      eStatus = MOS_STATUS_SUCCESS;
395 
396     CODECHAL_DECODE_FUNCTION_ENTER;
397 
398     if (static_cast<MhwVdboxMfxInterfaceG12*>(m_mfxInterface)->IsScalabilitySupported())
399     {
400         CODECHAL_DECODE_SCALABILITY_SETHINT_PARMS scalSetParms;
401         MOS_ZeroMemory(&scalSetParms, sizeof(CODECHAL_DECODE_SCALABILITY_SETHINT_PARMS));
402         if (!MOS_VE_CTXBASEDSCHEDULING_SUPPORTED(m_osInterface))
403         {
404             scalSetParms.bNeedSyncWithPrevious       = true;
405             scalSetParms.bSameEngineAsLastSubmission = false;
406             scalSetParms.bSFCInUse                   = false;
407         }
408         CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalDecodeScalability_SetHintParams_G12(m_scalabilityState, &scalSetParms));
409         CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalDecodeScalability_PopulateHintParams(m_scalabilityState, primCmdBuf));
410     }
411     else
412     {
413         if (!MOS_VE_CTXBASEDSCHEDULING_SUPPORTED(m_osInterface))
414         {
415             MOS_VIRTUALENGINE_SET_PARAMS  vesetParams;
416             MOS_ZeroMemory(&vesetParams, sizeof(vesetParams));
417             vesetParams.bNeedSyncWithPrevious       = true;
418             vesetParams.bSameEngineAsLastSubmission = false;
419             vesetParams.bSFCInUse                   = false;
420             CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalDecodeSinglePipeVE_SetHintParams(m_sinlgePipeVeState, &vesetParams));
421         }
422         CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalDecodeSinglePipeVE_PopulateHintParams(m_sinlgePipeVeState, primCmdBuf, true));
423     }
424 
425     return eStatus;
426 }
427 
DetermineSendProlgwithFrmTracking(bool * sendPrologWithFrameTracking)428 MOS_STATUS CodechalDecodeVp9G12::DetermineSendProlgwithFrmTracking(
429     bool                        *sendPrologWithFrameTracking)
430 {
431     MOS_STATUS       eStatus = MOS_STATUS_SUCCESS;
432 
433     CODECHAL_DECODE_FUNCTION_ENTER;
434 
435     CODECHAL_DECODE_CHK_NULL_RETURN(sendPrologWithFrameTracking);
436 
437     if (CodecHalDecodeScalabilityIsScalableMode(m_scalabilityState))
438     {
439         if (CodecHalDecodeScalability1stPhaseofSubmission(m_scalabilityState))
440         {
441             *sendPrologWithFrameTracking = true;
442         }
443     }
444     else
445     {
446         *sendPrologWithFrameTracking = true;
447     }
448 
449     return eStatus;
450 }
451 
RequestedSpaceSize(uint32_t requestedSize)452 uint32_t CodechalDecodeVp9G12::RequestedSpaceSize(uint32_t requestedSize)
453 {
454     if (m_scalabilityState && m_scalabilityState->bScalableDecodeMode)
455     {
456         //primary cmd buffer only including cmd buffer header .
457         return COMMAND_BUFFER_RESERVED_SPACE * 2;
458     }
459     else
460     {
461         return requestedSize;
462     }
463 }
464 
VerifyExtraSpace(uint32_t requestedSize,uint32_t additionalSizeNeeded)465 MOS_STATUS CodechalDecodeVp9G12::VerifyExtraSpace(
466     uint32_t requestedSize,
467     uint32_t additionalSizeNeeded)
468 {
469     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
470 
471     CODECHAL_DECODE_FUNCTION_ENTER;
472 
473     if (m_scalabilityState && m_scalabilityState->bScalableDecodeMode)
474     {
475         eStatus = MOS_STATUS_NO_SPACE;
476 
477         // Try a maximum of 3 attempts to request the required sizes from OS
478         // OS could reset the sizes if necessary, therefore, requires to re-verify
479         for (auto i = 0; (i < 3) && (eStatus != MOS_STATUS_SUCCESS); i++)
480         {
481             // Verify secondary cmd buffer
482             eStatus = (MOS_STATUS)m_osInterface->pfnVerifyCommandBufferSize(
483                 m_osInterface,
484                 requestedSize,
485                 MOS_VE_HAVE_SECONDARY_CMDBUFFER);
486 
487             // Resize command buffer if not enough
488             if (eStatus != MOS_STATUS_SUCCESS)
489             {
490                 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnResizeCommandBufferAndPatchList(
491                     m_osInterface,
492                     requestedSize + additionalSizeNeeded,
493                     0,
494                     MOS_VE_HAVE_SECONDARY_CMDBUFFER));
495                 // Set status to NO_SPACE to enter the commaned buffer size verification on next loop.
496                 eStatus = MOS_STATUS_NO_SPACE;
497             }
498         }
499     }
500 
501     return eStatus;
502 }
503 
AllocateHistogramSurface()504 MOS_STATUS CodechalDecodeVp9G12::AllocateHistogramSurface()
505 {
506     MOS_ALLOC_GFXRES_PARAMS allocParams;
507 
508     if (m_histogramSurface == nullptr)
509     {
510         m_histogramSurface = (MOS_SURFACE*)MOS_AllocAndZeroMemory(sizeof(MOS_SURFACE));
511         CODECHAL_DECODE_CHK_NULL_RETURN(m_histogramSurface);
512 
513         MOS_ZeroMemory(&allocParams, sizeof(MOS_ALLOC_GFXRES_PARAMS));
514         allocParams.Type = MOS_GFXRES_BUFFER;
515         allocParams.TileType = MOS_TILE_LINEAR;
516         allocParams.Format = Format_Buffer;
517         allocParams.dwBytes = 256 * 4;
518         allocParams.pBufName = "HistogramStreamOut";
519 
520         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource(
521             m_osInterface,
522             &allocParams,
523             &m_histogramSurface->OsResource));
524 
525         CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(
526             m_osInterface,
527             m_histogramSurface));
528     }
529 
530     if(m_decodeHistogram)
531         m_decodeHistogram->SetSrcHistogramSurface(m_histogramSurface);
532 
533     return MOS_STATUS_SUCCESS;
534 }
535 
AddPicStateMhwCmds(PMOS_COMMAND_BUFFER cmdBuffer)536 MOS_STATUS CodechalDecodeVp9G12::AddPicStateMhwCmds(
537     PMOS_COMMAND_BUFFER       cmdBuffer)
538 {
539     MOS_STATUS                              eStatus = MOS_STATUS_SUCCESS;
540     MHW_MI_VD_CONTROL_STATE_PARAMS          vdCtrlParam;
541 
542     CODECHAL_DECODE_FUNCTION_ENTER;
543 
544     CODECHAL_DECODE_CHK_NULL_RETURN(cmdBuffer);
545 
546     // Send VD_CONTROL_STATE Pipe Initialization
547     MOS_ZeroMemory(&vdCtrlParam, sizeof(MHW_MI_VD_CONTROL_STATE_PARAMS));
548     vdCtrlParam.initialization = true;
549     CODECHAL_DECODE_CHK_STATUS_RETURN(static_cast<MhwMiInterfaceG12 *>(m_miInterface)->AddMiVdControlStateCmd(cmdBuffer, &vdCtrlParam));
550 
551     CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpPipeModeSelectCmd(
552         cmdBuffer,
553         m_picMhwParams.PipeModeSelectParams));
554 
555     if (CodecHalDecodeScalabilityIsScalableMode(m_scalabilityState) &&
556         CodecHalDecodeScalabilityIsBEPhaseG12(m_scalabilityState))
557     {
558         // Send VD_CONTROL_STATE HcpPipeLock
559         MOS_ZeroMemory(&vdCtrlParam, sizeof(MHW_MI_VD_CONTROL_STATE_PARAMS));
560         vdCtrlParam.scalableModePipeLock = true;
561         CODECHAL_DECODE_CHK_STATUS_RETURN(static_cast<MhwMiInterfaceG12 *>(m_miInterface)->AddMiVdControlStateCmd(cmdBuffer, &vdCtrlParam));
562     }
563 #ifdef _DECODE_PROCESSING_SUPPORTED
564     if (!CodecHalDecodeScalabilityIsFEPhase(m_scalabilityState))
565     {
566         CODECHAL_DECODE_CHK_STATUS_RETURN(m_sfcState->AddSfcCommands(cmdBuffer));
567     }
568 #endif
569 #ifdef _MMC_SUPPORTED
570     CODECHAL_DECODE_CHK_STATUS_RETURN(m_mmc->SetSurfaceState(m_picMhwParams.SurfaceParams[0]));
571 #endif
572     CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpSurfaceCmd(
573         cmdBuffer,
574         m_picMhwParams.SurfaceParams[0]));
575 
576     // For non-key frame, send extra surface commands for reference pictures
577     if (m_vp9PicParams->PicFlags.fields.frame_type == CODEC_VP9_INTER_FRAME &&
578         !m_vp9PicParams->PicFlags.fields.intra_only)
579     {
580 #ifdef _MMC_SUPPORTED
581         //Get each reference surface state and be recorded by skipMask if current surface state is mmc disabled
582         uint8_t skipMask = 0xf8;
583         for (uint8_t i = 1; i < 4; i++)
584         {
585             CODECHAL_DECODE_CHK_STATUS_RETURN(m_mmc->SetSurfaceState(m_picMhwParams.SurfaceParams[i]));
586             if (m_picMhwParams.SurfaceParams[i]->mmcState == MOS_MEMCOMP_DISABLED)
587             {
588                 skipMask |= (1 << (i - 1));
589             }
590         }
591         CODECHAL_DECODE_NORMALMESSAGE("MMC skip mask is %d\n", skipMask);
592         for (uint8_t i = 1; i < 4; i++)
593         {
594             //Set each ref surface state as MOS_MEMCOMP_MC to satisfy MmcEnable in AddHcpSurfaceCmd
595             //Because each ref surface state should be programmed as the same
596             //The actual mmc state is recorded by skipMask and set each ref surface too
597             m_picMhwParams.SurfaceParams[i]->mmcState    = MOS_MEMCOMP_MC;
598             m_picMhwParams.SurfaceParams[i]->mmcSkipMask = skipMask;
599         }
600 #endif
601         for (uint8_t i = 1; i < 4; i++)
602         {
603             CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpSurfaceCmd(
604                 cmdBuffer,
605                 m_picMhwParams.SurfaceParams[i]));
606         }
607     }
608 
609     CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpPipeBufAddrCmd(
610         cmdBuffer,
611         m_picMhwParams.PipeBufAddrParams));
612 
613     CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpIndObjBaseAddrCmd(
614         cmdBuffer,
615         m_picMhwParams.IndObjBaseAddrParams));
616 
617     if (m_cencBuf)
618     {
619         CODECHAL_DECODE_CHK_STATUS_RETURN(SetCencBatchBuffer(cmdBuffer));
620     }
621     else
622     {
623         for (uint8_t i = 0; i < CODEC_VP9_MAX_SEGMENTS; i++)
624         {
625             // Error handling for illegal programming on segmentation fields @ KEY/INTRA_ONLY frames
626             PCODEC_VP9_SEG_PARAMS vp9SegData = &(m_picMhwParams.Vp9SegmentState->pVp9SegmentParams->SegData[i]);
627             if (vp9SegData->SegmentFlags.fields.SegmentReferenceEnabled &&
628                 (!m_vp9PicParams->PicFlags.fields.frame_type || m_vp9PicParams->PicFlags.fields.intra_only))
629             {
630                 vp9SegData->SegmentFlags.fields.SegmentReference = CODECHAL_DECODE_VP9_INTRA_FRAME;
631             }
632 
633             m_picMhwParams.Vp9SegmentState->ucCurrentSegmentId = i;
634             CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpVp9SegmentStateCmd(
635                 cmdBuffer,
636                 nullptr,
637                 m_picMhwParams.Vp9SegmentState));
638 
639             if (m_vp9PicParams->PicFlags.fields.segmentation_enabled == 0)
640             {
641                 break;
642             }
643         }
644 
645         CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpVp9PicStateCmd(
646             cmdBuffer,
647             nullptr,
648             m_picMhwParams.Vp9PicState));
649 
650         if (m_secureDecoder)
651         {
652             // Add secure decode command
653             CODECHAL_DECODE_CHK_STATUS_RETURN(m_secureDecoder->AddHcpSecureState(
654                 cmdBuffer,
655                 this));
656         }
657     }
658     return eStatus;
659 }
660 
SetFrameStates()661 MOS_STATUS CodechalDecodeVp9G12::SetFrameStates()
662 {
663     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
664 
665 
666 #ifdef _DECODE_PROCESSING_SUPPORTED
667     if (m_decodeParams.m_procParams)
668     {
669         CODECHAL_DECODE_CHK_STATUS_RETURN(AllocateHistogramSurface());
670 
671         ((DecodeProcessingParams *)m_decodeParams.m_procParams)->m_histogramSurface = m_histogramSurface;
672 
673         if(m_decodeHistogram)
674             m_decodeHistogram->SetSrcHistogramSurface(m_histogramSurface);
675 
676     }
677 #endif
678 
679     CodechalDecodeVp9::SetFrameStates();
680 
681     return eStatus;
682 }
683 
DecodeStateLevel()684 MOS_STATUS CodechalDecodeVp9G12 :: DecodeStateLevel()
685 {
686     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
687 
688     PERF_UTILITY_AUTO(__FUNCTION__, PERF_DECODE, PERF_LEVEL_HAL);
689     CODECHAL_DECODE_FUNCTION_ENTER;
690 
691     CODECHAL_DECODE_CHK_NULL_RETURN(m_hwInterface->GetCpInterface());
692 
693     if (m_secureDecoder && m_hcpDecPhase == CodechalHcpDecodePhaseInitialized)
694     {
695         CODECHAL_DECODE_CHK_STATUS_RETURN(m_secureDecoder->Execute(this));
696     }
697 
698     //HCP Decode Phase State Machine
699     DetermineDecodePhase();
700 
701     if (CodecHalDecodeScalabilityIsScalableMode(m_scalabilityState))
702     {
703         //Switch GPU context when necessary
704         CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalDecodeScalability_SwitchGpuContext(m_scalabilityState));
705     }
706 
707     MOS_COMMAND_BUFFER primCmdBuffer;
708     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &primCmdBuffer, 0));
709 
710     bool sendPrologWithFrameTracking;
711     CODECHAL_DECODE_CHK_STATUS_RETURN(DetermineSendProlgwithFrmTracking(&sendPrologWithFrameTracking));
712     if (sendPrologWithFrameTracking)
713     {
714         if (!CodecHalDecodeScalabilityIsScalableMode(m_scalabilityState))
715         {
716             MHW_MI_FORCE_WAKEUP_PARAMS forceWakeupParams;
717             MOS_ZeroMemory(&forceWakeupParams, sizeof(MHW_MI_FORCE_WAKEUP_PARAMS));
718             forceWakeupParams.bMFXPowerWellControl = false;
719             forceWakeupParams.bMFXPowerWellControlMask = true;
720             forceWakeupParams.bHEVCPowerWellControl = true;
721             forceWakeupParams.bHEVCPowerWellControlMask = true;
722             CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiForceWakeupCmd(
723                 &primCmdBuffer,
724                 &forceWakeupParams));
725         }
726         //Frame tracking functionality is called at the start of primary command buffer.
727         CODECHAL_DECODE_CHK_STATUS_RETURN(SendPrologWithFrameTracking(
728             &primCmdBuffer, true));
729     }
730 
731     PMOS_COMMAND_BUFFER cmdBufferInUse = &primCmdBuffer;
732     MOS_COMMAND_BUFFER  scdryCmdBuffer;
733     auto                mmioRegisters = m_hwInterface->GetMfxInterface()->GetMmioRegisters(m_vdboxIndex);
734 
735     if (CodecHalDecodeScalabilityIsScalableMode(m_scalabilityState) && MOS_VE_SUPPORTED(m_osInterface))
736     {
737         CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalDecodeScalability_GetCmdBufferToUse_G12(
738             m_scalabilityState,
739             &scdryCmdBuffer,
740             &cmdBufferInUse));
741 
742         MHW_MI_FORCE_WAKEUP_PARAMS forceWakeupParams;
743         MOS_ZeroMemory(&forceWakeupParams, sizeof(MHW_MI_FORCE_WAKEUP_PARAMS));
744         forceWakeupParams.bMFXPowerWellControl = false;
745         forceWakeupParams.bMFXPowerWellControlMask = true;
746         forceWakeupParams.bHEVCPowerWellControl = true;
747         forceWakeupParams.bHEVCPowerWellControlMask = true;
748         CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiForceWakeupCmd(
749             cmdBufferInUse,
750             &forceWakeupParams));
751 
752         if (cmdBufferInUse == &scdryCmdBuffer)
753         {
754             CODECHAL_DECODE_CHK_STATUS_RETURN(SendPrologWithFrameTracking(cmdBufferInUse, false));
755         }
756 
757         HalOcaInterface::On1stLevelBBStart(scdryCmdBuffer, *m_osInterface->pOsContext, m_osInterface->CurrentGpuContextHandle, *m_miInterface, *mmioRegisters);
758 
759     }
760     else
761     {
762         HalOcaInterface::On1stLevelBBStart(primCmdBuffer, *m_osInterface->pOsContext, m_osInterface->CurrentGpuContextHandle, *m_miInterface, *mmioRegisters);
763     }
764 
765     auto pipeModeSelectParams =
766         static_cast<PMHW_VDBOX_PIPE_MODE_SELECT_PARAMS_G12>(m_picMhwParams.PipeModeSelectParams);
767     *pipeModeSelectParams = {};
768     auto pipeBufAddrParams =
769         static_cast<PMHW_VDBOX_PIPE_BUF_ADDR_PARAMS_G12>(m_picMhwParams.PipeBufAddrParams);
770     *pipeBufAddrParams = {};
771     CODECHAL_DECODE_CHK_STATUS_RETURN(InitPicStateMhwParams());
772 
773     bool secureDecodeStartStatusFlag = true;
774     if (CodecHalDecodeScalabilityIsScalableMode(m_scalabilityState))
775     {
776         // Put all SecureDecode/Start Status related cmd into FE VDBOX
777         secureDecodeStartStatusFlag = CodecHalDecodeScalabilityIsFEPhase(m_scalabilityState);
778 
779         CodecHalDecodeScalablity_DecPhaseToHwWorkMode_G12(
780             pipeModeSelectParams->MultiEngineMode,
781             pipeModeSelectParams->PipeWorkMode);
782 
783         pipeBufAddrParams->presCABACSyntaxStreamOutBuffer =
784             m_scalabilityState->presCABACStreamOutBuffer;
785         pipeBufAddrParams->presIntraPredUpRightColStoreBuffer =
786             &m_scalabilityState->resIntraPredUpRightColStoreBuffer;
787         pipeBufAddrParams->presIntraPredLeftReconColStoreBuffer =
788             &m_scalabilityState->resIntraPredLeftReconColStoreBuffer;
789     }
790 
791     if (secureDecodeStartStatusFlag)
792     {
793         CODECHAL_DECODE_CHK_STATUS_RETURN(UpdatePicStateBuffers(cmdBufferInUse));
794 
795         if (m_statusQueryReportingEnabled)
796         {
797             CODECHAL_DECODE_CHK_STATUS_RETURN(StartStatusReport(
798                 cmdBufferInUse));
799         }
800         else
801         {
802             CODECHAL_DECODE_CHK_STATUS_RETURN(NullHW::StartPredicate(m_osInterface, m_miInterface, cmdBufferInUse));
803         }
804     }
805     else
806     {
807         CODECHAL_DECODE_CHK_STATUS_RETURN(NullHW::StartPredicate(m_osInterface, m_miInterface, cmdBufferInUse));
808     }
809 
810     if (CodecHalDecodeScalabilityIsScalableMode(m_scalabilityState))
811     {
812         CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalDecodeScalability_FEBESync_G12(
813             m_scalabilityState,
814             cmdBufferInUse,
815             m_osInterface->phasedSubmission));
816         if (m_perfFEBETimingEnabled && CodecHalDecodeScalabilityIsLastCompletePhase(m_scalabilityState))
817         {
818             CODECHAL_DECODE_CHK_STATUS_RETURN(m_perfProfiler->AddPerfCollectStartCmd((void *)this, m_osInterface, m_miInterface, &scdryCmdBuffer));
819         }
820     }
821 
822     if (CodecHalDecodeScalabilityIsBEPhaseG12(m_scalabilityState))
823     {
824         CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddWatchdogTimerStartCmd(cmdBufferInUse));
825     }
826 
827     CODECHAL_DECODE_CHK_STATUS_RETURN(AddPicStateMhwCmds(
828         cmdBufferInUse));
829 
830     if (CodecHalDecodeScalabilityIsBEPhaseG12(m_scalabilityState))
831     {
832         MHW_VDBOX_HCP_TILE_CODING_PARAMS_G12  hcpTileCodingParam;
833         CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalDecodeScalability_CalculateHcpTileCodingParams<MHW_VDBOX_HCP_TILE_CODING_PARAMS_G12>(
834             m_scalabilityState,
835             m_vp9PicParams,
836             &hcpTileCodingParam));
837         //insert 2 dummy VD_CONTROL_STATE packets with data=0 before every HCP_TILE_CODING
838         if (MEDIA_IS_WA(m_waTable, Wa_14010222001))
839         {
840             MHW_MI_VD_CONTROL_STATE_PARAMS vdCtrlParam;
841             MOS_ZeroMemory(&vdCtrlParam, sizeof(MHW_MI_VD_CONTROL_STATE_PARAMS));
842             for (int i = 0; i < 2; i++)
843             {
844                 CODECHAL_DECODE_CHK_STATUS_RETURN(static_cast<MhwMiInterfaceG12 *>(m_miInterface)->AddMiVdControlStateCmd(cmdBufferInUse, &vdCtrlParam));
845             }
846         }
847         CODECHAL_DECODE_CHK_STATUS_RETURN(static_cast<MhwVdboxHcpInterfaceG12*>(m_hcpInterface)->AddHcpTileCodingCmd(
848             cmdBufferInUse,
849             &hcpTileCodingParam));
850     }
851 
852     m_osInterface->pfnReturnCommandBuffer(m_osInterface, &primCmdBuffer, 0);
853     if (CodecHalDecodeScalabilityIsScalableMode(m_scalabilityState) && MOS_VE_SUPPORTED(m_osInterface))
854     {
855         CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalDecodeScalability_ReturnSdryCmdBuffer_G12(m_scalabilityState, &scdryCmdBuffer));
856     }
857 
858     return eStatus;
859 }
860 
DecodePrimitiveLevel()861 MOS_STATUS CodechalDecodeVp9G12 :: DecodePrimitiveLevel()
862 {
863     MOS_STATUS                          eStatus = MOS_STATUS_SUCCESS;
864     MHW_MI_VD_CONTROL_STATE_PARAMS      vdCtrlParam;
865 
866     PERF_UTILITY_AUTO(__FUNCTION__, PERF_DECODE, PERF_LEVEL_HAL);
867 
868     CODECHAL_DECODE_FUNCTION_ENTER;
869 
870     // Bitstream is incomplete, don't do any decoding work.
871     if (m_incompletePicture)
872     {
873         eStatus = MOS_STATUS_SUCCESS;
874         return eStatus;
875     }
876 
877     CODECHAL_DECODE_CHK_NULL_RETURN(m_osInterface);
878 
879     CODECHAL_DECODE_CHK_COND_RETURN(
880         (m_vdboxIndex > m_mfxInterface->GetMaxVdboxIndex()),
881         "ERROR - vdbox index exceed the maximum");
882 
883     m_osInterface->pfnSetPerfTag(
884         m_osInterface,
885         (uint16_t)(((m_mode << 4) & 0xF0) | (m_perfType & 0xF)));
886     m_osInterface->pfnResetPerfBufferID(m_osInterface);
887 
888     MOS_COMMAND_BUFFER primCmdBuffer;
889     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &primCmdBuffer, 0));
890 
891     PMOS_COMMAND_BUFFER cmdBufferInUse = &primCmdBuffer;
892     MOS_COMMAND_BUFFER  scdryCmdBuffer;
893     if (CodecHalDecodeScalabilityIsScalableMode(m_scalabilityState) && MOS_VE_SUPPORTED(m_osInterface))
894     {
895         CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalDecodeScalability_GetCmdBufferToUse_G12(
896             m_scalabilityState,
897             &scdryCmdBuffer,
898             &cmdBufferInUse));
899         CodecHalDecodeScalability_DecPhaseToSubmissionType_G12(m_scalabilityState,cmdBufferInUse);
900     }
901 
902     // store CS ENGINE ID register
903     if (static_cast<MhwVdboxMfxInterfaceG12*>(m_mfxInterface)->IsScalabilitySupported())
904     {
905         CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalDecodeScalability_ReadCSEngineIDReg_G12(
906             m_scalabilityState,
907             &m_decodeStatusBuf,
908             cmdBufferInUse));
909     }
910 
911     //no slice level command for Huc based DRM and scalability decode BE phases
912     if (m_cencBuf == nullptr && !CodecHalDecodeScalabilityIsBEPhaseG12(m_scalabilityState))
913     {
914         MHW_VDBOX_HCP_BSD_PARAMS bsdParams;
915         MOS_ZeroMemory(&bsdParams, sizeof(bsdParams));
916         bsdParams.dwBsdDataLength =
917             m_vp9PicParams->BSBytesInBuffer - m_vp9PicParams->UncompressedHeaderLengthInBytes;
918         bsdParams.dwBsdDataStartOffset = m_vp9PicParams->UncompressedHeaderLengthInBytes;
919 
920         CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpBsdObjectCmd(
921             cmdBufferInUse,
922             &bsdParams));
923     }
924 
925     // Send VD_CONTROL_STATE Memory Implict Flush
926     MOS_ZeroMemory(&vdCtrlParam, sizeof(MHW_MI_VD_CONTROL_STATE_PARAMS));
927     vdCtrlParam.memoryImplicitFlush = true;
928     CODECHAL_DECODE_CHK_STATUS_RETURN(static_cast<MhwMiInterfaceG12 *>(m_miInterface)->AddMiVdControlStateCmd(cmdBufferInUse, &vdCtrlParam));
929 
930     if (CodecHalDecodeScalabilityIsScalableMode(m_scalabilityState) &&
931         CodecHalDecodeScalabilityIsBEPhaseG12(m_scalabilityState))
932     {
933         // Send VD_CONTROL_STATE HCP Pipe Unlock
934         MOS_ZeroMemory(&vdCtrlParam, sizeof(MHW_MI_VD_CONTROL_STATE_PARAMS));
935         vdCtrlParam.scalableModePipeUnlock = true;
936         CODECHAL_DECODE_CHK_STATUS_RETURN(static_cast<MhwMiInterfaceG12 *>(m_miInterface)->AddMiVdControlStateCmd(cmdBufferInUse, &vdCtrlParam));
937     }
938 
939     // Send VD Pipe Flush command for SKL+
940     MHW_VDBOX_VD_PIPE_FLUSH_PARAMS vdpipeFlushParams;
941     MOS_ZeroMemory(&vdpipeFlushParams, sizeof(vdpipeFlushParams));
942     vdpipeFlushParams.Flags.bWaitDoneHEVC = 1;
943     vdpipeFlushParams.Flags.bFlushHEVC = 1;
944     vdpipeFlushParams.Flags.bWaitDoneVDCmdMsgParser = 1;
945     CODECHAL_DECODE_CHK_STATUS_RETURN(m_vdencInterface->AddVdPipelineFlushCmd(
946         cmdBufferInUse,
947         &vdpipeFlushParams));
948 
949     MHW_MI_FLUSH_DW_PARAMS flushDwParams;
950     MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
951     CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(
952         cmdBufferInUse,
953         &flushDwParams));
954 
955     if (CodecHalDecodeScalabilityIsFEPhase(m_scalabilityState))
956     {
957         if (m_scalabilityState->bIsEnableEndCurrentBatchBuffLevel)
958         {
959             CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalDecodeScalablity_GetFEReportedCabacStreamoutBufferSize(
960                 m_scalabilityState,
961                 cmdBufferInUse));
962         }
963         else
964         {
965             CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalDecodeScalablity_SetFECabacStreamoutOverflowStatus(
966                 m_scalabilityState,
967                 cmdBufferInUse));
968         }
969 
970         CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalDecodeScalability_SignalFE2BESemaphore(
971             m_scalabilityState,
972             cmdBufferInUse));
973 
974         if (m_perfFEBETimingEnabled)
975         {
976             CODECHAL_DECODE_CHK_STATUS_RETURN(m_perfProfiler->AddPerfCollectEndCmd((void *)this, m_osInterface, m_miInterface, &scdryCmdBuffer));
977         }
978     }
979 
980     //Sync for decode completion in scalable mode
981     if (CodecHalDecodeScalabilityIsBEPhaseG12(m_scalabilityState))
982     {
983         CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalDecodeScalability_BEsCompletionSync(
984             m_scalabilityState,
985             cmdBufferInUse));
986     }
987 
988     //if scalable decode,  BE0 finish means whole frame complete.
989     // Check if destination surface needs to be synchronized
990     bool syncDestSurface = true;
991     if (CodecHalDecodeScalabilityIsScalableMode(m_scalabilityState))
992     {
993         syncDestSurface = CodecHalDecodeScalabilityIsLastCompletePhase(m_scalabilityState);
994     }
995 
996     MOS_SYNC_PARAMS syncParams;
997     if (syncDestSurface)
998     {
999         syncParams                          = g_cInitSyncParams;
1000         syncParams.GpuContext               = m_videoContext;
1001         syncParams.presSyncResource         = &m_destSurface.OsResource;
1002         syncParams.bReadOnly                = false;
1003         syncParams.bDisableDecodeSyncLock   = m_disableDecodeSyncLock;
1004         syncParams.bDisableLockForTranscode = m_disableLockForTranscode;
1005 
1006         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnPerformOverlaySync(
1007             m_osInterface,
1008             &syncParams));
1009         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceWait(
1010             m_osInterface,
1011             &syncParams));
1012 
1013         // Update the resource tag (s/w tag) for On-Demand Sync
1014         m_osInterface->pfnSetResourceSyncTag(m_osInterface, &syncParams);
1015 
1016         // Update the tag in GPU Sync eStatus buffer (H/W Tag) to match the current S/W tag
1017         if (m_osInterface->bTagResourceSync)
1018         {
1019             CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->WriteSyncTagToResource(
1020                 cmdBufferInUse,
1021                 &syncParams));
1022         }
1023 
1024         if (m_statusQueryReportingEnabled)
1025         {
1026             CodechalDecodeStatusReport decodeStatusReport;
1027 
1028             decodeStatusReport.m_statusReportNumber = m_statusReportFeedbackNumber;
1029             decodeStatusReport.m_currDecodedPic     = m_vp9PicParams->CurrPic;
1030             decodeStatusReport.m_currDeblockedPic   = m_vp9PicParams->CurrPic;
1031             decodeStatusReport.m_codecStatus        = CODECHAL_STATUS_UNAVAILABLE;
1032             decodeStatusReport.m_numMbsAffected     = m_usFrameWidthAlignedMinBlk * m_usFrameHeightAlignedMinBlk;
1033             decodeStatusReport.m_currDecodedPicRes  = m_vp9RefList[m_vp9PicParams->CurrPic.FrameIdx]->resRefPic;
1034 
1035 #ifdef _DECODE_PROCESSING_SUPPORTED
1036             CODECHAL_DEBUG_TOOL(
1037                 if (m_downsampledSurfaces && m_sfcState && m_sfcState->m_sfcOutputSurface) {
1038                     m_downsampledSurfaces[m_vp9PicParams->CurrPic.FrameIdx].OsResource = m_sfcState->m_sfcOutputSurface->OsResource;
1039                     decodeStatusReport.m_currSfcOutputPicRes                           = &m_downsampledSurfaces[m_vp9PicParams->CurrPic.FrameIdx].OsResource;
1040                 })
1041 #endif
1042 
1043             // VP9 plug-in/out was NOT fully enabled; this is just to make sure driver would not crash in CodecHal_DecodeEndFrame(),
1044             // which requires the value of DecodeStatusReport.presCurrDecodedPic
1045             CODECHAL_DEBUG_TOOL(
1046                 decodeStatusReport.m_frameType = m_perfType;
1047             )
1048 
1049             CODECHAL_DECODE_CHK_STATUS_RETURN(EndStatusReport(
1050                 decodeStatusReport,
1051                 cmdBufferInUse));
1052         }
1053         else
1054         {
1055             CODECHAL_DECODE_CHK_STATUS_RETURN(NullHW::StopPredicate(m_osInterface, m_miInterface, cmdBufferInUse));
1056         }
1057     }
1058     else
1059     {
1060         CODECHAL_DECODE_CHK_STATUS_RETURN(NullHW::StopPredicate(m_osInterface, m_miInterface, cmdBufferInUse));
1061     }
1062 
1063     MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
1064     CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(
1065         cmdBufferInUse,
1066         &flushDwParams));
1067 
1068     CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(
1069         cmdBufferInUse,
1070         nullptr));
1071 
1072     m_osInterface->pfnReturnCommandBuffer(m_osInterface, &primCmdBuffer, 0);
1073     if (CodecHalDecodeScalabilityIsScalableMode(m_scalabilityState) && MOS_VE_SUPPORTED(m_osInterface))
1074     {
1075         CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalDecodeScalability_ReturnSdryCmdBuffer_G12(m_scalabilityState, &scdryCmdBuffer));
1076     }
1077 
1078     CODECHAL_DEBUG_TOOL(
1079 
1080         if (m_histogramDebug && m_histogramSurface) {
1081             CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
1082                 &m_histogramSurface->OsResource,
1083                 CodechalDbgAttr::attrSfcHistogram,
1084                 "_DEC",
1085                 256 * 4));
1086         }
1087 
1088         if (CodecHalDecodeScalabilityIsScalableMode(m_scalabilityState)) {
1089             CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalDecodeScalability_DbgDumpCmdBuffer_G12(
1090                 this,
1091                 m_scalabilityState,
1092                 m_debugInterface,
1093                 &primCmdBuffer));
1094         } else {
1095             CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer(
1096                 &primCmdBuffer,
1097                 CODECHAL_NUM_MEDIA_STATES,
1098                 "_DEC"));
1099             //CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHal_DbgReplaceAllCommands(
1100             //    m_debugInterface,
1101             //    &primCmdBuffer));
1102         }
1103 
1104         m_mmc->UpdateUserFeatureKey(&m_destSurface);)
1105 
1106     bool syncCompleteFrame =
1107             (m_copyDataBufferInUse && !m_osInterface->bSimIsActive);
1108     if (MOS_VE_SUPPORTED(m_osInterface) && CodecHalDecodeScalabilityIsScalableMode(m_scalabilityState))
1109     {
1110         syncCompleteFrame = syncCompleteFrame && CodecHalDecodeScalabilityIsFEPhase(m_scalabilityState);
1111     }
1112 
1113     MOS_SYNC_PARAMS copyDataSyncParams;
1114     if (syncCompleteFrame)
1115     {
1116         //Sync up complete frame
1117         copyDataSyncParams = g_cInitSyncParams;
1118         copyDataSyncParams.GpuContext = m_videoContextForWa;
1119         copyDataSyncParams.presSyncResource = &m_resSyncObjectWaContextInUse;
1120 
1121         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineSignal(
1122             m_osInterface,
1123             &copyDataSyncParams));
1124 
1125         copyDataSyncParams = g_cInitSyncParams;
1126         copyDataSyncParams.GpuContext = m_videoContext;
1127         copyDataSyncParams.presSyncResource = &m_resSyncObjectWaContextInUse;
1128 
1129         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineWait(
1130             m_osInterface,
1131             &copyDataSyncParams));
1132     }
1133 
1134     bool submitCommand = true;
1135     if (MOS_VE_SUPPORTED(m_osInterface) && CodecHalDecodeScalabilityIsScalableMode(m_scalabilityState))
1136     {
1137         submitCommand = CodecHalDecodeScalabilityIsToSubmitCmdBuffer_G12(m_scalabilityState);
1138         HalOcaInterface::On1stLevelBBEnd(scdryCmdBuffer, *m_osInterface);
1139     }
1140     else
1141     {
1142         HalOcaInterface::On1stLevelBBEnd(primCmdBuffer, *m_osInterface);
1143     }
1144 
1145     if (submitCommand)
1146     {
1147         uint32_t renderingFlags = m_videoContextUsesNullHw;
1148 
1149         //command buffer to submit is the primary cmd buffer.
1150         if ( MOS_VE_SUPPORTED(m_osInterface))
1151         {
1152             CODECHAL_DECODE_CHK_STATUS_RETURN(SetAndPopulateVEHintParams(&primCmdBuffer));
1153         }
1154 
1155         if (m_osInterface->phasedSubmission
1156             && MOS_VE_SUPPORTED(m_osInterface)
1157             && CodecHalDecodeScalabilityIsScalableMode(m_scalabilityState))
1158         {
1159             CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(
1160                 m_osInterface,
1161                 cmdBufferInUse,
1162                 renderingFlags));
1163         }
1164         else
1165         {
1166             CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(
1167                 m_osInterface,
1168                 &primCmdBuffer,
1169                 renderingFlags));
1170         }
1171     }
1172 
1173     // Reset status report
1174     if (m_statusQueryReportingEnabled)
1175     {
1176         bool resetStatusReport = true;
1177 
1178         //if scalable decode,  reset status report at final BE phase.
1179         if (CodecHalDecodeScalabilityIsScalableMode(m_scalabilityState))
1180         {
1181             resetStatusReport = CodecHalDecodeScalabilityIsFinalBEPhaseG12(m_scalabilityState);
1182         }
1183 
1184         if (resetStatusReport)
1185         {
1186             CODECHAL_DECODE_CHK_STATUS_RETURN(ResetStatusReport(
1187                 m_videoContextUsesNullHw));
1188         }
1189     }
1190 
1191 #ifdef CODECHAL_HUC_KERNEL_DEBUG
1192     CODECHAL_DEBUG_TOOL(
1193     CODECHAL_DECODE_CHK_STATUS(m_debugInterface->DumpHucRegion(
1194         &resHucSharedBuffer,
1195         0,
1196         CODEC_VP9_PROB_MAX_NUM_ELEM,
1197         15,
1198         "",
1199         false,
1200         1,
1201         CodechalHucRegionDumpType::hucRegionDumpDefault));
1202     )
1203 #endif
1204     CODECHAL_DEBUG_TOOL(
1205         CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
1206             &m_resVp9SegmentIdBuffer,
1207             CodechalDbgAttr::attrSegId,
1208             "SegId",
1209             (m_allocatedWidthInSb * m_allocatedHeightInSb * CODECHAL_CACHELINE_SIZE)));
1210         CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
1211             &(m_resVp9ProbBuffer[m_frameCtxIdx]),
1212             CodechalDbgAttr::attrCoefProb,
1213             "PakHwCoeffProbs",
1214             CODEC_VP9_PROB_MAX_NUM_ELEM));)
1215 
1216     // Needs to be re-set for Linux buffer re-use scenarios
1217     //pVp9State->pVp9RefList[pVp9PicParams->ucCurrPicIndex]->resRefPic =
1218     //    pVp9State->sDestSurface.OsResource;
1219 
1220     // Send the signal to indicate decode completion, in case On-Demand Sync is not present
1221     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceSignal(
1222         m_osInterface,
1223         &syncParams));
1224 
1225  #ifdef LINUX
1226 #ifdef _DECODE_PROCESSING_SUPPORTED
1227     CODECHAL_DEBUG_TOOL(
1228     if (m_sfcState->m_sfcOutputSurface)
1229     {
1230         MOS_SURFACE dstSurface;
1231         MOS_ZeroMemory(&dstSurface, sizeof(dstSurface));
1232         dstSurface.Format = Format_NV12;
1233         dstSurface.OsResource = m_sfcState->m_sfcOutputSurface->OsResource;
1234         CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(
1235                 m_osInterface,
1236                 &dstSurface));
1237 
1238         CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface(
1239                 &dstSurface,
1240                 CodechalDbgAttr::attrSfcOutputSurface,
1241                 "SfcDstSurf"));
1242     }
1243    )
1244 #endif
1245 #endif
1246     return eStatus;
1247 }
1248 
InitMmcState()1249 MOS_STATUS CodechalDecodeVp9G12::InitMmcState()
1250 {
1251 #ifdef _MMC_SUPPORTED
1252     m_mmc = MOS_New(CodechalMmcDecodeVp9G12, m_hwInterface, this);
1253     CODECHAL_DECODE_CHK_NULL_RETURN(m_mmc);
1254 #endif
1255     return MOS_STATUS_SUCCESS;
1256 }
1257 
AllocateStandard(CodechalSetting * settings)1258 MOS_STATUS CodechalDecodeVp9G12 :: AllocateStandard (
1259     CodechalSetting *          settings)
1260 {
1261     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1262 
1263     CODECHAL_DECODE_FUNCTION_ENTER;
1264 
1265     CODECHAL_DECODE_CHK_NULL_RETURN(settings);
1266 
1267     CODECHAL_DECODE_CHK_STATUS_RETURN(InitMmcState());
1268 
1269     m_width                      = settings->width;
1270     m_height                     = settings->height;
1271     if (settings->lumaChromaDepth & CODECHAL_LUMA_CHROMA_DEPTH_8_BITS)
1272         m_vp9DepthIndicator = 0;
1273     if (settings->lumaChromaDepth & CODECHAL_LUMA_CHROMA_DEPTH_10_BITS)
1274         m_vp9DepthIndicator = 1;
1275     if (settings->lumaChromaDepth & CODECHAL_LUMA_CHROMA_DEPTH_12_BITS)
1276         m_vp9DepthIndicator = 2;
1277     m_chromaFormatinProfile = settings->chromaFormat;
1278 #ifdef _DECODE_PROCESSING_SUPPORTED
1279     // Initialize SFC state
1280     m_sfcState = MOS_New(CodechalVp9SfcStateG12);
1281     CODECHAL_DECODE_CHK_STATUS_RETURN(m_sfcState->InitializeSfcState(
1282         this,
1283         m_hwInterface,
1284         m_osInterface));
1285 #endif
1286     MHW_VDBOX_STATE_CMDSIZE_PARAMS_G12   stateCmdSizeParams;
1287     stateCmdSizeParams.bHucDummyStream = false;
1288     stateCmdSizeParams.bScalableMode   = static_cast<MhwVdboxMfxInterfaceG12*>(m_mfxInterface)->IsScalabilitySupported();
1289     stateCmdSizeParams.bSfcInUse       = true;
1290     //FE has more commands than BE. To finer control of the cmd buffer size
1291 
1292     // Picture Level Commands
1293     m_hwInterface->GetHxxStateCommandSize(
1294         m_mode,
1295         &m_commandBufferSizeNeeded,
1296         &m_commandPatchListSizeNeeded,
1297         &stateCmdSizeParams);
1298 
1299     // Primitive Level Commands
1300     m_hwInterface->GetHxxPrimitiveCommandSize(
1301         m_mode,
1302         &m_standardDecodeSizeNeeded,
1303         &m_standardDecodePatchListSizeNeeded,
1304         false);
1305 
1306    if ( MOS_VE_SUPPORTED(m_osInterface))
1307     {
1308         if (static_cast<MhwVdboxMfxInterfaceG12*>(m_mfxInterface)->IsScalabilitySupported())
1309         {
1310             m_scalabilityState = (PCODECHAL_DECODE_SCALABILITY_STATE_G12)MOS_AllocAndZeroMemory(sizeof(CODECHAL_DECODE_SCALABILITY_STATE_G12));
1311             CODECHAL_DECODE_CHK_NULL_RETURN(m_scalabilityState);
1312             //scalability initialize
1313             CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalDecodeScalability_InitializeState_G12(
1314                 this,
1315                 m_scalabilityState,
1316                 m_hwInterface,
1317                 false,
1318                 settings));
1319         }
1320         else
1321         {
1322             //single pipe VE initialize
1323             m_sinlgePipeVeState = (PCODECHAL_DECODE_SINGLEPIPE_VIRTUALENGINE_STATE)MOS_AllocAndZeroMemory(sizeof(CODECHAL_DECODE_SINGLEPIPE_VIRTUALENGINE_STATE));
1324             CODECHAL_DECODE_CHK_NULL_RETURN(m_sinlgePipeVeState);
1325             CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalDecodeSinglePipeVE_InitInterface(m_osInterface, m_sinlgePipeVeState));
1326         }
1327     }
1328 
1329     CODECHAL_DECODE_CHK_STATUS_RETURN(CodechalDecodeVp9::AllocateResourcesFixedSizes());
1330 
1331     // Prepare Pic Params
1332     m_picMhwParams.PipeModeSelectParams = MOS_New(MHW_VDBOX_PIPE_MODE_SELECT_PARAMS_G12);
1333     m_picMhwParams.PipeBufAddrParams = MOS_New(MHW_VDBOX_PIPE_BUF_ADDR_PARAMS_G12);
1334     m_picMhwParams.IndObjBaseAddrParams = MOS_New(MHW_VDBOX_IND_OBJ_BASE_ADDR_PARAMS);
1335     m_picMhwParams.Vp9PicState = MOS_New(MHW_VDBOX_VP9_PIC_STATE);
1336     m_picMhwParams.Vp9SegmentState = MOS_New(MHW_VDBOX_VP9_SEGMENT_STATE);
1337 
1338     MOS_ZeroMemory(m_picMhwParams.IndObjBaseAddrParams, sizeof(MHW_VDBOX_IND_OBJ_BASE_ADDR_PARAMS));
1339     MOS_ZeroMemory(m_picMhwParams.Vp9PicState, sizeof(MHW_VDBOX_VP9_PIC_STATE));
1340     MOS_ZeroMemory(m_picMhwParams.Vp9SegmentState, sizeof(MHW_VDBOX_VP9_SEGMENT_STATE));
1341 
1342     for (uint16_t i = 0; i < 4; i++)
1343     {
1344         m_picMhwParams.SurfaceParams[i] = MOS_New(MHW_VDBOX_SURFACE_PARAMS);
1345         MOS_ZeroMemory(m_picMhwParams.SurfaceParams[i], sizeof(MHW_VDBOX_SURFACE_PARAMS));
1346     }
1347 
1348     return eStatus;
1349 }
1350