1 /*
2 * Copyright (c) 2021-2024, 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     decode_vvc_packet.cpp
24 //! \brief    Defines the interface for vvc decode packet
25 //!
26 #include "decode_vvc_packet.h"
27 #include "decode_status_report_defs.h"
28 #include "decode_predication_packet.h"
29 #include "decode_marker_packet.h"
30 #include "decode_utils.h"
31 #include "decode_status_report_defs.h"
32 #include "mos_solo_generic.h"
33 #include "decode_resource_auto_lock.h"
34 #include "hal_oca_interface_next.h"
35 
36 namespace decode {
37 
Init()38 MOS_STATUS VvcDecodePkt::Init()
39 {
40     DECODE_FUNC_CALL();
41 
42     DECODE_CHK_NULL(m_statusReport);
43     DECODE_CHK_NULL(m_featureManager);
44     DECODE_CHK_NULL(m_vvcPipeline);
45     DECODE_CHK_NULL(m_osInterface);
46     DECODE_CHK_NULL(m_vdencItf);
47 
48     DECODE_CHK_STATUS(CmdPacket::Init());
49 
50     CalculateVvcSliceLvlCmdSize();
51 
52     m_vvcBasicFeature = dynamic_cast<VvcBasicFeature*>(m_featureManager->GetFeature(FeatureIDs::basicFeature));
53     DECODE_CHK_NULL(m_vvcBasicFeature);
54 
55     m_allocator = m_vvcPipeline->GetDecodeAllocator();
56     DECODE_CHK_NULL(m_allocator);
57 
58     DECODE_CHK_STATUS(m_statusReport->RegistObserver(this));
59 
60     DecodeSubPacket* subPacket = m_vvcPipeline->GetSubPacket(DecodePacketId(m_vvcPipeline, vvcPictureSubPacketId));
61 
62     m_picturePkt = dynamic_cast<VvcDecodePicPkt*>(subPacket);
63     DECODE_CHK_NULL(m_picturePkt);
64     DECODE_CHK_STATUS(m_picturePkt->CalculateCommandSize(m_pictureStatesSize, m_picturePatchListSize));
65 
66     subPacket = m_vvcPipeline->GetSubPacket(DecodePacketId(m_vvcPipeline, vvcSliceSubPacketId));
67     m_slicePkt = dynamic_cast<VvcDecodeSlicePkt*>(subPacket);
68     DECODE_CHK_NULL(m_slicePkt);
69     DECODE_CHK_STATUS(m_slicePkt->CalculateCommandSize(m_sliceStatesSize, m_slicePatchListSize));
70     DECODE_CHK_STATUS(m_slicePkt->CalculateTileCommandSize(m_tileStateSize, m_tilePatchListSize));
71 
72     return MOS_STATUS_SUCCESS;
73 }
74 
Prepare()75 MOS_STATUS VvcDecodePkt::Prepare()
76 {
77     DECODE_FUNC_CALL();
78 
79     DECODE_CHK_NULL(m_vvcBasicFeature->m_vvcPicParams);
80     m_vvcPicParams = m_vvcBasicFeature->m_vvcPicParams;
81 
82     return MOS_STATUS_SUCCESS;
83 }
84 
Destroy()85 MOS_STATUS VvcDecodePkt::Destroy()
86 {
87     m_statusReport->UnregistObserver(this);
88 
89     return MOS_STATUS_SUCCESS;
90 }
91 
SetPerfTag(CODECHAL_MODE mode,uint16_t picCodingType)92 void VvcDecodePkt::SetPerfTag(CODECHAL_MODE mode, uint16_t picCodingType)
93 {
94     DECODE_FUNC_CALL();
95 
96     uint16_t perfTag = ((mode << 4) & 0xF0) | (picCodingType & 0xF);
97     m_osInterface->pfnIncPerfFrameID(m_osInterface);
98     m_osInterface->pfnSetPerfTag(m_osInterface, perfTag);
99     m_osInterface->pfnResetPerfBufferID(m_osInterface);
100 }
101 
IsPrologRequired()102 bool VvcDecodePkt::IsPrologRequired()
103 {
104     //If long format mode, vvc packet will be first packet to execute, need send prolog
105     //If not single task mode, vvc packet will submit separatly, also need send prolog
106     if (!m_vvcBasicFeature->m_shortFormatInUse || !m_vvcPipeline->IsSingleTaskPhaseSupported())
107     {
108         return true;
109     }
110 
111     return false;
112 }
113 
AddForceWakeup(MOS_COMMAND_BUFFER & cmdBuffer)114 MOS_STATUS VvcDecodePkt::AddForceWakeup(MOS_COMMAND_BUFFER& cmdBuffer)
115 {
116     DECODE_FUNC_CALL();
117 
118     auto &par = m_miItf->GETPAR_MI_FORCE_WAKEUP();
119     MOS_ZeroMemory(&par, sizeof(mhw::mi::MI_FORCE_WAKEUP_PAR));
120     par.bMFXPowerWellControl      = false;
121     par.bMFXPowerWellControlMask  = true;
122     par.bHEVCPowerWellControl     = true;
123     par.bHEVCPowerWellControlMask = true;
124 
125     DECODE_CHK_STATUS(m_miItf->ADDCMD_MI_FORCE_WAKEUP(&cmdBuffer));
126 
127     return MOS_STATUS_SUCCESS;
128 }
129 
SendPrologWithFrameTracking(MOS_COMMAND_BUFFER & cmdBuffer,bool frameTrackingRequested)130 MOS_STATUS VvcDecodePkt::SendPrologWithFrameTracking(MOS_COMMAND_BUFFER& cmdBuffer, bool frameTrackingRequested)
131 {
132     DecodeSubPacket* subPacket = m_vvcPipeline->GetSubPacket(DecodePacketId(m_vvcPipeline, markerSubPacketId));
133     DecodeMarkerPkt *makerPacket = dynamic_cast<DecodeMarkerPkt*>(subPacket);
134     DECODE_CHK_NULL(makerPacket);
135     DECODE_CHK_STATUS(makerPacket->Execute(cmdBuffer));
136 
137 #ifdef _MMC_SUPPORTED
138     m_mmcState = m_vvcPipeline->GetMmcState();
139     bool isMmcEnabled = (m_mmcState != nullptr && m_mmcState->IsMmcEnabled());
140 #endif
141 
142     MHW_GENERIC_PROLOG_PARAMS  genericPrologParams;
143     MOS_ZeroMemory(&genericPrologParams, sizeof(genericPrologParams));
144     genericPrologParams.pOsInterface = m_osInterface;
145     genericPrologParams.pvMiInterface = nullptr;
146 
147 #ifdef _MMC_SUPPORTED
148     genericPrologParams.bMmcEnabled = isMmcEnabled;
149 #endif
150 
151     DECODE_CHK_STATUS(Mhw_SendGenericPrologCmdNext(&cmdBuffer, &genericPrologParams, m_miItf));
152 
153     subPacket = m_vvcPipeline->GetSubPacket(DecodePacketId(m_vvcPipeline, predicationSubPacketId));
154     DecodePredicationPkt *predicationPacket = dynamic_cast<DecodePredicationPkt*>(subPacket);
155     DECODE_CHK_NULL(predicationPacket);
156     DECODE_CHK_STATUS(predicationPacket->Execute(cmdBuffer));
157 
158     return MOS_STATUS_SUCCESS;
159 }
160 
VdPipelineFlush(MOS_COMMAND_BUFFER & cmdBuffer)161 MOS_STATUS VvcDecodePkt::VdPipelineFlush(MOS_COMMAND_BUFFER & cmdBuffer)
162 {
163     DECODE_FUNC_CALL();
164 
165     auto &par = m_vdencItf->MHW_GETPAR_F(VD_PIPELINE_FLUSH)();
166     par       = {};
167 
168     par.waitDoneVDCmdMsgParser     = true;
169 #ifdef _MEDIA_RESERVED
170     par.vvcpPipelineCommandFlush   = true;
171     par.vvcpPipelineDone           = true;
172 #endif
173     DECODE_CHK_STATUS(m_vdencItf->MHW_ADDCMD_F(VD_PIPELINE_FLUSH)(&cmdBuffer));
174 
175     return MOS_STATUS_SUCCESS;
176 }
177 
MiFlush(MOS_COMMAND_BUFFER & cmdBuffer)178 MOS_STATUS VvcDecodePkt::MiFlush(MOS_COMMAND_BUFFER & cmdBuffer)
179 {
180     DECODE_FUNC_CALL();
181 
182     auto &par = m_miItf->GETPAR_MI_FLUSH_DW();
183     MOS_ZeroMemory(&par, sizeof(mhw::mi::MI_FLUSH_DW_PAR));
184     DECODE_CHK_STATUS(m_miItf->ADDCMD_MI_FLUSH_DW(&cmdBuffer));
185 
186     return MOS_STATUS_SUCCESS;
187 }
188 
Completed(void * mfxStatus,void * rcsStatus,void * statusReport)189 MOS_STATUS VvcDecodePkt::Completed(void *mfxStatus, void *rcsStatus, void *statusReport)
190 {
191     DECODE_FUNC_CALL();
192 
193     DECODE_CHK_NULL(mfxStatus);
194     DECODE_CHK_NULL(statusReport);
195     DECODE_CHK_NULL(m_vvcBasicFeature);
196 
197     DecodeStatusMfx *       decodeStatusMfx  = (DecodeStatusMfx *)mfxStatus;
198     DecodeStatusReportData *statusReportData = (DecodeStatusReportData *)statusReport;
199     DECODE_VERBOSEMESSAGE("Current Frame Index = %d", statusReportData->currDecodedPic.FrameIdx);
200 
201     return MOS_STATUS_SUCCESS;
202 }
203 
CalculateCommandSize(uint32_t & commandBufferSize,uint32_t & requestedPatchListSize)204 MOS_STATUS VvcDecodePkt::CalculateCommandSize(uint32_t &commandBufferSize, uint32_t &requestedPatchListSize)
205 {
206     commandBufferSize = CalculateCommandBufferSize();
207     requestedPatchListSize = CalculatePatchListSize();
208 
209     // Picture-level cmd / patch list size is added only one time
210     if (m_picCmdSizeCalculated == false)
211     {
212         commandBufferSize += CalculatePicCommandSize();
213         requestedPatchListSize += CalculatePicPatchListSize();
214         m_picCmdSizeCalculated = true;
215     }
216 
217     return MOS_STATUS_SUCCESS;
218 }
219 
CalculateCommandBufferSize()220 uint32_t VvcDecodePkt::CalculateCommandBufferSize()
221 {
222     // Cmd buffer size added per slice
223     return m_sliceStatesSize;
224 }
225 
CalculatePatchListSize()226 uint32_t VvcDecodePkt::CalculatePatchListSize()
227 {
228     // Patch list size added per slice
229     if (!m_osInterface->bUsesPatchList)
230     {
231         return 0;
232     }
233 
234     return m_slicePatchListSize;
235 }
236 
CalculatePicCommandSize()237 uint32_t VvcDecodePkt::CalculatePicCommandSize()
238 {
239     // add tile cmd size for each frame
240     uint32_t tileCmdSize = (m_vvcBasicFeature->m_tileCols * m_vvcBasicFeature->m_tileRows) * m_tileStateSize;
241 
242     return tileCmdSize + m_pictureStatesSize + COMMAND_BUFFER_RESERVED_SPACE;
243 }
244 
CalculatePicPatchListSize()245 uint32_t VvcDecodePkt::CalculatePicPatchListSize()
246 {
247     if (!m_osInterface->bUsesPatchList)
248     {
249         return 0;
250     }
251     // add tile patch list size for each frame
252     uint32_t tilePatchListSize = (m_vvcBasicFeature->m_tileCols * m_vvcBasicFeature->m_tileRows) * m_tilePatchListSize;
253 
254     return tilePatchListSize + m_picturePatchListSize;
255 }
256 
ReadVvcpStatus(MediaStatusReport * statusReport,MOS_COMMAND_BUFFER & cmdBuffer)257 MOS_STATUS VvcDecodePkt::ReadVvcpStatus(MediaStatusReport* statusReport, MOS_COMMAND_BUFFER& cmdBuffer)
258 {
259     DECODE_FUNC_CALL();
260 
261     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
262 
263     DECODE_CHK_NULL(statusReport);
264 
265     //TODO: VVC MMIO has new mechanism
266 
267     return eStatus;
268 }
269 
StartStatusReport(uint32_t srType,MOS_COMMAND_BUFFER * cmdBuffer)270 MOS_STATUS VvcDecodePkt::StartStatusReport(uint32_t srType, MOS_COMMAND_BUFFER* cmdBuffer)
271 {
272     DECODE_FUNC_CALL();
273     DECODE_CHK_NULL(cmdBuffer);
274     DECODE_CHK_STATUS(MediaPacket::StartStatusReportNext(srType, cmdBuffer));
275 
276     SetPerfTag(CODECHAL_MODE(CODECHAL_DECODE_MODE_VVCVLD), m_vvcBasicFeature->m_pictureCodingType);
277 
278     MediaPerfProfiler *perfProfiler = MediaPerfProfiler::Instance();
279     DECODE_CHK_NULL(perfProfiler);
280     DECODE_CHK_STATUS(perfProfiler->AddPerfCollectStartCmd(
281         (void *)m_vvcPipeline, m_osInterface, m_miItf, cmdBuffer));
282 
283     return MOS_STATUS_SUCCESS;
284 }
285 
EndStatusReport(uint32_t srType,MOS_COMMAND_BUFFER * cmdBuffer)286 MOS_STATUS VvcDecodePkt::EndStatusReport(uint32_t srType, MOS_COMMAND_BUFFER* cmdBuffer)
287 {
288     DECODE_FUNC_CALL();
289 
290     DECODE_CHK_NULL(cmdBuffer);
291 
292     DECODE_CHK_STATUS(ReadVvcpStatus(m_statusReport, *cmdBuffer));
293     DECODE_CHK_STATUS(MediaPacket::EndStatusReportNext(srType, cmdBuffer));
294 
295     MediaPerfProfiler *perfProfiler = MediaPerfProfiler::Instance();
296     DECODE_CHK_NULL(perfProfiler);
297     DECODE_CHK_STATUS(perfProfiler->AddPerfCollectEndCmd(
298         (void *)m_vvcPipeline, m_osInterface, m_miItf, cmdBuffer));
299 
300     return MOS_STATUS_SUCCESS;
301 }
302 
InitPicLevelCmdBuffer(MHW_BATCH_BUFFER & batchBuffer,uint8_t * batchBufBase)303 MOS_STATUS VvcDecodePkt::InitPicLevelCmdBuffer(MHW_BATCH_BUFFER &batchBuffer, uint8_t *batchBufBase)
304 {
305     DECODE_FUNC_CALL();
306 
307     auto &cmdBuffer = m_picCmdBuffer;
308     MOS_ZeroMemory(&cmdBuffer, sizeof(MOS_COMMAND_BUFFER));
309     cmdBuffer.pCmdBase   = (uint32_t*)batchBufBase;
310     cmdBuffer.pCmdPtr    = cmdBuffer.pCmdBase;
311     cmdBuffer.iRemaining = batchBuffer.iSize;
312     cmdBuffer.OsResource = batchBuffer.OsResource;
313 
314     return MOS_STATUS_SUCCESS;
315 }
316 
317 #if USE_CODECHAL_DEBUG_TOOL
DumpResources(DecodeStatusMfx * decodeStatusMfx,DecodeStatusReportData * statusReportData)318 MOS_STATUS VvcDecodePkt::DumpResources(
319     DecodeStatusMfx *       decodeStatusMfx,
320     DecodeStatusReportData *statusReportData)
321 {
322     DECODE_FUNC_CALL();
323     DECODE_CHK_NULL(decodeStatusMfx);
324     DECODE_CHK_NULL(statusReportData);
325 
326     return MOS_STATUS_SUCCESS;
327 }
328 #endif
329 
Submit(MOS_COMMAND_BUFFER * cmdBuffer,uint8_t packetPhase)330 MOS_STATUS VvcDecodePkt::Submit(
331     MOS_COMMAND_BUFFER* cmdBuffer,
332     uint8_t packetPhase)
333 {
334     DECODE_FUNC_CALL()
335 
336     PERF_UTILITY_AUTO(__FUNCTION__, PERF_DECODE, PERF_LEVEL_HAL);
337 
338     DECODE_CHK_NULL(cmdBuffer);
339     DECODE_CHK_NULL(m_hwInterface);
340 
341     m_isFirstSliceInFrame = (m_vvcBasicFeature->m_curSlice == 0) ? true : false;
342     m_isLastSliceInFrame = (m_vvcBasicFeature->m_curSlice == m_vvcBasicFeature->m_numSlices - 1) ? true : false;
343 
344     if (m_isFirstSliceInFrame)
345     {
346         DECODE_CHK_STATUS(m_miItf->SetWatchdogTimerThreshold(m_vvcBasicFeature->m_width, m_vvcBasicFeature->m_height, false));
347 
348         DECODE_CHK_STATUS(Mos_Solo_PreProcessDecode(m_osInterface, &m_vvcBasicFeature->m_destSurface));
349 
350         auto mmioRegisters = m_hwInterface->GetVdencInterfaceNext()->GetMmioRegisters(MHW_VDBOX_NODE_1);
351 
352         HalOcaInterfaceNext::On1stLevelBBStart(*cmdBuffer, (MOS_CONTEXT_HANDLE)m_osInterface->pOsContext, m_osInterface->CurrentGpuContextHandle, m_miItf, *mmioRegisters);
353         if (m_vvcBasicFeature->m_shortFormatInUse)
354         {
355             m_tileLevelBB = m_vvcPipeline->GetTileLvlCmdBuffer();
356         }
357     }
358 
359     DECODE_CHK_STATUS(PackPictureLevelCmds(*cmdBuffer));
360 
361     if (!m_vvcBasicFeature->m_shortFormatInUse)
362     {
363         DECODE_CHK_STATUS(PackSliceLevelCmds(*cmdBuffer));
364     }
365     else
366     {
367         DECODE_CHK_STATUS(PackS2LSliceLevelCmds(*cmdBuffer));
368     }
369 
370     if (m_isLastSliceInFrame)
371     {
372         HalOcaInterfaceNext::On1stLevelBBEnd(*cmdBuffer, *m_osInterface);
373         m_picCmdSizeCalculated = false; // Reset flag for running next frame
374     }
375 
376     if (m_isFirstSliceInFrame)
377     {
378         DECODE_CHK_STATUS(m_allocator->SyncOnResource(&m_vvcBasicFeature->m_resDataBuffer, false));
379     }
380 
381     m_vvcBasicFeature->m_curSlice++; //Update current slice index
382 
383     //Set ReadyToExecute to true for the last slice of the frame
384     Mos_Solo_SetReadyToExecute(m_osInterface, m_vvcBasicFeature->m_frameCompletedFlag);
385     DECODE_CHK_STATUS(Mos_Solo_PostProcessDecode(m_osInterface, &m_vvcBasicFeature->m_destSurface));
386 
387     return MOS_STATUS_SUCCESS;
388 }
389 
PackPictureLevelCmds(MOS_COMMAND_BUFFER & cmdBuffer)390 MOS_STATUS VvcDecodePkt::PackPictureLevelCmds(MOS_COMMAND_BUFFER& cmdBuffer)
391 {
392     DECODE_FUNC_CALL()
393 
394     PERF_UTILITY_AUTO(__FUNCTION__, PERF_DECODE, PERF_LEVEL_HAL);
395 
396     if (m_isFirstSliceInFrame)
397     {
398         if (IsPrologRequired())
399         {
400             DECODE_CHK_STATUS(AddForceWakeup(cmdBuffer));
401             DECODE_CHK_STATUS(SendPrologWithFrameTracking(cmdBuffer, true));
402         }
403         DECODE_CHK_STATUS(StartStatusReport(statusReportMfx, &cmdBuffer));
404     }
405 
406     DECODE_CHK_STATUS(m_picturePkt->InitVvcState(cmdBuffer));
407 
408     // For multi-slice case, picture level cmds are the same among different slices.
409     // Put them into 2nd level BB to prepare them only once for the 1st slice of the frame to reduce SW latency.
410     if (m_isFirstSliceInFrame)
411     {
412         m_picBatchBuf = m_picturePkt->GetPicLvlBB();
413 
414         if (m_picBatchBuf != nullptr)
415         {
416             ResourceAutoLock resLock(m_allocator, &m_picBatchBuf->OsResource);
417             uint8_t *batchBufBase = (uint8_t *)resLock.LockResourceForWrite();
418             DECODE_CHK_STATUS(InitPicLevelCmdBuffer(*m_picBatchBuf, batchBufBase));
419             DECODE_CHK_STATUS(m_picturePkt->Execute(m_picCmdBuffer));
420             DECODE_CHK_STATUS(m_miItf->AddMiBatchBufferEnd(&m_picCmdBuffer, nullptr));
421         }
422     }
423 
424     DECODE_CHK_STATUS(m_miItf->ADDCMD_MI_BATCH_BUFFER_START(&cmdBuffer, m_picBatchBuf));
425 
426     return MOS_STATUS_SUCCESS;
427 }
428 
CalculateVvcSliceLvlCmdSize()429 void VvcDecodePkt::CalculateVvcSliceLvlCmdSize()
430 {
431     m_vvcpSliceCmdSize = m_vvcpItf->GETSIZE_VVCP_SLICE_STATE() +
432                          m_vvcpItf->GETSIZE_VVCP_REF_IDX_STATE() * 2 +
433                          m_vvcpItf->GETSIZE_VVCP_WEIGHTOFFSET_STATE() * 2 +
434                          m_vvcpItf->GETSIZE_VVCP_BSD_OBJECT() +
435                          m_miItf->GETSIZE_MI_BATCH_BUFFER_START();
436 }
437 
PackS2LSliceLevelCmds(MOS_COMMAND_BUFFER & cmdBuffer)438 MOS_STATUS VvcDecodePkt::PackS2LSliceLevelCmds(MOS_COMMAND_BUFFER &cmdBuffer)
439 {
440     DECODE_FUNC_CALL()
441 
442     PERF_UTILITY_AUTO(__FUNCTION__, PERF_DECODE, PERF_LEVEL_HAL);
443     uint16_t sliceIdx = m_vvcBasicFeature->m_curSlice;
444 
445     if (sliceIdx < m_vvcBasicFeature->m_numSlices)
446     {
447         auto buf = m_vvcPipeline->GetSliceLvlCmdBuffer();
448         DECODE_CHK_NULL(buf);
449         buf->dwOffset = m_vvcPipeline->GetSliceLvlBufSize() * sliceIdx;
450         DECODE_CHK_STATUS(m_miItf->ADDCMD_MI_BATCH_BUFFER_START(&cmdBuffer, buf)); //Jump to Slice Batch Buffer
451         DECODE_CHK_STATUS(VdMemoryFlush(cmdBuffer));
452         DECODE_CHK_STATUS(VdPipelineFlush(cmdBuffer));
453     }
454     if (m_isLastSliceInFrame)
455     {
456         DECODE_CHK_STATUS(EnsureAllCommandsExecuted(cmdBuffer));
457         DECODE_CHK_STATUS(EndStatusReport(statusReportMfx, &cmdBuffer));
458         DECODE_CHK_STATUS(UpdateStatusReportNext(statusReportGlobalCount, &cmdBuffer));
459     }
460 
461     CODECHAL_DEBUG_TOOL(
462         if (m_mmcState) {
463             m_mmcState->UpdateUserFeatureKey(&(m_vvcBasicFeature->m_destSurface));
464         })
465 
466     if (m_isLastSliceInFrame)
467     {
468         DECODE_CHK_STATUS(m_miItf->AddMiBatchBufferEnd(&cmdBuffer, nullptr));
469     }
470     return MOS_STATUS_SUCCESS;
471 }
472 
PackSliceLevelCmds(MOS_COMMAND_BUFFER & cmdBuffer)473 MOS_STATUS VvcDecodePkt::PackSliceLevelCmds(MOS_COMMAND_BUFFER& cmdBuffer)
474 {
475     DECODE_FUNC_CALL()
476 
477     PERF_UTILITY_AUTO(__FUNCTION__, PERF_DECODE, PERF_LEVEL_HAL);
478 
479     uint16_t sliceIdx = m_vvcBasicFeature->m_curSlice;
480     if ( sliceIdx < m_vvcBasicFeature->m_numSlices)
481     {
482         DECODE_CHK_STATUS(m_slicePkt->Execute(cmdBuffer, m_vvcBasicFeature->m_sliceIdxInOrder[sliceIdx]));
483         DECODE_CHK_STATUS(VdMemoryFlush(cmdBuffer));
484         DECODE_CHK_STATUS(VdPipelineFlush(cmdBuffer));
485     }
486 
487     if (m_isLastSliceInFrame)
488     {
489         DECODE_CHK_STATUS(EnsureAllCommandsExecuted(cmdBuffer));
490         DECODE_CHK_STATUS(EndStatusReport(statusReportMfx, &cmdBuffer));
491         DECODE_CHK_STATUS(UpdateStatusReportNext(statusReportGlobalCount, &cmdBuffer));
492     }
493 
494     CODECHAL_DEBUG_TOOL(
495         if (m_mmcState)
496         {
497             m_mmcState->UpdateUserFeatureKey(&(m_vvcBasicFeature->m_destSurface));
498         })
499 
500     if (m_isLastSliceInFrame)
501     {
502         DECODE_CHK_STATUS(m_miItf->AddMiBatchBufferEnd(&cmdBuffer, nullptr));
503     }
504 
505     return MOS_STATUS_SUCCESS;
506 }
507 
VdMemoryFlush(MOS_COMMAND_BUFFER & cmdBuffer)508 MOS_STATUS VvcDecodePkt::VdMemoryFlush(MOS_COMMAND_BUFFER& cmdBuffer)
509 {
510     DECODE_FUNC_CALL()
511 
512     auto &par = m_vvcpItf->MHW_GETPAR_F(VVCP_VD_CONTROL_STATE)();
513     par       = {};
514 
515     par.memoryImplicitFlush = true;
516 
517     DECODE_CHK_STATUS(m_vvcpItf->MHW_ADDCMD_F(VVCP_VD_CONTROL_STATE)(&cmdBuffer));
518 
519     return MOS_STATUS_SUCCESS;
520 }
521 
EnsureAllCommandsExecuted(MOS_COMMAND_BUFFER & cmdBuffer)522 MOS_STATUS VvcDecodePkt::EnsureAllCommandsExecuted(MOS_COMMAND_BUFFER& cmdBuffer)
523 {
524     DECODE_FUNC_CALL()
525 
526     // Send MI_FLUSH command
527     auto &par = m_miItf->GETPAR_MI_FLUSH_DW();
528     par       = {};
529     auto *skuTable = m_vvcPipeline->GetSkuTable();
530     if (skuTable && MEDIA_IS_SKU(skuTable, FtrEnablePPCFlush))
531     {
532         // Add PPC fulsh
533         par.bEnablePPCFlush = true;
534     }
535     DECODE_CHK_STATUS(m_miItf->ADDCMD_MI_FLUSH_DW(&cmdBuffer));
536 
537     return MOS_STATUS_SUCCESS;
538 }
539 
540 }
541