1 /*
2 * Copyright (c) 2019-2023, 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     encode_av1_vdenc_packet.cpp
24 //! \brief    Defines the interface for av1 encode vdenc packet
25 //!
26 #include <numeric>
27 #include "encode_av1_vdenc_packet.h"
28 #include "encode_status_report_defs.h"
29 #include "codec_def_common_av1.h"
30 #include "media_perf_profiler.h"
31 #include "hal_oca_interface_next.h"
32 #include "mos_solo_generic.h"
33 
34 namespace encode{
Av1VdencPkt(MediaPipeline * pipeline,MediaTask * task,CodechalHwInterfaceNext * hwInterface)35     Av1VdencPkt::Av1VdencPkt(MediaPipeline* pipeline, MediaTask* task, CodechalHwInterfaceNext* hwInterface) :
36         CmdPacket(task),
37         m_pipeline(dynamic_cast<Av1VdencPipeline*>(pipeline)),
38         m_hwInterface(hwInterface)
39     {
40         ENCODE_CHK_NULL_NO_STATUS_RETURN(hwInterface);
41         ENCODE_CHK_NULL_NO_STATUS_RETURN(m_hwInterface);
42         ENCODE_CHK_NULL_NO_STATUS_RETURN(m_pipeline);
43 
44         m_osInterface = hwInterface->GetOsInterface();
45         m_statusReport = m_pipeline->GetStatusReportInstance();
46         m_featureManager = m_pipeline->GetPacketLevelFeatureManager(Av1Pipeline::Av1VdencPacket);
47 
48         m_vdencItf = std::static_pointer_cast<mhw::vdbox::vdenc::Itf>(m_hwInterface->GetVdencInterfaceNext());
49         m_avpItf   = std::static_pointer_cast<mhw::vdbox::avp::Itf>(m_hwInterface->GetAvpInterfaceNext());
50         m_miItf    = std::static_pointer_cast<mhw::mi::Itf> (m_hwInterface->GetMiInterfaceNext());
51 
52         if (m_vdencItf)
53         {
54             mhw::vdbox::vdenc::RowStorePar par = {};
55 
56             par.mode = mhw::vdbox::vdenc::RowStorePar::AV1;
57 
58             ENCODE_CHK_STATUS_NO_STATUS_RETURN(m_vdencItf->SetRowstoreCachingOffsets(par));
59         }
60         if(m_osInterface)
61         {
62             m_userSettingPtr = m_osInterface->pfnGetUserSettingInstance(m_osInterface);
63         }
64         if (!m_userSettingPtr)
65         {
66             ENCODE_NORMALMESSAGE("Initialize m_userSettingPtr instance failed!");
67         }
68     }
69 
StartStatusReport(uint32_t srType,MOS_COMMAND_BUFFER * cmdBuffer)70     MOS_STATUS Av1VdencPkt::StartStatusReport(
71         uint32_t            srType,
72         MOS_COMMAND_BUFFER *cmdBuffer)
73     {
74         ENCODE_FUNC_CALL();
75         ENCODE_CHK_NULL_RETURN(cmdBuffer);
76 
77         ENCODE_CHK_STATUS_RETURN(MediaPacket::StartStatusReportNext(srType, cmdBuffer));
78 
79         MediaPerfProfiler *perfProfiler = MediaPerfProfiler::Instance();
80         ENCODE_CHK_NULL_RETURN(perfProfiler);
81         ENCODE_CHK_STATUS_RETURN(perfProfiler->AddPerfCollectStartCmd(
82             (void *)m_pipeline, m_osInterface, m_miItf, cmdBuffer));
83 
84         return MOS_STATUS_SUCCESS;
85     }
86 
AddPictureVdencCommands(MOS_COMMAND_BUFFER & cmdBuffer)87     MOS_STATUS Av1VdencPkt::AddPictureVdencCommands(MOS_COMMAND_BUFFER &cmdBuffer)
88     {
89         ENCODE_FUNC_CALL();
90 
91         SETPAR_AND_ADDCMD(VDENC_CONTROL_STATE, m_vdencItf, &cmdBuffer);
92         SETPAR_AND_ADDCMD(VDENC_PIPE_MODE_SELECT, m_vdencItf, &cmdBuffer);
93         SETPAR_AND_ADDCMD(VDENC_SRC_SURFACE_STATE, m_vdencItf, &cmdBuffer);
94         SETPAR_AND_ADDCMD(VDENC_REF_SURFACE_STATE, m_vdencItf, &cmdBuffer);
95         SETPAR_AND_ADDCMD(VDENC_DS_REF_SURFACE_STATE, m_vdencItf, &cmdBuffer);
96         SETPAR_AND_ADDCMD(VDENC_PIPE_BUF_ADDR_STATE, m_vdencItf, &cmdBuffer);
97 
98         return MOS_STATUS_SUCCESS;
99     }
100 
EndStatusReport(uint32_t srType,MOS_COMMAND_BUFFER * cmdBuffer)101     MOS_STATUS Av1VdencPkt::EndStatusReport(uint32_t srType, MOS_COMMAND_BUFFER *cmdBuffer)
102     {
103         ENCODE_FUNC_CALL();
104         ENCODE_CHK_NULL_RETURN(cmdBuffer);
105 
106         ENCODE_CHK_STATUS_RETURN(ReadAvpStatus(m_vdboxIndex, m_statusReport, *cmdBuffer));
107         ENCODE_CHK_STATUS_RETURN(MediaPacket::EndStatusReportNext(srType, cmdBuffer));
108 
109         MediaPerfProfiler *perfProfiler = MediaPerfProfiler::Instance();
110         ENCODE_CHK_NULL_RETURN(perfProfiler);
111         ENCODE_CHK_STATUS_RETURN(perfProfiler->AddPerfCollectEndCmd(
112             (void *)m_pipeline, m_osInterface, m_miItf, cmdBuffer));
113 
114         return MOS_STATUS_SUCCESS;
115     }
116 
ReadAvpStatus(MHW_VDBOX_NODE_IND vdboxIndex,MediaStatusReport * statusReport,MOS_COMMAND_BUFFER & cmdBuffer)117     MOS_STATUS Av1VdencPkt::ReadAvpStatus(MHW_VDBOX_NODE_IND vdboxIndex, MediaStatusReport *statusReport, MOS_COMMAND_BUFFER &cmdBuffer)
118     {
119         ENCODE_FUNC_CALL();
120         MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
121 
122         CODEC_HW_FUNCTION_ENTER;
123 
124         ENCODE_CHK_NULL_RETURN(statusReport);
125         ENCODE_CHK_NULL_RETURN(m_hwInterface);
126 
127         MOS_RESOURCE *osResource = nullptr;
128         uint32_t      offset     = 0;
129 
130         EncodeStatusReadParams params;
131         MOS_ZeroMemory(&params, sizeof(params));
132 
133         ENCODE_CHK_STATUS_RETURN(statusReport->GetAddress(encode::statusReportMfxBitstreamByteCountPerFrame, osResource, offset));
134         params.resBitstreamByteCountPerFrame    = osResource;
135         params.bitstreamByteCountPerFrameOffset = offset;
136 
137         ENCODE_CHK_STATUS_RETURN(statusReport->GetAddress(encode::statusReportQPStatusCount, osResource, offset));
138         params.resQpStatusCount    = osResource;
139         params.qpStatusCountOffset = offset;
140 
141         ENCODE_CHK_STATUS_RETURN(statusReport->GetAddress(encode::statusReportImageStatusMask, osResource, offset));
142         params.resImageStatusMask    = osResource;
143         params.imageStatusMaskOffset = offset;
144 
145         ENCODE_CHK_STATUS_RETURN(statusReport->GetAddress(encode::statusReportImageStatusCtrl, osResource, offset));
146         params.resImageStatusCtrl    = osResource;
147         params.imageStatusCtrlOffset = offset;
148 
149         CODEC_HW_CHK_COND_RETURN((vdboxIndex > m_hwInterface->GetMaxVdboxIndex()), "ERROR - vdbox index exceed the maximum");
150 
151         auto &flushDwParams = m_miItf->MHW_GETPAR_F(MI_FLUSH_DW)();
152         flushDwParams       = {};
153         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_FLUSH_DW)(&cmdBuffer));
154 
155         ENCODE_CHK_NULL_RETURN(m_avpItf);
156         auto mmioRegisters = m_avpItf->GetMmioRegisters(vdboxIndex);
157 
158         auto &miStoreRegMemParams           = m_miItf->MHW_GETPAR_F(MI_STORE_REGISTER_MEM)();
159         miStoreRegMemParams                 = {};
160         miStoreRegMemParams.presStoreBuffer = params.resBitstreamByteCountPerFrame;
161         miStoreRegMemParams.dwOffset        = params.bitstreamByteCountPerFrameOffset;
162         miStoreRegMemParams.dwRegister      = mmioRegisters->avpAv1BitstreamByteCountTileRegOffset;
163         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_STORE_REGISTER_MEM)(&cmdBuffer));
164 
165         miStoreRegMemParams                 = {};
166         miStoreRegMemParams.presStoreBuffer = params.resQpStatusCount;
167         miStoreRegMemParams.dwOffset        = params.qpStatusCountOffset;
168         miStoreRegMemParams.dwRegister      = mmioRegisters->avpAv1QpStatusCountRegOffset;
169         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_STORE_REGISTER_MEM)(&cmdBuffer));
170 
171         miStoreRegMemParams                 = {};
172         miStoreRegMemParams.presStoreBuffer = params.resImageStatusMask;
173         miStoreRegMemParams.dwOffset        = params.imageStatusMaskOffset;
174         miStoreRegMemParams.dwRegister      = mmioRegisters->avpAv1ImageStatusMaskRegOffset;
175         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_STORE_REGISTER_MEM)(&cmdBuffer));
176 
177         miStoreRegMemParams                 = {};
178         miStoreRegMemParams.presStoreBuffer = params.resImageStatusCtrl;
179         miStoreRegMemParams.dwOffset        = params.imageStatusCtrlOffset;
180         miStoreRegMemParams.dwRegister      = mmioRegisters->avpAv1ImageStatusControlRegOffset;
181         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_STORE_REGISTER_MEM)(&cmdBuffer));
182 
183         flushDwParams = {};
184         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_FLUSH_DW)(&cmdBuffer));
185 
186         return MOS_STATUS_SUCCESS;
187     }
188 
Init()189     MOS_STATUS Av1VdencPkt::Init()
190     {
191         ENCODE_FUNC_CALL();
192         ENCODE_CHK_NULL_RETURN(m_statusReport);
193         ENCODE_CHK_STATUS_RETURN(CmdPacket::Init());
194 
195         m_basicFeature = dynamic_cast<Av1BasicFeature *>(m_featureManager->GetFeature(Av1FeatureIDs::basicFeature));
196         ENCODE_CHK_NULL_RETURN(m_basicFeature);
197 
198 #ifdef _MMC_SUPPORTED
199         m_mmcState = m_pipeline->GetMmcState();
200         ENCODE_CHK_NULL_RETURN(m_mmcState);
201         m_basicFeature->m_mmcState = m_mmcState;
202 #endif
203         m_allocator = m_pipeline->GetEncodeAllocator();
204         ENCODE_CHK_STATUS_RETURN(AllocateResources());
205 
206         ENCODE_CHK_STATUS_RETURN(m_statusReport->RegistObserver(this));
207 
208         CalculateVdencCommandsSize();
209         CalculateAvpCommandsSize();
210 
211         m_usePatchList = m_osInterface->bUsesPatchList;
212 
213         return MOS_STATUS_SUCCESS;
214     }
215 
Submit(MOS_COMMAND_BUFFER * commandBuffer,uint8_t packetPhase)216     MOS_STATUS Av1VdencPkt::Submit(MOS_COMMAND_BUFFER *commandBuffer, uint8_t packetPhase)
217     {
218         ENCODE_FUNC_CALL();
219 
220         ENCODE_CHK_NULL_RETURN(commandBuffer);
221         MOS_COMMAND_BUFFER &cmdBuffer = *commandBuffer;
222         ENCODE_CHK_STATUS_RETURN(Mos_Solo_PreProcessEncode(m_osInterface, &m_basicFeature->m_resBitstreamBuffer, &m_basicFeature->m_reconSurface));
223 
224         // Ensure the input is ready to be read.
225         // Currently, mos RegisterResource has sync limitation for Raw resource.
226         // Temporaly, call Resource Wait to do the sync explicitly.
227         // TODO, Refine it when MOS refactor ready.
228         MOS_SYNC_PARAMS syncParams;
229         syncParams                  = g_cInitSyncParams;
230         syncParams.GpuContext       = m_osInterface->pfnGetGpuContext(m_osInterface);
231         syncParams.presSyncResource = &m_basicFeature->m_rawSurface.OsResource;
232         syncParams.bReadOnly        = true;
233         ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceWait(m_osInterface, &syncParams));
234         m_osInterface->pfnSetResourceSyncTag(m_osInterface, &syncParams);
235 
236         // Set flag to boost GPU frequency for low latency in remote gaming scenario
237         cmdBuffer.Attributes.bFrequencyBoost = (m_av1SeqParams->ScenarioInfo == ESCENARIO_REMOTEGAMING);
238 
239         ENCODE_CHK_STATUS_RETURN(RegisterPostCdef());
240 
241         ENCODE_CHK_STATUS_RETURN(PatchPictureLevelCommands(packetPhase, cmdBuffer));
242 
243         ENCODE_CHK_STATUS_RETURN(PatchTileLevelCommands(cmdBuffer, packetPhase));
244 
245         ENCODE_CHK_STATUS_RETURN(PrepareHWMetaData(&cmdBuffer));
246 
247         ENCODE_CHK_STATUS_RETURN(Mos_Solo_PostProcessEncode(m_osInterface, &m_basicFeature->m_resBitstreamBuffer, &m_basicFeature->m_reconSurface));
248 #if MHW_HWCMDPARSER_ENABLED
249         auto instance = mhw::HwcmdParser::GetInstance();
250         if (instance)
251         {
252             instance->ParseCmdBuf(IGFX_UNKNOWN, cmdBuffer.pCmdBase, cmdBuffer.iOffset / sizeof(uint32_t));
253         }
254 #endif
255 #if USE_CODECHAL_DEBUG_TOOL
256         ENCODE_CHK_STATUS_RETURN(DumpStatistics());
257         ENCODE_CHK_STATUS_RETURN(Av1VdencPkt::DumpInput());
258 #endif  // USE_CODECHAL_DEBUG_TOOL
259         return MOS_STATUS_SUCCESS;
260     }
261 
AddCondBBEndFor2ndPass(MOS_COMMAND_BUFFER & cmdBuffer)262     MOS_STATUS Av1VdencPkt::AddCondBBEndFor2ndPass(MOS_COMMAND_BUFFER &cmdBuffer)
263     {
264         ENCODE_FUNC_CALL();
265 
266         if (m_pipeline->IsFirstPass() || m_pipeline->GetPassNum() == 1)
267         {
268             return MOS_STATUS_SUCCESS;
269         }
270 
271         auto &miConditionalBatchBufferEndParams = m_miItf->MHW_GETPAR_F(MI_CONDITIONAL_BATCH_BUFFER_END)();
272         miConditionalBatchBufferEndParams       = {};
273 
274         // VDENC uses HuC FW generated semaphore for conditional 2nd pass
275         miConditionalBatchBufferEndParams.presSemaphoreBuffer =
276             m_basicFeature->m_recycleBuf->GetBuffer(VdencBrcPakMmioBuffer, 0);
277 
278         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_CONDITIONAL_BATCH_BUFFER_END)(&cmdBuffer));
279 
280         return MOS_STATUS_SUCCESS;
281     }
282 
Construct3rdLevelBatch()283     MOS_STATUS Av1VdencPkt::Construct3rdLevelBatch()
284     {
285         MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
286 
287         //To be added. When BRC is enabled, some of the commands
288         //will be added into 3rd level batch
289 
290         return eStatus;
291     }
292 
UpdateUserFeatureKey(PMOS_SURFACE surface)293     MOS_STATUS Av1VdencPkt::UpdateUserFeatureKey(PMOS_SURFACE surface)
294     {
295         if (m_userFeatureUpdated_post_cdef)
296         {
297             return MOS_STATUS_SUCCESS;
298         }
299         m_userFeatureUpdated_post_cdef = true;
300 
301         ReportUserSetting(m_userSettingPtr,
302             "AV1 Post CDEF Recon Compressible",
303             surface->bCompressible,
304             MediaUserSetting::Group::Sequence);
305         ReportUserSetting(m_userSettingPtr,
306             "AV1 Post CDEF Recon Compress Mode",
307             surface->MmcState,
308             MediaUserSetting::Group::Sequence);
309 
310         return MOS_STATUS_SUCCESS;
311     }
312 
PatchPictureLevelCommands(const uint8_t & packetPhase,MOS_COMMAND_BUFFER & cmdBuffer)313     MOS_STATUS Av1VdencPkt::PatchPictureLevelCommands(const uint8_t &packetPhase, MOS_COMMAND_BUFFER  &cmdBuffer)
314     {
315         ENCODE_FUNC_CALL();
316 
317         ENCODE_CHK_STATUS_RETURN(m_miItf->SetWatchdogTimerThreshold(m_basicFeature->m_frameWidth, m_basicFeature->m_frameHeight, true));
318 
319         SetPerfTag();
320 
321         bool firstTaskInPhase = packetPhase & firstPacket;
322         if (!m_pipeline->IsSingleTaskPhaseSupported() || firstTaskInPhase)
323         {
324             ENCODE_CHK_STATUS_RETURN(AddForceWakeup(cmdBuffer));
325 
326             // Send command buffer header at the beginning (OS dependent)
327             ENCODE_CHK_STATUS_RETURN(SendPrologCmds(cmdBuffer));
328         }
329 
330         if (m_pipeline->IsDualEncEnabled())
331         {
332             auto scalability = m_pipeline->GetMediaScalability();
333             ENCODE_CHK_NULL_RETURN(scalability);
334             ENCODE_CHK_STATUS_RETURN(scalability->SyncPipe(syncOtherPipesForOne, 0, &cmdBuffer));
335         }
336 
337         ENCODE_CHK_STATUS_RETURN(AddCondBBEndFor2ndPass(cmdBuffer));
338 
339         if(m_pipeline->IsDualEncEnabled() && m_pipeline->IsFirstPipe())
340         {
341             PMOS_RESOURCE bsSizeBuf = m_basicFeature->m_recycleBuf->GetBuffer(PakInfo, 0);
342             ENCODE_CHK_NULL_RETURN(bsSizeBuf);
343             // clear bitstream size buffer at first tile
344             auto &miStoreDataParams            = m_miItf->MHW_GETPAR_F(MI_STORE_DATA_IMM)();
345             miStoreDataParams                  = {};
346             miStoreDataParams.pOsResource      = bsSizeBuf;
347             miStoreDataParams.dwResourceOffset = 0;
348             miStoreDataParams.dwValue          = 0;
349             ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_STORE_DATA_IMM)(&cmdBuffer));
350         }
351 
352         if (m_pipeline->IsFirstPipe())
353         {
354             ENCODE_CHK_STATUS_RETURN(StartStatusReport(statusReportMfx, &cmdBuffer));
355         }
356         else{
357             // add perf record for other pipes - first pipe perf record within StartStatusReport
358             MediaPerfProfiler *perfProfiler = MediaPerfProfiler::Instance();
359             ENCODE_CHK_NULL_RETURN(perfProfiler);
360             ENCODE_CHK_STATUS_RETURN(perfProfiler->AddPerfCollectStartCmd(
361                 (void *)m_pipeline, m_osInterface, m_miItf, &cmdBuffer));
362         }
363 
364         ENCODE_CHK_STATUS_RETURN(AddPictureVdencCommands(cmdBuffer));
365 
366         return MOS_STATUS_SUCCESS;
367     }
368 
SetPerfTag()369     void Av1VdencPkt::SetPerfTag()
370     {
371         ENCODE_FUNC_CALL();
372 
373         uint16_t callType = m_pipeline->IsFirstPass() ? CODECHAL_ENCODE_PERFTAG_CALL_PAK_ENGINE :
374             CODECHAL_ENCODE_PERFTAG_CALL_PAK_ENGINE_SECOND_PASS;
375         uint16_t picType  = (m_basicFeature->m_pictureCodingType == I_TYPE) ? 1 :
376             (m_basicFeature->m_ref.IsLowDelay() ? (m_basicFeature->m_ref.IsPFrame() ? 2 : 0) : 3);
377 
378         PerfTagSetting perfTag;
379         perfTag.Value             = 0;
380         perfTag.Mode              = (uint16_t)m_basicFeature->m_mode & CODECHAL_ENCODE_MODE_BIT_MASK;
381         perfTag.CallType          = callType;
382         perfTag.PictureCodingType = picType;
383         m_osInterface->pfnSetPerfTag(m_osInterface, perfTag.Value);
384         m_osInterface->pfnIncPerfBufferID(m_osInterface);
385     }
386 
PatchTileLevelCommands(MOS_COMMAND_BUFFER & cmdBuffer,uint8_t packetPhase)387     MOS_STATUS Av1VdencPkt::PatchTileLevelCommands(MOS_COMMAND_BUFFER &cmdBuffer, uint8_t packetPhase)
388     {
389         ENCODE_FUNC_CALL();
390 
391         uint16_t numTileColumns = 1;
392         uint16_t numTileRows    = 1;
393         RUN_FEATURE_INTERFACE_RETURN(Av1EncodeTile, Av1FeatureIDs::encodeTile, GetTileRowColumns, numTileRows, numTileColumns);
394 
395         ENCODE_CHK_NULL_RETURN(m_pipeline);
396         if (!m_pipeline->IsDualEncEnabled())
397         {
398             for (uint32_t tileRow = 0; tileRow < numTileRows; tileRow++)
399             {
400                 for (uint32_t tileCol = 0; tileCol < numTileColumns; tileCol++)
401                 {
402                     ENCODE_CHK_STATUS_RETURN(AddOneTileCommands(
403                         cmdBuffer,
404                         tileRow,
405                         tileCol));
406                 }
407             }
408         }
409         else
410         {
411             if (numTileRows != 1)  // dual encode only support column based workload submission
412             {
413                 ENCODE_ASSERTMESSAGE("dual encode cannot support multi rows submission yet.");
414                 return MOS_STATUS_INVALID_PARAMETER;
415             }
416             uint8_t dummyIdx = 0;
417             RUN_FEATURE_INTERFACE_RETURN(Av1EncodeTile, Av1FeatureIDs::encodeTile, GetDummyIdx, dummyIdx);
418             if (m_pipeline->GetCurrentPipe() == 0)
419             {
420                 for (auto i = 0; i < dummyIdx; i++)
421                 {
422                     ENCODE_CHK_STATUS_RETURN(AddOneTileCommands(
423                         cmdBuffer,
424                         0,
425                         i));
426                 }
427                 ENCODE_CHK_STATUS_RETURN(AddOneTileCommands(
428                     cmdBuffer,
429                     0,
430                     dummyIdx,
431                     1));
432             }
433             else
434             {
435                 for (auto i = dummyIdx; i < numTileColumns; i++)
436                 {
437                     ENCODE_CHK_STATUS_RETURN(AddOneTileCommands(
438                         cmdBuffer,
439                         0,
440                         i));
441                 }
442             }
443         }
444 
445         m_basicFeature->m_flushCmd = Av1BasicFeature::waitAvp;
446         SETPAR_AND_ADDCMD(VD_PIPELINE_FLUSH, m_vdencItf, &cmdBuffer);
447 
448         ENCODE_CHK_STATUS_RETURN(EnsureAllCommandsExecuted(cmdBuffer));
449 
450         // Wait all pipe cmds done for the packet
451         auto scalability = m_pipeline->GetMediaScalability();
452         ENCODE_CHK_NULL_RETURN(scalability);
453         ENCODE_CHK_STATUS_RETURN(scalability->SyncPipe(syncOnePipeWaitOthers, 0, &cmdBuffer));
454 
455         if (m_pipeline->IsFirstPipe())
456         {
457             if (m_pipeline->IsDualEncEnabled())
458             {
459                 for (auto i = 0; i < m_pipeline->GetPipeNum(); ++i)
460                 {
461                     ENCODE_CHK_STATUS_RETURN(scalability->ResetSemaphore(syncOnePipeWaitOthers, i, &cmdBuffer));
462                 }
463             }
464             ENCODE_CHK_STATUS_RETURN(EndStatusReport(statusReportMfx, &cmdBuffer));
465         }
466         else {
467             // add perf record for other pipes - first pipe perf record within EndStatusReport
468             MediaPerfProfiler* perfProfiler = MediaPerfProfiler::Instance();
469             ENCODE_CHK_NULL_RETURN(perfProfiler);
470             ENCODE_CHK_STATUS_RETURN(perfProfiler->AddPerfCollectEndCmd(
471                 (void*)m_pipeline, m_osInterface, m_miItf, &cmdBuffer));
472         }
473 
474         auto brcFeature = dynamic_cast<Av1Brc *>(m_featureManager->GetFeature(Av1FeatureIDs::av1BrcFeature));
475         ENCODE_CHK_NULL_RETURN(brcFeature);
476 
477         if (Mos_Solo_Extension((MOS_CONTEXT_HANDLE)m_osInterface->pOsContext))
478         {
479             ENCODE_CHK_STATUS_RETURN(MediaPacket::UpdateStatusReportNext(statusReportGlobalCount, &cmdBuffer));
480         }
481         else if (brcFeature->IsBRCEnabled() && m_osInterface->bInlineCodecStatusUpdate)
482         {
483             ENCODE_CHK_STATUS_RETURN(UpdateStatusReport(statusReportGlobalCount, &cmdBuffer));
484         }
485         else if (m_pipeline->IsLastPass() && m_pipeline->IsFirstPipe())
486         {
487             ENCODE_CHK_STATUS_RETURN(MediaPacket::UpdateStatusReportNext(statusReportGlobalCount, &cmdBuffer));
488         }
489 
490         if (m_pipeline->IsDualEncEnabled())
491         {
492             SETPAR_AND_ADDCMD(VDENC_CONTROL_STATE, m_vdencItf, &cmdBuffer);
493         }
494 
495         CODECHAL_DEBUG_TOOL(
496             if (m_mmcState) {
497                 m_mmcState->UpdateUserFeatureKey(&(m_basicFeature->m_reconSurface));
498             })
499 
500         if (m_basicFeature->m_postCdefReconSurfaceFlag)
501         {
502             PCODEC_REF_LIST currRefList  = m_basicFeature->m_ref.GetCurrRefList();
503             ENCODE_CHK_NULL_RETURN(currRefList);
504             MOS_SURFACE *postCdefSurface = m_basicFeature->m_trackedBuf->GetSurface(
505                 BufferType::postCdefReconSurface, currRefList->ucScalingIdx);
506             ENCODE_CHK_NULL_RETURN(postCdefSurface);
507             CODECHAL_DEBUG_TOOL(
508                 if (m_mmcState) {
509                     UpdateUserFeatureKey(postCdefSurface);
510             })
511         }
512 
513         UpdateParameters();
514 
515         return MOS_STATUS_SUCCESS;
516     }
517 
AddForceWakeup(MOS_COMMAND_BUFFER & cmdBuffer)518     MOS_STATUS Av1VdencPkt::AddForceWakeup(MOS_COMMAND_BUFFER &cmdBuffer)
519     {
520         ENCODE_FUNC_CALL();
521 
522         auto &forceWakeupParams                     = m_miItf->MHW_GETPAR_F(MI_FORCE_WAKEUP)();
523         forceWakeupParams                           = {};
524         forceWakeupParams.bMFXPowerWellControl      = true;
525         forceWakeupParams.bMFXPowerWellControlMask  = true;
526         forceWakeupParams.bHEVCPowerWellControl     = true;
527         forceWakeupParams.bHEVCPowerWellControlMask = true;
528 
529         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_FORCE_WAKEUP)(&cmdBuffer));
530 
531         return MOS_STATUS_SUCCESS;
532     }
533 
SendPrologCmds(MOS_COMMAND_BUFFER & cmdBuffer)534     MOS_STATUS Av1VdencPkt::SendPrologCmds(
535         MOS_COMMAND_BUFFER &cmdBuffer)
536     {
537         MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
538 
539         ENCODE_FUNC_CALL();
540 
541 #ifdef _MMC_SUPPORTED
542         ENCODE_CHK_NULL_RETURN(m_mmcState);
543         ENCODE_CHK_STATUS_RETURN(m_mmcState->SendPrologCmd(&cmdBuffer, false));
544 #endif
545 
546         MHW_GENERIC_PROLOG_PARAMS genericPrologParams;
547         MOS_ZeroMemory(&genericPrologParams, sizeof(genericPrologParams));
548         genericPrologParams.pOsInterface  = m_osInterface;
549         genericPrologParams.pvMiInterface = nullptr;
550         genericPrologParams.bMmcEnabled   = m_mmcState ? m_mmcState->IsMmcEnabled() : false;
551         ENCODE_CHK_STATUS_RETURN(Mhw_SendGenericPrologCmdNext(&cmdBuffer, &genericPrologParams, m_miItf));
552 
553         return eStatus;
554     }
555 
UpdateParameters()556     void Av1VdencPkt::UpdateParameters()
557     {
558         ENCODE_FUNC_CALL();
559 
560         m_prevFrameType  = m_av1PicParams->PicFlags.fields.frame_type;
561         if(m_pipeline->IsLastPass() && m_pipeline->IsFirstPipe())
562         {
563             m_basicFeature->m_encodedFrameNum++;
564         }
565 
566         if (!m_pipeline->IsSingleTaskPhaseSupported())
567         {
568             m_osInterface->pfnResetPerfBufferID(m_osInterface);
569         }
570     }
571 
SetPipeBufAddr(PMHW_VDBOX_PIPE_BUF_ADDR_PARAMS pipeBufAddrParams,MHW_VDBOX_SURFACE_PARAMS & srcSurfaceParams,MHW_VDBOX_SURFACE_PARAMS & reconSurfaceParams)572     MOS_STATUS Av1VdencPkt::SetPipeBufAddr(
573         PMHW_VDBOX_PIPE_BUF_ADDR_PARAMS pipeBufAddrParams,
574         MHW_VDBOX_SURFACE_PARAMS &      srcSurfaceParams,
575         MHW_VDBOX_SURFACE_PARAMS &      reconSurfaceParams)
576     {
577         ENCODE_FUNC_CALL();
578         ENCODE_CHK_NULL_RETURN(srcSurfaceParams.psSurface);
579         ENCODE_CHK_NULL_RETURN(reconSurfaceParams.psSurface);
580 
581 #ifdef _MMC_SUPPORTED
582         ENCODE_CHK_NULL_RETURN(m_mmcState);
583         if (m_mmcState->IsMmcEnabled())
584         {
585             ENCODE_CHK_STATUS_RETURN(m_mmcState->GetSurfaceMmcState(&m_basicFeature->m_reconSurface, &pipeBufAddrParams->PreDeblockSurfMmcState));
586             ENCODE_CHK_STATUS_RETURN(m_mmcState->GetSurfaceMmcState(&m_basicFeature->m_rawSurface, &pipeBufAddrParams->RawSurfMmcState));
587             ENCODE_CHK_STATUS_RETURN(m_mmcState->GetSurfaceMmcFormat(srcSurfaceParams.psSurface, &srcSurfaceParams.dwCompressionFormat));
588             ENCODE_CHK_STATUS_RETURN(m_mmcState->GetSurfaceMmcFormat(reconSurfaceParams.psSurface, &reconSurfaceParams.dwCompressionFormat));
589         }
590         else
591         {
592             pipeBufAddrParams->PreDeblockSurfMmcState = MOS_MEMCOMP_DISABLED;
593             pipeBufAddrParams->RawSurfMmcState        = MOS_MEMCOMP_DISABLED;
594         }
595 #endif
596 
597         CODECHAL_DEBUG_TOOL(
598             m_basicFeature->m_reconSurface.MmcState = pipeBufAddrParams->PreDeblockSurfMmcState;)
599 
600         return MOS_STATUS_SUCCESS;
601     }
602 
SetSurfaceState(PMHW_VDBOX_SURFACE_PARAMS surfaceStateParams)603     MOS_STATUS Av1VdencPkt::SetSurfaceState(
604         PMHW_VDBOX_SURFACE_PARAMS surfaceStateParams)
605     {
606         MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
607 
608         ENCODE_CHK_NULL_RETURN(surfaceStateParams);
609         ENCODE_CHK_NULL_RETURN(surfaceStateParams->psSurface);
610 
611         ENCODE_FUNC_CALL();
612 
613 #ifdef _MMC_SUPPORTED
614         ENCODE_CHK_NULL_RETURN(m_mmcState);
615         if (m_mmcState->IsMmcEnabled())
616         {
617             ENCODE_CHK_STATUS_RETURN(m_mmcState->GetSurfaceMmcState(surfaceStateParams->psSurface, &surfaceStateParams->mmcState));
618             ENCODE_CHK_STATUS_RETURN(m_mmcState->GetSurfaceMmcFormat(surfaceStateParams->psSurface, &surfaceStateParams->dwCompressionFormat));
619         }
620         else
621         {
622             surfaceStateParams->mmcState = MOS_MEMCOMP_DISABLED;
623         }
624 #endif
625         return eStatus;
626     }
627 
Prepare()628     MOS_STATUS Av1VdencPkt::Prepare()
629     {
630         ENCODE_FUNC_CALL();
631 
632         Av1Pipeline *pipeline = dynamic_cast<Av1Pipeline *>(m_pipeline);
633         ENCODE_CHK_NULL_RETURN(pipeline);
634 
635         m_av1SeqParams  = ((Av1BasicFeature *)m_basicFeature)->m_av1SeqParams;
636         m_av1PicParams  = ((Av1BasicFeature *)m_basicFeature)->m_av1PicParams;
637         m_nalUnitParams = ((Av1BasicFeature *)m_basicFeature)->m_nalUnitParams;
638 
639         SetRowstoreCachingOffsets();
640 
641         return MOS_STATUS_SUCCESS;
642     }
643 
SetRowstoreCachingOffsets()644     MOS_STATUS Av1VdencPkt::SetRowstoreCachingOffsets()
645     {
646         // Get row store cache offset as all the needed information is got here
647         if (m_avpItf->IsRowStoreCachingSupported())
648         {
649             MHW_VDBOX_ROWSTORE_PARAMS rowStoreParams;
650 
651             rowStoreParams.Mode             = codechalEncodeModeAv1;
652             rowStoreParams.dwPicWidth       = MOS_ALIGN_CEIL(m_basicFeature->m_frameWidth, av1MinBlockWidth);
653             rowStoreParams.ucChromaFormat   = m_basicFeature->m_outputChromaFormat;
654             rowStoreParams.ucBitDepthMinus8 = m_basicFeature->m_is10Bit ? 2 : 0;
655 
656             ENCODE_CHK_STATUS_RETURN(m_hwInterface->SetRowstoreCachingOffsets(&rowStoreParams));
657         }
658         return MOS_STATUS_SUCCESS;
659     }
660 
Completed(void * mfxStatus,void * rcsStatus,void * statusReport)661     MOS_STATUS Av1VdencPkt::Completed(void *mfxStatus, void *rcsStatus, void *statusReport)
662     {
663         ENCODE_FUNC_CALL();
664 
665         ENCODE_CHK_NULL_RETURN(mfxStatus);
666         ENCODE_CHK_NULL_RETURN(statusReport);
667         ENCODE_CHK_NULL_RETURN(m_basicFeature);
668 
669         EncodeStatusMfx        *encodeStatusMfx  = (EncodeStatusMfx *)mfxStatus;
670         EncodeStatusReportData *statusReportData = (EncodeStatusReportData *)statusReport;
671 
672         uint32_t statBufIdx     = statusReportData->currOriginalPic.FrameIdx;
673         const EncodeReportTileData *tileReportData = nullptr;
674         RUN_FEATURE_INTERFACE_RETURN(Av1EncodeTile, Av1FeatureIDs::encodeTile, GetReportTileData, statBufIdx, tileReportData);
675         ENCODE_CHK_NULL_RETURN(tileReportData);
676 
677         MOS_RESOURCE *tileRecordBuffer = nullptr;
678         RUN_FEATURE_INTERFACE_RETURN(Av1EncodeTile, Av1FeatureIDs::encodeTile, GetTileRecordBuffer, statBufIdx, tileRecordBuffer);
679         ENCODE_CHK_NULL_RETURN(tileRecordBuffer);
680 
681         MOS_LOCK_PARAMS lockFlags;
682         MOS_ZeroMemory(&lockFlags, sizeof(MOS_LOCK_PARAMS));
683         PakHwTileSizeRecord *tileRecord =
684             (PakHwTileSizeRecord *)m_allocator->Lock(tileRecordBuffer, &lockFlags);
685         ENCODE_CHK_NULL_RETURN(tileRecord);
686 
687         statusReportData->bitstreamSize = 0;
688         for (uint32_t i = 0; i < statusReportData->numberTilesInFrame; i++)
689         {
690             if (tileRecord[i].Length == 0)
691             {
692                 statusReportData->codecStatus = CODECHAL_STATUS_INCOMPLETE;
693                 return MOS_STATUS_SUCCESS;
694             }
695 
696             statusReportData->bitstreamSize += tileRecord[i].Length;
697         }
698 
699 #if (_DEBUG || _RELEASE_INTERNAL)
700         if (m_basicFeature->m_enableSWStitching)
701         {
702             PerformSwStitch(tileReportData, tileRecord, statusReportData);
703         }
704 #endif
705         if (tileRecord)
706         {
707             m_allocator->UnLock(tileRecordBuffer);
708         }
709 
710         statusReportData->numberPasses = (uint8_t)encodeStatusMfx->imageStatusCtrl.avpTotalNumPass + 1;  //initial pass is considered to be 0,hence +1 to report;
711         ENCODE_VERBOSEMESSAGE("statusReportData->numberPasses: %d\n", statusReportData->numberPasses);
712 
713         uint32_t log2MaxSbSize   = av1MiSizeLog2 + av1MinMibSizeLog2;
714         uint32_t frameWidthInSb  = MOS_ALIGN_CEIL(statusReportData->frameWidth, (1 << log2MaxSbSize)) >> log2MaxSbSize;
715         uint32_t frameHeightInSb = MOS_ALIGN_CEIL(statusReportData->frameHeight, (1 << log2MaxSbSize)) >> log2MaxSbSize;
716         if (frameWidthInSb != 0 && frameHeightInSb != 0)
717         {
718             ENCODE_CHK_NULL_RETURN(m_basicFeature->m_av1SeqParams);
719             statusReportData->qpY = (uint8_t)(((uint32_t)encodeStatusMfx->qpStatusCount.avpCumulativeQP) / (frameWidthInSb * frameHeightInSb));
720             ENCODE_VERBOSEMESSAGE("statusReportData->qpY: %d\n", statusReportData->qpY);
721         }
722 
723         CODECHAL_DEBUG_TOOL(
724             ENCODE_CHK_STATUS_RETURN(DumpResources(encodeStatusMfx, statusReportData)););
725 
726         m_basicFeature->Reset((CODEC_REF_LIST *)statusReportData->currRefList);
727 
728         return MOS_STATUS_SUCCESS;
729     }
730 
731 #if (_DEBUG || _RELEASE_INTERNAL)
PerformSwStitch(const EncodeReportTileData * tileReportData,PakHwTileSizeRecord * tileRecord,EncodeStatusReportData * statusReportData)732     MOS_STATUS Av1VdencPkt::PerformSwStitch(
733         const EncodeReportTileData *tileReportData,
734         PakHwTileSizeRecord *       tileRecord,
735         EncodeStatusReportData *    statusReportData)
736     {
737         ENCODE_FUNC_CALL();
738 
739         ENCODE_CHK_NULL_RETURN(tileReportData);
740         ENCODE_CHK_NULL_RETURN(tileRecord);
741 
742         uint8_t *tempBsBuffer = nullptr, *bufPtr = nullptr;
743         tempBsBuffer = bufPtr = (uint8_t *)MOS_AllocAndZeroMemory(statusReportData->bitstreamSize);
744         ENCODE_CHK_NULL_RETURN(tempBsBuffer);
745 
746         PCODEC_REF_LIST currRefList = (PCODEC_REF_LIST)statusReportData->currRefList;
747 
748         MOS_LOCK_PARAMS lockFlags;
749         MOS_ZeroMemory(&lockFlags, sizeof(MOS_LOCK_PARAMS));
750         lockFlags.ReadOnly = 1;
751         uint8_t *bitstream = (uint8_t *)m_allocator->Lock(
752             &currRefList->resBitstreamBuffer,
753             &lockFlags);
754         if (bitstream == nullptr)
755         {
756             MOS_FreeMemory(tempBsBuffer);
757             ENCODE_CHK_NULL_RETURN(nullptr);
758         }
759 
760         for (uint32_t i = 0; i < statusReportData->numberTilesInFrame; i++)
761         {
762             uint32_t offset = MOS_ALIGN_CEIL(tileReportData[i].bitstreamByteOffset * CODECHAL_CACHELINE_SIZE, MOS_PAGE_SIZE);
763             uint32_t len    = tileRecord[i].Length;
764 
765             MOS_SecureMemcpy(bufPtr, len, &bitstream[offset], len);
766             bufPtr += len;
767         }
768 
769         MOS_SecureMemcpy(bitstream, statusReportData->bitstreamSize, tempBsBuffer, statusReportData->bitstreamSize);
770         MOS_ZeroMemory(&bitstream[statusReportData->bitstreamSize], m_basicFeature->m_bitstreamSize - statusReportData->bitstreamSize);
771 
772         if (bitstream)
773         {
774             m_allocator->UnLock(&currRefList->resBitstreamBuffer);
775         }
776 
777         MOS_FreeMemory(tempBsBuffer);
778 
779         return MOS_STATUS_SUCCESS;
780     }
781 #endif
782 
Destroy()783     MOS_STATUS Av1VdencPkt::Destroy()
784     {
785         ENCODE_FUNC_CALL();
786 
787         m_statusReport->UnregistObserver(this);
788         return MOS_STATUS_SUCCESS;
789     }
790 
AllocateResources()791     MOS_STATUS Av1VdencPkt::AllocateResources()
792     {
793         ENCODE_FUNC_CALL();
794 
795         ENCODE_CHK_NULL_RETURN(m_allocator);
796         ENCODE_CHK_NULL_RETURN(m_pipeline);
797         MOS_ALLOC_GFXRES_PARAMS allocParamsForBufferLinear;
798         MOS_ZeroMemory(&allocParamsForBufferLinear, sizeof(MOS_ALLOC_GFXRES_PARAMS));
799         allocParamsForBufferLinear.Type               = MOS_GFXRES_BUFFER;
800         allocParamsForBufferLinear.TileType           = MOS_TILE_LINEAR;
801         allocParamsForBufferLinear.Format             = Format_Buffer;
802         allocParamsForBufferLinear.Flags.bNotLockable = true;
803 
804         uint32_t maxTileNumber              = CODECHAL_GET_WIDTH_IN_BLOCKS(m_basicFeature->m_frameWidth, av1MinTileWidth) *
805                                               CODECHAL_GET_HEIGHT_IN_BLOCKS(m_basicFeature->m_frameHeight, av1MinTileHeight);
806 
807         allocParamsForBufferLinear.dwBytes  = MOS_ROUNDUP_DIVIDE(m_basicFeature->m_frameWidth, av1SuperBlockWidth) * MHW_CACHELINE_SIZE * 2 * 2;
808         allocParamsForBufferLinear.pBufName = "vdencIntraRowStoreScratch";
809         allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ;
810         m_vdencIntraRowStoreScratch         = m_allocator->AllocateResource(allocParamsForBufferLinear, false);
811         ENCODE_CHK_NULL_RETURN(m_vdencIntraRowStoreScratch);
812 
813         allocParamsForBufferLinear.Flags.bNotLockable = !(m_basicFeature->m_lockableResource);
814         allocParamsForBufferLinear.dwBytes  = MOS_ALIGN_CEIL(m_basicFeature->m_vdencBrcStatsBufferSize * maxTileNumber, MHW_CACHELINE_SIZE);
815         allocParamsForBufferLinear.pBufName = "VDEncStatsBuffer";
816         allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_WRITE;
817         m_resVDEncStatsBuffer               = m_allocator->AllocateResource(allocParamsForBufferLinear, false);
818         ENCODE_CHK_NULL_RETURN(m_resVDEncStatsBuffer);
819 
820         if (m_osInterface->bInlineCodecStatusUpdate)
821         {
822             MOS_LOCK_PARAMS lockFlagsWriteOnly;
823             MOS_ZeroMemory(&lockFlagsWriteOnly, sizeof(MOS_LOCK_PARAMS));
824             lockFlagsWriteOnly.WriteOnly = 1;
825 
826             m_atomicScratchBuf.size = MOS_ALIGN_CEIL(sizeof(AtomicScratchBuffer), sizeof(uint64_t));
827             allocParamsForBufferLinear.Type     = MOS_GFXRES_BUFFER;
828             allocParamsForBufferLinear.TileType = MOS_TILE_LINEAR;
829             allocParamsForBufferLinear.Format   = Format_Buffer;
830 
831             uint32_t size        = MHW_CACHELINE_SIZE * 4 * 2;  //  each set of scratch is 4 cacheline size, and allocate 2 set.
832             allocParamsForBufferLinear.dwBytes      = size;
833             allocParamsForBufferLinear.pBufName     = "atomic sratch buffer";
834             allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ_WRITE_CACHE;
835 
836             m_atomicScratchBuf.resAtomicScratchBuffer = m_allocator->AllocateResource(allocParamsForBufferLinear, false);
837 
838             ENCODE_CHK_NULL_RETURN(m_atomicScratchBuf.resAtomicScratchBuffer);
839 
840             uint8_t *data = (uint8_t *)m_osInterface->pfnLockResource(
841                 m_osInterface,
842                 m_atomicScratchBuf.resAtomicScratchBuffer,
843                 &lockFlagsWriteOnly);
844 
845             ENCODE_CHK_NULL_RETURN(data);
846 
847             MOS_ZeroMemory(data, size);
848             m_atomicScratchBuf.pData             = (uint32_t *)data;
849             m_atomicScratchBuf.size              = size;
850             m_atomicScratchBuf.zeroValueOffset   = 0;
851             m_atomicScratchBuf.operand1Offset    = MHW_CACHELINE_SIZE;
852             m_atomicScratchBuf.operand2Offset    = MHW_CACHELINE_SIZE * 2;
853             m_atomicScratchBuf.operand3Offset    = MHW_CACHELINE_SIZE * 3;
854             m_atomicScratchBuf.encodeUpdateIndex = 0;
855             m_atomicScratchBuf.tearDownIndex     = 1;
856             m_atomicScratchBuf.operandSetSize    = MHW_CACHELINE_SIZE * 4;
857 
858             ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnUnlockResource(m_osInterface, m_atomicScratchBuf.resAtomicScratchBuffer));
859         }
860 
861         mhw::vdbox::avp::AvpBufferSizePar avpBufSizeParam;
862         memset(&avpBufSizeParam, 0, sizeof(avpBufSizeParam));
863         avpBufSizeParam.bitDepthIdc      = (m_basicFeature->m_bitDepth - 8) >> 1;
864         avpBufSizeParam.height           = CODECHAL_GET_HEIGHT_IN_BLOCKS(m_basicFeature->m_frameHeight, av1SuperBlockHeight);
865         avpBufSizeParam.width            = CODECHAL_GET_WIDTH_IN_BLOCKS(m_basicFeature->m_frameWidth, av1SuperBlockWidth);
866         avpBufSizeParam.tileWidth        = CODECHAL_GET_HEIGHT_IN_BLOCKS(av1MaxTileWidth, av1SuperBlockWidth);
867         avpBufSizeParam.isSb128x128      = 0;
868         avpBufSizeParam.curFrameTileNum  = av1MaxTileNum;
869         avpBufSizeParam.numTileCol       = av1MaxTileColumn;
870         avpBufSizeParam.numOfActivePipes = 1;
871         avpBufSizeParam.chromaFormat     = m_basicFeature->m_chromaFormat;
872 
873         MOS_ALLOC_GFXRES_PARAMS allocParams;
874         MOS_ZeroMemory(&allocParams, sizeof(MOS_ALLOC_GFXRES_PARAMS));
875         allocParams.Type               = MOS_GFXRES_BUFFER;
876         allocParams.TileType           = MOS_TILE_LINEAR;
877         allocParams.Format             = Format_Buffer;
878         allocParams.Flags.bNotLockable = false;
879         uint32_t numResources          = m_pipeline->IsDualEncEnabled() ? AV1_NUM_OF_DUAL_CTX : 1;
880         for (auto i = 0; i < AV1_NUM_OF_DUAL_CTX; i++)
881         {
882             // Bistream decode Tile Line rowstore buffer
883             if (!m_avpItf->IsBufferRowstoreCacheEnabled(mhw::vdbox::avp::bsdTileLineBuffer))
884             {
885                 ENCODE_CHK_STATUS_RETURN(m_avpItf->GetAvpBufSize(mhw::vdbox::avp::bsdTileLineBuffer, &avpBufSizeParam));
886                 allocParams.dwBytes                                      = avpBufSizeParam.bufferSize;
887                 allocParams.pBufName                                     = "Bitstream Decoder Encoder Tile Line Rowstore Read Write buffer";
888                 m_basicFeature->m_bitstreamDecoderEncoderTileLineRowstoreReadWriteBuffer[i] = m_allocator->AllocateResource(allocParams, false);
889             }
890 
891             // Deblocker Filter Tile Line Read/Write Y Buffer
892             ENCODE_CHK_STATUS_RETURN(m_avpItf->GetAvpBufSize(mhw::vdbox::avp::deblockTileLineYBuffer, &avpBufSizeParam));
893             allocParams.dwBytes = avpBufSizeParam.bufferSize;
894             allocParams.pBufName = "Deblocker Filter Tile Line Read Write Y Buffer";
895             m_basicFeature->m_deblockerFilterTileLineReadWriteYBuffer[i] = m_allocator->AllocateResource(allocParams, false);
896 
897             // Deblocker Filter Tile Line Read/Write U Buffer
898             ENCODE_CHK_STATUS_RETURN(m_avpItf->GetAvpBufSize(mhw::vdbox::avp::deblockTileLineUBuffer, &avpBufSizeParam));
899             allocParams.dwBytes = avpBufSizeParam.bufferSize;
900             allocParams.pBufName = "Deblocker Filter Tile Line Read Write U Buffer";
901             m_basicFeature->m_deblockerFilterTileLineReadWriteUBuffer[i] = m_allocator->AllocateResource(allocParams, false);
902 
903             // Deblocker Filter Tile Line Read/Write V Buffer
904             ENCODE_CHK_STATUS_RETURN(m_avpItf->GetAvpBufSize(mhw::vdbox::avp::deblockTileLineVBuffer, &avpBufSizeParam));
905             allocParams.dwBytes = avpBufSizeParam.bufferSize;
906             allocParams.pBufName = "Deblocker Filter Tile Line Read Write V Buffer";
907             m_basicFeature->m_deblockerFilterTileLineReadWriteVBuffer[i] = m_allocator->AllocateResource(allocParams, false);
908 
909             // Deblocker Filter Tile Column Read/Write Y Buffer
910             ENCODE_CHK_STATUS_RETURN(m_avpItf->GetAvpBufSize(mhw::vdbox::avp::deblockTileColYBuffer, &avpBufSizeParam));
911             allocParams.dwBytes = avpBufSizeParam.bufferSize;
912             allocParams.pBufName = "Deblocker Filter Tile Column Read Write Y Buffer";
913             m_basicFeature->m_deblockerFilterTileColumnReadWriteYBuffer[i]  = m_allocator->AllocateResource(allocParams, false);
914 
915             // Deblocker Filter Tile Column Read/Write U Buffer
916             ENCODE_CHK_STATUS_RETURN(m_avpItf->GetAvpBufSize(mhw::vdbox::avp::deblockTileColUBuffer, &avpBufSizeParam));
917             allocParams.dwBytes = avpBufSizeParam.bufferSize;
918             allocParams.pBufName = "Deblocker Filter Tile Column Read Write U Buffer";
919             m_basicFeature->m_deblockerFilterTileColumnReadWriteUBuffer[i]  = m_allocator->AllocateResource(allocParams, false);
920 
921             // Deblocker Filter Tile Column Read/Write V Buffer
922             ENCODE_CHK_STATUS_RETURN(m_avpItf->GetAvpBufSize(mhw::vdbox::avp::deblockTileColVBuffer, &avpBufSizeParam));
923             allocParams.dwBytes = avpBufSizeParam.bufferSize;
924             allocParams.pBufName = "Deblocker Filter Tile Column Read Write V Buffer";
925             m_basicFeature->m_deblockerFilterTileColumnReadWriteVBuffer[i]  = m_allocator->AllocateResource(allocParams, false);
926 
927             // CDEF Filter Line Read/Write Buffer
928             ENCODE_CHK_STATUS_RETURN(m_avpItf->GetAvpBufSize(mhw::vdbox::avp::cdefLineBuffer, &avpBufSizeParam));
929             allocParams.dwBytes                             = avpBufSizeParam.bufferSize;
930             allocParams.pBufName                            = "CDEF Filter Line Read Write Buffer";
931             m_basicFeature->m_cdefFilterLineReadWriteBuffer[i] = m_allocator->AllocateResource(allocParams, false);
932 
933             // CDEF Filter Tile Line Read/Write Buffer
934             ENCODE_CHK_STATUS_RETURN(m_avpItf->GetAvpBufSize(mhw::vdbox::avp::cdefTileLineBuffer, &avpBufSizeParam));
935             allocParams.dwBytes                                 = avpBufSizeParam.bufferSize;
936             allocParams.pBufName                                = "CDEF Filter Tile Line Read Write Buffer";
937             m_basicFeature->m_cdefFilterTileLineReadWriteBuffer[i] = m_allocator->AllocateResource(allocParams, false);
938 
939             // CDEF Filter Tile Column Read/Write Buffer
940             ENCODE_CHK_STATUS_RETURN(m_avpItf->GetAvpBufSize(mhw::vdbox::avp::cdefTileColBuffer, &avpBufSizeParam));
941             allocParams.dwBytes                                   = avpBufSizeParam.bufferSize;
942             allocParams.pBufName                                  = "CDEF Filter Tile Column Read Write Buffer";
943             m_basicFeature->m_cdefFilterTileColumnReadWriteBuffer[i] = m_allocator->AllocateResource(allocParams, false);
944 
945             // CDEF Filter Meta Tile Line Read Write Buffer
946             ENCODE_CHK_STATUS_RETURN(m_avpItf->GetAvpBufSize(mhw::vdbox::avp::cdefMetaTileLineBuffer, &avpBufSizeParam));
947             allocParams.dwBytes                                     = avpBufSizeParam.bufferSize;
948             allocParams.pBufName                                    = "CDEF Filter Meta Tile Line Read Write Buffer";
949             m_basicFeature->m_cdefFilterMetaTileLineReadWriteBuffer[i] = m_allocator->AllocateResource(allocParams, false);
950 
951             // CDEF Filter Meta Tile Column Read Write Buffer
952             ENCODE_CHK_STATUS_RETURN(m_avpItf->GetAvpBufSize(mhw::vdbox::avp::cdefMetaTileColBuffer, &avpBufSizeParam));
953             allocParams.dwBytes                                       = avpBufSizeParam.bufferSize;
954             allocParams.pBufName                                      = "CDEF Filter Meta Tile Column Read Write Buffer";
955             m_basicFeature->m_cdefFilterMetaTileColumnReadWriteBuffer[i] = m_allocator->AllocateResource(allocParams, false);
956 
957             // CDEF Filter Top Left Corner Read Write Buffer
958             ENCODE_CHK_STATUS_RETURN(m_avpItf->GetAvpBufSize(mhw::vdbox::avp::cdefTopLeftCornerBuffer, &avpBufSizeParam));
959             allocParams.dwBytes                                      = avpBufSizeParam.bufferSize;
960             allocParams.pBufName                                     = "CDEF Filter Top Left Corner Read Write Buffer";
961             m_basicFeature->m_cdefFilterTopLeftCornerReadWriteBuffer[i] = m_allocator->AllocateResource(allocParams, false);
962         }
963 
964         return MOS_STATUS_SUCCESS;
965     }
966 
ReadPakMmioRegisters(PMOS_COMMAND_BUFFER cmdBuf,bool firstTile)967     MOS_STATUS Av1VdencPkt::ReadPakMmioRegisters(PMOS_COMMAND_BUFFER cmdBuf, bool firstTile)
968     {
969         ENCODE_FUNC_CALL();
970 
971         ENCODE_CHK_NULL_RETURN(cmdBuf);
972 
973         auto mmioRegs = m_miItf->GetMmioRegisters();
974         auto mmioRegsAvp = m_avpItf->GetMmioRegisters(MHW_VDBOX_NODE_1);
975         ENCODE_CHK_NULL_RETURN(mmioRegs);
976         PMOS_RESOURCE bsSizeBuf = m_basicFeature->m_recycleBuf->GetBuffer(PakInfo, 0);
977         ENCODE_CHK_NULL_RETURN(bsSizeBuf);
978 
979         if (firstTile)
980         {
981             // clear bitstream size buffer at first tile
982             auto &miStoreDataParams            = m_miItf->MHW_GETPAR_F(MI_STORE_DATA_IMM)();
983             miStoreDataParams                  = {};
984             miStoreDataParams.pOsResource      = bsSizeBuf;
985             miStoreDataParams.dwResourceOffset = 0;
986             miStoreDataParams.dwValue          = 0;
987             ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_STORE_DATA_IMM)(cmdBuf));
988         }
989 
990         // load current tile size to VCS_GPR0_Lo
991         auto &miLoadRegaParams         = m_miItf->MHW_GETPAR_F(MI_LOAD_REGISTER_REG)();
992         miLoadRegaParams               = {};
993         miLoadRegaParams.dwSrcRegister = mmioRegsAvp->avpAv1BitstreamByteCountTileRegOffset;
994         miLoadRegaParams.dwDstRegister = mmioRegs->generalPurposeRegister0LoOffset;
995         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_LOAD_REGISTER_REG)(cmdBuf));
996 
997         // load bitstream size buffer to VCS_GPR4_Lo
998         auto &miLoadRegMemParams           = m_miItf->MHW_GETPAR_F(MI_LOAD_REGISTER_MEM)();
999         miLoadRegMemParams                 = {};
1000         miLoadRegMemParams.presStoreBuffer = bsSizeBuf;
1001         miLoadRegMemParams.dwOffset        = 0;
1002         miLoadRegMemParams.dwRegister      = mmioRegs->generalPurposeRegister4LoOffset;
1003         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_LOAD_REGISTER_MEM)(cmdBuf));
1004 
1005         mhw::mi::MHW_MI_ALU_PARAMS aluParams[4] = {};
1006         int32_t aluCount               = 0;
1007 
1008         //load1 srca, reg1
1009         aluParams[aluCount].AluOpcode  = MHW_MI_ALU_LOAD;
1010         aluParams[aluCount].Operand1   = MHW_MI_ALU_SRCA;
1011         aluParams[aluCount].Operand2   = MHW_MI_ALU_GPREG0;
1012         ++aluCount;
1013 
1014         //load2 srcb, reg2
1015         aluParams[aluCount].AluOpcode  = MHW_MI_ALU_LOAD;
1016         aluParams[aluCount].Operand1   = MHW_MI_ALU_SRCB;
1017         aluParams[aluCount].Operand2   = MHW_MI_ALU_GPREG4;
1018         ++aluCount;
1019 
1020         //add srca + srcb
1021         aluParams[aluCount].AluOpcode  = MHW_MI_ALU_ADD;
1022         ++aluCount;
1023 
1024         //store reg1, accu
1025         aluParams[aluCount].AluOpcode  = MHW_MI_ALU_STORE;
1026         aluParams[aluCount].Operand1   = MHW_MI_ALU_GPREG0;
1027         aluParams[aluCount].Operand2   = MHW_MI_ALU_ACCU;
1028         ++aluCount;
1029 
1030         auto &miMathParams              = m_miItf->MHW_GETPAR_F(MI_MATH)();
1031         miMathParams                    = {};
1032         miMathParams.dwNumAluParams     = aluCount;
1033         miMathParams.pAluPayload        = aluParams;
1034         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_MATH)(cmdBuf));
1035 
1036         //store VCS_GPR0_Lo to bitstream size buffer
1037         auto &miStoreRegMemParams              = m_miItf->MHW_GETPAR_F(MI_STORE_REGISTER_MEM)();
1038         miStoreRegMemParams                                  = {};
1039         miStoreRegMemParams.presStoreBuffer                  = bsSizeBuf;
1040         miStoreRegMemParams.dwOffset                         = 0;
1041         miStoreRegMemParams.dwRegister                       = mmioRegs->generalPurposeRegister0LoOffset;
1042         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_STORE_REGISTER_MEM)(cmdBuf));
1043 
1044         // Make Flush DW call to make sure all previous work is done
1045         auto &flushDwParams              = m_miItf->MHW_GETPAR_F(MI_FLUSH_DW)();
1046         flushDwParams                    = {};
1047         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_FLUSH_DW)(cmdBuf));
1048 
1049         return MOS_STATUS_SUCCESS;
1050     }
1051 
ReadPakMmioRegistersAtomic(PMOS_COMMAND_BUFFER cmdBuf)1052     MOS_STATUS Av1VdencPkt::ReadPakMmioRegistersAtomic(PMOS_COMMAND_BUFFER cmdBuf)
1053     {
1054         ENCODE_FUNC_CALL();
1055 
1056         ENCODE_CHK_NULL_RETURN(cmdBuf);
1057 
1058         auto mmioRegs = m_miItf->GetMmioRegisters();
1059         auto mmioRegsAvp = m_avpItf->GetMmioRegisters(MHW_VDBOX_NODE_1);
1060         ENCODE_CHK_NULL_RETURN(mmioRegs);
1061 
1062         PMOS_RESOURCE bsSizeBuf = m_basicFeature->m_recycleBuf->GetBuffer(PakInfo, 0);
1063         ENCODE_CHK_NULL_RETURN(bsSizeBuf);
1064         ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnSkipResourceSync(bsSizeBuf));
1065 
1066         // load current tile size to VCS_GPR0_Lo
1067         auto &miLoadRegaParams         = m_miItf->MHW_GETPAR_F(MI_LOAD_REGISTER_REG)();
1068         miLoadRegaParams               = {};
1069         miLoadRegaParams.dwSrcRegister = mmioRegsAvp->avpAv1BitstreamByteCountTileRegOffset;
1070         miLoadRegaParams.dwDstRegister = mmioRegs->generalPurposeRegister0LoOffset;
1071         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_LOAD_REGISTER_REG)(cmdBuf));
1072 
1073         // clear VCS_GPR0_Hi for sanity
1074         auto &miLoadRegImmParams         = m_miItf->MHW_GETPAR_F(MI_LOAD_REGISTER_IMM)();
1075         miLoadRegImmParams               = {};
1076         miLoadRegImmParams.dwData        = 0;
1077         miLoadRegImmParams.dwRegister    = mmioRegs->generalPurposeRegister0HiOffset;
1078         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_LOAD_REGISTER_IMM)(cmdBuf));
1079 
1080         m_hwInterface->SendMiAtomicDwordIndirectDataCmd(bsSizeBuf, MHW_MI_ATOMIC_ADD, cmdBuf);
1081 
1082         // Make Flush DW call to make sure all previous work is done
1083         auto &flushDwParams              = m_miItf->MHW_GETPAR_F(MI_FLUSH_DW)();
1084         flushDwParams                    = {};
1085         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_FLUSH_DW)(cmdBuf));
1086 
1087         return MOS_STATUS_SUCCESS;
1088     }
1089 
CalculateCommandSize(uint32_t & commandBufferSize,uint32_t & requestedPatchListSize)1090     MOS_STATUS Av1VdencPkt::CalculateCommandSize(uint32_t &commandBufferSize, uint32_t &requestedPatchListSize)
1091     {
1092         commandBufferSize = CalculateCommandBufferSize();
1093         requestedPatchListSize = CalculatePatchListSize();
1094         return MOS_STATUS_SUCCESS;
1095     }
1096 
CalculateCommandBufferSize()1097     uint32_t Av1VdencPkt::CalculateCommandBufferSize()
1098     {
1099         ENCODE_FUNC_CALL();
1100         uint32_t commandBufferSize = 0;
1101 
1102         uint32_t tileNum = 1;
1103         RUN_FEATURE_INTERFACE_RETURN(Av1EncodeTile, Av1FeatureIDs::encodeTile, GetTileNum, tileNum);
1104 
1105         // To be refined later, differentiate BRC and CQP
1106         commandBufferSize =
1107             m_pictureStatesSize +
1108             (m_tileStatesSize * tileNum);
1109 
1110         // 4K align since allocation is in chunks of 4K bytes.
1111         commandBufferSize = MOS_ALIGN_CEIL(commandBufferSize, CODECHAL_PAGE_SIZE);
1112 
1113         return commandBufferSize;
1114     }
1115 
CalculatePatchListSize()1116     uint32_t Av1VdencPkt::CalculatePatchListSize()
1117     {
1118         ENCODE_FUNC_CALL();
1119         uint32_t requestedPatchListSize = 0;
1120 
1121         uint32_t tileNum = 1;
1122         RUN_FEATURE_INTERFACE_RETURN(Av1EncodeTile, Av1FeatureIDs::encodeTile, GetTileNum, tileNum);
1123 
1124         if (m_usePatchList)
1125         {
1126             requestedPatchListSize =
1127                 m_picturePatchListSize +
1128                 (m_tilePatchListSize * tileNum);
1129         }
1130 
1131         return requestedPatchListSize;
1132     }
1133 
CalculateVdencCommandsSize()1134     MOS_STATUS Av1VdencPkt::CalculateVdencCommandsSize()
1135     {
1136         uint32_t vdencPictureStatesSize    = 0;
1137         uint32_t vdencPicturePatchListSize = 0;
1138         uint32_t vdencTileStatesSize       = 0;
1139         uint32_t vdencTilePatchListSize    = 0;
1140 
1141         // Picture Level Commands
1142         ENCODE_CHK_STATUS_RETURN(GetVdencStateCommandsDataSize(
1143             &vdencPictureStatesSize,
1144             &vdencPicturePatchListSize));
1145 
1146         m_pictureStatesSize    += vdencPictureStatesSize;
1147         m_picturePatchListSize += vdencPicturePatchListSize;
1148 
1149         // Tile Level Commands
1150         ENCODE_CHK_STATUS_RETURN(GetVdencPrimitiveCommandsDataSize(
1151             &vdencTileStatesSize,
1152             &vdencTilePatchListSize));
1153 
1154         m_tileStatesSize    += vdencTileStatesSize;
1155         m_tilePatchListSize += vdencTilePatchListSize;
1156 
1157         return MOS_STATUS_SUCCESS;
1158     }
1159 
CalculateAvpPictureStateCommandSize(uint32_t * commandsSize,uint32_t * patchListSize)1160     MOS_STATUS Av1VdencPkt::CalculateAvpPictureStateCommandSize(uint32_t * commandsSize, uint32_t * patchListSize)
1161     {
1162         *commandsSize = m_miItf->MHW_GETSIZE_F(MI_FLUSH_DW)() * 25 +                                           //8 for UpdateStatusReport, 2 for profiler, 15 for metadata
1163                         m_miItf->MHW_GETSIZE_F(MI_STORE_DATA_IMM)() * 16 +                                     //4 For UpdateStatusReport, 6 for profiler, 6 for metadata
1164                         m_miItf->MHW_GETSIZE_F(MI_STORE_REGISTER_MEM)() * 31 +                                 //16 for profiler 15 for metadata
1165                         m_miItf->MHW_GETSIZE_F(MI_LOAD_REGISTER_MEM)() * 15 +                                 //16 for profiler 15 for metadata
1166                         m_miItf->MHW_GETSIZE_F(MI_ATOMIC)() * 19 +                                              //For UpdateStatusReport, 15 for metadata
1167                         m_miItf->MHW_GETSIZE_F(MI_COPY_MEM_MEM)() * (sizeof(MetadataAV1PostFeature) / 4 + 4);  //for metadata
1168 
1169         *patchListSize = PATCH_LIST_COMMAND(mhw::mi::Itf::MI_FLUSH_DW_CMD) * 25            +
1170                          PATCH_LIST_COMMAND(mhw::mi::Itf::MI_STORE_DATA_IMM_CMD) * 16      +
1171                          PATCH_LIST_COMMAND(mhw::mi::Itf::MI_STORE_REGISTER_MEM_CMD) * 31  +
1172                          PATCH_LIST_COMMAND(mhw::mi::Itf::MI_LOAD_REGISTER_MEM_CMD) * 15   +
1173                          PATCH_LIST_COMMAND(mhw::mi::Itf::MI_ATOMIC_CMD) * 19              +
1174                          PATCH_LIST_COMMAND(mhw::mi::Itf::MI_COPY_MEM_MEM_CMD) * (sizeof(MetadataAV1PostFeature) / 4 + 4);
1175 
1176         return MOS_STATUS_SUCCESS;
1177     }
1178 
CalculateAvpCommandsSize()1179     MOS_STATUS Av1VdencPkt::CalculateAvpCommandsSize()
1180     {
1181         uint32_t avpPictureStatesSize    = 0;
1182         uint32_t avpPicturePatchListSize = 0;
1183         uint32_t avpTileStatesSize       = 0;
1184         uint32_t avpTilePatchListSize    = 0;
1185 
1186         // Picture Level Commands
1187         ENCODE_CHK_STATUS_RETURN(CalculateAvpPictureStateCommandSize(&avpPictureStatesSize, &avpPicturePatchListSize));
1188 
1189         m_pictureStatesSize    += avpPictureStatesSize;
1190         m_picturePatchListSize += avpPicturePatchListSize;
1191 
1192         // Tile Level Commands
1193         ENCODE_CHK_STATUS_RETURN(GetAvpPrimitiveCommandsDataSize(
1194             &avpTileStatesSize,
1195             &avpTilePatchListSize));
1196 
1197         m_tileStatesSize    += avpTileStatesSize;
1198         m_tilePatchListSize += avpTilePatchListSize;
1199 
1200         return MOS_STATUS_SUCCESS;
1201     }
1202 
MHW_SETPAR_DECL_SRC(VD_PIPELINE_FLUSH,Av1VdencPkt)1203     MHW_SETPAR_DECL_SRC(VD_PIPELINE_FLUSH, Av1VdencPkt)
1204     {
1205         switch (m_basicFeature->m_flushCmd)
1206         {
1207         case Av1BasicFeature::waitVdenc:
1208             params                           = {};
1209             params.waitDoneVDCmdMsgParser    = true;
1210             params.waitDoneVDENC             = true;
1211             params.flushVDENC                = true;
1212             params.flushAV1                  = true;
1213             params.waitDoneAV1               = true;
1214             break;
1215         case Av1BasicFeature::waitAvp:
1216             params                           = {};
1217             params.waitDoneVDCmdMsgParser    = true;
1218             params.waitDoneAV1               = true;
1219             params.flushAV1                  = true;
1220             break;
1221         }
1222 
1223         return MOS_STATUS_SUCCESS;
1224     }
1225 
MHW_SETPAR_DECL_SRC(VDENC_PIPE_MODE_SELECT,Av1VdencPkt)1226     MHW_SETPAR_DECL_SRC(VDENC_PIPE_MODE_SELECT, Av1VdencPkt)
1227     {
1228         params.pakObjCmdStreamOut = m_vdencPakObjCmdStreamOutEnabled;
1229 
1230         // needs to be enabled for 1st pass in multi-pass case
1231         // This bit is ignored if PAK only second pass is enabled.
1232         if ((m_pipeline->GetCurrentPass() == 0) && !m_pipeline->IsLastPass())
1233         {
1234             params.pakObjCmdStreamOut = true;
1235         }
1236 
1237         return MOS_STATUS_SUCCESS;
1238     }
1239 
MHW_SETPAR_DECL_SRC(VDENC_PIPE_BUF_ADDR_STATE,Av1VdencPkt)1240     MHW_SETPAR_DECL_SRC(VDENC_PIPE_BUF_ADDR_STATE, Av1VdencPkt)
1241     {
1242         params.intraRowStoreScratchBuffer       = m_vdencIntraRowStoreScratch;
1243         params.tileRowStoreBuffer               = m_vdencTileRowStoreBuffer;
1244         params.cumulativeCuCountStreamOutBuffer = m_resCumulativeCuCountStreamoutBuffer;
1245 
1246         return MOS_STATUS_SUCCESS;
1247     }
1248 
MHW_SETPAR_DECL_SRC(VDENC_HEVC_VP9_TILE_SLICE_STATE,Av1VdencPkt)1249     MHW_SETPAR_DECL_SRC(VDENC_HEVC_VP9_TILE_SLICE_STATE, Av1VdencPkt)
1250     {
1251         switch (m_pipeline->GetPipeNum())
1252         {
1253         case 0:
1254         case 1:
1255             params.numPipe = VDENC_PIPE_SINGLE_PIPE;
1256             break;
1257         case 2:
1258             params.numPipe = VDENC_PIPE_TWO_PIPE;
1259             break;
1260         case 4:
1261             params.numPipe = VDENC_PIPE_FOUR_PIPE;
1262             break;
1263         default:
1264             params.numPipe = VDENC_PIPE_INVALID;
1265         }
1266 
1267         return MOS_STATUS_SUCCESS;
1268     }
1269 
MHW_SETPAR_DECL_SRC(AVP_SURFACE_STATE,Av1VdencPkt)1270     MHW_SETPAR_DECL_SRC(AVP_SURFACE_STATE, Av1VdencPkt)
1271     {
1272         params.surfaceStateId = m_curAvpSurfStateId;
1273 
1274         return MOS_STATUS_SUCCESS;
1275     }
1276 
MHW_SETPAR_DECL_SRC(AVP_PIPE_MODE_SELECT,Av1VdencPkt)1277     MHW_SETPAR_DECL_SRC(AVP_PIPE_MODE_SELECT, Av1VdencPkt)
1278     {
1279         params.multiEngineMode = MHW_VDBOX_HCP_MULTI_ENGINE_MODE_FE_LEGACY;
1280         params.pipeWorkingMode = MHW_VDBOX_HCP_PIPE_WORK_MODE_LEGACY;
1281 
1282         return MOS_STATUS_SUCCESS;
1283     }
1284 
MHW_SETPAR_DECL_SRC(AVP_PIPE_BUF_ADDR_STATE,Av1VdencPkt)1285     MHW_SETPAR_DECL_SRC(AVP_PIPE_BUF_ADDR_STATE, Av1VdencPkt)
1286     {
1287 
1288         uint32_t idx                             = m_pipeline->IsDualEncEnabled() ? m_pipeline->GetCurrentPipe() : 0;
1289         params.bsTileLineRowstoreBuffer          = m_basicFeature->m_bitstreamDecoderEncoderTileLineRowstoreReadWriteBuffer[idx];
1290         params.deblockTileLineYBuffer            = m_basicFeature->m_deblockerFilterTileLineReadWriteYBuffer[idx];
1291         params.deblockTileLineUBuffer            = m_basicFeature->m_deblockerFilterTileLineReadWriteUBuffer[idx];
1292         params.deblockTileLineVBuffer            = m_basicFeature->m_deblockerFilterTileLineReadWriteVBuffer[idx];
1293         params.deblockTileColumnYBuffer          = m_basicFeature->m_deblockerFilterTileColumnReadWriteYBuffer[idx];
1294         params.deblockTileColumnUBuffer          = m_basicFeature->m_deblockerFilterTileColumnReadWriteUBuffer[idx];
1295         params.deblockTileColumnVBuffer          = m_basicFeature->m_deblockerFilterTileColumnReadWriteVBuffer[idx];
1296         params.cdefLineBuffer                    = m_basicFeature->m_cdefFilterLineReadWriteBuffer[idx];
1297         params.cdefTileLineBuffer                = m_basicFeature->m_cdefFilterTileLineReadWriteBuffer[idx];
1298         params.cdefTileColumnBuffer              = m_basicFeature->m_cdefFilterTileColumnReadWriteBuffer[idx];
1299         params.cdefMetaTileLineBuffer            = m_basicFeature->m_cdefFilterMetaTileLineReadWriteBuffer[idx];
1300         params.cdefMetaTileColumnBuffer          = m_basicFeature->m_cdefFilterMetaTileColumnReadWriteBuffer[idx];
1301         params.cdefTopLeftCornerBuffer           = m_basicFeature->m_cdefFilterTopLeftCornerReadWriteBuffer[idx];
1302 
1303         return MOS_STATUS_SUCCESS;
1304     }
1305 
MHW_SETPAR_DECL_SRC(AVP_IND_OBJ_BASE_ADDR_STATE,Av1VdencPkt)1306     MHW_SETPAR_DECL_SRC(AVP_IND_OBJ_BASE_ADDR_STATE, Av1VdencPkt)
1307     {
1308         params.mvObjectOffset = m_mvOffset;
1309         params.mvObjectSize   = m_basicFeature->m_mbCodeSize - m_mvOffset;
1310 
1311         return MOS_STATUS_SUCCESS;
1312     }
1313 
MHW_SETPAR_DECL_SRC(AVP_PIC_STATE,Av1VdencPkt)1314     MHW_SETPAR_DECL_SRC(AVP_PIC_STATE, Av1VdencPkt)
1315     {
1316         params.notFirstPass = !m_pipeline->IsFirstPass();
1317 
1318         return MOS_STATUS_SUCCESS;
1319     }
1320 
MHW_SETPAR_DECL_SRC(AVP_TILE_CODING,Av1VdencPkt)1321     MHW_SETPAR_DECL_SRC(AVP_TILE_CODING, Av1VdencPkt)
1322     {
1323         uint32_t tileIdx = 0;
1324         RUN_FEATURE_INTERFACE_RETURN(Av1EncodeTile, Av1FeatureIDs::encodeTile, GetTileIdx, tileIdx);
1325         params.disableFrameContextUpdateFlag = m_av1PicParams->PicFlags.fields.disable_frame_end_update_cdf || (tileIdx != m_av1PicParams->context_update_tile_id);
1326 
1327         return MOS_STATUS_SUCCESS;
1328     }
1329 
AddAllCmds_AVP_SURFACE_STATE(PMOS_COMMAND_BUFFER cmdBuffer) const1330     MOS_STATUS Av1VdencPkt::AddAllCmds_AVP_SURFACE_STATE(PMOS_COMMAND_BUFFER cmdBuffer) const
1331     {
1332         ENCODE_FUNC_CALL();
1333 
1334         ENCODE_CHK_NULL_RETURN(cmdBuffer);
1335         ENCODE_CHK_NULL_RETURN(m_basicFeature);
1336 
1337         m_curAvpSurfStateId = srcInputPic;
1338         SETPAR_AND_ADDCMD(AVP_SURFACE_STATE, m_avpItf, cmdBuffer);
1339 
1340         m_curAvpSurfStateId = origUpscaledSrc;
1341         SETPAR_AND_ADDCMD(AVP_SURFACE_STATE, m_avpItf, cmdBuffer);
1342 
1343         m_curAvpSurfStateId = reconPic;
1344         SETPAR_AND_ADDCMD(AVP_SURFACE_STATE, m_avpItf, cmdBuffer);
1345 
1346         m_curAvpSurfStateId = av1CdefPixelsStreamout;
1347         SETPAR_AND_ADDCMD(AVP_SURFACE_STATE, m_avpItf, cmdBuffer);
1348 
1349         if (m_av1PicParams->PicFlags.fields.frame_type != keyFrame && m_av1PicParams->PicFlags.fields.frame_type != intraOnlyFrame)
1350         {
1351             for (uint8_t i = 0; i < av1TotalRefsPerFrame; i++)
1352             {
1353                 m_curAvpSurfStateId = i + av1IntraFrame;
1354                 SETPAR_AND_ADDCMD(AVP_SURFACE_STATE, m_avpItf, cmdBuffer);
1355             }
1356         }
1357 
1358         return MOS_STATUS_SUCCESS;
1359     }
1360 
AddAllCmds_AVP_PAK_INSERT_OBJECT(PMOS_COMMAND_BUFFER cmdBuffer) const1361     MOS_STATUS Av1VdencPkt::AddAllCmds_AVP_PAK_INSERT_OBJECT(PMOS_COMMAND_BUFFER cmdBuffer) const
1362     {
1363         ENCODE_FUNC_CALL();
1364 
1365         ENCODE_CHK_NULL_RETURN(m_osInterface);
1366         ENCODE_CHK_NULL_RETURN(cmdBuffer);
1367 
1368         auto &params = m_avpItf->MHW_GETPAR_F(AVP_PAK_INSERT_OBJECT)();
1369         params       = {};
1370 
1371         auto GetExtraData = [&]() { return params.bsBuffer->pBase + params.offset; };
1372         auto GetExtraSize = [&]() { return (params.bitSize + 7) >> 3; };
1373 
1374         // First, Send all other OBU bit streams other than tile group OBU when it's first tile in frame
1375         uint32_t   tileIdx    = 0;
1376         const bool tgOBUValid = m_basicFeature->m_slcData[0].BitSize > 0 ? true : false;
1377 
1378         RUN_FEATURE_INTERFACE_RETURN(Av1EncodeTile, Av1FeatureIDs::encodeTile, GetTileIdx, tileIdx);
1379         auto brcFeature = dynamic_cast<Av1Brc *>(m_featureManager->GetFeature(Av1FeatureIDs::av1BrcFeature));
1380         ENCODE_CHK_NULL_RETURN(brcFeature);
1381         if (tileIdx == 0)
1382         {
1383             uint32_t nalNum = 0;
1384             for (uint8_t i = 0; i < MAX_NUM_OBU_TYPES && m_nalUnitParams[i]->uiSize > 0; i++)
1385             {
1386                 nalNum++;
1387             }
1388 
1389             params.bsBuffer             = &m_basicFeature->m_bsBuffer;
1390             params.endOfHeaderInsertion = false;
1391 
1392             // Support multiple packed header buffer
1393             for (uint32_t i = 0; i < nalNum; i++)
1394             {
1395                 const uint32_t nalUnitSize   = m_nalUnitParams[i]->uiSize;
1396                 const uint32_t nalUnitOffset = m_nalUnitParams[i]->uiOffset;
1397 
1398                 ENCODE_ASSERT(nalUnitSize < CODECHAL_ENCODE_AV1_PAK_INSERT_UNCOMPRESSED_HEADER);
1399 
1400                 params.bitSize    = nalUnitSize * 8;
1401                 params.offset     = nalUnitOffset;
1402                 params.lastHeader = !tgOBUValid && (i+1 == nalNum);
1403 
1404                 if (IsFrameHeader(*(m_basicFeature->m_bsBuffer.pBase + nalUnitOffset)))
1405                 {
1406                     if (brcFeature->IsBRCEnabled())
1407                     {
1408                         auto pakInsertOutputBatchBuffer = brcFeature->GetPakInsertOutputBatchBuffer(m_pipeline->m_currRecycledBufIdx);
1409                         ENCODE_CHK_NULL_RETURN(pakInsertOutputBatchBuffer);
1410                         // send pak insert obj cmds after back annotation
1411                         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_BATCH_BUFFER_START)(cmdBuffer, pakInsertOutputBatchBuffer));
1412                         auto slbbData = brcFeature->GetSLBData();
1413                         HalOcaInterfaceNext::OnSubLevelBBStart(
1414                             *cmdBuffer,
1415                             m_osInterface->pOsContext,
1416                             &pakInsertOutputBatchBuffer->OsResource,
1417                             pakInsertOutputBatchBuffer->dwOffset,
1418                             false,
1419                             slbbData.pakInsertSlbSize);
1420 
1421                     }
1422                     else
1423                     {
1424                         m_avpItf->MHW_ADDCMD_F(AVP_PAK_INSERT_OBJECT)(cmdBuffer);
1425                         m_osInterface->pfnAddCommand(cmdBuffer, GetExtraData(), GetExtraSize());
1426                     }
1427                 }
1428                 else
1429                 {
1430                     m_avpItf->MHW_ADDCMD_F(AVP_PAK_INSERT_OBJECT)(cmdBuffer);
1431                     m_osInterface->pfnAddCommand(cmdBuffer, GetExtraData(), GetExtraSize());
1432                 }
1433             }
1434         }
1435 
1436         // Second, Send tile group OBU when it is first tile in tile group
1437         if (tgOBUValid)
1438         {
1439             ENCODE_CHK_NULL_RETURN(m_featureManager);
1440 
1441             auto tileFeature = dynamic_cast<Av1EncodeTile *>(m_featureManager->GetFeature(Av1FeatureIDs::encodeTile));
1442             ENCODE_CHK_NULL_RETURN(tileFeature);
1443 
1444             MHW_CHK_STATUS_RETURN(tileFeature->MHW_SETPAR_F(AVP_PAK_INSERT_OBJECT)(params));
1445             if (params.bitSize)
1446             {
1447                 m_avpItf->MHW_ADDCMD_F(AVP_PAK_INSERT_OBJECT)(cmdBuffer);
1448                 m_osInterface->pfnAddCommand(cmdBuffer, GetExtraData(), GetExtraSize());
1449             }
1450         }
1451 
1452         return MOS_STATUS_SUCCESS;
1453     }
1454 
AddAllCmds_AVP_PIPE_MODE_SELECT(PMOS_COMMAND_BUFFER cmdBuffer) const1455     MOS_STATUS Av1VdencPkt::AddAllCmds_AVP_PIPE_MODE_SELECT(PMOS_COMMAND_BUFFER cmdBuffer) const
1456     {
1457         ENCODE_FUNC_CALL();
1458 
1459         ENCODE_CHK_NULL_RETURN(cmdBuffer);
1460 
1461         auto &vdControlStateParams          = m_miItf->MHW_GETPAR_F(VD_CONTROL_STATE)();
1462         vdControlStateParams                = {};
1463         vdControlStateParams.initialization = true;
1464         vdControlStateParams.avpEnabled     = true;
1465         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(VD_CONTROL_STATE)(cmdBuffer));
1466 
1467         // for Gen11+, we need to add MFX wait for both KIN and VRT before and after AVP Pipemode select...
1468         SETPAR_AND_ADDCMD(MFX_WAIT, m_miItf, cmdBuffer);
1469 
1470         SETPAR_AND_ADDCMD(AVP_PIPE_MODE_SELECT, m_avpItf, cmdBuffer);
1471 
1472         // for Gen11+, we need to add MFX wait for both KIN and VRT before and after AVP Pipemode select...
1473         SETPAR_AND_ADDCMD(MFX_WAIT, m_miItf, cmdBuffer);
1474 
1475         if (m_pipeline->IsDualEncEnabled())
1476         {
1477             vdControlStateParams = {};
1478             vdControlStateParams.avpEnabled           = true;
1479             vdControlStateParams.scalableModePipeLock = true;
1480 
1481             ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(VD_CONTROL_STATE)(cmdBuffer));
1482         }
1483 
1484         return MOS_STATUS_SUCCESS;
1485     }
1486 
AddAllCmds_AVP_SEGMENT_STATE(PMOS_COMMAND_BUFFER cmdBuffer) const1487     MOS_STATUS Av1VdencPkt::AddAllCmds_AVP_SEGMENT_STATE(PMOS_COMMAND_BUFFER cmdBuffer) const
1488     {
1489         ENCODE_FUNC_CALL();
1490 
1491         ENCODE_CHK_NULL_RETURN(cmdBuffer);
1492         ENCODE_CHK_NULL_RETURN(m_featureManager);
1493 
1494         auto &par           = m_avpItf->MHW_GETPAR_F(AVP_SEGMENT_STATE)();
1495         par                 = {};
1496         auto segmentFeature = dynamic_cast<Av1Segmentation *>(m_featureManager->GetFeature(Av1FeatureIDs::av1Segmentation));
1497         ENCODE_CHK_NULL_RETURN(segmentFeature);
1498 
1499         MHW_CHK_STATUS_RETURN(segmentFeature->MHW_SETPAR_F(AVP_SEGMENT_STATE)(par));
1500 
1501         const bool segmentEnabled = par.av1SegmentParams.m_enabled;
1502 
1503         for (uint8_t i = 0; i < av1MaxSegments; i++)
1504         {
1505             par.currentSegmentId = i;
1506             m_avpItf->MHW_ADDCMD_F(AVP_SEGMENT_STATE)(cmdBuffer);
1507 
1508             // If segmentation is not enabled, then AV1_SEGMENT_STATE must still be sent once for SegmentID = 0
1509             // If i == numSegments -1, means all segments are issued, break the loop
1510             if (!segmentEnabled || (i == par.numSegments - 1))
1511             {
1512                 break;
1513             }
1514         }
1515 
1516         return MOS_STATUS_SUCCESS;
1517     }
1518 
GetVdencStateCommandsDataSize(uint32_t * commandsSize,uint32_t * patchListSize) const1519     MOS_STATUS Av1VdencPkt::GetVdencStateCommandsDataSize(uint32_t *commandsSize, uint32_t *patchListSize) const
1520     {
1521         uint32_t            maxSize          = 0;
1522         uint32_t            patchListMaxSize = 0;
1523 
1524         maxSize = maxSize +
1525             m_vdencItf->MHW_GETSIZE_F(VDENC_CONTROL_STATE)() +
1526             m_vdencItf->MHW_GETSIZE_F(VDENC_PIPE_MODE_SELECT)() +
1527             m_vdencItf->MHW_GETSIZE_F(VDENC_SRC_SURFACE_STATE)() +
1528             m_vdencItf->MHW_GETSIZE_F(VDENC_REF_SURFACE_STATE)() +
1529             m_vdencItf->MHW_GETSIZE_F(VDENC_DS_REF_SURFACE_STATE)() +
1530             m_vdencItf->MHW_GETSIZE_F(VDENC_PIPE_BUF_ADDR_STATE)() +
1531             m_vdencItf->MHW_GETSIZE_F(VDENC_WALKER_STATE)() +
1532             m_vdencItf->MHW_GETSIZE_F(VD_PIPELINE_FLUSH)();
1533 
1534         patchListMaxSize = patchListMaxSize +
1535             PATCH_LIST_COMMAND(mhw::mi::Itf::MI_FLUSH_DW_CMD) +
1536             PATCH_LIST_COMMAND(mhw::mi::Itf::MI_BATCH_BUFFER_START_CMD) +
1537             PATCH_LIST_COMMAND(mhw::vdbox::vdenc::Itf::VDENC_PIPE_BUF_ADDR_STATE_CMD);
1538 
1539         maxSize = maxSize +
1540             m_miItf->MHW_GETSIZE_F(MI_LOAD_REGISTER_IMM)()*8 +
1541             m_miItf->MHW_GETSIZE_F(MI_FLUSH_DW)() +
1542             m_miItf->MHW_GETSIZE_F(MI_BATCH_BUFFER_START)() +
1543             m_miItf->MHW_GETSIZE_F(MI_BATCH_BUFFER_END)();
1544 
1545         ENCODE_CHK_NULL_RETURN(commandsSize);
1546         ENCODE_CHK_NULL_RETURN(patchListSize);
1547         *commandsSize  = maxSize;
1548         *patchListSize = patchListMaxSize;
1549 
1550         return MOS_STATUS_SUCCESS;
1551     }
1552 
UpdateStatusReport(uint32_t srType,MOS_COMMAND_BUFFER * cmdBuffer)1553     MOS_STATUS Av1VdencPkt::UpdateStatusReport(uint32_t srType, MOS_COMMAND_BUFFER *cmdBuffer)
1554     {
1555         ENCODE_FUNC_CALL();
1556         ENCODE_CHK_NULL_RETURN(cmdBuffer);
1557 
1558         //initialize following
1559         MOS_RESOURCE *osResourceInline = nullptr;
1560         uint32_t      offsetInline     = 0;
1561         m_statusReport->GetAddress(statusReportGlobalCount, osResourceInline, offsetInline);
1562         offsetInline             = m_atomicScratchBuf.operandSetSize * m_atomicScratchBuf.encodeUpdateIndex;
1563         uint32_t zeroValueOffset = offsetInline;
1564         uint32_t operand1Offset  = offsetInline + m_atomicScratchBuf.operand1Offset;
1565         uint32_t operand2Offset  = offsetInline + m_atomicScratchBuf.operand2Offset;
1566         uint32_t operand3Offset  = offsetInline + m_atomicScratchBuf.operand3Offset;
1567         auto     mmioRegisters   = m_hwInterface->GetVdencInterfaceNext()->GetMmioRegisters(m_vdboxIndex);
1568 
1569         // Make Flush DW call to make sure all previous work is done
1570         auto &flushDwParams = m_miItf->MHW_GETPAR_F(MI_FLUSH_DW)();
1571         flushDwParams       = {};
1572         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_FLUSH_DW)(cmdBuffer));
1573 
1574         // n1_lo = 0x00
1575         auto &storeDataParams            = m_miItf->MHW_GETPAR_F(MI_STORE_DATA_IMM)();
1576         storeDataParams                  = {};
1577         storeDataParams.pOsResource      = m_atomicScratchBuf.resAtomicScratchBuffer;
1578         storeDataParams.dwResourceOffset = operand1Offset;
1579         storeDataParams.dwValue          = 0x00;
1580         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_STORE_DATA_IMM)(cmdBuffer));
1581 
1582         // n2_lo = dwImageStatusMask
1583         auto &copyMemMemParams       = m_miItf->MHW_GETPAR_F(MI_COPY_MEM_MEM)();
1584         copyMemMemParams             = {};
1585         copyMemMemParams.presSrc     = m_basicFeature->m_recycleBuf->GetBuffer(VdencBrcPakMmioBuffer, 0);
1586         copyMemMemParams.dwSrcOffset = (sizeof(uint32_t) * 1);
1587         copyMemMemParams.presDst     = m_atomicScratchBuf.resAtomicScratchBuffer;
1588         copyMemMemParams.dwDstOffset = operand2Offset;
1589         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_COPY_MEM_MEM)(cmdBuffer));
1590 
1591         // VCS_GPR0_Lo = ImageStatusCtrl
1592         auto &registerMemParams           = m_miItf->MHW_GETPAR_F(MI_LOAD_REGISTER_MEM)();
1593         registerMemParams                 = {};
1594         registerMemParams.presStoreBuffer = m_basicFeature->m_recycleBuf->GetBuffer(VdencBrcPakMmioBuffer, 0);
1595         registerMemParams.dwOffset        = (sizeof(uint32_t) * 0);
1596         registerMemParams.dwRegister      = mmioRegisters->generalPurposeRegister0LoOffset;  // VCS_GPR0_Lo
1597         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_LOAD_REGISTER_MEM)(cmdBuffer));
1598 
1599         // Reset GPR4_Lo
1600         registerMemParams                 = {};
1601         registerMemParams.presStoreBuffer = m_atomicScratchBuf.resAtomicScratchBuffer;
1602         registerMemParams.dwOffset        = zeroValueOffset;                                 //Offset 0, has value of 0.
1603         registerMemParams.dwRegister      = mmioRegisters->generalPurposeRegister4LoOffset;  // VCS_GPR4
1604         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_LOAD_REGISTER_MEM)(cmdBuffer));
1605 
1606         // Make Flush DW call to make sure all previous work is done
1607         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_FLUSH_DW)(cmdBuffer));
1608 
1609         // step-1: n2_lo = n2_lo & VCS_GPR0_Lo = dwImageStatusMask & ImageStatusCtrl
1610         auto &atomicParams            = m_miItf->MHW_GETPAR_F(MI_ATOMIC)();
1611         atomicParams                  = {};
1612         atomicParams.pOsResource      = m_atomicScratchBuf.resAtomicScratchBuffer;
1613         atomicParams.dwResourceOffset = operand2Offset;
1614         atomicParams.dwDataSize       = sizeof(uint32_t);
1615         atomicParams.Operation        = mhw::mi::MHW_MI_ATOMIC_AND;
1616         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_ATOMIC)(cmdBuffer));
1617 
1618         // n3_lo = 0
1619         storeDataParams                  = {};
1620         storeDataParams.pOsResource      = m_atomicScratchBuf.resAtomicScratchBuffer;
1621         storeDataParams.dwResourceOffset = operand3Offset;
1622         storeDataParams.dwValue          = 0;
1623         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_STORE_DATA_IMM)(cmdBuffer));
1624 
1625         // Make Flush DW call to make sure all previous work is done
1626         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_FLUSH_DW)(cmdBuffer));
1627 
1628         // GPR0_lo = n1_lo = 0
1629         registerMemParams                 = {};
1630         registerMemParams.presStoreBuffer = m_atomicScratchBuf.resAtomicScratchBuffer;
1631         registerMemParams.dwOffset        = operand1Offset;
1632         registerMemParams.dwRegister      = mmioRegisters->generalPurposeRegister0LoOffset;  // VCS_GPR0
1633         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_LOAD_REGISTER_MEM)(cmdBuffer));
1634 
1635         // Reset GPR4_Lo
1636         registerMemParams                 = {};
1637         registerMemParams.presStoreBuffer = m_atomicScratchBuf.resAtomicScratchBuffer;
1638         registerMemParams.dwOffset        = zeroValueOffset;                                 //Offset 0, has value of 0.
1639         registerMemParams.dwRegister      = mmioRegisters->generalPurposeRegister4LoOffset;  // VCS_GPR4
1640         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_LOAD_REGISTER_MEM)(cmdBuffer));
1641 
1642         // Make Flush DW call to make sure all previous work is done
1643         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_FLUSH_DW)(cmdBuffer));
1644 
1645         // step-2: n2_lo == n1_lo ? 0 : n2_lo
1646         // compare n1 vs n2. i.e. GRP0 vs. memory of operand2
1647         atomicParams                  = {};
1648         atomicParams.pOsResource      = m_atomicScratchBuf.resAtomicScratchBuffer;
1649         atomicParams.dwResourceOffset = operand2Offset;
1650         atomicParams.dwDataSize       = sizeof(uint32_t);
1651         atomicParams.Operation        = mhw::mi::MHW_MI_ATOMIC_CMP;
1652         atomicParams.bReturnData      = true;
1653         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_ATOMIC)(cmdBuffer));
1654 
1655         // n2_hi = 1
1656         storeDataParams                  = {};
1657         storeDataParams.pOsResource      = m_atomicScratchBuf.resAtomicScratchBuffer;
1658         storeDataParams.dwResourceOffset = operand2Offset + sizeof(uint32_t);
1659         storeDataParams.dwValue          = 1;
1660         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_STORE_DATA_IMM)(cmdBuffer));
1661 
1662         // n3_hi = 1
1663         storeDataParams                  = {};
1664         storeDataParams.pOsResource      = m_atomicScratchBuf.resAtomicScratchBuffer;
1665         storeDataParams.dwResourceOffset = operand3Offset + sizeof(uint32_t);
1666         storeDataParams.dwValue          = 1;
1667         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_STORE_DATA_IMM)(cmdBuffer));
1668 
1669         // VCS_GPR0_Lo = n3_lo = 0
1670         registerMemParams                 = {};
1671         registerMemParams.presStoreBuffer = m_atomicScratchBuf.resAtomicScratchBuffer;
1672         registerMemParams.dwOffset        = operand3Offset;
1673         registerMemParams.dwRegister      = mmioRegisters->generalPurposeRegister0LoOffset;  // VCS_GPR0_Lo
1674         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_LOAD_REGISTER_MEM)(cmdBuffer));
1675 
1676         // GPR0_Hi = n2_hi = 1
1677         registerMemParams                 = {};
1678         registerMemParams.presStoreBuffer = m_atomicScratchBuf.resAtomicScratchBuffer;
1679         registerMemParams.dwOffset        = operand2Offset + sizeof(uint32_t);               // update 1
1680         registerMemParams.dwRegister      = mmioRegisters->generalPurposeRegister0HiOffset;  // VCS_GPR0_Hi
1681         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_LOAD_REGISTER_MEM)(cmdBuffer));
1682 
1683         // Reset GPR4_Lo and GPR4_Hi
1684         registerMemParams                 = {};
1685         registerMemParams.presStoreBuffer = m_atomicScratchBuf.resAtomicScratchBuffer;
1686         registerMemParams.dwOffset        = zeroValueOffset;
1687         registerMemParams.dwRegister      = mmioRegisters->generalPurposeRegister4LoOffset;  // VCS_GPR4_Lo
1688         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_LOAD_REGISTER_MEM)(cmdBuffer));
1689 
1690         registerMemParams                 = {};
1691         registerMemParams.presStoreBuffer = m_atomicScratchBuf.resAtomicScratchBuffer;
1692         registerMemParams.dwOffset        = zeroValueOffset;
1693         registerMemParams.dwRegister      = mmioRegisters->generalPurposeRegister4HiOffset;  // VCS_GPR4_Hi
1694         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_LOAD_REGISTER_MEM)(cmdBuffer));
1695 
1696         // Make Flush DW call to make sure all previous work is done
1697         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_FLUSH_DW)(cmdBuffer));
1698 
1699         // step-3: n2 = (n2 == 0:1) ? 0:0 : n2      // uint64_t CMP
1700         // If n2==0 (Lo) and 1 (Hi), covert n2 to 0 (Lo)and 0 (Hi), else no change.
1701         // n2 == 0:1 means encoding completsion. the n2 memory will be updated with 0:0, otherwise, no change.
1702         atomicParams                  = {};
1703         atomicParams.pOsResource      = m_atomicScratchBuf.resAtomicScratchBuffer;
1704         atomicParams.dwResourceOffset = operand2Offset;
1705         atomicParams.dwDataSize       = sizeof(uint64_t);
1706         atomicParams.Operation        = mhw::mi::MHW_MI_ATOMIC_CMP;
1707         atomicParams.bReturnData      = true;
1708         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_ATOMIC)(cmdBuffer));
1709 
1710         // Make Flush DW call to make sure all previous work is done
1711         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_FLUSH_DW)(cmdBuffer));
1712 
1713         // VCS_GPR0_Lo = n3_hi = 1
1714         registerMemParams                 = {};
1715         registerMemParams.presStoreBuffer = m_atomicScratchBuf.resAtomicScratchBuffer;
1716         registerMemParams.dwOffset        = operand3Offset + sizeof(uint32_t);
1717         registerMemParams.dwRegister      = mmioRegisters->generalPurposeRegister0LoOffset;  // VCS_GPR0_Lo
1718         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_LOAD_REGISTER_MEM)(cmdBuffer));
1719 
1720         // Make Flush DW call to make sure all previous work is done
1721         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_FLUSH_DW)(cmdBuffer));
1722 
1723         // step-4: n2_hi = n2_hi ^ VCS_GPR0_Lo = n2_hi ^ n3_hi
1724         atomicParams                  = {};
1725         atomicParams.pOsResource      = m_atomicScratchBuf.resAtomicScratchBuffer;
1726         atomicParams.dwResourceOffset = operand2Offset + sizeof(uint32_t);
1727         atomicParams.dwDataSize       = sizeof(uint32_t);
1728         atomicParams.Operation        = mhw::mi::MHW_MI_ATOMIC_XOR;
1729         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_ATOMIC)(cmdBuffer));
1730 
1731         // VCS_GPR0_Lo = n2_hi
1732         registerMemParams                 = {};
1733         registerMemParams.presStoreBuffer = m_atomicScratchBuf.resAtomicScratchBuffer;
1734         registerMemParams.dwOffset        = operand2Offset + sizeof(uint32_t);
1735         registerMemParams.dwRegister      = mmioRegisters->generalPurposeRegister0LoOffset;  // VCS_GPR0_Lo
1736         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_LOAD_REGISTER_MEM)(cmdBuffer));
1737 
1738         // step-5: m_storeData = m_storeData + VCS_GPR0_Lo = m_storeData + n2_hi
1739         // if not completed n2_hi should be 0, then m_storeData = m_storeData + 0
1740         // if completed, n2_hi should be 1, then m_storeData = m_storeData + 1
1741         auto &miLoadRegMemParams           = m_miItf->MHW_GETPAR_F(MI_LOAD_REGISTER_MEM)();
1742         miLoadRegMemParams                 = {};
1743         miLoadRegMemParams.presStoreBuffer = osResourceInline;
1744         miLoadRegMemParams.dwOffset        = 0;
1745         miLoadRegMemParams.dwRegister      = mmioRegisters->generalPurposeRegister4LoOffset;
1746         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_LOAD_REGISTER_MEM)(cmdBuffer));
1747 
1748         mhw::mi::MHW_MI_ALU_PARAMS aluParams[4] = {0};
1749         int                        aluCount     = 0;
1750 
1751         //load1 srca, reg1
1752         aluParams[aluCount].AluOpcode = MHW_MI_ALU_LOAD;
1753         aluParams[aluCount].Operand1  = MHW_MI_ALU_SRCA;
1754         aluParams[aluCount].Operand2  = MHW_MI_ALU_GPREG0;
1755         ++aluCount;
1756         //load srcb, reg2
1757         aluParams[aluCount].AluOpcode = MHW_MI_ALU_LOAD;
1758         aluParams[aluCount].Operand1  = MHW_MI_ALU_SRCB;
1759         aluParams[aluCount].Operand2  = MHW_MI_ALU_GPREG4;
1760         ++aluCount;
1761         //add
1762         aluParams[aluCount].AluOpcode = MHW_MI_ALU_ADD;
1763         ++aluCount;
1764         //store reg1, accu
1765         aluParams[aluCount].AluOpcode = MHW_MI_ALU_STORE;
1766         aluParams[aluCount].Operand1  = MHW_MI_ALU_GPREG0;
1767         aluParams[aluCount].Operand2  = MHW_MI_ALU_ACCU;
1768         ++aluCount;
1769 
1770         auto &miMathParams          = m_miItf->MHW_GETPAR_F(MI_MATH)();
1771         miMathParams                = {};
1772         miMathParams.dwNumAluParams = aluCount;
1773         miMathParams.pAluPayload    = aluParams;
1774         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_MATH)(cmdBuffer));
1775 
1776         auto &miStoreRegMemParams           = m_miItf->MHW_GETPAR_F(MI_STORE_REGISTER_MEM)();
1777         miStoreRegMemParams                 = {};
1778         miStoreRegMemParams.presStoreBuffer = osResourceInline;
1779         miStoreRegMemParams.dwOffset        = 0;
1780         miStoreRegMemParams.dwRegister      = mmioRegisters->generalPurposeRegister0LoOffset;
1781         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_STORE_REGISTER_MEM)(cmdBuffer));
1782 
1783         // Make Flush DW call to make sure all previous work is done
1784         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_FLUSH_DW)(cmdBuffer));
1785 
1786         return MOS_STATUS_SUCCESS;
1787     }
1788 
GetVdencPrimitiveCommandsDataSize(uint32_t * commandsSize,uint32_t * patchListSize) const1789     MOS_STATUS Av1VdencPkt::GetVdencPrimitiveCommandsDataSize(uint32_t *commandsSize, uint32_t *patchListSize) const
1790     {
1791         uint32_t            maxSize          = 0;
1792         uint32_t            patchListMaxSize = 0;
1793 
1794         maxSize = maxSize +
1795             m_vdencItf->MHW_GETSIZE_F(VDENC_HEVC_VP9_TILE_SLICE_STATE)() +
1796             m_vdencItf->MHW_GETSIZE_F(VDENC_CMD1)() +
1797             m_vdencItf->MHW_GETSIZE_F(VDENC_CMD2)() +
1798             m_vdencItf->MHW_GETSIZE_F(VDENC_WALKER_STATE)();
1799 
1800         ENCODE_CHK_NULL_RETURN(commandsSize);
1801         ENCODE_CHK_NULL_RETURN(patchListSize);
1802         *commandsSize  = maxSize;
1803         *patchListSize = patchListMaxSize;
1804 
1805         return MOS_STATUS_SUCCESS;
1806     }
1807 
GetAvpPrimitiveCommandsDataSize(uint32_t * commandsSize,uint32_t * patchListSize) const1808     MOS_STATUS Av1VdencPkt::GetAvpPrimitiveCommandsDataSize(uint32_t *commandsSize, uint32_t *patchListSize) const
1809     {
1810         uint32_t maxSize          = 0;
1811         uint32_t patchListMaxSize = 0;
1812 
1813         maxSize = m_miItf->MHW_GETSIZE_F(MI_BATCH_BUFFER_START)() * AV1_MAX_NUM_OF_BATCH_BUFFER +
1814             m_miItf->MHW_GETSIZE_F(VD_CONTROL_STATE)()                                          +
1815             m_miItf->MHW_GETSIZE_F(MFX_WAIT)()                                                  +
1816             m_avpItf->MHW_GETSIZE_F(AVP_PIPE_MODE_SELECT)()                                     +
1817             m_miItf->MHW_GETSIZE_F(MFX_WAIT)()                                                  +
1818             m_avpItf->MHW_GETSIZE_F(AVP_SURFACE_STATE)() * av1SurfaceNums                       +
1819             m_avpItf->MHW_GETSIZE_F(AVP_PIPE_BUF_ADDR_STATE)()                                  +
1820             m_avpItf->MHW_GETSIZE_F(AVP_IND_OBJ_BASE_ADDR_STATE)()                              +
1821             m_avpItf->MHW_GETSIZE_F(AVP_PIC_STATE)()                                            +
1822             m_avpItf->MHW_GETSIZE_F(AVP_INTER_PRED_STATE)()                                     +
1823             m_avpItf->MHW_GETSIZE_F(AVP_SEGMENT_STATE)() * AV1_MAX_NUM_OF_SEGMENTS              +
1824             m_avpItf->MHW_GETSIZE_F(AVP_INLOOP_FILTER_STATE)()                                  +
1825             m_avpItf->MHW_GETSIZE_F(AVP_TILE_CODING)()                                          +
1826             m_avpItf->MHW_GETSIZE_F(AVP_PAK_INSERT_OBJECT)() * MAX_NUM_OBU_TYPES                +
1827             m_miItf->MHW_GETSIZE_F(MI_BATCH_BUFFER_END)();
1828 
1829         patchListMaxSize =
1830             PATCH_LIST_COMMAND(mhw::mi::Itf::MI_BATCH_BUFFER_START_CMD) * AV1_MAX_NUM_OF_BATCH_BUFFER +
1831             PATCH_LIST_COMMAND(mhw::vdbox::avp::Itf::VD_PIPELINE_FLUSH_CMD)                           +
1832             PATCH_LIST_COMMAND(mhw::vdbox::avp::Itf::AVP_PIPE_MODE_SELECT_CMD)                        +
1833             PATCH_LIST_COMMAND(mhw::vdbox::avp::Itf::AVP_SURFACE_STATE_CMD) * av1SurfaceNums          +
1834             PATCH_LIST_COMMAND(mhw::vdbox::avp::Itf::AVP_PIPE_BUF_ADDR_STATE_CMD)                     +
1835             PATCH_LIST_COMMAND(mhw::vdbox::avp::Itf::AVP_IND_OBJ_BASE_ADDR_STATE_CMD)                 +
1836             PATCH_LIST_COMMAND(mhw::vdbox::avp::Itf::AVP_PIC_STATE_CMD)                               +
1837             PATCH_LIST_COMMAND(mhw::vdbox::avp::Itf::AVP_INTER_PRED_STATE_CMD)                        +
1838             PATCH_LIST_COMMAND(mhw::vdbox::avp::Itf::AVP_SEGMENT_STATE_CMD) * AV1_MAX_NUM_OF_SEGMENTS +
1839             PATCH_LIST_COMMAND(mhw::vdbox::avp::Itf::AVP_INLOOP_FILTER_STATE_CMD)                     +
1840             PATCH_LIST_COMMAND(mhw::vdbox::avp::Itf::AVP_TILE_CODING_CMD)                             +
1841             PATCH_LIST_COMMAND(mhw::vdbox::avp::Itf::AVP_PAK_INSERT_OBJECT_CMD) * MAX_NUM_OBU_TYPES;
1842 
1843         ENCODE_CHK_NULL_RETURN(commandsSize);
1844         ENCODE_CHK_NULL_RETURN(patchListSize);
1845         *commandsSize  = maxSize;
1846         *patchListSize = patchListMaxSize;
1847 
1848         return MOS_STATUS_SUCCESS;
1849     }
1850 
PrepareHWMetaData(MOS_COMMAND_BUFFER * cmdBuffer)1851     MOS_STATUS Av1VdencPkt::PrepareHWMetaData(MOS_COMMAND_BUFFER *cmdBuffer)
1852     {
1853         ENCODE_FUNC_CALL();
1854 
1855         ENCODE_CHK_NULL_RETURN(m_basicFeature);
1856         if (!m_basicFeature->m_resMetadataBuffer)
1857         {
1858             return MOS_STATUS_SUCCESS;
1859         }
1860 
1861         AV1MetaDataOffset AV1ResourceOffset = m_basicFeature->m_AV1metaDataOffset;
1862         MetaDataOffset    resourceOffset    = m_basicFeature->m_metaDataOffset;
1863 
1864         //ENCODER_OUTPUT_METADATA
1865         auto &storeDataParams = m_miItf->MHW_GETPAR_F(MI_STORE_DATA_IMM)();
1866         storeDataParams       = {};
1867 
1868         ENCODE_CHK_STATUS_RETURN(PrepareHWMetaDataFromDriver(cmdBuffer, resourceOffset, AV1ResourceOffset));
1869         ENCODE_CHK_STATUS_RETURN(PrepareHWMetaDataFromStreamout(cmdBuffer, resourceOffset, AV1ResourceOffset));
1870         ENCODE_CHK_STATUS_RETURN(PrepareHWMetaDataFromRegister(cmdBuffer, resourceOffset));
1871 
1872         return MOS_STATUS_SUCCESS;
1873     }
PrepareHWMetaDataFromStreamout(MOS_COMMAND_BUFFER * cmdBuffer,const MetaDataOffset resourceOffset,const AV1MetaDataOffset AV1ResourceOffset)1874     MOS_STATUS Av1VdencPkt::PrepareHWMetaDataFromStreamout(MOS_COMMAND_BUFFER *cmdBuffer, const MetaDataOffset resourceOffset, const AV1MetaDataOffset AV1ResourceOffset)
1875     {
1876         ENCODE_FUNC_CALL();
1877         uint32_t tileNum     = 0;
1878         auto     tileFeature = dynamic_cast<Av1EncodeTile *>(m_featureManager->GetFeature(Av1FeatureIDs::encodeTile));
1879         ENCODE_CHK_NULL_RETURN(tileFeature);
1880         ENCODE_CHK_STATUS_RETURN(tileFeature->GetTileNum(tileNum));
1881 
1882         uint32_t      frameSubregionOffset = resourceOffset.dwMetaDataSize;
1883         MOS_RESOURCE *tileRecordBuffer     = nullptr;
1884         RUN_FEATURE_INTERFACE_RETURN(Av1EncodeTile, Av1FeatureIDs::encodeTile, GetTileRecordBuffer, m_basicFeature->m_currOriginalPic.FrameIdx, tileRecordBuffer);  //curroriginalpic.frameidx
1885         ENCODE_CHK_NULL_RETURN(tileRecordBuffer);
1886 
1887         m_basicFeature->m_numSlices = tileNum;
1888         auto &miCpyMemMemParams     = m_miItf->MHW_GETPAR_F(MI_COPY_MEM_MEM)();
1889         auto &storeDataParams       = m_miItf->MHW_GETPAR_F(MI_STORE_DATA_IMM)();
1890 
1891         //memeset EncodedBitstreamWrittenBytesCount
1892         storeDataParams             = {};
1893         storeDataParams.pOsResource = m_basicFeature->m_resMetadataBuffer;
1894         storeDataParams.dwResourceOffset = resourceOffset.dwEncodedBitstreamWrittenBytesCount;
1895         storeDataParams.dwValue          = 0;
1896         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_STORE_DATA_IMM)(cmdBuffer));
1897 
1898         for (uint32_t tileIdx = 0; tileIdx < tileNum; tileIdx++)
1899         {
1900             uint32_t frameSubregionOffset = resourceOffset.dwMetaDataSize + tileIdx * resourceOffset.dwMetaDataSubRegionSize;
1901             miCpyMemMemParams.presSrc     = tileRecordBuffer;
1902             miCpyMemMemParams.dwSrcOffset = tileIdx * sizeof(PakHwTileSizeRecord) + 2 * sizeof(uint32_t);  //skip dword0 dword1
1903             miCpyMemMemParams.presDst     = m_basicFeature->m_resMetadataBuffer;
1904             miCpyMemMemParams.dwDstOffset = frameSubregionOffset + resourceOffset.dwbSize;
1905             ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_COPY_MEM_MEM)(cmdBuffer));
1906 
1907             storeDataParams.dwResourceOffset = frameSubregionOffset + resourceOffset.dwbStartOffset;
1908             if (tileIdx == tileNum - 1)
1909                 storeDataParams.dwValue = 0;
1910             else
1911                 storeDataParams.dwValue = TILE_SIZE_BYTES;
1912             ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_STORE_DATA_IMM)(cmdBuffer));
1913 
1914             storeDataParams.dwResourceOffset = frameSubregionOffset + resourceOffset.dwbHeaderSize;
1915             storeDataParams.dwValue          = 0;
1916             ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_STORE_DATA_IMM)(cmdBuffer));
1917 
1918             //count for fame bytescount
1919             ENCODE_CHK_STATUS_RETURN(CalAtomic(m_basicFeature->m_resMetadataBuffer, resourceOffset.dwEncodedBitstreamWrittenBytesCount, tileRecordBuffer, tileIdx * sizeof(PakHwTileSizeRecord) + 2 * sizeof(uint32_t), mhw::mi::MHW_MI_ATOMIC_ADD, cmdBuffer));
1920         }
1921         if (m_basicFeature->m_av1SeqParams->RateControlMethod != RATECONTROL_CQP)
1922         {
1923             auto brcFeature = dynamic_cast<Av1Brc *>(m_featureManager->GetFeature(Av1FeatureIDs::av1BrcFeature));
1924             ENCODE_CHK_NULL_RETURN(brcFeature);
1925             auto vdenc2ndLevelBatchBuffer = brcFeature->GetVdenc2ndLevelBatchBuffer(m_pipeline->m_currRecycledBufIdx);
1926             auto slbbData                 = brcFeature->GetSLBData();
1927 
1928             //qp
1929             uint32_t qpOffset     = resourceOffset.dwMetaDataSize + tileNum * resourceOffset.dwMetaDataSubRegionSize + resourceOffset.dwTilePartitionSize + AV1ResourceOffset.dwQuantization + AV1ResourceOffset.dwBaseQIndex;
1930             uint32_t QPOffsetSLBB = slbbData.secondAvpPicStateOffset + 4 * sizeof(uint32_t);//dword 4
1931             ENCODE_CHK_STATUS_RETURN(readBRCMetaDataFromSLBB(cmdBuffer, m_basicFeature->m_resMetadataBuffer, qpOffset, &vdenc2ndLevelBatchBuffer->OsResource, QPOffsetSLBB, 0xFF0000));
1932 
1933             //loop filter
1934             uint32_t loopFilterOffset     = resourceOffset.dwMetaDataSize + tileNum * resourceOffset.dwMetaDataSubRegionSize + resourceOffset.dwTilePartitionSize + AV1ResourceOffset.dwLoopFilter;
1935             uint32_t loopFilterOffsetSLBB = slbbData.avpInloopFilterStateOffset + sizeof(uint32_t);  //dword 1
1936             ENCODE_CHK_STATUS_RETURN(readBRCMetaDataFromSLBB(cmdBuffer, m_basicFeature->m_resMetadataBuffer, loopFilterOffset + AV1ResourceOffset.dwLoopFilterLevel, &vdenc2ndLevelBatchBuffer->OsResource, loopFilterOffsetSLBB, 0x3F));
1937             ENCODE_CHK_STATUS_RETURN(readBRCMetaDataFromSLBB(cmdBuffer, m_basicFeature->m_resMetadataBuffer, loopFilterOffset + AV1ResourceOffset.dwLoopFilterLevel + sizeof(uint64_t), &vdenc2ndLevelBatchBuffer->OsResource, loopFilterOffsetSLBB, 0xFC0));
1938             ENCODE_CHK_STATUS_RETURN(readBRCMetaDataFromSLBB(cmdBuffer, m_basicFeature->m_resMetadataBuffer, loopFilterOffset + AV1ResourceOffset.dwLoopFilterLevelU, &vdenc2ndLevelBatchBuffer->OsResource, loopFilterOffsetSLBB, 0x3F000));
1939             ENCODE_CHK_STATUS_RETURN(readBRCMetaDataFromSLBB(cmdBuffer, m_basicFeature->m_resMetadataBuffer, loopFilterOffset + AV1ResourceOffset.dwLoopFilterLevelV, &vdenc2ndLevelBatchBuffer->OsResource, loopFilterOffsetSLBB, 0xFC0000));
1940             ENCODE_CHK_STATUS_RETURN(readBRCMetaDataFromSLBB(cmdBuffer, m_basicFeature->m_resMetadataBuffer, loopFilterOffset + AV1ResourceOffset.dwLoopFilterSharpnessLevel, &vdenc2ndLevelBatchBuffer->OsResource, loopFilterOffsetSLBB, 0x7000000));
1941 
1942             //cdef
1943             uint32_t CDEFOffset     = resourceOffset.dwMetaDataSize + tileNum * resourceOffset.dwMetaDataSubRegionSize + resourceOffset.dwTilePartitionSize + AV1ResourceOffset.dwCDEF;
1944             uint32_t CDEFOffsetSLBB = slbbData.avpInloopFilterStateOffset + 5 * sizeof(uint32_t);  //dword 5
1945             ENCODE_CHK_STATUS_RETURN(readBRCMetaDataFromSLBB(cmdBuffer, m_basicFeature->m_resMetadataBuffer, CDEFOffset + AV1ResourceOffset.dwCdefBits, &vdenc2ndLevelBatchBuffer->OsResource, CDEFOffsetSLBB, 0x30000000));
1946             ENCODE_CHK_STATUS_RETURN(readBRCMetaDataFromSLBB(cmdBuffer, m_basicFeature->m_resMetadataBuffer, CDEFOffset + AV1ResourceOffset.dwCdefDampingMinus3, &vdenc2ndLevelBatchBuffer->OsResource, CDEFOffsetSLBB, 0xC0000000));
1947             for (uint32_t i = 0; i < 8; i++)
1948             {
1949                 ENCODE_CHK_STATUS_RETURN(readBRCMetaDataFromSLBB(cmdBuffer, m_basicFeature->m_resMetadataBuffer, CDEFOffset + AV1ResourceOffset.dwCdefYPriStrength + i * sizeof(uint64_t), &vdenc2ndLevelBatchBuffer->OsResource, CDEFOffsetSLBB + (i / 4) * sizeof(uint32_t), 0x3c << (i % 4 * 6)));
1950                 ENCODE_CHK_STATUS_RETURN(readBRCMetaDataFromSLBB(cmdBuffer, m_basicFeature->m_resMetadataBuffer, CDEFOffset + AV1ResourceOffset.dwCdefYSecStrength + i * sizeof(uint64_t), &vdenc2ndLevelBatchBuffer->OsResource, CDEFOffsetSLBB + (i / 4) * sizeof(uint32_t), 0x03 << (i % 4 * 6)));
1951                 ENCODE_CHK_STATUS_RETURN(readBRCMetaDataFromSLBB(cmdBuffer, m_basicFeature->m_resMetadataBuffer, CDEFOffset + AV1ResourceOffset.dwCdefUVPriStrength + i * sizeof(uint64_t), &vdenc2ndLevelBatchBuffer->OsResource, CDEFOffsetSLBB + (2 + i / 4) * sizeof(uint32_t), 0x3c << (i % 4 * 6)));
1952                 ENCODE_CHK_STATUS_RETURN(readBRCMetaDataFromSLBB(cmdBuffer, m_basicFeature->m_resMetadataBuffer, CDEFOffset + AV1ResourceOffset.dwCdefUVSecStrength + i * sizeof(uint64_t), &vdenc2ndLevelBatchBuffer->OsResource, CDEFOffsetSLBB + (2 + i / 4) * sizeof(uint32_t), 0x03 << (i % 4 * 6)));
1953             }
1954         }
1955 
1956         return MOS_STATUS_SUCCESS;
1957     }
1958 
PrepareHWMetaDataFromRegister(MOS_COMMAND_BUFFER * cmdBuffer,const MetaDataOffset resourceOffset)1959     MOS_STATUS Av1VdencPkt::PrepareHWMetaDataFromRegister(MOS_COMMAND_BUFFER *cmdBuffer, const MetaDataOffset resourceOffset)
1960     {
1961         ENCODE_FUNC_CALL();
1962 
1963         //qpy
1964         auto  mmioRegisters               = m_avpItf->GetMmioRegisters(m_vdboxIndex);
1965         ENCODE_CHK_NULL_RETURN(mmioRegisters);
1966         auto &storeRegMemParams           = m_miItf->MHW_GETPAR_F(MI_STORE_REGISTER_MEM)();
1967         storeRegMemParams                 = {};
1968         storeRegMemParams.presStoreBuffer = m_basicFeature->m_resMetadataBuffer;
1969         storeRegMemParams.dwOffset        = resourceOffset.dwEncodeStats + resourceOffset.dwAverageQP;
1970         storeRegMemParams.dwRegister      = mmioRegisters->avpAv1QpStatusCountRegOffset;  //This register stores cummulative QP for all SBs
1971         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_STORE_REGISTER_MEM)(cmdBuffer));
1972 
1973         return MOS_STATUS_SUCCESS;
1974     }
1975 
PrepareHWMetaDataFromDriver(MOS_COMMAND_BUFFER * cmdBuffer,const MetaDataOffset resourceOffset,const AV1MetaDataOffset AV1ResourceOffset)1976     MOS_STATUS Av1VdencPkt::PrepareHWMetaDataFromDriver(MOS_COMMAND_BUFFER *cmdBuffer, const MetaDataOffset resourceOffset, const AV1MetaDataOffset AV1ResourceOffset)
1977     {
1978         ENCODE_FUNC_CALL();
1979 
1980         auto &storeDataParams            = m_miItf->MHW_GETPAR_F(MI_STORE_DATA_IMM)();
1981         storeDataParams                  = {};
1982         storeDataParams.pOsResource      = m_basicFeature->m_resMetadataBuffer;
1983         storeDataParams.pOsResource      = m_basicFeature->m_resMetadataBuffer;
1984         storeDataParams.dwResourceOffset = resourceOffset.dwEncodeErrorFlags;
1985         storeDataParams.dwValue          = 0;
1986         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_STORE_DATA_IMM)(cmdBuffer));
1987 
1988         uint32_t tileNum     = 0;
1989         auto     tileFeature = dynamic_cast<Av1EncodeTile *>(m_featureManager->GetFeature(Av1FeatureIDs::encodeTile));
1990         ENCODE_CHK_NULL_RETURN(tileFeature);
1991         ENCODE_CHK_STATUS_RETURN(tileFeature->GetTileNum(tileNum));
1992         storeDataParams.dwResourceOffset = resourceOffset.dwWrittenSubregionsCount;
1993         storeDataParams.dwValue          = tileNum;  //frame subregion num
1994         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_STORE_DATA_IMM)(cmdBuffer));
1995 
1996         PMOS_RESOURCE           previewMetadataBuffer = nullptr;
1997         MOS_ALLOC_GFXRES_PARAMS allocParams;
1998         MOS_ZeroMemory(&allocParams, sizeof(MOS_ALLOC_GFXRES_PARAMS));
1999         allocParams.Type               = MOS_GFXRES_BUFFER;
2000         allocParams.TileType           = MOS_TILE_LINEAR;
2001         allocParams.Format             = Format_Buffer;
2002         allocParams.Flags.bNotLockable = false;
2003         allocParams.dwBytes            = sizeof(MetadataAV1PostFeature);
2004         allocParams.pBufName           = "feature values for resMetadataBuffer";
2005         previewMetadataBuffer          = m_allocator->AllocateResource(allocParams, false);
2006 
2007         MOS_LOCK_PARAMS lockFlags;
2008         MOS_ZeroMemory(&lockFlags, sizeof(MOS_LOCK_PARAMS));
2009         lockFlags.WriteOnly = 1;
2010         uint8_t *data       = (uint8_t *)m_osInterface->pfnLockResource(
2011             m_osInterface,
2012             previewMetadataBuffer,
2013             &lockFlags);
2014 
2015         MetadataAV1PostFeature *previewMetadata = reinterpret_cast<MetadataAV1PostFeature *>(data);
2016         ENCODE_CHK_NULL_RETURN(previewMetadata);
2017 
2018         uint16_t numTileRows = 0;
2019         uint16_t numTileCols = 0;
2020         RUN_FEATURE_INTERFACE_RETURN(Av1EncodeTile, Av1FeatureIDs::encodeTile, GetTileRowColumns, numTileRows, numTileCols);
2021         previewMetadata->tilePartition.ColCount            = numTileCols;
2022         previewMetadata->tilePartition.ContextUpdateTileId = m_basicFeature->m_av1PicParams->context_update_tile_id;
2023         previewMetadata->tilePartition.RowCount            = numTileRows;
2024         for (int rowIdx = 0; rowIdx < numTileRows; rowIdx++)
2025         {
2026             previewMetadata->tilePartition.RowHeights[rowIdx] = m_basicFeature->m_av1PicParams->height_in_sbs_minus_1[rowIdx] + 1;
2027         }
2028         for (int colIdx = 0; colIdx < numTileCols; colIdx++)
2029         {
2030             previewMetadata->tilePartition.ColWidths[colIdx] = m_basicFeature->m_av1PicParams->width_in_sbs_minus_1[colIdx] + 1;
2031         }
2032 
2033         previewMetadata->postFeature.CompoundPredictionType = m_basicFeature->m_av1PicParams->dwModeControlFlags.fields.reference_mode == referenceModeSelect;
2034 
2035         previewMetadata->postFeature.LoopFilter.LoopFilterLevel[0]       = m_basicFeature->m_av1PicParams->filter_level[0];
2036         previewMetadata->postFeature.LoopFilter.LoopFilterLevel[1]       = m_basicFeature->m_av1PicParams->filter_level[1];
2037         previewMetadata->postFeature.LoopFilter.LoopFilterLevelU         = m_basicFeature->m_av1PicParams->filter_level_u;
2038         previewMetadata->postFeature.LoopFilter.LoopFilterLevelV         = m_basicFeature->m_av1PicParams->filter_level_v;
2039         previewMetadata->postFeature.LoopFilter.LoopFilterSharpnessLevel = m_basicFeature->m_av1PicParams->cLoopFilterInfoFlags.fields.sharpness_level;
2040         previewMetadata->postFeature.LoopFilter.LoopFilterDeltaEnabled   = m_basicFeature->m_av1PicParams->cLoopFilterInfoFlags.fields.mode_ref_delta_enabled;
2041         previewMetadata->postFeature.LoopFilter.UpdateRefDelta           = m_basicFeature->m_av1PicParams->cLoopFilterInfoFlags.fields.mode_ref_delta_update;
2042         previewMetadata->postFeature.LoopFilter.UpdateModeDelta          = m_basicFeature->m_av1PicParams->cLoopFilterInfoFlags.fields.mode_ref_delta_update;
2043         for (int i = 0; i < 8; i++)
2044             previewMetadata->postFeature.LoopFilter.RefDeltas[i] = m_basicFeature->m_av1PicParams->ref_deltas[i];
2045         for (int i = 0; i < 2; i++)
2046             previewMetadata->postFeature.LoopFilter.ModeDeltas[i] = m_basicFeature->m_av1PicParams->mode_deltas[i];
2047 
2048         previewMetadata->postFeature.LoopFilterDelta.DeltaLFPresent = m_basicFeature->m_av1PicParams->dwModeControlFlags.fields.delta_lf_present_flag;
2049         previewMetadata->postFeature.LoopFilterDelta.DeltaLFMulti   = m_basicFeature->m_av1PicParams->dwModeControlFlags.fields.delta_lf_multi;
2050         previewMetadata->postFeature.LoopFilterDelta.DeltaLFRes     = m_basicFeature->m_av1PicParams->dwModeControlFlags.fields.log2_delta_lf_res;
2051 
2052         previewMetadata->postFeature.Quantization.BaseQIndex   = m_basicFeature->m_av1PicParams->base_qindex;
2053         previewMetadata->postFeature.Quantization.QMY          = m_basicFeature->m_av1PicParams->wQMatrixFlags.fields.qm_y;
2054         previewMetadata->postFeature.Quantization.QMU          = m_basicFeature->m_av1PicParams->wQMatrixFlags.fields.qm_u;
2055         previewMetadata->postFeature.Quantization.QMV          = m_basicFeature->m_av1PicParams->wQMatrixFlags.fields.qm_v;
2056         previewMetadata->postFeature.Quantization.UsingQMatrix = m_basicFeature->m_av1PicParams->wQMatrixFlags.fields.using_qmatrix;
2057         previewMetadata->postFeature.Quantization.UACDeltaQ    = m_basicFeature->m_av1PicParams->u_ac_delta_q;
2058         previewMetadata->postFeature.Quantization.UDCDeltaQ    = m_basicFeature->m_av1PicParams->u_dc_delta_q;
2059         previewMetadata->postFeature.Quantization.VACDeltaQ    = m_basicFeature->m_av1PicParams->v_ac_delta_q;
2060         previewMetadata->postFeature.Quantization.VDCDeltaQ    = m_basicFeature->m_av1PicParams->v_dc_delta_q;
2061         previewMetadata->postFeature.Quantization.YDCDeltaQ    = m_basicFeature->m_av1PicParams->y_dc_delta_q;
2062 
2063         previewMetadata->postFeature.QuantizationDelta.DeltaQPresent = m_basicFeature->m_av1PicParams->dwModeControlFlags.fields.delta_q_present_flag;
2064         previewMetadata->postFeature.QuantizationDelta.DeltaQRes     = m_basicFeature->m_av1PicParams->dwModeControlFlags.fields.log2_delta_q_res;
2065 
2066         previewMetadata->postFeature.CDEF.CdefBits          = m_basicFeature->m_av1PicParams->cdef_bits;
2067         previewMetadata->postFeature.CDEF.CdefDampingMinus3 = m_basicFeature->m_av1PicParams->cdef_damping_minus_3;
2068         for (int i = 0; i < 8; i++)
2069         {
2070             previewMetadata->postFeature.CDEF.CdefYPriStrength[i]  = m_basicFeature->m_av1PicParams->cdef_y_strengths[i] / 4;
2071             previewMetadata->postFeature.CDEF.CdefUVPriStrength[i] = m_basicFeature->m_av1PicParams->cdef_uv_strengths[i] / 4;
2072             previewMetadata->postFeature.CDEF.CdefYSecStrength[i]  = m_basicFeature->m_av1PicParams->cdef_y_strengths[i] % 4;
2073             previewMetadata->postFeature.CDEF.CdefUVSecStrength[i] = m_basicFeature->m_av1PicParams->cdef_uv_strengths[i] % 4;
2074         }
2075 
2076         previewMetadata->postFeature.SegmentationConfig.UpdateMap      = m_basicFeature->m_av1PicParams->stAV1Segments.SegmentFlags.fields.update_map;
2077         previewMetadata->postFeature.SegmentationConfig.UpdateData     = m_basicFeature->m_av1PicParams->stAV1Segments.SegmentFlags.fields.update_map;
2078         previewMetadata->postFeature.SegmentationConfig.TemporalUpdate = m_av1PicParams->stAV1Segments.SegmentFlags.fields.temporal_update;
2079         previewMetadata->postFeature.SegmentationConfig.NumSegments    = m_basicFeature->m_av1PicParams->stAV1Segments.SegmentFlags.fields.SegmentNumber;
2080         for (int i = 0; i < 8; i++)
2081         {
2082             previewMetadata->postFeature.SegmentationConfig.SegmentsData[i].EnabledFeatures = m_basicFeature->m_av1PicParams->stAV1Segments.feature_mask[i];
2083             for (int j = 0; j < 8; j++)
2084                 previewMetadata->postFeature.SegmentationConfig.SegmentsData[i].FeatureValue[j] = m_basicFeature->m_av1PicParams->stAV1Segments.feature_data[i][j];
2085         }
2086 
2087         previewMetadata->postFeature.PrimaryRefFrame = m_basicFeature->m_av1PicParams->primary_ref_frame;
2088         for (int i = 0; i < 7; i++)
2089             previewMetadata->postFeature.ReferenceIndices[i] = m_basicFeature->m_av1PicParams->ref_frame_idx[i];
2090 
2091         ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnUnlockResource(m_osInterface, previewMetadataBuffer));
2092 
2093         auto &miCpyMemMemParams   = m_miItf->MHW_GETPAR_F(MI_COPY_MEM_MEM)();
2094         miCpyMemMemParams.presSrc = previewMetadataBuffer;
2095         for (uint32_t i = 0; i < allocParams.dwBytes; i += 4)
2096         {
2097             miCpyMemMemParams.dwSrcOffset = i;
2098             miCpyMemMemParams.presDst     = m_basicFeature->m_resMetadataBuffer;
2099             miCpyMemMemParams.dwDstOffset = resourceOffset.dwMetaDataSize + tileNum * resourceOffset.dwMetaDataSubRegionSize + i;
2100             ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_COPY_MEM_MEM)(cmdBuffer));
2101         }
2102 
2103         return MOS_STATUS_SUCCESS;
2104     }
readBRCMetaDataFromSLBB(MOS_COMMAND_BUFFER * cmdBuffer,PMOS_RESOURCE presDst,uint32_t dstOffset,PMOS_RESOURCE presSrc,uint32_t srcOffset,uint32_t significantBits)2105     MOS_STATUS Av1VdencPkt::readBRCMetaDataFromSLBB(MOS_COMMAND_BUFFER *cmdBuffer, PMOS_RESOURCE presDst, uint32_t dstOffset, PMOS_RESOURCE presSrc, uint32_t srcOffset, uint32_t significantBits)
2106     {
2107         auto &miCpyMemMemParams = m_miItf->MHW_GETPAR_F(MI_COPY_MEM_MEM)();
2108         miCpyMemMemParams             = {};
2109 
2110         miCpyMemMemParams.presSrc     = presSrc;
2111         miCpyMemMemParams.dwSrcOffset = srcOffset;
2112         miCpyMemMemParams.presDst     = presDst;
2113         miCpyMemMemParams.dwDstOffset = dstOffset;
2114         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_COPY_MEM_MEM)(cmdBuffer));
2115 
2116         auto &atomicParams             = m_miItf->MHW_GETPAR_F(MI_ATOMIC)();
2117         atomicParams                   = {};
2118         atomicParams.pOsResource       = presDst;
2119         atomicParams.dwResourceOffset  = dstOffset;
2120         atomicParams.dwDataSize        = sizeof(uint32_t);
2121         atomicParams.Operation         = mhw::mi::MHW_MI_ATOMIC_AND;
2122         atomicParams.bInlineData       = true;
2123         atomicParams.dwOperand1Data[0] = significantBits;
2124         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_ATOMIC)(cmdBuffer));
2125 
2126         // load current tile size to VCS_GPR0_Lo
2127         auto  mmioRegs                     = m_miItf->GetMmioRegisters();
2128         auto &miLoadRegMemParams           = m_miItf->MHW_GETPAR_F(MI_LOAD_REGISTER_MEM)();
2129         miLoadRegMemParams                 = {};
2130         miLoadRegMemParams.presStoreBuffer = presDst;
2131         miLoadRegMemParams.dwOffset        = dstOffset;
2132         miLoadRegMemParams.dwRegister      = mmioRegs->generalPurposeRegister0LoOffset;
2133         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_LOAD_REGISTER_MEM)(cmdBuffer));
2134 
2135 
2136         uint32_t SHRNum          = static_cast<uint32_t>(log2(significantBits & (significantBits - 1) ^ significantBits));
2137         uint32_t miMathCmdNum    = 0;
2138         uint32_t SHRbit[6]       = {};
2139         auto getSHRbits = [](uint32_t SHRNum, uint32_t &miMathCmdNum, uint32_t *SHRbit) {
2140             uint32_t x = SHRNum;
2141             uint32_t y = SHRNum;
2142             while (x > 0)
2143             {
2144                 x &= (x - 1);
2145                 SHRbit[miMathCmdNum] = y ^ x;
2146                 y                    = x;
2147                 miMathCmdNum++;
2148             }
2149         };
2150         getSHRbits(SHRNum, miMathCmdNum, SHRbit);
2151 
2152         for (uint32_t i = 0; i < miMathCmdNum; i++)
2153         {
2154             mhw::mi::MHW_MI_ALU_PARAMS aluParams[4] = {};
2155             uint32_t                   aluCount     = 0;
2156             //load shr bits to register4
2157             auto &miLoadRegImmParams      = m_miItf->MHW_GETPAR_F(MI_LOAD_REGISTER_IMM)();
2158             miLoadRegImmParams            = {};
2159             miLoadRegImmParams.dwData     = SHRbit[i];
2160             miLoadRegImmParams.dwRegister = mmioRegs->generalPurposeRegister4LoOffset;
2161             ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_LOAD_REGISTER_IMM)(cmdBuffer));
2162 
2163             //load1 srca, reg1
2164             aluParams[aluCount].AluOpcode = MHW_MI_ALU_LOAD;
2165             aluParams[aluCount].Operand1  = MHW_MI_ALU_SRCA;
2166             aluParams[aluCount].Operand2  = MHW_MI_ALU_GPREG0;
2167             ++aluCount;
2168 
2169             //load2 srcb, reg2
2170             aluParams[aluCount].AluOpcode = MHW_MI_ALU_LOAD;
2171             aluParams[aluCount].Operand1  = MHW_MI_ALU_SRCB;
2172             aluParams[aluCount].Operand2  = MHW_MI_ALU_GPREG4;
2173             ++aluCount;
2174 
2175             aluParams[aluCount].AluOpcode = MHW_MI_ALU_SHR;
2176             ++aluCount;
2177 
2178             aluParams[aluCount].AluOpcode = MHW_MI_ALU_STORE;
2179             aluParams[aluCount].Operand1  = MHW_MI_ALU_GPREG0;
2180             aluParams[aluCount].Operand2  = MHW_MI_ALU_ACCU;
2181             ++aluCount;
2182 
2183             auto &miMathParams          = m_miItf->MHW_GETPAR_F(MI_MATH)();
2184             miMathParams                = {};
2185             miMathParams.dwNumAluParams = aluCount;
2186             miMathParams.pAluPayload    = aluParams;
2187             ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_MATH)(cmdBuffer));
2188         }
2189 
2190         //store VCS_GPR0_Lo metadata buffer
2191         auto &miStoreRegMemParams           = m_miItf->MHW_GETPAR_F(MI_STORE_REGISTER_MEM)();
2192         miStoreRegMemParams                 = {};
2193         miStoreRegMemParams.presStoreBuffer = presDst;
2194         miStoreRegMemParams.dwOffset        = dstOffset;
2195         miStoreRegMemParams.dwRegister      = mmioRegs->generalPurposeRegister0LoOffset;
2196         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_STORE_REGISTER_MEM)(cmdBuffer));
2197 
2198         // Make Flush DW call to make sure all previous work is done
2199         auto &flushDwParams = m_miItf->MHW_GETPAR_F(MI_FLUSH_DW)();
2200         flushDwParams       = {};
2201         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_FLUSH_DW)(cmdBuffer));
2202 
2203         return MOS_STATUS_SUCCESS;
2204     }
2205 
PrepareHWMetaDataFromStreamoutTileLevel(MOS_COMMAND_BUFFER * cmdBuffer,uint32_t tileCol,uint32_t tileRow)2206     MOS_STATUS Av1VdencPkt::PrepareHWMetaDataFromStreamoutTileLevel(MOS_COMMAND_BUFFER *cmdBuffer, uint32_t tileCol, uint32_t tileRow)
2207     {
2208         ENCODE_FUNC_CALL();
2209         ENCODE_CHK_NULL_RETURN(cmdBuffer);
2210 
2211         ENCODE_CHK_NULL_RETURN(m_basicFeature);
2212         if (!m_basicFeature->m_resMetadataBuffer)
2213         {
2214             return MOS_STATUS_SUCCESS;
2215         }
2216         MetaDataOffset    resourceOffset    = m_basicFeature->m_metaDataOffset;
2217 
2218         //lcu count Intra/Inter/Skip CU Cnt
2219         PMOS_RESOURCE tileStatisticsPakStreamoutBuffer = m_basicFeature->m_tileStatisticsPakStreamoutBuffer;
2220         ENCODE_CHK_NULL_RETURN(tileStatisticsPakStreamoutBuffer);
2221 
2222         auto &miCpyMemMemParams       = m_miItf->MHW_GETPAR_F(MI_COPY_MEM_MEM)();
2223         auto &storeDataParams         = m_miItf->MHW_GETPAR_F(MI_STORE_DATA_IMM)();
2224         storeDataParams               = {};
2225         storeDataParams.pOsResource   = m_basicFeature->m_resMetadataBuffer;
2226 
2227         if (tileCol == 0 && tileRow == 0)
2228         {
2229             // LCUSkipIn8x8Unit
2230             miCpyMemMemParams.presSrc     = tileStatisticsPakStreamoutBuffer;
2231             miCpyMemMemParams.dwSrcOffset = 61 * sizeof(uint32_t);
2232             miCpyMemMemParams.presDst     = m_basicFeature->m_resMetadataBuffer;
2233             miCpyMemMemParams.dwDstOffset = resourceOffset.dwEncodeStats + resourceOffset.dwSkipCodingUnitsCount;
2234             ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_COPY_MEM_MEM)(cmdBuffer));
2235 
2236             // NumCU_IntraDC, NumCU_IntraPlanar, NumCU_IntraAngular
2237             miCpyMemMemParams.dwSrcOffset = 24 * sizeof(uint32_t);
2238             miCpyMemMemParams.dwDstOffset = resourceOffset.dwEncodeStats + resourceOffset.dwIntraCodingUnitsCount;
2239             ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_COPY_MEM_MEM)(cmdBuffer));
2240 
2241             // NumCU_MVdirL0, NumCU_MVdirL1, NumCU_MVdirBi
2242             miCpyMemMemParams.dwSrcOffset = 85 * sizeof(uint32_t);
2243             miCpyMemMemParams.dwDstOffset = resourceOffset.dwEncodeStats + resourceOffset.dwInterCodingUnitsCount;
2244             ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_COPY_MEM_MEM)(cmdBuffer));
2245         }
2246         else
2247         {
2248             ENCODE_CHK_STATUS_RETURN(CalAtomic(m_basicFeature->m_resMetadataBuffer, resourceOffset.dwEncodeStats + resourceOffset.dwSkipCodingUnitsCount, tileStatisticsPakStreamoutBuffer, 61 * sizeof(uint32_t), mhw::mi::MHW_MI_ATOMIC_ADD, cmdBuffer));
2249             ENCODE_CHK_STATUS_RETURN(CalAtomic(m_basicFeature->m_resMetadataBuffer, resourceOffset.dwEncodeStats + resourceOffset.dwIntraCodingUnitsCount, tileStatisticsPakStreamoutBuffer, 24 * sizeof(uint32_t), mhw::mi::MHW_MI_ATOMIC_ADD, cmdBuffer));
2250             ENCODE_CHK_STATUS_RETURN(CalAtomic(m_basicFeature->m_resMetadataBuffer, resourceOffset.dwEncodeStats + resourceOffset.dwInterCodingUnitsCount, tileStatisticsPakStreamoutBuffer, 85 * sizeof(uint32_t), mhw::mi::MHW_MI_ATOMIC_ADD, cmdBuffer));
2251         }
2252         // NumCU_IntraDC, NumCU_IntraPlanar, NumCU_IntraAngular
2253         ENCODE_CHK_STATUS_RETURN(CalAtomic(m_basicFeature->m_resMetadataBuffer, resourceOffset.dwEncodeStats + resourceOffset.dwIntraCodingUnitsCount, tileStatisticsPakStreamoutBuffer, 25 * sizeof(uint32_t), mhw::mi::MHW_MI_ATOMIC_ADD, cmdBuffer));
2254         ENCODE_CHK_STATUS_RETURN(CalAtomic(m_basicFeature->m_resMetadataBuffer, resourceOffset.dwEncodeStats + resourceOffset.dwIntraCodingUnitsCount, tileStatisticsPakStreamoutBuffer, 26 * sizeof(uint32_t), mhw::mi::MHW_MI_ATOMIC_ADD, cmdBuffer));
2255         ENCODE_CHK_STATUS_RETURN(CalAtomic(m_basicFeature->m_resMetadataBuffer, resourceOffset.dwEncodeStats + resourceOffset.dwIntraCodingUnitsCount, tileStatisticsPakStreamoutBuffer, 27 * sizeof(uint32_t), mhw::mi::MHW_MI_ATOMIC_ADD, cmdBuffer));
2256         ENCODE_CHK_STATUS_RETURN(CalAtomic(m_basicFeature->m_resMetadataBuffer, resourceOffset.dwEncodeStats + resourceOffset.dwIntraCodingUnitsCount, tileStatisticsPakStreamoutBuffer, 28 * sizeof(uint32_t), mhw::mi::MHW_MI_ATOMIC_ADD, cmdBuffer));
2257         ENCODE_CHK_STATUS_RETURN(CalAtomic(m_basicFeature->m_resMetadataBuffer, resourceOffset.dwEncodeStats + resourceOffset.dwIntraCodingUnitsCount, tileStatisticsPakStreamoutBuffer, 29 * sizeof(uint32_t), mhw::mi::MHW_MI_ATOMIC_ADD, cmdBuffer));
2258         ENCODE_CHK_STATUS_RETURN(CalAtomic(m_basicFeature->m_resMetadataBuffer, resourceOffset.dwEncodeStats + resourceOffset.dwIntraCodingUnitsCount, tileStatisticsPakStreamoutBuffer, 30 * sizeof(uint32_t), mhw::mi::MHW_MI_ATOMIC_ADD, cmdBuffer));
2259         ENCODE_CHK_STATUS_RETURN(CalAtomic(m_basicFeature->m_resMetadataBuffer, resourceOffset.dwEncodeStats + resourceOffset.dwIntraCodingUnitsCount, tileStatisticsPakStreamoutBuffer, 31 * sizeof(uint32_t), mhw::mi::MHW_MI_ATOMIC_ADD, cmdBuffer));
2260         ENCODE_CHK_STATUS_RETURN(CalAtomic(m_basicFeature->m_resMetadataBuffer, resourceOffset.dwEncodeStats + resourceOffset.dwIntraCodingUnitsCount, tileStatisticsPakStreamoutBuffer, 32 * sizeof(uint32_t), mhw::mi::MHW_MI_ATOMIC_ADD, cmdBuffer));
2261         ENCODE_CHK_STATUS_RETURN(CalAtomic(m_basicFeature->m_resMetadataBuffer, resourceOffset.dwEncodeStats + resourceOffset.dwIntraCodingUnitsCount, tileStatisticsPakStreamoutBuffer, 33 * sizeof(uint32_t), mhw::mi::MHW_MI_ATOMIC_ADD, cmdBuffer));
2262         ENCODE_CHK_STATUS_RETURN(CalAtomic(m_basicFeature->m_resMetadataBuffer, resourceOffset.dwEncodeStats + resourceOffset.dwIntraCodingUnitsCount, tileStatisticsPakStreamoutBuffer, 34 * sizeof(uint32_t), mhw::mi::MHW_MI_ATOMIC_ADD, cmdBuffer));
2263         ENCODE_CHK_STATUS_RETURN(CalAtomic(m_basicFeature->m_resMetadataBuffer, resourceOffset.dwEncodeStats + resourceOffset.dwIntraCodingUnitsCount, tileStatisticsPakStreamoutBuffer, 35 * sizeof(uint32_t), mhw::mi::MHW_MI_ATOMIC_ADD, cmdBuffer));
2264         ENCODE_CHK_STATUS_RETURN(CalAtomic(m_basicFeature->m_resMetadataBuffer, resourceOffset.dwEncodeStats + resourceOffset.dwIntraCodingUnitsCount, tileStatisticsPakStreamoutBuffer, 36 * sizeof(uint32_t), mhw::mi::MHW_MI_ATOMIC_ADD, cmdBuffer));
2265 
2266         // NumCU_MVdirL0, NumCU_MVdirL1, NumCU_MVdirBi
2267         ENCODE_CHK_STATUS_RETURN(CalAtomic(m_basicFeature->m_resMetadataBuffer, resourceOffset.dwEncodeStats + resourceOffset.dwInterCodingUnitsCount, tileStatisticsPakStreamoutBuffer, 86 * sizeof(uint32_t), mhw::mi::MHW_MI_ATOMIC_ADD, cmdBuffer));
2268         ENCODE_CHK_STATUS_RETURN(CalAtomic(m_basicFeature->m_resMetadataBuffer, resourceOffset.dwEncodeStats + resourceOffset.dwInterCodingUnitsCount, tileStatisticsPakStreamoutBuffer, 87 * sizeof(uint32_t), mhw::mi::MHW_MI_ATOMIC_ADD, cmdBuffer));
2269 
2270         // Average MV_X/MV_Y, report (0,0) as temp solution, later may need kernel involved
2271         storeDataParams.dwResourceOffset = resourceOffset.dwEncodeStats + resourceOffset.dwAverageMotionEstimationXDirection;
2272         storeDataParams.dwValue          = 0;
2273         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_STORE_DATA_IMM)(cmdBuffer));
2274 
2275         storeDataParams.dwResourceOffset = resourceOffset.dwEncodeStats + resourceOffset.dwAverageMotionEstimationYDirection;
2276         storeDataParams.dwValue          = 0;
2277         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_STORE_DATA_IMM)(cmdBuffer));
2278 
2279         return MOS_STATUS_SUCCESS;
2280     }
2281 
CalAtomic(PMOS_RESOURCE presDst,uint32_t dstOffset,PMOS_RESOURCE presSrc,uint32_t srcOffset,mhw::mi::MHW_COMMON_MI_ATOMIC_OPCODE opCode,MOS_COMMAND_BUFFER * cmdBuffer)2282     inline MOS_STATUS Av1VdencPkt::CalAtomic(PMOS_RESOURCE presDst, uint32_t dstOffset, PMOS_RESOURCE presSrc, uint32_t srcOffset, mhw::mi::MHW_COMMON_MI_ATOMIC_OPCODE opCode, MOS_COMMAND_BUFFER *cmdBuffer)
2283     {
2284         ENCODE_FUNC_CALL();
2285         ENCODE_CHK_NULL_RETURN(cmdBuffer);
2286 
2287         auto  mmioRegisters      = m_hwInterface->GetVdencInterfaceNext()->GetMmioRegisters(m_vdboxIndex);
2288         ENCODE_CHK_NULL_RETURN(mmioRegisters);
2289         auto &miLoadRegMemParams = m_miItf->MHW_GETPAR_F(MI_LOAD_REGISTER_MEM)();
2290         auto &flushDwParams      = m_miItf->MHW_GETPAR_F(MI_FLUSH_DW)();
2291         auto &atomicParams       = m_miItf->MHW_GETPAR_F(MI_ATOMIC)();
2292 
2293         miLoadRegMemParams = {};
2294         flushDwParams      = {};
2295         atomicParams       = {};
2296 
2297         miLoadRegMemParams.presStoreBuffer = presSrc;
2298         miLoadRegMemParams.dwOffset        = srcOffset;
2299         miLoadRegMemParams.dwRegister      = mmioRegisters->generalPurposeRegister0LoOffset;
2300         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_LOAD_REGISTER_MEM)(cmdBuffer));
2301 
2302         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_FLUSH_DW)(cmdBuffer));
2303 
2304         atomicParams.pOsResource      = presDst;
2305         atomicParams.dwResourceOffset = dstOffset;
2306         atomicParams.dwDataSize       = sizeof(uint32_t);
2307         atomicParams.Operation        = opCode;
2308         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_ATOMIC)(cmdBuffer));
2309 
2310         return MOS_STATUS_SUCCESS;
2311     }
2312 
2313 #if USE_CODECHAL_DEBUG_TOOL
DumpInput()2314     MOS_STATUS Av1VdencPkt::DumpInput()
2315     {
2316         ENCODE_FUNC_CALL();
2317         ENCODE_CHK_NULL_RETURN(m_pipeline);
2318         ENCODE_CHK_NULL_RETURN(m_basicFeature);
2319 
2320         CodechalDebugInterface *debugInterface = m_pipeline->GetDebugInterface();
2321         ENCODE_CHK_NULL_RETURN(debugInterface);
2322 
2323         debugInterface->m_DumpInputNum         = m_basicFeature->m_frameNum - 1;
2324 
2325         ENCODE_CHK_NULL_RETURN(m_basicFeature->m_ref.GetCurrRefList());
2326         CODEC_REF_LIST currRefList             = *((CODEC_REF_LIST *)m_basicFeature->m_ref.GetCurrRefList());
2327 
2328         ENCODE_CHK_STATUS_RETURN(debugInterface->DumpYUVSurface(
2329             &currRefList.sRefRawBuffer,
2330             CodechalDbgAttr::attrEncodeRawInputSurface,
2331             "SrcSurf"));
2332         ENCODE_CHK_STATUS_RETURN(m_basicFeature->m_ref.DumpInput(m_pipeline));
2333 
2334         return MOS_STATUS_SUCCESS;
2335     }
DumpResources(EncodeStatusMfx * encodeStatusMfx,EncodeStatusReportData * statusReportData)2336     MOS_STATUS Av1VdencPkt::DumpResources(EncodeStatusMfx *encodeStatusMfx, EncodeStatusReportData *statusReportData)
2337     {
2338         ENCODE_FUNC_CALL();
2339         ENCODE_CHK_NULL_RETURN(encodeStatusMfx);
2340         ENCODE_CHK_NULL_RETURN(statusReportData);
2341         ENCODE_CHK_NULL_RETURN(m_pipeline);
2342         ENCODE_CHK_NULL_RETURN(m_statusReport);
2343         ENCODE_CHK_NULL_RETURN(m_basicFeature);
2344         ENCODE_CHK_NULL_RETURN(m_basicFeature->m_trackedBuf);
2345 
2346         CodechalDebugInterface *debugInterface = m_pipeline->GetStatusReportDebugInterface();
2347         ENCODE_CHK_NULL_RETURN(debugInterface);
2348 
2349         CODEC_REF_LIST currRefList = *((CODEC_REF_LIST *)statusReportData->currRefList);
2350         currRefList.RefPic         = statusReportData->currOriginalPic;
2351 
2352         debugInterface->m_currPic            = statusReportData->currOriginalPic;
2353         debugInterface->m_bufferDumpFrameNum = m_statusReport->GetReportedCount();
2354         debugInterface->m_frameType          = encodeStatusMfx->pictureCodingType;
2355 
2356         if (m_resVDEncPakObjCmdStreamOutBuffer != nullptr)
2357         {
2358             ENCODE_CHK_STATUS_RETURN(debugInterface->DumpBuffer(
2359                 m_resVDEncPakObjCmdStreamOutBuffer,
2360                 CodechalDbgAttr::attrPakObjStreamout,
2361                 "_PakObj",
2362                 m_basicFeature->m_mbCodeSize + 8 * CODECHAL_CACHELINE_SIZE,
2363                 0,
2364                 CODECHAL_NUM_MEDIA_STATES));
2365         }
2366 
2367         ENCODE_CHK_STATUS_RETURN(debugInterface->DumpBuffer(
2368             &currRefList.resBitstreamBuffer,
2369             CodechalDbgAttr::attrBitstream,
2370             "_PAK",
2371             statusReportData->bitstreamSize,
2372             0,
2373             CODECHAL_NUM_MEDIA_STATES));
2374 
2375         ENCODE_CHK_STATUS_RETURN(debugInterface->DumpData(
2376             statusReportData,
2377             sizeof(EncodeStatusReportData),
2378             CodechalDbgAttr::attrStatusReport,
2379             "EncodeStatusReport_Buffer"));
2380 
2381         MOS_SURFACE *ds4xSurface = m_basicFeature->m_trackedBuf->GetSurface(
2382             BufferType::ds4xSurface, currRefList.ucScalingIdx);
2383 
2384         if (ds4xSurface != nullptr)
2385         {
2386             ENCODE_CHK_STATUS_RETURN(debugInterface->DumpYUVSurface(
2387                 ds4xSurface,
2388                 CodechalDbgAttr::attrReconstructedSurface,
2389                 "4xScaledSurf"))
2390         }
2391 
2392         MOS_SURFACE *ds8xSurface = m_basicFeature->m_trackedBuf->GetSurface(
2393             BufferType::ds8xSurface, currRefList.ucScalingIdx);
2394 
2395         if (ds8xSurface != nullptr)
2396         {
2397             ENCODE_CHK_STATUS_RETURN(debugInterface->DumpYUVSurface(
2398                 ds8xSurface,
2399                 CodechalDbgAttr::attrReconstructedSurface,
2400                 "8xScaledSurf"))
2401         }
2402 
2403         MOS_RESOURCE *mbCodedBuffer = m_basicFeature->m_trackedBuf->GetBuffer(
2404             BufferType::mbCodedBuffer, currRefList.ucScalingIdx);
2405         if (mbCodedBuffer != nullptr)
2406         {
2407             ENCODE_CHK_STATUS_RETURN(debugInterface->DumpBuffer(
2408                 mbCodedBuffer,
2409                 CodechalDbgAttr::attrVdencOutput,
2410                 "_MbCode",
2411                 m_basicFeature->m_mbCodeSize,
2412                 0,
2413                 CODECHAL_NUM_MEDIA_STATES));
2414         }
2415 
2416         auto streamInBufferSize = (MOS_ALIGN_CEIL(m_basicFeature->m_frameWidth, 64) / 32) * (MOS_ALIGN_CEIL(m_basicFeature->m_frameHeight, 64) / 32) * CODECHAL_CACHELINE_SIZE;
2417         PMOS_RESOURCE streamInBuffer = m_basicFeature->m_recycleBuf->GetBuffer(RecycleResId::StreamInBuffer, debugInterface->m_bufferDumpFrameNum);
2418         if (streamInBuffer != nullptr)
2419         {
2420             ENCODE_CHK_STATUS_RETURN(debugInterface->DumpBuffer(
2421                 streamInBuffer,
2422                 CodechalDbgAttr::attrStreamIn,
2423                 "StreamIn",
2424                 streamInBufferSize,
2425                 0,
2426                 CODECHAL_NUM_MEDIA_STATES));
2427         }
2428 
2429         ENCODE_CHK_STATUS_RETURN(debugInterface->DumpYUVSurface(
2430             &currRefList.sRefReconBuffer,
2431             CodechalDbgAttr::attrReconstructedSurface,
2432             "ReconSurf",
2433             CODECHAL_NUM_MEDIA_STATES,
2434             m_basicFeature->m_frameWidth,
2435             m_basicFeature->m_frameHeight))
2436 
2437         MOS_SURFACE* postCdefSurface = m_basicFeature->m_trackedBuf->GetSurface(
2438             BufferType::postCdefReconSurface, currRefList.ucScalingIdx);
2439         if (postCdefSurface != nullptr)
2440         {
2441             ENCODE_CHK_STATUS_RETURN(debugInterface->DumpYUVSurface(
2442                 postCdefSurface,
2443                 CodechalDbgAttr::attrReconstructedSurface,
2444                 "PostCdefReconSurf",
2445                 CODECHAL_NUM_MEDIA_STATES,
2446                 m_basicFeature->m_frameWidth,
2447                 m_basicFeature->m_frameHeight))
2448         }
2449 
2450         return MOS_STATUS_SUCCESS;
2451     }
DumpStatistics()2452     MOS_STATUS Av1VdencPkt::DumpStatistics()
2453     {
2454         CodechalDebugInterface *debugInterface =  m_pipeline->GetStatusReportDebugInterface();
2455         ENCODE_CHK_NULL_RETURN(debugInterface);
2456 
2457         ENCODE_CHK_STATUS_RETURN(debugInterface->DumpBuffer(
2458             m_basicFeature->m_tileStatisticsPakStreamoutBuffer,
2459             CodechalDbgAttr::attrTileBasedStats,
2460             "Pak_Tile_Stats",
2461             512,
2462             0,
2463             CODECHAL_NUM_MEDIA_STATES));
2464 
2465         MOS_RESOURCE* tileStatisticsBuffer = nullptr;
2466         RUN_FEATURE_INTERFACE_RETURN(Av1EncodeTile, FeatureIDs::encodeTile, GetTileBasedStatisticsBuffer, 0, tileStatisticsBuffer);
2467         ENCODE_CHK_NULL_RETURN(tileStatisticsBuffer);
2468         uint32_t offset = 0;
2469         RUN_FEATURE_INTERFACE_RETURN(Av1EncodeTile, Av1FeatureIDs::encodeTile, GetTileStatsOffset, offset);
2470 
2471         ENCODE_CHK_STATUS_RETURN(debugInterface->DumpBuffer(
2472             tileStatisticsBuffer,
2473             CodechalDbgAttr::attrFrameState,
2474             "VDEnc_Frame_Stats",
2475             m_hwInterface->m_pakIntTileStatsSize,
2476             offset,
2477             CODECHAL_NUM_MEDIA_STATES));
2478 
2479         MOS_RESOURCE *pakinfo = m_basicFeature->m_recycleBuf->GetBuffer(PakInfo, 0);
2480         ENCODE_CHK_NULL_RETURN(pakinfo);
2481         ENCODE_CHK_STATUS_RETURN(debugInterface->DumpBuffer(
2482             pakinfo,
2483             CodechalDbgAttr::attrFrameState,
2484             "VDEnc_PAK_INFO",
2485             MOS_ALIGN_CEIL(sizeof(Av1VdencPakInfo), CODECHAL_PAGE_SIZE),
2486             0,
2487             CODECHAL_NUM_MEDIA_STATES));
2488 
2489         return MOS_STATUS_SUCCESS;
2490     }
2491 #endif
2492 
2493 }  // namespace encode
2494