1 /*
2 * Copyright (c) 2021, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 //!
23 //! \file decode_av1_packet.cpp
24 //! \brief Defines the interface for av1 decode packet
25 //!
26 #include "decode_av1_packet.h"
27 #include "decode_status_report_defs.h"
28 #include "decode_predication_packet.h"
29 #include "decode_marker_packet.h"
30
31 namespace decode {
32
Init()33 MOS_STATUS Av1DecodePkt::Init()
34 {
35 DECODE_FUNC_CALL();
36 DECODE_CHK_NULL(m_miItf);
37 DECODE_CHK_NULL(m_statusReport);
38 DECODE_CHK_NULL(m_featureManager);
39 DECODE_CHK_NULL(m_av1Pipeline);
40 DECODE_CHK_NULL(m_osInterface);
41
42 DECODE_CHK_STATUS(CmdPacket::Init());
43
44 m_av1BasicFeature = dynamic_cast<Av1BasicFeature*>(m_featureManager->GetFeature(FeatureIDs::basicFeature));
45 DECODE_CHK_NULL(m_av1BasicFeature);
46
47 m_allocator = m_av1Pipeline->GetDecodeAllocator();
48 DECODE_CHK_NULL(m_allocator);
49
50 DECODE_CHK_STATUS(m_statusReport->RegistObserver(this));
51
52 DecodeSubPacket* subPacket = m_av1Pipeline->GetSubPacket(DecodePacketId(m_av1Pipeline, av1PictureSubPacketId));
53
54 m_picturePkt = dynamic_cast<Av1DecodePicPkt*>(subPacket);
55 DECODE_CHK_NULL(m_picturePkt);
56 DECODE_CHK_STATUS(m_picturePkt->CalculateCommandSize(m_pictureStatesSize, m_picturePatchListSize));
57
58 subPacket = m_av1Pipeline->GetSubPacket(DecodePacketId(m_av1Pipeline, av1TileSubPacketId));
59 m_tilePkt = dynamic_cast<Av1DecodeTilePkt*>(subPacket);
60 DECODE_CHK_NULL(m_tilePkt);
61 DECODE_CHK_STATUS(m_tilePkt->CalculateCommandSize(m_tileStatesSize, m_tilePatchListSize));
62
63 m_secondLevelBBArray = m_allocator->AllocateBatchBufferArray(
64 m_pictureStatesSize, 1, CODEC_NUM_AV1_SECOND_BB, true, lockableVideoMem);
65 DECODE_CHK_NULL(m_secondLevelBBArray);
66
67 return MOS_STATUS_SUCCESS;
68 }
69
Prepare()70 MOS_STATUS Av1DecodePkt::Prepare()
71 {
72 DECODE_FUNC_CALL();
73
74 DECODE_CHK_NULL(m_av1BasicFeature->m_av1PicParams);
75 m_av1PicParams = m_av1BasicFeature->m_av1PicParams;
76
77 return MOS_STATUS_SUCCESS;
78 }
79
Destroy()80 MOS_STATUS Av1DecodePkt::Destroy()
81 {
82 m_statusReport->UnregistObserver(this);
83 if (m_allocator != nullptr)
84 {
85 DECODE_CHK_STATUS(m_allocator->Destroy(m_secondLevelBBArray));
86 }
87
88 return MOS_STATUS_SUCCESS;
89 }
90
SetPerfTag(CODECHAL_MODE mode,uint16_t picCodingType)91 void Av1DecodePkt::SetPerfTag(CODECHAL_MODE mode, uint16_t picCodingType)
92 {
93 DECODE_FUNC_CALL();
94
95 uint16_t perfTag = ((mode << 4) & 0xF0) | (picCodingType & 0xF);
96 m_osInterface->pfnIncPerfFrameID(m_osInterface);
97 m_osInterface->pfnSetPerfTag(m_osInterface, perfTag);
98 m_osInterface->pfnResetPerfBufferID(m_osInterface);
99 }
100
IsPrologRequired()101 bool Av1DecodePkt::IsPrologRequired()
102 {
103 return true; // if ScalableMode, should set to false.
104 }
105
AddForceWakeup(MOS_COMMAND_BUFFER & cmdBuffer)106 MOS_STATUS Av1DecodePkt::AddForceWakeup(MOS_COMMAND_BUFFER& cmdBuffer)
107 {
108 DECODE_FUNC_CALL();
109
110 auto &par = m_miItf->GETPAR_MI_FORCE_WAKEUP();
111 MOS_ZeroMemory(&par, sizeof(mhw::mi::MI_FORCE_WAKEUP_PAR));
112 par.bMFXPowerWellControl = false;
113 par.bMFXPowerWellControlMask = true;
114 par.bHEVCPowerWellControl = true;
115 par.bHEVCPowerWellControlMask = true;
116
117 DECODE_CHK_STATUS(m_miItf->ADDCMD_MI_FORCE_WAKEUP(&cmdBuffer));
118
119 return MOS_STATUS_SUCCESS;
120 }
121
SendPrologWithFrameTracking(MOS_COMMAND_BUFFER & cmdBuffer,bool frameTrackingRequested)122 MOS_STATUS Av1DecodePkt::SendPrologWithFrameTracking(MOS_COMMAND_BUFFER& cmdBuffer, bool frameTrackingRequested)
123 {
124 DecodeSubPacket* subPacket = m_av1Pipeline->GetSubPacket(DecodePacketId(m_av1Pipeline, markerSubPacketId));
125 DecodeMarkerPkt *makerPacket = dynamic_cast<DecodeMarkerPkt*>(subPacket);
126 DECODE_CHK_NULL(makerPacket);
127 DECODE_CHK_STATUS(makerPacket->Execute(cmdBuffer));
128
129 #ifdef _MMC_SUPPORTED
130 m_mmcState = m_av1Pipeline->GetMmcState();
131 bool isMmcEnabled = (m_mmcState != nullptr && m_mmcState->IsMmcEnabled());
132 if (isMmcEnabled)
133 {
134 DECODE_CHK_STATUS(m_mmcState->SendPrologCmd(&cmdBuffer, false));
135 }
136 #endif
137
138 MHW_GENERIC_PROLOG_PARAMS genericPrologParams;
139 MOS_ZeroMemory(&genericPrologParams, sizeof(genericPrologParams));
140 genericPrologParams.pOsInterface = m_osInterface;
141 genericPrologParams.pvMiInterface = nullptr;
142
143 #ifdef _MMC_SUPPORTED
144 genericPrologParams.bMmcEnabled = isMmcEnabled;
145 #endif
146
147 DECODE_CHK_STATUS(Mhw_SendGenericPrologCmdNext(&cmdBuffer, &genericPrologParams, m_miItf));
148
149 subPacket = m_av1Pipeline->GetSubPacket(DecodePacketId(m_av1Pipeline, predicationSubPacketId));
150 DecodePredicationPkt *predicationPacket = dynamic_cast<DecodePredicationPkt*>(subPacket);
151 DECODE_CHK_NULL(predicationPacket);
152 DECODE_CHK_STATUS(predicationPacket->Execute(cmdBuffer));
153
154 return MOS_STATUS_SUCCESS;
155 }
156
VdPipelineFlush(MOS_COMMAND_BUFFER & cmdBuffer)157 MOS_STATUS Av1DecodePkt::VdPipelineFlush(MOS_COMMAND_BUFFER & cmdBuffer)
158 {
159 DECODE_FUNC_CALL();
160
161 auto &par = m_vdencItf->GETPAR_VD_PIPELINE_FLUSH();
162 par = {};
163 par.waitDoneAV1 = 1;
164 par.flushAV1 = 1;
165 par.waitDoneVDCmdMsgParser = 1;
166 m_vdencItf->ADDCMD_VD_PIPELINE_FLUSH(&cmdBuffer);
167
168 return MOS_STATUS_SUCCESS;
169 }
170
MiFlush(MOS_COMMAND_BUFFER & cmdBuffer)171 MOS_STATUS Av1DecodePkt::MiFlush(MOS_COMMAND_BUFFER & cmdBuffer)
172 {
173 DECODE_FUNC_CALL();
174
175 auto &par = m_miItf->GETPAR_MI_FLUSH_DW();
176 MOS_ZeroMemory(&par, sizeof(mhw::mi::MI_FLUSH_DW_PAR));
177 DECODE_CHK_STATUS(m_miItf->ADDCMD_MI_FLUSH_DW(&cmdBuffer));
178
179 return MOS_STATUS_SUCCESS;
180 }
181
Completed(void * mfxStatus,void * rcsStatus,void * statusReport)182 MOS_STATUS Av1DecodePkt::Completed(void *mfxStatus, void *rcsStatus, void *statusReport)
183 {
184 DECODE_FUNC_CALL();
185
186 DECODE_CHK_NULL(mfxStatus);
187 DECODE_CHK_NULL(statusReport);
188 DECODE_CHK_NULL(m_av1BasicFeature);
189
190 DecodeStatusMfx * decodeStatusMfx = (DecodeStatusMfx *)mfxStatus;
191 DecodeStatusReportData *statusReportData = (DecodeStatusReportData *)statusReport;
192 DECODE_VERBOSEMESSAGE("Current Frame Index = %d", statusReportData->currDecodedPic.FrameIdx);
193
194 return MOS_STATUS_SUCCESS;
195 }
196
CalculateCommandSize(uint32_t & commandBufferSize,uint32_t & requestedPatchListSize)197 MOS_STATUS Av1DecodePkt::CalculateCommandSize(uint32_t &commandBufferSize, uint32_t &requestedPatchListSize)
198 {
199 commandBufferSize = CalculateCommandBufferSize();
200 requestedPatchListSize = CalculatePatchListSize();
201 return MOS_STATUS_SUCCESS;
202 }
203
CalculateCommandBufferSize()204 uint32_t Av1DecodePkt::CalculateCommandBufferSize()
205 {
206 uint32_t commandBufferSize = 0;
207
208 commandBufferSize = m_pictureStatesSize + m_tileStatesSize;
209
210 return (commandBufferSize + COMMAND_BUFFER_RESERVED_SPACE);
211 }
212
CalculatePatchListSize()213 uint32_t Av1DecodePkt::CalculatePatchListSize()
214 {
215 if (!m_osInterface->bUsesPatchList)
216 {
217 return 0;
218 }
219
220 uint32_t requestedPatchListSize = 0;
221
222 requestedPatchListSize = m_picturePatchListSize + m_tilePatchListSize;
223
224 return requestedPatchListSize;
225 }
226
ReadAvpStatus(MediaStatusReport * statusReport,MOS_COMMAND_BUFFER & cmdBuffer)227 MOS_STATUS Av1DecodePkt::ReadAvpStatus(MediaStatusReport* statusReport, MOS_COMMAND_BUFFER& cmdBuffer)
228 {
229 DECODE_FUNC_CALL();
230
231 DECODE_CHK_NULL(statusReport);
232
233 if (!m_osInterface->bSimIsActive)
234 {
235 MOS_RESOURCE* osResource = nullptr;
236 uint32_t offset = 0;
237
238 auto &par = m_miItf->GETPAR_MI_STORE_REGISTER_MEM();
239 MOS_ZeroMemory(&par, sizeof(mhw::mi::MI_STORE_REGISTER_MEM_PAR));
240
241 DECODE_CHK_NULL(m_hwInterface->GetAvpInterfaceNext());
242 auto mmioRegistersAvp = m_hwInterface->GetAvpInterfaceNext()->GetMmioRegisters(MHW_VDBOX_NODE_1);
243
244 DECODE_CHK_STATUS(statusReport->GetAddress(decode::DecodeStatusReportType::DecErrorStatusOffset, osResource, offset));
245 par.presStoreBuffer = osResource;
246 par.dwOffset = offset;
247 par.dwRegister = mmioRegistersAvp->avpAv1DecErrorStatusAddrRegOffset;
248
249 DECODE_CHK_STATUS(m_miItf->ADDCMD_MI_STORE_REGISTER_MEM(&cmdBuffer));
250 }
251
252 return MOS_STATUS_SUCCESS;
253 }
254
StartStatusReport(uint32_t srType,MOS_COMMAND_BUFFER * cmdBuffer)255 MOS_STATUS Av1DecodePkt::StartStatusReport(uint32_t srType, MOS_COMMAND_BUFFER* cmdBuffer)
256 {
257 DECODE_FUNC_CALL();
258
259 DECODE_CHK_STATUS(MediaPacket::StartStatusReportNext(srType, cmdBuffer));
260
261 SetPerfTag(CODECHAL_DECODE_MODE_AV1VLD, m_av1BasicFeature->m_pictureCodingType);
262 MediaPerfProfiler *perfProfiler = MediaPerfProfiler::Instance();
263 DECODE_CHK_NULL(perfProfiler);
264 DECODE_CHK_STATUS(perfProfiler->AddPerfCollectStartCmd(
265 (void*)m_av1Pipeline, m_osInterface, m_miItf, cmdBuffer));
266
267 return MOS_STATUS_SUCCESS;
268 }
269
EndStatusReport(uint32_t srType,MOS_COMMAND_BUFFER * cmdBuffer)270 MOS_STATUS Av1DecodePkt::EndStatusReport(uint32_t srType, MOS_COMMAND_BUFFER* cmdBuffer)
271 {
272 DECODE_FUNC_CALL();
273
274 DECODE_CHK_NULL(cmdBuffer);
275 DECODE_CHK_STATUS(ReadAvpStatus( m_statusReport, *cmdBuffer));
276 DECODE_CHK_STATUS(MediaPacket::EndStatusReportNext(srType, cmdBuffer));
277
278 MediaPerfProfiler *perfProfiler = MediaPerfProfiler::Instance();
279 DECODE_CHK_NULL(perfProfiler);
280 DECODE_CHK_STATUS(perfProfiler->AddPerfCollectEndCmd(
281 (void*)m_av1Pipeline, m_osInterface, m_miItf, cmdBuffer));
282
283 // Add Mi flush here to ensure end status tag flushed to memory earlier than completed count
284 DECODE_CHK_STATUS(MiFlush(*cmdBuffer));
285
286 return MOS_STATUS_SUCCESS;
287 }
288
InitPicLevelCmdBuffer(MHW_BATCH_BUFFER & batchBuffer,uint8_t * batchBufBase)289 MOS_STATUS Av1DecodePkt::InitPicLevelCmdBuffer(MHW_BATCH_BUFFER &batchBuffer, uint8_t *batchBufBase)
290 {
291 DECODE_FUNC_CALL();
292
293 auto &cmdBuffer = m_picCmdBuffer;
294 MOS_ZeroMemory(&cmdBuffer, sizeof(MOS_COMMAND_BUFFER));
295 cmdBuffer.pCmdBase = (uint32_t*)batchBufBase;
296 cmdBuffer.pCmdPtr = cmdBuffer.pCmdBase;
297 cmdBuffer.iRemaining = batchBuffer.iSize;
298 cmdBuffer.OsResource = batchBuffer.OsResource;
299
300 return MOS_STATUS_SUCCESS;
301 }
302
303 }
304