1 /*
2 * Copyright (c) 2017-2020, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 //!
23 //! \file codechal_decode_vp8_g12.cpp
24 //! \brief Implements the decode interface extension for VP8.
25 //! \details Implements all functions and constants required by CodecHal for VP8 decoding.
26 //!
27
28 #include "codechal_decoder.h"
29 #include "codechal_decode_vp8_g12.h"
30 #include "codechal_mmc_decode_vp8_g12.h"
31 #include "mhw_vdbox_mfx_g12_X.h"
32 #include "hal_oca_interface.h"
33
~CodechalDecodeVp8G12()34 CodechalDecodeVp8G12::~CodechalDecodeVp8G12()
35 {
36 CODECHAL_DECODE_FUNCTION_ENTER;
37
38 if (m_veState != nullptr)
39 {
40 MOS_FreeMemAndSetNull(m_veState);
41 m_veState = nullptr;
42 }
43 }
44
SetFrameStates()45 MOS_STATUS CodechalDecodeVp8G12::SetFrameStates()
46 {
47 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
48
49 CODECHAL_DECODE_FUNCTION_ENTER;
50
51 CODECHAL_DECODE_CHK_STATUS_RETURN(CodechalDecodeVp8::SetFrameStates());
52
53 if ( MOS_VE_SUPPORTED(m_osInterface))
54 {
55 MOS_VIRTUALENGINE_SET_PARAMS vesetParams;
56
57 MOS_ZeroMemory(&vesetParams, sizeof(vesetParams));
58 vesetParams.bSFCInUse = false;
59 vesetParams.bNeedSyncWithPrevious = true;
60 vesetParams.bSameEngineAsLastSubmission = false;
61 CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalDecodeSinglePipeVE_SetHintParams(m_veState, &vesetParams));
62 }
63
64 #ifdef _MMC_SUPPORTED
65 // To WA invalid aux data caused HW issue when MMC on
66 if (m_mmc && m_mmc->IsMmcEnabled() && MEDIA_IS_WA(m_waTable, Wa_1408785368) &&
67 !Mos_ResourceIsNull(&m_destSurface.OsResource) &&
68 m_destSurface.OsResource.bConvertedFromDDIResource)
69 {
70 CODECHAL_DECODE_VERBOSEMESSAGE("Clear CCS by VE resolve before frame %d submission", m_frameNum);
71 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnDecompResource(m_osInterface, &m_destSurface.OsResource));
72 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSetGpuContext(m_osInterface, m_videoContext));
73 }
74 #endif
75
76 return eStatus;
77 }
78
DecodeStateLevel()79 MOS_STATUS CodechalDecodeVp8G12::DecodeStateLevel()
80 {
81 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
82
83 CODECHAL_DECODE_FUNCTION_ENTER;
84
85 PCODEC_REF_LIST *vp8RefList = m_vp8RefList;
86
87 uint8_t lastRefPicIndex = m_vp8PicParams->ucLastRefPicIndex;
88 uint8_t goldenRefPicIndex = m_vp8PicParams->ucGoldenRefPicIndex;
89 uint8_t altRefPicIndex = m_vp8PicParams->ucAltRefPicIndex;
90
91 PMOS_SURFACE destSurface = &m_destSurface;
92 if (m_vp8PicParams->key_frame) // reference surface should be nullptr when key_frame == true
93 {
94 m_presLastRefSurface = nullptr;
95 m_presGoldenRefSurface = nullptr;
96 m_presAltRefSurface = nullptr;
97 }
98 else
99 {
100 m_presLastRefSurface = &(vp8RefList[lastRefPicIndex]->resRefPic);
101 m_presGoldenRefSurface = &(vp8RefList[goldenRefPicIndex]->resRefPic);
102 m_presAltRefSurface = &(vp8RefList[altRefPicIndex]->resRefPic);
103 }
104
105 MOS_COMMAND_BUFFER cmdBuffer;
106 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
107
108 auto mmioRegisters = m_hwInterface->GetMfxInterface()->GetMmioRegisters(m_vdboxIndex);
109 HalOcaInterface::On1stLevelBBStart(cmdBuffer, *m_osInterface->pOsContext, m_osInterface->CurrentGpuContextHandle, *m_miInterface, *mmioRegisters);
110
111 MHW_MI_FORCE_WAKEUP_PARAMS forceWakeupParams;
112 MOS_ZeroMemory(&forceWakeupParams, sizeof(MHW_MI_FORCE_WAKEUP_PARAMS));
113 forceWakeupParams.bMFXPowerWellControl = true;
114 forceWakeupParams.bMFXPowerWellControlMask = true;
115 forceWakeupParams.bHEVCPowerWellControl = false;
116 forceWakeupParams.bHEVCPowerWellControlMask = true;
117 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiForceWakeupCmd(
118 &cmdBuffer,
119 &forceWakeupParams));
120
121 MHW_VDBOX_PIPE_MODE_SELECT_PARAMS pipeModeSelectParams;
122 pipeModeSelectParams.Mode = m_mode;
123 pipeModeSelectParams.bStreamOutEnabled = m_streamOutEnabled;
124 pipeModeSelectParams.bPostDeblockOutEnable = m_deblockingEnabled;
125 pipeModeSelectParams.bPreDeblockOutEnable = !m_deblockingEnabled;
126 pipeModeSelectParams.bShortFormatInUse = m_shortFormatInUse;
127
128 MHW_VDBOX_SURFACE_PARAMS surfaceParams;
129 MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams));
130 surfaceParams.Mode = m_mode;
131 surfaceParams.psSurface = destSurface;
132
133 MHW_VDBOX_PIPE_BUF_ADDR_PARAMS pipeBufAddrParams;
134 pipeBufAddrParams.Mode = m_mode;
135
136 if (m_deblockingEnabled)
137 {
138 pipeBufAddrParams.psPostDeblockSurface = &m_destSurface;
139 }
140 else
141 {
142 pipeBufAddrParams.psPreDeblockSurface = &m_destSurface;
143 }
144
145 #ifdef _MMC_SUPPORTED
146 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mmc->SetPipeBufAddr(&pipeBufAddrParams));
147 #endif
148
149 // when there is no last, golden and alternate reference,
150 // the index is set to the destination frame index
151 pipeBufAddrParams.presReferences[CodechalDecodeLastRef] = m_presLastRefSurface;
152 pipeBufAddrParams.presReferences[CodechalDecodeGoldenRef] = m_presGoldenRefSurface;
153 pipeBufAddrParams.presReferences[CodechalDecodeAlternateRef] = m_presAltRefSurface;
154
155 pipeBufAddrParams.presMfdIntraRowStoreScratchBuffer = &m_resMfdIntraRowStoreScratchBuffer;
156 pipeBufAddrParams.presMfdDeblockingFilterRowStoreScratchBuffer = &m_resMfdDeblockingFilterRowStoreScratchBuffer;
157 if (m_streamOutEnabled)
158 {
159 pipeBufAddrParams.presStreamOutBuffer =
160 &(m_streamOutBuffer[m_streamOutCurrBufIdx]);
161 }
162
163 // set all ref pic addresses to valid addresses for error concealment purpose
164 for (uint32_t i = 0; i <= CodechalDecodeAlternateRef; i++)
165 {
166 if (pipeBufAddrParams.presReferences[i] == nullptr &&
167 MEDIA_IS_WA(m_waTable, WaDummyReference) &&
168 !Mos_ResourceIsNull(&m_dummyReference.OsResource))
169 {
170 pipeBufAddrParams.presReferences[i] = &m_dummyReference.OsResource;
171 }
172 }
173
174 #ifdef _MMC_SUPPORTED
175 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mmc->CheckReferenceList(&pipeBufAddrParams));
176
177 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mmc->SetRefrenceSync(m_disableDecodeSyncLock, m_disableLockForTranscode));
178 #endif
179
180 MHW_VDBOX_IND_OBJ_BASE_ADDR_PARAMS indObjBaseAddrParams;
181 MOS_ZeroMemory(&indObjBaseAddrParams, sizeof(indObjBaseAddrParams));
182 indObjBaseAddrParams.Mode = m_mode;
183 indObjBaseAddrParams.dwDataSize = m_dataSize;
184 indObjBaseAddrParams.presDataBuffer = &m_resDataBuffer;
185
186 MHW_VDBOX_BSP_BUF_BASE_ADDR_PARAMS bspBufBaseAddrParams;
187 MOS_ZeroMemory(&bspBufBaseAddrParams, sizeof(bspBufBaseAddrParams));
188 bspBufBaseAddrParams.presBsdMpcRowStoreScratchBuffer = &m_resBsdMpcRowStoreScratchBuffer;
189 bspBufBaseAddrParams.presMprRowStoreScratchBuffer = &m_resMprRowStoreScratchBuffer;
190
191 MHW_VDBOX_VP8_PIC_STATE vp8PicState;
192 vp8PicState.pVp8PicParams = m_vp8PicParams;
193 vp8PicState.pVp8IqMatrixParams = m_vp8IqMatrixParams;
194 vp8PicState.presSegmentationIdStreamBuffer = &m_resSegmentationIdStreamBuffer;
195 vp8PicState.dwCoefProbTableOffset = 0;
196 vp8PicState.presCoefProbBuffer = &m_resCoefProbBuffer;
197
198 CODECHAL_DECODE_CHK_STATUS_RETURN(SendPrologWithFrameTracking(
199 &cmdBuffer, true));
200
201 if (m_statusQueryReportingEnabled)
202 {
203 CODECHAL_DECODE_CHK_STATUS_RETURN(StartStatusReport(&cmdBuffer));
204 }
205
206 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxPipeModeSelectCmd(&cmdBuffer, &pipeModeSelectParams));
207
208 #ifdef _MMC_SUPPORTED
209 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mmc->SetSurfaceState(&surfaceParams));
210 #endif
211 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxSurfaceCmd(&cmdBuffer, &surfaceParams));
212
213 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxPipeBufAddrCmd(&cmdBuffer, &pipeBufAddrParams));
214
215 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxIndObjBaseAddrCmd(&cmdBuffer, &indObjBaseAddrParams));
216
217 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxBspBufBaseAddrCmd(&cmdBuffer, &bspBufBaseAddrParams));
218
219 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxVp8PicCmd(&cmdBuffer, &vp8PicState));
220
221 m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
222
223 return eStatus;
224 }
225
DecodePrimitiveLevel()226 MOS_STATUS CodechalDecodeVp8G12::DecodePrimitiveLevel()
227 {
228 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
229
230 CODECHAL_DECODE_FUNCTION_ENTER;
231
232 CODECHAL_DECODE_CHK_NULL_RETURN(m_osInterface);
233 MOS_COMMAND_BUFFER cmdBuffer;
234 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
235
236 if (m_incompletePicture)
237 {
238 MHW_MI_FORCE_WAKEUP_PARAMS forceWakeupParams;
239 MOS_ZeroMemory(&forceWakeupParams, sizeof(MHW_MI_FORCE_WAKEUP_PARAMS));
240 forceWakeupParams.bMFXPowerWellControl = true;
241 forceWakeupParams.bMFXPowerWellControlMask = true;
242 forceWakeupParams.bHEVCPowerWellControl = false;
243 forceWakeupParams.bHEVCPowerWellControlMask = true;
244 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiForceWakeupCmd(
245 &cmdBuffer,
246 &forceWakeupParams));
247 }
248
249 // Fill BSD Object Commands
250 MHW_VDBOX_VP8_BSD_PARAMS vp8BsdParams;
251 vp8BsdParams.pVp8PicParams = m_vp8PicParams;
252
253 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfdVp8BsdObjectCmd(&cmdBuffer, &vp8BsdParams));
254
255 // Check if destination surface needs to be synchronized
256 MOS_SYNC_PARAMS syncParams;
257 syncParams = g_cInitSyncParams;
258 syncParams.GpuContext = m_videoContext;
259 syncParams.presSyncResource = &m_destSurface.OsResource;
260 syncParams.bReadOnly = false;
261 syncParams.bDisableDecodeSyncLock = m_disableDecodeSyncLock;
262 syncParams.bDisableLockForTranscode = m_disableLockForTranscode;
263
264 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnPerformOverlaySync(m_osInterface, &syncParams));
265 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceWait(m_osInterface, &syncParams));
266
267 // Update the resource tag (s/w tag) for On-Demand Sync
268 m_osInterface->pfnSetResourceSyncTag(m_osInterface, &syncParams);
269
270 MHW_MI_FLUSH_DW_PARAMS flushDwParams;
271 MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
272
273 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(&cmdBuffer, &flushDwParams));
274
275 // Update the tag in GPU Sync eStatus buffer (H/W Tag) to match the current S/W tag
276 if (m_osInterface->bTagResourceSync)
277 {
278 CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->WriteSyncTagToResource(&cmdBuffer, &syncParams));
279 }
280
281 if (m_statusQueryReportingEnabled)
282 {
283 CodechalDecodeStatusReport decodeStatusReport;
284
285 decodeStatusReport.m_statusReportNumber = m_statusReportFeedbackNumber;
286 decodeStatusReport.m_currDecodedPic = m_vp8PicParams->CurrPic;
287 decodeStatusReport.m_currDeblockedPic = m_vp8PicParams->CurrPic;
288 decodeStatusReport.m_codecStatus = CODECHAL_STATUS_UNAVAILABLE;
289 decodeStatusReport.m_currDecodedPicRes = m_vp8RefList[m_vp8PicParams->CurrPic.FrameIdx]->resRefPic;
290 CODECHAL_DEBUG_TOOL(
291 decodeStatusReport.m_secondField = CodecHal_PictureIsBottomField(m_vp8PicParams->CurrPic);
292 decodeStatusReport.m_frameType = m_perfType;)
293 CODECHAL_DECODE_CHK_STATUS_RETURN(EndStatusReport(decodeStatusReport, &cmdBuffer));
294 }
295
296 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(&cmdBuffer, nullptr));
297
298 m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
299
300 CODECHAL_DEBUG_TOOL(
301 CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer(
302 &cmdBuffer,
303 CODECHAL_NUM_MEDIA_STATES,
304 "_DEC"));
305 )
306
307 if ( MOS_VE_SUPPORTED(m_osInterface))
308 {
309 CodecHalDecodeSinglePipeVE_PopulateHintParams(m_veState, &cmdBuffer, false);
310 }
311
312 if (m_huCCopyInUse)
313 {
314 syncParams = g_cInitSyncParams;
315 syncParams.GpuContext = m_videoContextForWa;
316 syncParams.presSyncResource = &m_resSyncObjectWaContextInUse;
317
318 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineSignal(m_osInterface, &syncParams));
319
320 syncParams = g_cInitSyncParams;
321 syncParams.GpuContext = m_videoContext;
322 syncParams.presSyncResource = &m_resSyncObjectWaContextInUse;
323
324 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineWait(m_osInterface, &syncParams));
325
326 m_huCCopyInUse = false;
327 }
328
329 HalOcaInterface::On1stLevelBBEnd(cmdBuffer, *m_osInterface);
330
331 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, m_videoContextUsesNullHw));
332
333 CODECHAL_DEBUG_TOOL(
334 m_mmc->UpdateUserFeatureKey(&m_destSurface);)
335
336 if (m_statusQueryReportingEnabled)
337 {
338 CODECHAL_DECODE_CHK_STATUS_RETURN(ResetStatusReport(m_videoContextUsesNullHw));
339 }
340
341 // Needs to be re-set for Linux buffer re-use scenarios
342 m_vp8RefList[m_vp8PicParams->ucCurrPicIndex]->resRefPic =
343 m_destSurface.OsResource;
344
345 // Send the signal to indicate decode completion, in case On-Demand Sync is not present
346 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceSignal(m_osInterface, &syncParams));
347
348 return eStatus;
349 }
350
AllocateStandard(CodechalSetting * settings)351 MOS_STATUS CodechalDecodeVp8G12::AllocateStandard(
352 CodechalSetting * settings)
353 {
354 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
355
356 CODECHAL_DECODE_FUNCTION_ENTER;
357
358 CODECHAL_DECODE_CHK_NULL_RETURN(settings);
359
360 CODECHAL_DECODE_CHK_STATUS_RETURN(CodechalDecodeVp8::AllocateStandard(settings));
361
362 if ( MOS_VE_SUPPORTED(m_osInterface))
363 {
364 static_cast<MhwVdboxMfxInterfaceG12*>(m_mfxInterface)->DisableScalabilitySupport();
365
366 //single pipe VE initialize
367 m_veState = (PCODECHAL_DECODE_SINGLEPIPE_VIRTUALENGINE_STATE)MOS_AllocAndZeroMemory(sizeof(CODECHAL_DECODE_SINGLEPIPE_VIRTUALENGINE_STATE));
368 CODECHAL_DECODE_CHK_NULL_RETURN(m_veState);
369 CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalDecodeSinglePipeVE_InitInterface(m_osInterface, m_veState));
370 }
371
372 return eStatus;
373 }
374
InitMmcState()375 MOS_STATUS CodechalDecodeVp8G12::InitMmcState()
376 {
377 #ifdef _MMC_SUPPORTED
378 m_mmc = MOS_New(CodechalMmcDecodeVp8G12, m_hwInterface, this);
379 CODECHAL_DECODE_CHK_NULL_RETURN(m_mmc);
380 #endif
381 return MOS_STATUS_SUCCESS;
382 }
383
CodechalDecodeVp8G12(CodechalHwInterface * hwInterface,CodechalDebugInterface * debugInterface,PCODECHAL_STANDARD_INFO standardInfo)384 CodechalDecodeVp8G12::CodechalDecodeVp8G12(
385 CodechalHwInterface *hwInterface,
386 CodechalDebugInterface* debugInterface,
387 PCODECHAL_STANDARD_INFO standardInfo) :
388 CodechalDecodeVp8(hwInterface, debugInterface, standardInfo)
389 {
390 CODECHAL_DECODE_FUNCTION_ENTER;
391
392 CODECHAL_DECODE_CHK_NULL_NO_STATUS_RETURN(m_osInterface);
393
394 m_osInterface->pfnVirtualEngineSupported(m_osInterface, true, true);
395 }
396
397