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 //!
24 //! \file codechal_decode_vc1_g12.cpp
25 //! \brief Implements the decode interface extension for Gen12 VC1.
26 //! \details Implements all functions required by CodecHal for Gen12 VC1 decoding.
27 //!
28
29 #include "codeckrnheader.h"
30
31 #if defined(ENABLE_KERNELS) && !defined(_FULL_OPEN_SOURCE)
32 #include "igcodeckrn_g12.h"
33 #endif
34
35 #include "codechal_decode_vc1_g12.h"
36 #include "codechal_secure_decode_interface.h"
37 #include "mhw_vdbox_mfx_g12_X.h"
38 #include "codechal_mmc_decode_vc1_g12.h"
39 #include "mhw_render_g12_X.h"
40 #include "hal_oca_interface.h"
41
InitMmcState()42 MOS_STATUS CodechalDecodeVc1G12::InitMmcState()
43 {
44 #ifdef _MMC_SUPPORTED
45 m_mmc = MOS_New(CodechalMmcDecodeVc1G12, m_hwInterface, this);
46 CODECHAL_DECODE_CHK_NULL_RETURN(m_mmc);
47 #endif
48 return MOS_STATUS_SUCCESS;
49 }
50
AllocateStandard(CodechalSetting * settings)51 MOS_STATUS CodechalDecodeVc1G12::AllocateStandard(
52 CodechalSetting * settings)
53 {
54 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
55
56 CODECHAL_DECODE_FUNCTION_ENTER;
57
58 CODECHAL_DECODE_CHK_NULL_RETURN(settings);
59
60 CODECHAL_DECODE_CHK_STATUS_RETURN(CodechalDecodeVc1::AllocateStandard(settings));
61
62 #ifdef _MMC_SUPPORTED
63 // Disable Decode MMC for IGFX
64 if (!MEDIA_IS_SKU(m_hwInterface->GetSkuTable(), FtrFlatPhysCCS))
65 {
66 m_mmc->SetMmcDisabled();
67 }
68
69 // To WA invalid aux data caused HW issue when MMC on
70 if (m_mmc->IsMmcEnabled() && (MEDIA_IS_WA(m_waTable, Wa_1408785368) || MEDIA_IS_WA(m_waTable, Wa_22010493002)))
71 {
72 //Add HUC STATE Commands
73 MHW_VDBOX_STATE_CMDSIZE_PARAMS stateCmdSizeParams;
74
75 m_hwInterface->GetHucStateCommandSize(
76 CODECHAL_DECODE_MODE_VC1VLD,
77 &m_HucStateCmdBufferSizeNeeded,
78 &m_HucPatchListSizeNeeded,
79 &stateCmdSizeParams);
80 }
81 #endif
82
83 if ( MOS_VE_SUPPORTED(m_osInterface))
84 {
85 static_cast<MhwVdboxMfxInterfaceG12*>(m_mfxInterface)->DisableScalabilitySupport();
86
87 //single pipe VE initialize
88 m_veState = (PCODECHAL_DECODE_SINGLEPIPE_VIRTUALENGINE_STATE)MOS_AllocAndZeroMemory(sizeof(CODECHAL_DECODE_SINGLEPIPE_VIRTUALENGINE_STATE));
89 CODECHAL_DECODE_CHK_NULL_RETURN(m_veState);
90 CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalDecodeSinglePipeVE_InitInterface(m_osInterface, m_veState));
91 }
92
93 return eStatus;
94 }
95
SetGpuCtxCreatOption(CodechalSetting * codecHalSetting)96 MOS_STATUS CodechalDecodeVc1G12::SetGpuCtxCreatOption(
97 CodechalSetting *codecHalSetting)
98 {
99 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
100
101 CODECHAL_DECODE_FUNCTION_ENTER;
102
103 if (!MOS_VE_CTXBASEDSCHEDULING_SUPPORTED(m_osInterface))
104 {
105 CodechalDecode::SetGpuCtxCreatOption(codecHalSetting);
106 }
107 else
108 {
109 m_gpuCtxCreatOpt = MOS_New(MOS_GPUCTX_CREATOPTIONS_ENHANCED);
110 bool sfcInUse = (codecHalSetting->sfcInUseHinted && codecHalSetting->downsamplingHinted
111 && (MEDIA_IS_SKU(m_skuTable, FtrSFCPipe) && !MEDIA_IS_SKU(m_skuTable, FtrDisableVDBox2SFC)));
112 CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalDecodeSinglePipeVE_ConstructParmsForGpuCtxCreation(
113 m_veState,
114 (PMOS_GPUCTX_CREATOPTIONS_ENHANCED)m_gpuCtxCreatOpt,
115 sfcInUse));
116 m_videoContext = MOS_GPU_CONTEXT_VIDEO;
117 }
118
119 return eStatus;
120 }
121
SetFrameStates()122 MOS_STATUS CodechalDecodeVc1G12::SetFrameStates()
123 {
124 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
125
126 CODECHAL_DECODE_FUNCTION_ENTER;
127
128 CODECHAL_DECODE_CHK_STATUS_RETURN(CodechalDecodeVc1::SetFrameStates());
129
130 if (MOS_VE_SUPPORTED(m_osInterface) && !MOS_VE_CTXBASEDSCHEDULING_SUPPORTED(m_osInterface))
131 {
132 MOS_VIRTUALENGINE_SET_PARAMS vesetParams;
133
134 MOS_ZeroMemory(&vesetParams, sizeof(vesetParams));
135 vesetParams.bSFCInUse = false;
136 vesetParams.bNeedSyncWithPrevious = true;
137 vesetParams.bSameEngineAsLastSubmission = false;
138 CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalDecodeSinglePipeVE_SetHintParams(m_veState, &vesetParams));
139 }
140
141 #ifdef _MMC_SUPPORTED
142 bool isBPicture = m_mfxInterface->IsVc1BPicture(
143 m_vc1PicParams->CurrPic,
144 m_vc1PicParams->picture_fields.is_first_field,
145 m_vc1PicParams->picture_fields.picture_type);
146
147 bool isOverlapSmoothingFilter = false;
148
149 isOverlapSmoothingFilter |= m_vc1PicParams->sequence_fields.AdvancedProfileFlag &&
150 m_vc1PicParams->sequence_fields.overlap;
151
152 isOverlapSmoothingFilter |= !(isBPicture ||
153 (m_vc1PicParams->pic_quantizer_fields.pic_quantizer_scale < 9) ||
154 !m_vc1PicParams->sequence_fields.overlap);
155
156 isOverlapSmoothingFilter |= m_intelEntrypointInUse &&
157 (m_mode == CODECHAL_DECODE_MODE_VC1VLD) &&
158 m_vc1PicParams->conditional_overlap_flag;
159
160 //For VC1 frame with overlap smoothing filter enabled, force to post-deblock if MMC on
161 if (m_mmc && m_mmc->IsMmcEnabled() && isOverlapSmoothingFilter)
162 {
163 m_deblockingEnabled = true;
164 }
165 #endif
166
167 return eStatus;
168 }
169
DecodeStateLevel()170 MOS_STATUS CodechalDecodeVc1G12::DecodeStateLevel()
171 {
172 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
173
174 CODECHAL_DECODE_FUNCTION_ENTER;
175 #ifdef _MMC_SUPPORTED
176 // To make sure aux table is clear when MMC off(IGFX)
177 // Can not clear aux table for DGFX because of stolen memory
178 if (!m_mmc->IsMmcEnabled() && !Mos_ResourceIsNull(&m_destSurface.OsResource) && m_destSurface.OsResource.bConvertedFromDDIResource)
179 {
180 if (m_secureDecoder && m_secureDecoder->IsAuxDataInvalid(&m_destSurface.OsResource))
181 {
182 // Not use CODECHAL_DECODE_CHK_STATUS_RETURN() here to avoid adding local variable
183 // Error can still be caught by CODECHAL_DECODE_CHK_STATUS_RETURN() in InitAuxSurface
184 CODECHAL_DECODE_VERBOSEMESSAGE("Clear CCS for secure decode before frame %d submission", m_frameNum);
185 CODECHAL_DECODE_CHK_STATUS_RETURN(m_secureDecoder->InitAuxSurface(&m_destSurface.OsResource, false, true));
186 }
187 else
188 {
189 CODECHAL_DECODE_VERBOSEMESSAGE("Clear CCS by Huc Copy before frame %d submission", m_frameNum);
190 CODECHAL_DECODE_CHK_STATUS_RETURN(static_cast<CodecHalMmcStateG12 *>(m_mmc)->ClearAuxSurf(
191 this, m_miInterface, &m_destSurface.OsResource, m_veState));
192 }
193 }
194 #endif
195
196 PCODEC_REF_LIST *vc1RefList;
197 vc1RefList = &(m_vc1RefList[0]);
198
199 uint8_t destIdx = m_vc1PicParams->CurrPic.FrameIdx;
200 uint8_t fwdRefIdx = (uint8_t)m_vc1PicParams->ForwardRefIdx;
201 uint8_t bwdRefIdx = (uint8_t)m_vc1PicParams->BackwardRefIdx;
202
203 bool isIPicture = m_mfxInterface->IsVc1IPicture(
204 m_vc1PicParams->CurrPic,
205 m_vc1PicParams->picture_fields.is_first_field,
206 m_vc1PicParams->picture_fields.picture_type)
207 ? true
208 : false;
209 bool isPPicture = m_mfxInterface->IsVc1PPicture(
210 m_vc1PicParams->CurrPic,
211 m_vc1PicParams->picture_fields.is_first_field,
212 m_vc1PicParams->picture_fields.picture_type)
213 ? true
214 : false;
215 bool isBPicture = m_mfxInterface->IsVc1BPicture(
216 m_vc1PicParams->CurrPic,
217 m_vc1PicParams->picture_fields.is_first_field,
218 m_vc1PicParams->picture_fields.picture_type)
219 ? true
220 : false;
221
222 PMOS_SURFACE destSurface;
223 PMOS_RESOURCE fwdRefSurface, bwdRefSurface;
224 if (m_unequalFieldWaInUse && CodecHal_PictureIsField(m_vc1PicParams->CurrPic))
225 {
226 destSurface =
227 &(m_unequalFieldSurface[vc1RefList[destIdx]->dwUnequalFieldSurfaceIdx]);
228 fwdRefSurface =
229 &(m_unequalFieldSurface[vc1RefList[fwdRefIdx]->dwUnequalFieldSurfaceIdx].OsResource);
230 bwdRefSurface =
231 &(m_unequalFieldSurface[vc1RefList[bwdRefIdx]->dwUnequalFieldSurfaceIdx].OsResource);
232
233 // Overwrite the actual surface height with the coded height and width of the frame
234 // for VC1 since it's possible for a VC1 frame to change size during playback
235 destSurface->dwWidth = m_width;
236 destSurface->dwHeight = m_height;
237 }
238 else
239 {
240 destSurface = &m_destSurface;
241 fwdRefSurface = &(vc1RefList[fwdRefIdx]->resRefPic);
242 bwdRefSurface = &(vc1RefList[bwdRefIdx]->resRefPic);
243 }
244
245 // WA for SP/MP short format
246 if (m_shortFormatInUse &&
247 !m_vc1PicParams->sequence_fields.AdvancedProfileFlag)
248 {
249 CODECHAL_DECODE_CHK_STATUS_RETURN(ConstructBistreamBuffer());
250 }
251
252 MOS_COMMAND_BUFFER cmdBuffer;
253 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
254
255 auto mmioRegisters = m_hwInterface->GetMfxInterface()->GetMmioRegisters(m_vdboxIndex);
256 HalOcaInterface::On1stLevelBBStart(cmdBuffer, *m_osInterface->pOsContext, m_osInterface->CurrentGpuContextHandle, *m_miInterface, *mmioRegisters);
257
258 MHW_MI_FORCE_WAKEUP_PARAMS forceWakeupParams;
259 MOS_ZeroMemory(&forceWakeupParams, sizeof(MHW_MI_FORCE_WAKEUP_PARAMS));
260 forceWakeupParams.bMFXPowerWellControl = true;
261 forceWakeupParams.bMFXPowerWellControlMask = true;
262 forceWakeupParams.bHEVCPowerWellControl = false;
263 forceWakeupParams.bHEVCPowerWellControlMask = true;
264 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiForceWakeupCmd(
265 &cmdBuffer,
266 &forceWakeupParams));
267
268 MHW_VDBOX_PIPE_MODE_SELECT_PARAMS pipeModeSelectParams;
269 pipeModeSelectParams.Mode = m_mode;
270 pipeModeSelectParams.bStreamOutEnabled = m_streamOutEnabled;
271 pipeModeSelectParams.bPostDeblockOutEnable = m_deblockingEnabled;
272 pipeModeSelectParams.bPreDeblockOutEnable = !m_deblockingEnabled;
273 pipeModeSelectParams.bShortFormatInUse = m_shortFormatInUse;
274 pipeModeSelectParams.bVC1OddFrameHeight = m_vc1OddFrameHeight;
275
276 MHW_VDBOX_SURFACE_PARAMS surfaceParams;
277 MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams));
278 surfaceParams.Mode = m_mode;
279 surfaceParams.psSurface = destSurface;
280
281 MHW_VDBOX_PIPE_BUF_ADDR_PARAMS pipeBufAddrParams;
282 pipeBufAddrParams.Mode = m_mode;
283 if (m_deblockingEnabled)
284 {
285 pipeBufAddrParams.psPostDeblockSurface = destSurface;
286 }
287 else
288 {
289 pipeBufAddrParams.psPreDeblockSurface = destSurface;
290 }
291
292 #ifdef _MMC_SUPPORTED
293 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mmc->SetPipeBufAddr(&pipeBufAddrParams));
294 #endif
295
296 // when there is not a forward or backward reference,
297 // the index is set to the destination frame index
298 m_presReferences[CodechalDecodeFwdRefTop] =
299 m_presReferences[CodechalDecodeFwdRefBottom] =
300 fwdRefSurface;
301 m_presReferences[CodechalDecodeBwdRefTop] =
302 m_presReferences[CodechalDecodeBwdRefBottom] =
303 bwdRefSurface;
304 // special case for second fields
305 if (!m_vc1PicParams->picture_fields.is_first_field &&
306 !m_mfxInterface->IsVc1IPicture(
307 m_vc1PicParams->CurrPic,
308 m_vc1PicParams->picture_fields.is_first_field,
309 m_vc1PicParams->picture_fields.picture_type))
310 {
311 if (m_vc1PicParams->picture_fields.top_field_first)
312 {
313 m_presReferences[CodechalDecodeFwdRefTop] =
314 &destSurface->OsResource;
315 }
316 else
317 {
318 m_presReferences[CodechalDecodeFwdRefBottom] =
319 &destSurface->OsResource;
320 }
321 }
322
323 // set all ref pic addresses to valid addresses for error concealment purpose
324 for (uint32_t i = 0; i < CODEC_MAX_NUM_REF_FRAME_NON_AVC; i++)
325 {
326 if (m_presReferences[i] == nullptr &&
327 MEDIA_IS_WA(m_waTable, WaDummyReference) &&
328 !Mos_ResourceIsNull(&m_dummyReference.OsResource))
329 {
330 m_presReferences[i] = &m_dummyReference.OsResource;
331 }
332 }
333
334 CODECHAL_DECODE_CHK_STATUS_RETURN(MOS_SecureMemcpy(pipeBufAddrParams.presReferences, sizeof(PMOS_RESOURCE) * CODEC_MAX_NUM_REF_FRAME_NON_AVC, m_presReferences, sizeof(PMOS_RESOURCE) * CODEC_MAX_NUM_REF_FRAME_NON_AVC));
335
336 pipeBufAddrParams.presMfdDeblockingFilterRowStoreScratchBuffer =
337 &m_resMfdDeblockingFilterRowStoreScratchBuffer;
338
339 if (m_streamOutEnabled)
340 {
341 pipeBufAddrParams.presStreamOutBuffer =
342 &(m_streamOutBuffer[m_streamOutCurrBufIdx]);
343 }
344
345 #ifdef _MMC_SUPPORTED
346 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mmc->CheckReferenceList(&pipeBufAddrParams));
347
348 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mmc->SetRefrenceSync(m_disableDecodeSyncLock, m_disableLockForTranscode));
349 #endif
350
351 CODECHAL_DEBUG_TOOL(
352 for (int i = 0; i < CODEC_MAX_NUM_REF_FRAME_NON_AVC; i++)
353 {
354 if (pipeBufAddrParams.presReferences[i])
355 {
356 MOS_SURFACE dstSurface;
357
358 MOS_ZeroMemory(&dstSurface, sizeof(MOS_SURFACE));
359 dstSurface.Format = Format_NV12;
360 dstSurface.OsResource = *(pipeBufAddrParams.presReferences[i]);
361 CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(
362 m_osInterface,
363 &dstSurface));
364
365 m_debugInterface->m_refIndex = (uint16_t)i;
366 std::string refSurfName = "RefSurf[" + std::to_string(static_cast<uint32_t>(m_debugInterface->m_refIndex)) + "]";
367 CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface(
368 &dstSurface,
369 CodechalDbgAttr::attrDecodeReferenceSurfaces,
370 refSurfName.data()));
371 }
372 }
373 )
374
375 MHW_VDBOX_IND_OBJ_BASE_ADDR_PARAMS indObjBaseAddrParams;
376 MOS_ZeroMemory(&indObjBaseAddrParams, sizeof(indObjBaseAddrParams));
377 indObjBaseAddrParams.Mode = m_mode;
378 if (m_shortFormatInUse &&
379 !m_vc1PicParams->sequence_fields.AdvancedProfileFlag)
380 {
381 indObjBaseAddrParams.dwDataSize = m_dataSize + CODECHAL_DECODE_VC1_STUFFING_BYTES;
382 indObjBaseAddrParams.presDataBuffer = &m_resPrivateBistreamBuffer;
383 }
384 else
385 {
386 indObjBaseAddrParams.dwDataSize = m_dataSize;
387 indObjBaseAddrParams.presDataBuffer = &m_resDataBuffer;
388 }
389
390 MHW_VDBOX_BSP_BUF_BASE_ADDR_PARAMS bspBufBaseAddrParams;
391 MOS_ZeroMemory(&bspBufBaseAddrParams, sizeof(bspBufBaseAddrParams));
392 bspBufBaseAddrParams.presBsdMpcRowStoreScratchBuffer = &m_resBsdMpcRowStoreScratchBuffer;
393
394 if (m_vc1PicParams->raw_coding.bitplane_present || m_shortFormatInUse)
395 {
396 bspBufBaseAddrParams.presBitplaneBuffer = &m_resBitplaneBuffer;
397 }
398
399 MHW_VDBOX_VC1_PRED_PIPE_PARAMS vc1PredPipeParams;
400 vc1PredPipeParams.pVc1PicParams = m_vc1PicParams;
401 vc1PredPipeParams.ppVc1RefList = vc1RefList;
402
403 MHW_VDBOX_VC1_PIC_STATE vc1PicState;
404 vc1PicState.pVc1PicParams = m_vc1PicParams;
405 vc1PicState.Mode = m_mode;
406 vc1PicState.ppVc1RefList = vc1RefList;
407 vc1PicState.wPrevAnchorPictureTFF = m_prevAnchorPictureTff;
408 vc1PicState.bPrevEvenAnchorPictureIsP = m_prevEvenAnchorPictureIsP;
409 vc1PicState.bPrevOddAnchorPictureIsP = m_prevOddAnchorPictureIsP;
410
411 if (m_shortFormatInUse)
412 {
413 // WA for WMP. WMP does not provide REFDIST for I/P pictures correctly
414 if (m_vc1PicParams->sequence_fields.AdvancedProfileFlag &&
415 CodecHal_PictureIsField(m_vc1PicParams->CurrPic) &&
416 (isIPicture || isPPicture) &&
417 m_vc1PicParams->reference_fields.reference_distance_flag)
418 {
419 if (m_vc1PicParams->picture_fields.is_first_field)
420 {
421 CODECHAL_DECODE_CHK_STATUS_RETURN(ParsePictureHeader());
422 m_referenceDistance = m_vc1PicParams->reference_fields.reference_distance;
423 }
424 else
425 {
426 m_vc1PicParams->reference_fields.reference_distance = m_referenceDistance;
427 }
428 }
429
430 // WA for WMP. WMP does not provide BFRACTION correctly. So parse picture header to get BFRACTION
431 if (isBPicture)
432 {
433 if (m_vc1PicParams->picture_fields.is_first_field)
434 {
435 CODECHAL_DECODE_CHK_STATUS_RETURN(ParsePictureHeader());
436 }
437 }
438 }
439
440 MHW_VDBOX_VC1_DIRECTMODE_PARAMS vc1DirectmodeParams;
441 if (m_mode == CODECHAL_DECODE_MODE_VC1VLD)
442 {
443 uint8_t dmvBufferIdx = (m_vc1PicParams->CurrPic.PicFlags == PICTURE_BOTTOM_FIELD) ? CODECHAL_DECODE_VC1_DMV_ODD : CODECHAL_DECODE_VC1_DMV_EVEN;
444 vc1DirectmodeParams.presDmvReadBuffer = &m_resVc1BsdMvData[dmvBufferIdx];
445 vc1DirectmodeParams.presDmvWriteBuffer = &m_resVc1BsdMvData[dmvBufferIdx];
446 }
447
448 CODECHAL_DECODE_CHK_STATUS_RETURN(SendPrologWithFrameTracking(&cmdBuffer, !m_olpNeeded));
449
450 if (m_statusQueryReportingEnabled)
451 {
452 CODECHAL_DECODE_CHK_STATUS_RETURN(StartStatusReport(&cmdBuffer));
453 }
454
455 if (!CodecHal_PictureIsField(m_vc1PicParams->CurrPic) &&
456 m_vc1PicParams->picture_fields.picture_type == vc1SkippedFrame)
457 {
458 // no further picture level commands needed for skipped frames
459 m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
460
461 return eStatus;
462 }
463
464 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxPipeModeSelectCmd(&cmdBuffer, &pipeModeSelectParams));
465
466 #ifdef _MMC_SUPPORTED
467 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mmc->SetSurfaceState(&surfaceParams));
468 #endif
469 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxSurfaceCmd(&cmdBuffer, &surfaceParams));
470
471 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxPipeBufAddrCmd(&cmdBuffer, &pipeBufAddrParams));
472
473 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxIndObjBaseAddrCmd(&cmdBuffer, &indObjBaseAddrParams));
474
475 if (m_mode == CODECHAL_DECODE_MODE_VC1VLD)
476 {
477 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxBspBufBaseAddrCmd(&cmdBuffer, &bspBufBaseAddrParams));
478 }
479
480 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxVc1PredPipeCmd(&cmdBuffer, &vc1PredPipeParams));
481
482 if (m_intelEntrypointInUse || m_mode == CODECHAL_DECODE_MODE_VC1IT)
483 {
484 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxVc1LongPicCmd(&cmdBuffer, &vc1PicState));
485 }
486 else if (m_shortFormatInUse)
487 {
488 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfdVc1ShortPicCmd(&cmdBuffer, &vc1PicState));
489 }
490 else
491 {
492 CODECHAL_DECODE_ASSERTMESSAGE("Unsupported decode mode.");
493 eStatus = MOS_STATUS_UNKNOWN;
494 return eStatus;
495 }
496
497 if (m_mode == CODECHAL_DECODE_MODE_VC1VLD)
498 {
499 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxVc1DirectmodeCmd(&cmdBuffer, &vc1DirectmodeParams));
500 }
501
502 m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
503
504 return eStatus;
505 }
506
DecodePrimitiveLevelVLD()507 MOS_STATUS CodechalDecodeVc1G12::DecodePrimitiveLevelVLD()
508 {
509 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
510
511 CODECHAL_DECODE_FUNCTION_ENTER;
512
513 MOS_SYNC_PARAMS syncParams;
514
515 // static VC1 slice parameters
516 MHW_VDBOX_VC1_SLICE_STATE vc1SliceState;
517 vc1SliceState.presDataBuffer = &m_resDataBuffer;
518
519 uint16_t frameFieldHeightInMb;
520 CodecHal_GetFrameFieldHeightInMb(
521 m_vc1PicParams->CurrPic,
522 m_picHeightInMb,
523 frameFieldHeightInMb);
524
525 CODECHAL_DECODE_CHK_NULL_RETURN(m_osInterface);
526
527 MOS_COMMAND_BUFFER cmdBuffer;
528 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
529
530 if (m_incompletePicture)
531 {
532 MHW_MI_FORCE_WAKEUP_PARAMS forceWakeupParams;
533 MOS_ZeroMemory(&forceWakeupParams, sizeof(MHW_MI_FORCE_WAKEUP_PARAMS));
534 forceWakeupParams.bMFXPowerWellControl = true;
535 forceWakeupParams.bMFXPowerWellControlMask = true;
536 forceWakeupParams.bHEVCPowerWellControl = false;
537 forceWakeupParams.bHEVCPowerWellControlMask = true;
538 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiForceWakeupCmd(
539 &cmdBuffer,
540 &forceWakeupParams));
541 }
542
543 if (!CodecHal_PictureIsField(m_vc1PicParams->CurrPic) &&
544 m_vc1PicParams->picture_fields.picture_type == vc1SkippedFrame)
545 {
546 if (!bSkipFrameReported)
547 {
548 MOS_USER_FEATURE_VALUE_WRITE_DATA userFeatureWriteData;
549 MOS_ZeroMemory(&userFeatureWriteData, sizeof(userFeatureWriteData));
550 userFeatureWriteData.Value.i32Data = true;
551 userFeatureWriteData.ValueID = __MEDIA_USER_FEATURE_VALUE_SKIP_FRAME_IN_USE_ID;
552 MOS_UserFeature_WriteValues_ID(nullptr, &userFeatureWriteData, 1, m_osInterface->pOsContext);
553 bSkipFrameReported = true;
554 }
555
556 CODECHAL_DECODE_CHK_STATUS_RETURN(HandleSkipFrame());
557 goto submit;
558 }
559 else
560 {
561 PCODEC_VC1_SLICE_PARAMS slc = m_vc1SliceParams;
562 bool firstValidSlice = true;
563 int prevValidSlc = 0;
564 for (uint32_t slcCount = 0; slcCount < m_numSlices; slcCount++)
565 {
566 m_vldSliceRecord[slcCount].dwSliceYOffset = slc->slice_vertical_position;
567 m_vldSliceRecord[slcCount].dwNextSliceYOffset = frameFieldHeightInMb; // init to last slice
568
569 int32_t lLength = slc->slice_data_size >> 3;
570 int32_t lOffset = slc->macroblock_offset >> 3;
571
572 CodechalResLock ResourceLock(m_osInterface, &m_resDataBuffer);
573 auto buf = (uint8_t*)ResourceLock.Lock(CodechalResLock::readOnly);
574 if(buf != nullptr)
575 {
576 buf += slc->slice_data_offset;
577 }
578 if (lOffset > 3 && buf != nullptr &&
579 m_vc1PicParams->sequence_fields.AdvancedProfileFlag)
580 {
581 int i = 0;
582 int j = 0;
583 for (i = 0, j = 0; i < lOffset - 1; i++, j++)
584 {
585 if (!buf[j] && !buf[j + 1] && buf[j + 2] == 3 && buf[j + 3] < 4)
586 {
587 i++, j += 2;
588 }
589 }
590 if (i == lOffset - 1)
591 {
592 if (!buf[j] && !buf[j + 1] && buf[j + 2] == 3 && buf[j + 3] < 4)
593 {
594 buf[j + 2] = 0;
595 j++;
596 }
597 j++;
598 }
599 lOffset = (8 * j + slc->macroblock_offset % 8)>>3;
600 }
601
602 // Check that the slice data does not overrun the bitstream buffer size
603 if ((slc->slice_data_offset + lLength) > m_dataSize)
604 {
605 lLength = m_dataSize - slc->slice_data_offset;
606
607 if (lLength < 0)
608 {
609 lLength = 0;
610 }
611 }
612
613 // Error handling for garbage data
614 if (slc->slice_data_offset > m_dataSize)
615 {
616 slc++;
617 m_vldSliceRecord[slcCount].dwSkip = true;
618 continue;
619 }
620
621 // Check offset not larger than slice length, can have slice length of 0
622 if (lOffset > lLength)
623 {
624 slc++;
625 m_vldSliceRecord[slcCount].dwSkip = true;
626 continue;
627 }
628
629 // Check that the slices do not overlap, else do not send the lower slice
630 if (!firstValidSlice &&
631 (m_vldSliceRecord[slcCount].dwSliceYOffset <= m_vldSliceRecord[prevValidSlc].dwSliceYOffset))
632 {
633 slc++;
634 m_vldSliceRecord[slcCount].dwSkip = true;
635 continue;
636 }
637
638 if (firstValidSlice)
639 {
640 // Ensure that the first slice starts from 0
641 m_vldSliceRecord[slcCount].dwSliceYOffset = 0;
642 slc->slice_vertical_position = 0;
643 }
644 else
645 {
646 // Set next slice start Y offset of previous slice
647 m_vldSliceRecord[prevValidSlc].dwNextSliceYOffset =
648 m_vldSliceRecord[slcCount].dwSliceYOffset;
649 }
650
651 if (m_shortFormatInUse)
652 {
653 if (m_vc1PicParams->sequence_fields.AdvancedProfileFlag)
654 {
655 if ((slc->macroblock_offset >> 3) < CODECHAL_DECODE_VC1_SC_PREFIX_LENGTH)
656 {
657 slc++;
658 m_vldSliceRecord[slcCount].dwSkip = true;
659 continue;
660 }
661
662 // set macroblock_offset of the first slice to 0 to avoid crash
663 if (slcCount == 0)
664 {
665 slc->macroblock_offset = CODECHAL_DECODE_VC1_SC_PREFIX_LENGTH << 3;
666 }
667
668 lOffset = CODECHAL_DECODE_VC1_SC_PREFIX_LENGTH;
669 }
670 else // Simple Profile or Main Profile
671 {
672 {
673 lOffset = CODECHAL_DECODE_VC1_STUFFING_BYTES - 1;
674 lLength += CODECHAL_DECODE_VC1_STUFFING_BYTES;
675 slc->macroblock_offset += CODECHAL_DECODE_VC1_STUFFING_BYTES << 3;
676 slc->macroblock_offset &= (~0x7); // Clear bit offset of first MB for short format
677 }
678 }
679 }
680
681 m_vldSliceRecord[slcCount].dwOffset = lOffset;
682 m_vldSliceRecord[slcCount].dwLength = lLength - lOffset;
683 firstValidSlice = false;
684 prevValidSlc = slcCount;
685 slc++;
686 }
687
688 if (m_shortFormatInUse &&
689 m_vc1PicParams->sequence_fields.AdvancedProfileFlag)
690 {
691 CODECHAL_DECODE_CHK_STATUS_RETURN(GetSliceMbDataOffset());
692 }
693
694 // Reset slc pointer
695 slc -= m_numSlices;
696
697 //------------------------------------
698 // Fill BSD Object Commands
699 //------------------------------------
700 for (uint32_t slcCount = 0; slcCount < m_numSlices; slcCount++)
701 {
702 if (m_vldSliceRecord[slcCount].dwSkip)
703 {
704 slc++;
705 continue;
706 }
707
708 vc1SliceState.pSlc = slc;
709 vc1SliceState.dwOffset = m_vldSliceRecord[slcCount].dwOffset;
710 vc1SliceState.dwLength = m_vldSliceRecord[slcCount].dwLength;
711 vc1SliceState.dwNextVerticalPosition = m_vldSliceRecord[slcCount].dwNextSliceYOffset;
712
713 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfdVc1BsdObjectCmd(&cmdBuffer, &vc1SliceState));
714
715 slc++;
716 }
717
718 // Free VLD slice record
719 MOS_ZeroMemory(m_vldSliceRecord, (m_numSlices * sizeof(CODECHAL_VC1_VLD_SLICE_RECORD)));
720 }
721
722 // Check if destination surface needs to be synchronized
723 if (m_unequalFieldWaInUse &&
724 CodecHal_PictureIsField(m_vc1PicParams->CurrPic) &&
725 !m_vc1PicParams->picture_fields.is_first_field)
726 {
727 MHW_MI_FLUSH_DW_PARAMS flushDwParams;
728 MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
729
730 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(&cmdBuffer, &flushDwParams));
731 }
732 else
733 {
734 // Check if destination surface needs to be synchronized
735 syncParams = g_cInitSyncParams;
736 syncParams.GpuContext = m_videoContext;
737 syncParams.presSyncResource = &m_destSurface.OsResource;
738 syncParams.bReadOnly = false;
739 syncParams.bDisableDecodeSyncLock = m_disableDecodeSyncLock;
740 syncParams.bDisableLockForTranscode = m_disableLockForTranscode;
741
742 if (!CodecHal_PictureIsField(m_vc1PicParams->CurrPic) ||
743 m_vc1PicParams->picture_fields.is_first_field)
744 {
745 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnPerformOverlaySync(m_osInterface, &syncParams));
746 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceWait(m_osInterface, &syncParams));
747
748 // Update the resource tag (s/w tag) for On-Demand Sync
749 m_osInterface->pfnSetResourceSyncTag(m_osInterface, &syncParams);
750 }
751
752 MHW_MI_FLUSH_DW_PARAMS flushDwParams;
753 MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
754
755 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(&cmdBuffer, &flushDwParams));
756
757 // Update the tag in GPU Sync eStatus buffer (H/W Tag) to match the current S/W tag
758 if (m_osInterface->bTagResourceSync &&
759 !(CodecHal_PictureIsField(m_vc1PicParams->CurrPic) && m_vc1PicParams->picture_fields.is_first_field))
760 {
761 CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->WriteSyncTagToResource(&cmdBuffer, &syncParams));
762 }
763 }
764
765 submit:
766 if (m_statusQueryReportingEnabled)
767 {
768 CodechalDecodeStatusReport decodeStatusReport;
769
770 decodeStatusReport.m_statusReportNumber = m_statusReportFeedbackNumber;
771 decodeStatusReport.m_currDecodedPic = m_vc1PicParams->CurrPic;
772 if (m_olpNeeded)
773 {
774 CODECHAL_DEBUG_TOOL(
775 decodeStatusReport.m_currDeblockedPic.FrameIdx = (uint8_t)m_vc1PicParams->DeblockedPicIdx;
776 decodeStatusReport.m_currDeblockedPic.PicFlags = PICTURE_FRAME;)
777 decodeStatusReport.m_deblockedPicResOlp = m_deblockSurface.OsResource;
778 }
779 else
780 {
781 decodeStatusReport.m_currDeblockedPic = m_vc1PicParams->CurrPic;
782 }
783 decodeStatusReport.m_codecStatus = CODECHAL_STATUS_UNAVAILABLE;
784 decodeStatusReport.m_currDecodedPicRes = m_vc1RefList[m_vc1PicParams->CurrPic.FrameIdx]->resRefPic;
785
786 CODECHAL_DEBUG_TOOL(
787 decodeStatusReport.m_secondField =
788 (m_vc1PicParams->picture_fields.is_first_field == 1) ? false : true;
789 decodeStatusReport.m_olpNeeded = m_olpNeeded;
790 decodeStatusReport.m_frameType = m_perfType;)
791
792 CODECHAL_DECODE_CHK_STATUS_RETURN(EndStatusReport(decodeStatusReport, &cmdBuffer));
793 }
794
795 #if (_DEBUG || _RELEASE_INTERNAL)
796 uint32_t curIdx = (GetDecodeStatusBuf()->m_currIndex + CODECHAL_DECODE_STATUS_NUM - 1) % CODECHAL_DECODE_STATUS_NUM;
797 uint32_t frameCrcOffset = curIdx * sizeof(CodechalDecodeStatus) + GetDecodeStatusBuf()->m_decFrameCrcOffset + sizeof(uint32_t) * 2;
798 std::vector<MOS_RESOURCE> vSemaResource{GetDecodeStatusBuf()->m_statusBuffer};
799 m_debugInterface->DetectCorruptionHw(m_hwInterface, &m_frameCountTypeBuf, curIdx, frameCrcOffset, vSemaResource, &cmdBuffer, m_frameNum);
800 #endif
801
802 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(&cmdBuffer, nullptr));
803
804 m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
805
806 CODECHAL_DEBUG_TOOL(
807 CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer(
808 &cmdBuffer,
809 CODECHAL_NUM_MEDIA_STATES,
810 "_DEC"));
811
812 //CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHal_DbgReplaceAllCommands(
813 // m_debugInterface,
814 // &cmdBuffer));
815 )
816
817 if ( MOS_VE_SUPPORTED(m_osInterface))
818 {
819 CodecHalDecodeSinglePipeVE_PopulateHintParams(m_veState, &cmdBuffer, false);
820 }
821
822 if (m_huCCopyInUse)
823 {
824 syncParams = g_cInitSyncParams;
825 syncParams.GpuContext = m_videoContextForWa;
826 syncParams.presSyncResource = &m_resSyncObjectWaContextInUse;
827
828 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineSignal(m_osInterface, &syncParams));
829
830 syncParams = g_cInitSyncParams;
831 syncParams.GpuContext = m_videoContext;
832 syncParams.presSyncResource = &m_resSyncObjectWaContextInUse;
833
834 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineWait(m_osInterface, &syncParams));
835
836 m_huCCopyInUse = false;
837 }
838
839 HalOcaInterface::On1stLevelBBEnd(cmdBuffer, *m_osInterface);
840
841 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, m_videoContextUsesNullHw));
842
843 CODECHAL_DEBUG_TOOL(
844 m_mmc->UpdateUserFeatureKey(&m_destSurface);)
845
846 if (m_unequalFieldWaInUse &&
847 CodecHal_PictureIsField(m_vc1PicParams->CurrPic) &&
848 !m_vc1PicParams->picture_fields.is_first_field)
849 {
850 CODECHAL_DECODE_CHK_NULL_RETURN(m_vc1RefList);
851
852 uint32_t destFrameIdx = m_vc1PicParams->CurrPic.FrameIdx;
853
854 CODECHAL_DECODE_CHK_STATUS_RETURN(FormatUnequalFieldPicture(
855 m_unequalFieldSurface[m_vc1RefList[destFrameIdx]->dwUnequalFieldSurfaceIdx],
856 m_destSurface,
857 true,
858 m_videoContextUsesNullHw ? true : false));
859 }
860
861 if (m_olpNeeded)
862 {
863 if (!bOlpReported)
864 {
865 MOS_USER_FEATURE_VALUE_WRITE_DATA userFeatureWriteData;
866 MOS_ZeroMemory(&userFeatureWriteData, sizeof(userFeatureWriteData));
867 userFeatureWriteData.Value.i32Data = m_olpNeeded;
868 userFeatureWriteData.ValueID = __MEDIA_USER_FEATURE_VALUE_OLP_IN_USE_ID;
869 MOS_UserFeature_WriteValues_ID(nullptr, &userFeatureWriteData, 1, m_osInterface->pOsContext);
870 bOlpReported = true;
871 }
872
873 CODECHAL_DECODE_CHK_STATUS_RETURN(PerformVc1Olp());
874 }
875 else
876 {
877 if (m_statusQueryReportingEnabled)
878 {
879 CODECHAL_DECODE_CHK_STATUS_RETURN(ResetStatusReport(m_videoContextUsesNullHw));
880 }
881 }
882
883 // Needs to be re-set for Linux buffer re-use scenarios
884 m_vc1RefList[m_vc1PicParams->CurrPic.FrameIdx]->resRefPic = m_destSurface.OsResource;
885
886 // Send the signal to indicate decode completion, in case On-Demand Sync is not present
887 if (!(CodecHal_PictureIsField(m_vc1PicParams->CurrPic) &&
888 m_vc1PicParams->picture_fields.is_first_field))
889 {
890 MOS_SYNC_PARAMS syncParams;
891 syncParams = g_cInitSyncParams;
892 syncParams.GpuContext = m_videoContext;
893 syncParams.presSyncResource = &m_destSurface.OsResource;
894
895 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceSignal(m_osInterface, &syncParams));
896
897 if (m_olpNeeded)
898 {
899 syncParams = g_cInitSyncParams;
900 syncParams.GpuContext = m_renderContext;
901 syncParams.presSyncResource = &m_deblockSurface.OsResource;
902
903 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceSignal(m_osInterface, &syncParams));
904 }
905 }
906
907 m_olpNeeded = false;
908
909 return eStatus;
910 }
911
DecodePrimitiveLevelIT()912 MOS_STATUS CodechalDecodeVc1G12::DecodePrimitiveLevelIT()
913 {
914 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
915
916 CODECHAL_DECODE_FUNCTION_ENTER;
917
918 MOS_SYNC_PARAMS syncParams;
919
920 PCODEC_VC1_MB_PARAMS mb = m_vc1MbParams;
921
922 MHW_VDBOX_VC1_MB_STATE vc1MbState;
923 MOS_ZeroMemory(&vc1MbState, sizeof(vc1MbState));
924
925 // static VC1 MB parameters
926 vc1MbState.presDataBuffer = &m_resDataBuffer;
927 vc1MbState.pVc1PicParams = m_vc1PicParams;
928 vc1MbState.pWaTable = m_waTable;
929 vc1MbState.pDeblockDataBuffer = m_deblockDataBuffer;
930 vc1MbState.dwDataSize = m_dataSize;
931 vc1MbState.wPicWidthInMb = m_picWidthInMb;
932 vc1MbState.wPicHeightInMb = m_picHeightInMb;
933 vc1MbState.PicFlags = m_vc1PicParams->CurrPic.PicFlags;
934 vc1MbState.bFieldPolarity = m_fieldPolarity;
935
936 uint16_t frameFieldHeightInMb;
937 CodecHal_GetFrameFieldHeightInMb(
938 m_vc1PicParams->CurrPic,
939 m_picHeightInMb,
940 frameFieldHeightInMb);
941
942 CODECHAL_DECODE_CHK_NULL_RETURN(m_osInterface);
943
944 MOS_COMMAND_BUFFER cmdBuffer;
945 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
946
947 if (m_incompletePicture)
948 {
949 MHW_MI_FORCE_WAKEUP_PARAMS forceWakeupParams;
950 MOS_ZeroMemory(&forceWakeupParams, sizeof(MHW_MI_FORCE_WAKEUP_PARAMS));
951 forceWakeupParams.bMFXPowerWellControl = true;
952 forceWakeupParams.bMFXPowerWellControlMask = true;
953 forceWakeupParams.bHEVCPowerWellControl = false;
954 forceWakeupParams.bHEVCPowerWellControlMask = true;
955 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiForceWakeupCmd(
956 &cmdBuffer,
957 &forceWakeupParams));
958 }
959
960 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferStartCmd(&cmdBuffer, &m_itObjectBatchBuffer));
961
962 CODECHAL_DECODE_CHK_STATUS_RETURN(Mhw_LockBb(m_osInterface, &m_itObjectBatchBuffer));
963
964 PMHW_BATCH_BUFFER batchBuffer = &m_itObjectBatchBuffer;
965
966 uint32_t mbAddress = 0;
967 uint32_t mbCount;
968 for (mbCount = 0; mbCount < m_numMacroblocks; mbCount++)
969 {
970 vc1MbState.pMb = mb + mbCount;
971
972 // Skipped MBs before current MB
973 uint16_t skippedMBs = (mbCount) ?
974 (mb[mbCount].mb_address - mb[mbCount - 1].mb_address - 1) :
975 (mb[mbCount].mb_address);
976
977 while (skippedMBs--)
978 {
979 vc1MbState.bMbHorizOrigin = (uint8_t)(mbAddress % m_picWidthInMb);
980 vc1MbState.bMbVertOrigin = (uint8_t)(mbAddress / m_picWidthInMb);
981 vc1MbState.bSkipped = true;
982
983 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfdVc1ItObjectCmd(batchBuffer, &vc1MbState));
984
985 mbAddress++;
986 }
987
988 // Current MB
989 if (mbCount + 1 == m_numMacroblocks)
990 {
991 vc1MbState.dwLength = m_dataSize - mb[mbCount].data_offset;
992 }
993 else
994 {
995 vc1MbState.dwLength = mb[mbCount + 1].data_offset - mb[mbCount].data_offset;
996 }
997
998 vc1MbState.bMbHorizOrigin = mb[mbCount].mb_address % m_picWidthInMb;
999 vc1MbState.bMbVertOrigin = mb[mbCount].mb_address / m_picWidthInMb;
1000 vc1MbState.dwOffset = (vc1MbState.dwLength) ? mb[mbCount].data_offset : 0;
1001 vc1MbState.bSkipped = false;
1002
1003 if (m_vc1PicParams->entrypoint_fields.loopfilter)
1004 {
1005 eStatus = MOS_SecureMemcpy(vc1MbState.DeblockData,
1006 CODEC_NUM_BLOCK_PER_MB,
1007 m_deblockDataBuffer + CODEC_NUM_BLOCK_PER_MB * mb[mbCount].mb_address,
1008 CODEC_NUM_BLOCK_PER_MB);
1009 if (eStatus != MOS_STATUS_SUCCESS)
1010 {
1011 CODECHAL_DECODE_ASSERTMESSAGE("Failed to copy memory.");
1012 m_olpNeeded = false;
1013 return eStatus;
1014 }
1015 }
1016
1017 if (!mb[mbCount].mb_type.intra_mb)
1018 {
1019 if (mb[mbCount].mb_type.motion_forward || mb[mbCount].mb_type.motion_backward)
1020 {
1021 PackMotionVectors(
1022 &vc1MbState,
1023 (short *)mb[mbCount].motion_vector,
1024 (short *)vc1MbState.PackedLumaMvs,
1025 (short *)&vc1MbState.PackedChromaMv);
1026 }
1027 else
1028 {
1029 mb[mbCount].mb_type.motion_forward = 1;
1030 MOS_ZeroMemory(vc1MbState.PackedLumaMvs, sizeof(vc1MbState.PackedLumaMvs)); // MV's of zero
1031 vc1MbState.bMotionSwitch = 0;
1032 }
1033 }
1034
1035 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfdVc1ItObjectCmd(batchBuffer, &vc1MbState));
1036
1037 mbAddress = mb[mbCount].mb_address;
1038 }
1039
1040 m_fieldPolarity = vc1MbState.bFieldPolarity;
1041
1042 // skipped MBs at the end
1043 uint16_t skippedMBs = m_picWidthInMb * frameFieldHeightInMb - mb[mbCount - 1].mb_address - 1;
1044
1045 while (skippedMBs--)
1046 {
1047 vc1MbState.bSkipped = true;
1048 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfdVc1ItObjectCmd(batchBuffer, &vc1MbState));
1049 }
1050
1051 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(nullptr, &m_itObjectBatchBuffer));
1052
1053 CODECHAL_DEBUG_TOOL(
1054 CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->Dump2ndLvlBatch(
1055 batchBuffer,
1056 CODECHAL_NUM_MEDIA_STATES,
1057 "_DEC"));
1058 )
1059
1060 CODECHAL_DECODE_CHK_STATUS_RETURN(Mhw_UnlockBb(m_osInterface, &m_itObjectBatchBuffer, true));
1061
1062 // Check if destination surface needs to be synchronized
1063 if (m_unequalFieldWaInUse &&
1064 CodecHal_PictureIsField(m_vc1PicParams->CurrPic))
1065 {
1066 if (!m_vc1PicParams->picture_fields.is_first_field)
1067 {
1068 MHW_MI_FLUSH_DW_PARAMS flushDwParams;
1069 MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
1070
1071 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(&cmdBuffer, &flushDwParams));
1072 }
1073 }
1074 else
1075 {
1076 syncParams = g_cInitSyncParams;
1077 syncParams.GpuContext = m_videoContext;
1078 syncParams.presSyncResource = &m_destSurface.OsResource;
1079 syncParams.bReadOnly = false;
1080 syncParams.bDisableDecodeSyncLock = m_disableDecodeSyncLock;
1081 syncParams.bDisableLockForTranscode = m_disableLockForTranscode;
1082
1083 if (!CodecHal_PictureIsField(m_vc1PicParams->CurrPic) ||
1084 m_vc1PicParams->picture_fields.is_first_field)
1085 {
1086 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnPerformOverlaySync(m_osInterface, &syncParams));
1087 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceWait(m_osInterface, &syncParams));
1088
1089 // Update the resource tag (s/w tag) for On-Demand Sync
1090 m_osInterface->pfnSetResourceSyncTag(m_osInterface, &syncParams);
1091 }
1092
1093 MHW_MI_FLUSH_DW_PARAMS flushDwParams;
1094 MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
1095
1096 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(&cmdBuffer, &flushDwParams));
1097
1098 // Update the tag in GPU Sync eStatus buffer (H/W Tag) to match the current S/W tag
1099 if (m_osInterface->bTagResourceSync &&
1100 !(CodecHal_PictureIsField(m_vc1PicParams->CurrPic) && m_vc1PicParams->picture_fields.is_first_field))
1101 {
1102 CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->WriteSyncTagToResource(&cmdBuffer, &syncParams));
1103 }
1104 }
1105
1106 if (m_statusQueryReportingEnabled)
1107 {
1108 CodechalDecodeStatusReport decodeStatusReport;
1109
1110 decodeStatusReport.m_statusReportNumber = m_statusReportFeedbackNumber;
1111 decodeStatusReport.m_currDecodedPic = m_vc1PicParams->CurrPic;
1112 if (m_olpNeeded)
1113 {
1114 CODECHAL_DEBUG_TOOL(
1115 decodeStatusReport.m_currDeblockedPic.FrameIdx = (uint8_t)m_vc1PicParams->DeblockedPicIdx;
1116 decodeStatusReport.m_currDeblockedPic.PicFlags = PICTURE_FRAME;)
1117 decodeStatusReport.m_deblockedPicResOlp = m_deblockSurface.OsResource;
1118 }
1119 else
1120 {
1121 decodeStatusReport.m_currDeblockedPic = m_vc1PicParams->CurrPic;
1122 }
1123 decodeStatusReport.m_codecStatus = CODECHAL_STATUS_UNAVAILABLE;
1124 decodeStatusReport.m_currDecodedPicRes = m_vc1RefList[m_vc1PicParams->CurrPic.FrameIdx]->resRefPic;
1125
1126 CODECHAL_DEBUG_TOOL(
1127 decodeStatusReport.m_secondField =
1128 (m_vc1PicParams->picture_fields.is_first_field == 1) ? false : true;
1129 decodeStatusReport.m_olpNeeded = m_olpNeeded;
1130 decodeStatusReport.m_frameType = m_perfType;)
1131
1132 CODECHAL_DECODE_CHK_STATUS_RETURN(EndStatusReport(decodeStatusReport, &cmdBuffer));
1133 }
1134
1135 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(&cmdBuffer, nullptr));
1136
1137 m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
1138
1139 CODECHAL_DEBUG_TOOL(
1140 CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer(
1141 &cmdBuffer,
1142 CODECHAL_NUM_MEDIA_STATES,
1143 "_DEC"));
1144
1145 //CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHal_DbgReplaceAllCommands(
1146 // m_debugInterface,
1147 // &cmdBuffer));
1148 )
1149
1150 if ( MOS_VE_SUPPORTED(m_osInterface))
1151 {
1152 CodecHalDecodeSinglePipeVE_PopulateHintParams(m_veState, &cmdBuffer, false);
1153 }
1154
1155 if (m_huCCopyInUse)
1156 {
1157 syncParams = g_cInitSyncParams;
1158 syncParams.GpuContext = m_videoContextForWa;
1159 syncParams.presSyncResource = &m_resSyncObjectWaContextInUse;
1160
1161 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineSignal(m_osInterface, &syncParams));
1162
1163 syncParams = g_cInitSyncParams;
1164 syncParams.GpuContext = m_videoContext;
1165 syncParams.presSyncResource = &m_resSyncObjectWaContextInUse;
1166
1167 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineWait(m_osInterface, &syncParams));
1168
1169 m_huCCopyInUse = false;
1170 }
1171
1172 HalOcaInterface::On1stLevelBBEnd(cmdBuffer, *m_osInterface);
1173
1174 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, m_videoContextUsesNullHw));
1175
1176 CODECHAL_DEBUG_TOOL(
1177 m_mmc->UpdateUserFeatureKey(&m_destSurface);)
1178
1179 if (m_unequalFieldWaInUse &&
1180 CodecHal_PictureIsField(m_vc1PicParams->CurrPic) &&
1181 !m_vc1PicParams->picture_fields.is_first_field)
1182 {
1183 CODECHAL_DECODE_CHK_NULL_RETURN(m_vc1RefList);
1184
1185 uint32_t destFrameIdx = m_vc1PicParams->CurrPic.FrameIdx;
1186
1187 CODECHAL_DECODE_CHK_STATUS_RETURN(FormatUnequalFieldPicture(
1188 m_unequalFieldSurface[m_vc1RefList[destFrameIdx]->dwUnequalFieldSurfaceIdx],
1189 m_destSurface,
1190 true,
1191 m_videoContextUsesNullHw ? true : false));
1192 }
1193
1194 if (m_olpNeeded)
1195 {
1196 CODECHAL_DECODE_CHK_STATUS_RETURN(PerformVc1Olp());
1197 }
1198 else
1199 {
1200 if (m_statusQueryReportingEnabled)
1201 {
1202 CODECHAL_DECODE_CHK_STATUS_RETURN(ResetStatusReport(m_videoContextUsesNullHw));
1203 }
1204 }
1205
1206 // Needs to be re-set for Linux buffer re-use scenarios
1207 m_vc1RefList[m_vc1PicParams->CurrPic.FrameIdx]->resRefPic = m_destSurface.OsResource;
1208
1209 // Send the signal to indicate decode completion, in case On-Demand Sync is not present
1210 if (!(CodecHal_PictureIsField(m_vc1PicParams->CurrPic) &&
1211 m_vc1PicParams->picture_fields.is_first_field))
1212 {
1213 MOS_SYNC_PARAMS syncParams;
1214 syncParams = g_cInitSyncParams;
1215 syncParams.GpuContext = m_videoContext;
1216 syncParams.presSyncResource = &m_destSurface.OsResource;
1217
1218 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceSignal(m_osInterface, &syncParams));
1219
1220 if (m_olpNeeded)
1221 {
1222 syncParams = g_cInitSyncParams;
1223 syncParams.GpuContext = m_renderContext;
1224 syncParams.presSyncResource = &m_deblockSurface.OsResource;
1225
1226 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceSignal(m_osInterface, &syncParams));
1227 }
1228 }
1229
1230 m_olpNeeded = false;
1231
1232 return eStatus;
1233 }
1234
HandleSkipFrame()1235 MOS_STATUS CodechalDecodeVc1G12::HandleSkipFrame()
1236 {
1237 MOS_COMMAND_BUFFER cmdBuffer;
1238 MHW_MI_FLUSH_DW_PARAMS flushDwParams;
1239 MHW_GENERIC_PROLOG_PARAMS genericPrologParams;
1240 MOS_SURFACE srcSurface;
1241 uint8_t fwdRefIdx;
1242 uint32_t surfaceSize;
1243 MOS_SYNC_PARAMS syncParams;
1244 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1245
1246 CODECHAL_DECODE_FUNCTION_ENTER;
1247
1248 fwdRefIdx = (uint8_t)m_vc1PicParams->ForwardRefIdx;
1249
1250 MOS_ZeroMemory(&srcSurface, sizeof(MOS_SURFACE));
1251 srcSurface.Format = Format_NV12;
1252 srcSurface.OsResource = m_vc1RefList[fwdRefIdx]->resRefPic;
1253 CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(m_osInterface, &srcSurface));
1254
1255 CODECHAL_DECODE_CHK_NULL_RETURN(srcSurface.OsResource.pGmmResInfo);
1256 surfaceSize = ((srcSurface.OsResource.pGmmResInfo->GetArraySize()) > 1) ?
1257 ((uint32_t)(srcSurface.OsResource.pGmmResInfo->GetQPitchPlanar(GMM_PLANE_Y) *
1258 srcSurface.OsResource.pGmmResInfo->GetRenderPitch())) :
1259 (uint32_t)(srcSurface.OsResource.pGmmResInfo->GetSizeMainSurface());
1260
1261 if (m_hwInterface->m_noHuC)
1262 {
1263 CodechalDataCopyParams dataCopyParams;
1264 MOS_ZeroMemory(&dataCopyParams, sizeof(CodechalDataCopyParams));
1265 dataCopyParams.srcResource = &srcSurface.OsResource;
1266 dataCopyParams.srcSize = surfaceSize;
1267 dataCopyParams.srcOffset = srcSurface.dwOffset;
1268 dataCopyParams.dstResource = &m_destSurface.OsResource;
1269 dataCopyParams.dstSize = surfaceSize;
1270 dataCopyParams.dstOffset = m_destSurface.dwOffset;
1271
1272 CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->CopyDataSourceWithDrv(&dataCopyParams));
1273 }
1274 else
1275 {
1276 m_huCCopyInUse = true;
1277
1278 syncParams = g_cInitSyncParams;
1279 syncParams.GpuContext = m_videoContext;
1280 syncParams.presSyncResource = &m_resSyncObjectVideoContextInUse;
1281
1282 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineSignal(m_osInterface, &syncParams));
1283
1284 syncParams = g_cInitSyncParams;
1285 syncParams.GpuContext = m_videoContextForWa;
1286 syncParams.presSyncResource = &m_resSyncObjectVideoContextInUse;
1287
1288 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineWait(m_osInterface, &syncParams));
1289
1290 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSetGpuContext(m_osInterface, m_videoContextForWa));
1291 m_osInterface->pfnResetOsStates(m_osInterface);
1292
1293 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
1294
1295 CODECHAL_DECODE_CHK_STATUS_RETURN(SendPrologWithFrameTracking(&cmdBuffer, false));
1296
1297 CODECHAL_DECODE_CHK_STATUS_RETURN(HucCopy(
1298 &cmdBuffer, // pCmdBuffer
1299 &srcSurface.OsResource, // presSrc
1300 &m_destSurface.OsResource, // presDst
1301 surfaceSize, // u32CopyLength
1302 srcSurface.dwOffset, // u32CopyInputOffset
1303 m_destSurface.dwOffset)); // u32CopyOutputOffset
1304 #ifdef _MMC_SUPPORTED
1305 auto mmc = static_cast<CodechalMmcDecodeVc1G12*>(m_mmc);
1306 CODECHAL_DECODE_CHK_STATUS_RETURN(mmc->CopyAuxSurfForSkip(&cmdBuffer, &srcSurface.OsResource, &m_destSurface.OsResource));
1307 #endif
1308 syncParams = g_cInitSyncParams;
1309 syncParams.GpuContext = m_videoContextForWa;
1310 syncParams.presSyncResource = &m_destSurface.OsResource;
1311 syncParams.bReadOnly = false;
1312 syncParams.bDisableDecodeSyncLock = m_disableDecodeSyncLock;
1313 syncParams.bDisableLockForTranscode = m_disableLockForTranscode;
1314
1315 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnPerformOverlaySync(m_osInterface, &syncParams));
1316 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceWait(m_osInterface, &syncParams));
1317
1318 // Update the resource tag (s/w tag) for On-Demand Sync
1319 m_osInterface->pfnSetResourceSyncTag(m_osInterface, &syncParams);
1320
1321 // Update the tag in GPU Sync eStatus buffer (H/W Tag) to match the current S/W tag
1322 if (m_osInterface->bTagResourceSync)
1323 {
1324 CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->WriteSyncTagToResource(
1325 &cmdBuffer,
1326 &syncParams));
1327 }
1328
1329 MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
1330 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(
1331 &cmdBuffer,
1332 &flushDwParams));
1333
1334 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(
1335 &cmdBuffer,
1336 nullptr));
1337
1338 m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
1339
1340 if ( MOS_VE_SUPPORTED(m_osInterface))
1341 {
1342 CodecHalDecodeSinglePipeVE_PopulateHintParams(m_veState, &cmdBuffer, false);
1343 }
1344
1345 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, m_videoContextUsesNullHw));
1346
1347 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSetGpuContext(m_osInterface, m_videoContext));
1348 }
1349
1350 return (MOS_STATUS)eStatus;
1351 }
1352
PerformVc1Olp()1353 MOS_STATUS CodechalDecodeVc1G12::PerformVc1Olp()
1354 {
1355 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1356
1357 CODECHAL_DECODE_FUNCTION_ENTER;
1358
1359 MhwRenderInterface *renderEngineInterface = m_hwInterface->GetRenderInterface();
1360 PMHW_KERNEL_STATE kernelState = &m_olpKernelState;
1361 PMHW_STATE_HEAP_INTERFACE stateHeapInterface = renderEngineInterface->m_stateHeapInterface;
1362
1363 CODECHAL_DECODE_CHK_NULL_RETURN(stateHeapInterface);
1364
1365 MOS_SYNC_PARAMS syncParams;
1366 syncParams = g_cInitSyncParams;
1367 syncParams.GpuContext = m_videoContext;
1368 syncParams.presSyncResource = &m_resSyncObject;
1369
1370 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineSignal(m_osInterface, &syncParams));
1371
1372 syncParams = g_cInitSyncParams;
1373 syncParams.GpuContext = m_renderContext;
1374 syncParams.presSyncResource = &m_resSyncObject;
1375
1376 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineWait(m_osInterface, &syncParams));
1377
1378 // Initialize DSH kernel region
1379 m_osInterface->pfnSetGpuContext(m_osInterface, m_renderContext);
1380 m_osInterface->pfnResetOsStates(m_osInterface);
1381
1382 m_osInterface->pfnSetPerfTag(
1383 m_osInterface,
1384 (uint16_t)(((m_mode << 4) & 0xF0) | OLP_TYPE));
1385 m_osInterface->pfnResetPerfBufferID(m_osInterface);
1386
1387 CodecHalGetResourceInfo(m_osInterface, &m_deblockSurface); // DstSurface
1388
1389 CODECHAL_DECODE_CHK_STATUS_RETURN(stateHeapInterface->pfnRequestSshSpaceForCmdBuf(
1390 stateHeapInterface,
1391 kernelState->KernelParams.iBTCount));
1392
1393 CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->AssignDshAndSshSpace(
1394 stateHeapInterface,
1395 kernelState,
1396 false,
1397 m_olpDshSize,
1398 false,
1399 m_decodeStatusBuf.m_swStoreData));
1400
1401 MHW_INTERFACE_DESCRIPTOR_PARAMS idParams;
1402 MOS_ZeroMemory(&idParams, sizeof(idParams));
1403 idParams.pKernelState = kernelState;
1404 CODECHAL_DECODE_CHK_STATUS_RETURN(stateHeapInterface->pfnSetInterfaceDescriptor(
1405 stateHeapInterface,
1406 1,
1407 &idParams));
1408 CODECHAL_DECODE_CHK_STATUS_RETURN(SetCurbeOlp());
1409
1410 // Send HW commands (including SSH)
1411 MOS_COMMAND_BUFFER cmdBuffer;
1412 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
1413
1414 MHW_PIPE_CONTROL_PARAMS pipeControlParams;
1415 MOS_ZeroMemory(&pipeControlParams, sizeof(pipeControlParams));
1416
1417 CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->GetDefaultSSEuSetting(CODECHAL_MEDIA_STATE_OLP, false, false, false));
1418
1419 CODECHAL_DECODE_CHK_STATUS_RETURN(SendPrologWithFrameTracking(
1420 &cmdBuffer, true));
1421
1422 if (renderEngineInterface->GetL3CacheConfig()->bL3CachingEnabled)
1423 {
1424 CODECHAL_DECODE_CHK_STATUS_RETURN(renderEngineInterface->SetL3Cache(&cmdBuffer));
1425 }
1426
1427 CODECHAL_DECODE_CHK_STATUS_RETURN(renderEngineInterface->EnablePreemption(&cmdBuffer));
1428
1429 CODECHAL_DECODE_CHK_STATUS_RETURN(renderEngineInterface->AddPipelineSelectCmd(&cmdBuffer, false));
1430
1431 CODECHAL_DECODE_CHK_STATUS_RETURN(stateHeapInterface->pfnSetBindingTable(
1432 stateHeapInterface,
1433 kernelState));
1434
1435 // common function for codec needed when we make change for AVC
1436 MHW_RCS_SURFACE_PARAMS surfaceParamsSrc;
1437 MOS_ZeroMemory(&surfaceParamsSrc, sizeof(surfaceParamsSrc));
1438 surfaceParamsSrc.dwNumPlanes = 2; // Y, UV
1439 surfaceParamsSrc.psSurface = &m_destSurface;
1440 surfaceParamsSrc.psSurface->dwDepth = 1; // depth needs to be 0 for codec 2D surface
1441 // Y Plane
1442 surfaceParamsSrc.dwBindingTableOffset[MHW_Y_PLANE] = CODECHAL_DECODE_VC1_OLP_SRC_Y;
1443 surfaceParamsSrc.ForceSurfaceFormat[MHW_Y_PLANE] = MHW_GFX3DSTATE_SURFACEFORMAT_R8_UNORM;
1444 // UV Plane
1445 surfaceParamsSrc.dwBindingTableOffset[MHW_U_PLANE] = CODECHAL_DECODE_VC1_OLP_SRC_UV;
1446 surfaceParamsSrc.ForceSurfaceFormat[MHW_U_PLANE] = MHW_GFX3DSTATE_SURFACEFORMAT_R16_UINT;
1447 surfaceParamsSrc.dwBaseAddrOffset[MHW_U_PLANE] =
1448 m_destSurface.dwPitch *
1449 MOS_ALIGN_FLOOR(m_destSurface.UPlaneOffset.iYOffset, MOS_YTILE_H_ALIGNMENT);
1450 surfaceParamsSrc.dwHeightToUse[MHW_U_PLANE] = surfaceParamsSrc.psSurface->dwHeight / 2;
1451 surfaceParamsSrc.dwYOffset[MHW_U_PLANE] =
1452 (m_destSurface.UPlaneOffset.iYOffset % MOS_YTILE_H_ALIGNMENT);
1453 surfaceParamsSrc.dwCacheabilityControl =
1454 m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_PRE_DEBLOCKING_CODEC].Value;
1455
1456 #ifdef _MMC_SUPPORTED
1457 if (m_mmc)
1458 {
1459 CODECHAL_SURFACE_CODEC_PARAMS srcSurfaceParam = {};
1460 srcSurfaceParam.psSurface = &m_destSurface;
1461 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mmc->SetSurfaceParams(&srcSurfaceParam));
1462 }
1463 #endif
1464
1465 MHW_RCS_SURFACE_PARAMS surfaceParamsDst;
1466 MOS_ZeroMemory(&surfaceParamsDst, sizeof(surfaceParamsDst));
1467 surfaceParamsDst = surfaceParamsSrc;
1468 surfaceParamsDst.bIsWritable = true;
1469 surfaceParamsDst.psSurface = &m_deblockSurface;
1470 surfaceParamsDst.psSurface->dwDepth = 1; // depth needs to be 0 for codec 2D surface
1471 surfaceParamsDst.dwBindingTableOffset[MHW_Y_PLANE] = CODECHAL_DECODE_VC1_OLP_DST_Y;
1472 surfaceParamsDst.dwBindingTableOffset[MHW_U_PLANE] = CODECHAL_DECODE_VC1_OLP_DST_UV;
1473 surfaceParamsDst.dwCacheabilityControl =
1474 m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_POST_DEBLOCKING_CODEC].Value;
1475
1476 #ifdef _MMC_SUPPORTED
1477 if (m_mmc)
1478 {
1479 CODECHAL_SURFACE_CODEC_PARAMS dstSurfaceParam = {};
1480 dstSurfaceParam.psSurface = &m_deblockSurface;
1481 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mmc->SetSurfaceParams(&dstSurfaceParam));
1482 }
1483 #endif
1484
1485 CODECHAL_DECODE_CHK_STATUS_RETURN(stateHeapInterface->pfnSetSurfaceState(
1486 stateHeapInterface,
1487 kernelState,
1488 &cmdBuffer,
1489 1,
1490 &surfaceParamsSrc));
1491 CODECHAL_DECODE_CHK_STATUS_RETURN(stateHeapInterface->pfnSetSurfaceState(
1492 stateHeapInterface,
1493 kernelState,
1494 &cmdBuffer,
1495 1,
1496 &surfaceParamsDst));
1497
1498 MHW_STATE_BASE_ADDR_PARAMS stateBaseAddrParams;
1499 MOS_ZeroMemory(&stateBaseAddrParams, sizeof(stateBaseAddrParams));
1500 MOS_RESOURCE *dsh = nullptr, *ish = nullptr;
1501 CODECHAL_DECODE_CHK_NULL_RETURN(dsh = kernelState->m_dshRegion.GetResource());
1502 CODECHAL_DECODE_CHK_NULL_RETURN(ish = kernelState->m_ishRegion.GetResource());
1503 stateBaseAddrParams.presDynamicState = dsh;
1504 stateBaseAddrParams.dwDynamicStateSize = kernelState->m_dshRegion.GetHeapSize();
1505 stateBaseAddrParams.presInstructionBuffer = ish;
1506 stateBaseAddrParams.dwInstructionBufferSize = kernelState->m_ishRegion.GetHeapSize();
1507 stateBaseAddrParams.mocs4GeneralState = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_UNCACHED].Gen12.Index;
1508 stateBaseAddrParams.mocs4DynamicState = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_UNCACHED].Gen12.Index;
1509 stateBaseAddrParams.mocs4SurfaceState = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_UNCACHED].Gen12.Index;
1510 stateBaseAddrParams.mocs4IndirectObjectBuffer = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_UNCACHED].Gen12.Index;
1511 stateBaseAddrParams.mocs4StatelessDataport = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_UNCACHED].Gen12.Index;
1512 CODECHAL_DECODE_CHK_STATUS_RETURN(renderEngineInterface->AddStateBaseAddrCmd(&cmdBuffer, &stateBaseAddrParams));
1513
1514 MHW_VFE_PARAMS_G12 vfeParams= {};
1515 vfeParams.pKernelState = kernelState;
1516 CODECHAL_DECODE_CHK_STATUS_RETURN(renderEngineInterface->AddMediaVfeCmd(&cmdBuffer, &vfeParams));
1517
1518 MHW_CURBE_LOAD_PARAMS curbeLoadParams;
1519 MOS_ZeroMemory(&curbeLoadParams, sizeof(curbeLoadParams));
1520 curbeLoadParams.pKernelState = kernelState;
1521 CODECHAL_DECODE_CHK_STATUS_RETURN(renderEngineInterface->AddMediaCurbeLoadCmd(&cmdBuffer, &curbeLoadParams));
1522
1523 MHW_ID_LOAD_PARAMS idLoadParams;
1524 MOS_ZeroMemory(&idLoadParams, sizeof(idLoadParams));
1525 idLoadParams.pKernelState = kernelState;
1526 idLoadParams.dwNumKernelsLoaded = 1;
1527 CODECHAL_DECODE_CHK_STATUS_RETURN(renderEngineInterface->AddMediaIDLoadCmd(&cmdBuffer, &idLoadParams));
1528
1529 CODECHAL_DEBUG_TOOL(
1530 CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
1531 CODECHAL_MEDIA_STATE_OLP,
1532 MHW_DSH_TYPE,
1533 kernelState));
1534
1535 CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
1536 CODECHAL_MEDIA_STATE_OLP,
1537 MHW_SSH_TYPE,
1538 kernelState));
1539 )
1540
1541 CODECHAL_DECODE_VC1_OLP_PARAMS vc1OlpParams;
1542 vc1OlpParams.pCmdBuffer = &cmdBuffer;
1543 vc1OlpParams.pPipeControlParams = &pipeControlParams;
1544 vc1OlpParams.pStateBaseAddrParams = &stateBaseAddrParams;
1545 vc1OlpParams.pVfeParams = &vfeParams;
1546 vc1OlpParams.pCurbeLoadParams = &curbeLoadParams;
1547 vc1OlpParams.pIdLoadParams = &idLoadParams;
1548 CODECHAL_DECODE_CHK_STATUS_RETURN(AddVc1OlpCmd(&vc1OlpParams));
1549
1550 // Check if destination surface needs to be synchronized, before command buffer submission
1551 syncParams = g_cInitSyncParams;
1552 syncParams.GpuContext = m_renderContext;
1553 syncParams.presSyncResource = &m_deblockSurface.OsResource;
1554 syncParams.bReadOnly = false;
1555 syncParams.bDisableDecodeSyncLock = m_disableDecodeSyncLock;
1556 syncParams.bDisableLockForTranscode = m_disableLockForTranscode;
1557
1558 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnPerformOverlaySync(m_osInterface, &syncParams));
1559 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceWait(m_osInterface, &syncParams));
1560
1561 // Update the resource tag (s/w tag) for On-Demand Sync
1562 m_osInterface->pfnSetResourceSyncTag(m_osInterface, &syncParams);
1563
1564 // Update GPU Sync tag for on demand synchronization
1565 if (m_osInterface->bTagResourceSync)
1566 {
1567 pipeControlParams.dwFlushMode = MHW_FLUSH_WRITE_CACHE;
1568 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddPipeControl(&cmdBuffer, nullptr, &pipeControlParams));
1569 CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->WriteSyncTagToResource(&cmdBuffer, &syncParams));
1570 }
1571 CODECHAL_DECODE_CHK_STATUS_RETURN(stateHeapInterface->pfnSubmitBlocks(
1572 stateHeapInterface,
1573 kernelState));
1574 CODECHAL_DECODE_CHK_STATUS_RETURN(stateHeapInterface->pfnUpdateGlobalCmdBufId(
1575 stateHeapInterface));
1576
1577 // Add PipeControl to invalidate ISP and MediaState to avoid PageFault issue
1578 // This code is temporal and it will be moved to batch buffer end in short
1579 MOS_ZeroMemory(&pipeControlParams, sizeof(pipeControlParams));
1580 pipeControlParams.dwFlushMode = MHW_FLUSH_WRITE_CACHE;
1581 pipeControlParams.bGenericMediaStateClear = true;
1582 pipeControlParams.bIndirectStatePointersDisable = true;
1583 pipeControlParams.bDisableCSStall = false;
1584 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddPipeControl(&cmdBuffer, nullptr, &pipeControlParams));
1585
1586 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(&cmdBuffer, nullptr));
1587
1588 // To clear the SSEU values in the hw interface struct, so next kernel can be programmed correctly
1589 CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->UpdateSSEuForCmdBuffer(&cmdBuffer, false, true));
1590
1591 m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
1592
1593 CODECHAL_DEBUG_TOOL(
1594 CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer(
1595 &cmdBuffer,
1596 CODECHAL_MEDIA_STATE_OLP,
1597 "_DEC"));
1598 )
1599
1600 if ( MOS_VE_SUPPORTED(m_osInterface))
1601 {
1602 CodecHalDecodeSinglePipeVE_PopulateHintParams(m_veState, &cmdBuffer, false);
1603 }
1604
1605 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, m_renderContextUsesNullHw));
1606
1607 if (m_statusQueryReportingEnabled)
1608 {
1609 CODECHAL_DECODE_CHK_STATUS_RETURN(ResetStatusReport(m_renderContextUsesNullHw));
1610 }
1611
1612 m_osInterface->pfnSetGpuContext(m_osInterface, m_videoContext);
1613
1614 return eStatus;
1615 }
1616
CodechalDecodeVc1G12(CodechalHwInterface * hwInterface,CodechalDebugInterface * debugInterface,PCODECHAL_STANDARD_INFO standardInfo)1617 CodechalDecodeVc1G12::CodechalDecodeVc1G12(
1618 CodechalHwInterface *hwInterface,
1619 CodechalDebugInterface* debugInterface,
1620 PCODECHAL_STANDARD_INFO standardInfo) :
1621 CodechalDecodeVc1(hwInterface, debugInterface, standardInfo)
1622 {
1623 CODECHAL_DECODE_FUNCTION_ENTER;
1624
1625 CODECHAL_DECODE_CHK_NULL_NO_STATUS_RETURN(hwInterface);
1626 CODECHAL_DECODE_CHK_NULL_NO_STATUS_RETURN(m_osInterface);
1627
1628 m_osInterface->pfnVirtualEngineSupported(m_osInterface, true, true);
1629
1630 m_olpCurbeStaticDataLength = CODECHAL_DECODE_VC1_CURBE_SIZE_OLP;
1631
1632 uint32_t kuid = 0;
1633 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1634
1635 #if defined(ENABLE_KERNELS) && !defined(_FULL_OPEN_SOURCE)
1636 eStatus = CodecHalGetKernelBinaryAndSize(
1637 (uint8_t *)IGCODECKRN_G12,
1638 IDR_CODEC_AllVC1_NV12,
1639 &m_olpKernelBase,
1640 &m_olpKernelSize);
1641 #endif
1642
1643 CODECHAL_DECODE_ASSERT(eStatus == MOS_STATUS_SUCCESS);
1644
1645 hwInterface->GetStateHeapSettings()->dwNumSyncTags = CODECHAL_DECODE_VC1_NUM_SYNC_TAGS;
1646 hwInterface->GetStateHeapSettings()->dwIshSize =
1647 MOS_ALIGN_CEIL(m_olpKernelSize, (1 << MHW_KERNEL_OFFSET_SHIFT));
1648 hwInterface->GetStateHeapSettings()->dwDshSize = CODECHAL_DECODE_VC1_INITIAL_DSH_SIZE;
1649 }
1650
~CodechalDecodeVc1G12()1651 CodechalDecodeVc1G12::~CodechalDecodeVc1G12()
1652 {
1653 CODECHAL_DECODE_FUNCTION_ENTER;
1654
1655 if (m_veState != nullptr)
1656 {
1657 MOS_FreeMemAndSetNull(m_veState);
1658 m_veState = nullptr;
1659 }
1660 }
1661
CalcRequestedSpace(uint32_t & requestedSize,uint32_t & additionalSizeNeeded,uint32_t & requestedPatchListSize)1662 void CodechalDecodeVc1G12::CalcRequestedSpace(
1663 uint32_t &requestedSize,
1664 uint32_t &additionalSizeNeeded,
1665 uint32_t &requestedPatchListSize)
1666 {
1667 CODECHAL_DECODE_FUNCTION_ENTER;
1668
1669 requestedSize = m_commandBufferSizeNeeded + m_HucStateCmdBufferSizeNeeded +
1670 (m_standardDecodeSizeNeeded * (m_decodeParams.m_numSlices + 1));
1671 requestedPatchListSize = m_commandPatchListSizeNeeded + m_HucPatchListSizeNeeded +
1672 (m_standardDecodePatchListSizeNeeded * (m_decodeParams.m_numSlices + 1));
1673 additionalSizeNeeded = COMMAND_BUFFER_RESERVED_SPACE;
1674 }
1675