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