1 /*
2 * Copyright (c) 2011-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 codechal_decoder.cpp
24 //! \brief Implements the decode interface for CodecHal.
25 //! \details The decode interface is further sub-divided by standard, this file is for the base interface which is shared by all decode standards.
26 //!
27
28 #include "codechal_decoder.h"
29 #include "codechal_secure_decode_interface.h"
30 #include "mos_solo_generic.h"
31 #include "codechal_debug.h"
32 #include "codechal_decode_histogram.h"
33
34 #ifdef _HEVC_DECODE_SUPPORTED
35 #include "codechal_decode_hevc.h"
36 #endif
37
38 #ifdef _VP9_DECODE_SUPPORTED
39 #include "codechal_decode_vp9.h"
40 #endif
41
42 #ifdef _HYBRID_HEVC_DECODE_SUPPORTED
43 #include "codechal_decode_hybrid_hevc.h"
44 #endif
45
46 #ifdef _HYBRID_VP9_DECODE_SUPPORTED
47 #include "codechal_decode_hybrid_vp9.h"
48 #endif
49
50 #ifdef _AVC_DECODE_SUPPORTED
51 #include "codechal_decode_avc.h"
52 #endif
53
54 #ifdef _JPEG_DECODE_SUPPORTED
55 #include "codechal_decode_jpeg.h"
56 #endif
57
58 #ifdef _VC1_DECODE_SUPPORTED
59 #include "codechal_decode_vc1.h"
60 #endif
61
62 #ifdef _VP8_DECODE_SUPPORTED
63 #include "codechal_decode_vp8.h"
64 #endif
65
66 #ifdef _MPEG2_DECODE_SUPPORTED
67 #include "codechal_decode_mpeg2.h"
68 #endif
69
AllocateBuffer(PMOS_RESOURCE resource,uint32_t size,const char * name,bool initialize,uint8_t value,bool bPersistent)70 MOS_STATUS CodechalDecode::AllocateBuffer(
71 PMOS_RESOURCE resource,
72 uint32_t size,
73 const char *name,
74 bool initialize,
75 uint8_t value,
76 bool bPersistent)
77 {
78 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
79
80 CODECHAL_DECODE_FUNCTION_ENTER;
81
82 CODECHAL_DECODE_CHK_NULL_RETURN(m_osInterface);
83 CODECHAL_DECODE_CHK_NULL_RETURN(resource);
84
85 MOS_ALLOC_GFXRES_PARAMS allocParams;
86 MOS_ZeroMemory(&allocParams, sizeof(MOS_ALLOC_GFXRES_PARAMS));
87 allocParams.Type = MOS_GFXRES_BUFFER;
88 allocParams.TileType = MOS_TILE_LINEAR;
89 allocParams.Format = Format_Buffer;
90 allocParams.dwBytes = size;
91 allocParams.pBufName = name;
92 allocParams.bIsPersistent = bPersistent;
93
94 CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(m_osInterface->pfnAllocateResource(
95 m_osInterface,
96 &allocParams,
97 resource),
98 "Failed to allocate %s.", name);
99
100 if (initialize)
101 {
102 CodechalResLock ResourceLock(m_osInterface, resource);
103 auto data = (uint8_t*)ResourceLock.Lock(CodechalResLock::writeOnly);
104 CODECHAL_DECODE_CHK_NULL_RETURN(data);
105
106 MOS_FillMemory(data, size, value);
107 }
108
109 return eStatus;
110 }
111
AllocateSurface(PMOS_SURFACE surface,uint32_t width,uint32_t height,const char * name,MOS_FORMAT format,bool isCompressible)112 MOS_STATUS CodechalDecode::AllocateSurface(
113 PMOS_SURFACE surface,
114 uint32_t width,
115 uint32_t height,
116 const char *name,
117 MOS_FORMAT format,
118 bool isCompressible)
119 {
120 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
121
122 CODECHAL_DECODE_FUNCTION_ENTER;
123
124 CODECHAL_DECODE_CHK_NULL_RETURN(m_osInterface);
125 CODECHAL_DECODE_CHK_NULL_RETURN(surface);
126
127 MOS_ALLOC_GFXRES_PARAMS allocParams;
128 MOS_ZeroMemory(&allocParams, sizeof(MOS_ALLOC_GFXRES_PARAMS));
129 allocParams.Type = MOS_GFXRES_2D;
130 allocParams.TileType = MOS_TILE_Y;
131 allocParams.Format = format;
132 allocParams.dwWidth = width;
133 allocParams.dwHeight = height;
134 allocParams.dwArraySize = 1;
135 allocParams.pBufName = name;
136 allocParams.bIsCompressible = isCompressible;
137
138 CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(m_osInterface->pfnAllocateResource(
139 m_osInterface,
140 &allocParams,
141 &surface->OsResource),
142 "Failed to allocate %s.", name);
143
144 CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(
145 m_osInterface,
146 surface));
147
148 return eStatus;
149 }
150
HucCopy(PMOS_COMMAND_BUFFER cmdBuffer,PMOS_RESOURCE src,PMOS_RESOURCE dst,uint32_t copyLength,uint32_t copyInputOffset,uint32_t copyOutputOffset)151 MOS_STATUS CodechalDecode::HucCopy(
152 PMOS_COMMAND_BUFFER cmdBuffer,
153 PMOS_RESOURCE src,
154 PMOS_RESOURCE dst,
155 uint32_t copyLength,
156 uint32_t copyInputOffset,
157 uint32_t copyOutputOffset)
158 {
159 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
160
161 CODECHAL_DECODE_FUNCTION_ENTER;
162
163 CODECHAL_DECODE_CHK_NULL_RETURN(cmdBuffer);
164 CODECHAL_DECODE_CHK_NULL_RETURN(src);
165 CODECHAL_DECODE_CHK_NULL_RETURN(dst);
166
167 CodechalHucStreamoutParams hucStreamOutParams;
168 MOS_ZeroMemory(&hucStreamOutParams, sizeof(hucStreamOutParams));
169
170 // Ind Obj Addr command
171 hucStreamOutParams.dataBuffer = src;
172 hucStreamOutParams.dataSize = copyLength + copyInputOffset;
173 hucStreamOutParams.dataOffset = MOS_ALIGN_FLOOR(copyInputOffset, MHW_PAGE_SIZE);
174 hucStreamOutParams.streamOutObjectBuffer = dst;
175 hucStreamOutParams.streamOutObjectSize = copyLength + copyOutputOffset;
176 hucStreamOutParams.streamOutObjectOffset = MOS_ALIGN_FLOOR(copyOutputOffset, MHW_PAGE_SIZE);
177
178 // Stream object params
179 hucStreamOutParams.indStreamInLength = copyLength;
180 hucStreamOutParams.inputRelativeOffset = copyInputOffset - hucStreamOutParams.dataOffset;
181 hucStreamOutParams.outputRelativeOffset = copyOutputOffset - hucStreamOutParams.streamOutObjectOffset;
182
183 CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->PerformHucStreamOut(
184 &hucStreamOutParams,
185 cmdBuffer));
186
187 return eStatus;
188 }
189
LinearToYTiledAddress(uint32_t x,uint32_t y,uint32_t pitch)190 uint32_t CodechalDecode::LinearToYTiledAddress(
191 uint32_t x,
192 uint32_t y,
193 uint32_t pitch)
194 {
195 uint32_t tileW = 128;
196 uint32_t tileH = 32;
197
198 uint32_t tileSize = tileW * tileH;
199
200 uint32_t rowSize = (pitch / tileW) * tileSize;
201
202 uint32_t xOffWithinTile = x % tileW;
203 uint32_t yOffWithinTile = y % tileH;
204
205 uint32_t tileNumberInX = x / tileW;
206 uint32_t tileNumberInY = y / tileH;
207
208 uint32_t tileOffset =
209 rowSize * tileNumberInY +
210 tileSize * tileNumberInX +
211 tileH * 16 * (xOffWithinTile / 16) +
212 yOffWithinTile * 16 +
213 (xOffWithinTile % 16);
214
215 return tileOffset;
216 }
217
CodechalDecode(CodechalHwInterface * hwInterface,CodechalDebugInterface * debugInterface,PCODECHAL_STANDARD_INFO standardInfo)218 CodechalDecode::CodechalDecode (
219 CodechalHwInterface *hwInterface,
220 CodechalDebugInterface *debugInterface,
221 PCODECHAL_STANDARD_INFO standardInfo):
222 Codechal(*hwInterface, debugInterface)
223 {
224 CODECHAL_DECODE_FUNCTION_ENTER;
225
226 CODECHAL_PUBLIC_CHK_NULL_NO_STATUS_RETURN(hwInterface);
227 CODECHAL_PUBLIC_CHK_NULL_NO_STATUS_RETURN(hwInterface->GetOsInterface());
228 MOS_UNUSED(debugInterface);
229
230 m_hwInterface = hwInterface;
231 m_osInterface = hwInterface->GetOsInterface();
232
233 if (m_hwInterface->bEnableVdboxBalancingbyUMD && m_osInterface->bEnableVdboxBalancing)
234 {
235 m_hwInterface->m_getVdboxNodeByUMD = true;
236 }
237 m_userSettingPtr = m_osInterface->pfnGetUserSettingInstance(m_osInterface);
238
239 #if USE_CODECHAL_DEBUG_TOOL
240 CODECHAL_PUBLIC_CHK_NULL_NO_STATUS_RETURN(debugInterface);
241 m_debugInterface = debugInterface;
242 #endif // USE_CODECHAL_DEBUG_TOOL
243
244 MOS_ZeroMemory(&m_dummyReference, sizeof(MOS_SURFACE));
245
246 CODECHAL_DECODE_CHK_NULL_NO_STATUS_RETURN(hwInterface);
247 CODECHAL_DECODE_CHK_NULL_NO_STATUS_RETURN(hwInterface->GetOsInterface());
248 CODECHAL_DECODE_CHK_NULL_NO_STATUS_RETURN(hwInterface->GetMiInterface());
249 CODECHAL_DECODE_CHK_NULL_NO_STATUS_RETURN(hwInterface->GetCpInterface());
250 CODECHAL_DECODE_CHK_NULL_NO_STATUS_RETURN(standardInfo);
251
252 m_mfxInterface = hwInterface->GetMfxInterface();
253 m_hcpInterface = hwInterface->GetHcpInterface();
254 m_hucInterface = hwInterface->GetHucInterface();
255 m_vdencInterface = hwInterface->GetVdencInterface();
256 m_miInterface = hwInterface->GetMiInterface();
257 m_cpInterface = hwInterface->GetCpInterface();
258 m_hwInterface = hwInterface;
259
260 PLATFORM platform;
261 m_osInterface->pfnGetPlatform(m_osInterface, &platform);
262 m_waTable = m_osInterface->pfnGetWaTable(m_osInterface);
263 CODECHAL_DECODE_CHK_NULL_NO_STATUS_RETURN(m_waTable);
264 m_skuTable = m_osInterface->pfnGetSkuTable(m_osInterface);
265 CODECHAL_DECODE_CHK_NULL_NO_STATUS_RETURN(m_skuTable);
266
267 m_mode = standardInfo->Mode;
268 m_isHybridDecoder = standardInfo->bIsHybridCodec ? true : false;
269
270 m_pCodechalOcaDumper = MOS_New(CodechalOcaDumper);
271 CODECHAL_DECODE_CHK_NULL_NO_STATUS_RETURN(m_pCodechalOcaDumper);
272
273 #if (_DEBUG || _RELEASE_INTERNAL)
274 AllocateDecodeOutputBuf();
275 #endif
276 }
277
SetGpuCtxCreatOption(CodechalSetting * codecHalSetting)278 MOS_STATUS CodechalDecode::SetGpuCtxCreatOption(
279 CodechalSetting * codecHalSetting)
280 {
281 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
282
283 MOS_UNUSED(codecHalSetting);
284
285 m_gpuCtxCreatOpt = MOS_New(MOS_GPUCTX_CREATOPTIONS);
286 CODECHAL_DECODE_CHK_NULL_RETURN(m_gpuCtxCreatOpt);
287
288 return eStatus;
289 }
290
CreateGpuContexts(CodechalSetting * codecHalSettings)291 MOS_STATUS CodechalDecode::CreateGpuContexts(
292 CodechalSetting *codecHalSettings)
293 {
294 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
295
296 CODECHAL_DECODE_CHK_NULL_RETURN(codecHalSettings);
297
298 MHW_VDBOX_GPUNODE_LIMIT gpuNodeLimit;
299 gpuNodeLimit.bHuCInUse = false;
300 gpuNodeLimit.bHcpInUse = m_hcpInUse;
301 gpuNodeLimit.bSfcInUse = IsSfcInUse(codecHalSettings);
302
303 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->FindGpuNodeToUse(
304 &gpuNodeLimit));
305
306 m_videoGpuNode = (MOS_GPU_NODE)(gpuNodeLimit.dwGpuNodeToUse);
307
308 CODECHAL_UPDATE_VDBOX_USER_FEATURE(m_videoGpuNode, m_osInterface->pOsContext);
309 CodecHalDecodeMapGpuNodeToGpuContex(m_videoGpuNode, m_videoContext, false);
310
311 CODECHAL_DECODE_CHK_STATUS_RETURN(SetGpuCtxCreatOption(codecHalSettings));
312 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnCreateGpuContext(
313 m_osInterface,
314 m_videoContext,
315 m_videoGpuNode,
316 m_gpuCtxCreatOpt));
317
318 // Create Video2 Context for MPEG2 WA and JPEG incomplete bitstream & VP9 / HEVC DRC support
319 // For decode device, we use VDBOX0 always for the WA context
320 // For AVC,VC1,VP9, use WA context for huc stream out copy
321 if (Mos_Solo_IsInUse(m_osInterface))
322 {
323 Mos_Solo_DecodeMapGpuNodeToGpuContex(MOS_GPU_NODE_VIDEO, m_videoContextForWa, true, false);
324 }
325 else
326 {
327 CodecHalDecodeMapGpuNodeToGpuContex(MOS_GPU_NODE_VIDEO, m_videoContextForWa, true);
328 }
329
330 MOS_GPUCTX_CREATOPTIONS_ENHANCED createOption;
331 createOption.UsingSFC = codecHalSettings->sfcInUseHinted && codecHalSettings->downsamplingHinted
332 && (MEDIA_IS_SKU(m_skuTable, FtrSFCPipe)) && !(MEDIA_IS_SKU(m_skuTable, FtrDisableVDBox2SFC));
333 eStatus = (MOS_STATUS)m_osInterface->pfnCreateGpuContext(
334 m_osInterface,
335 m_videoContextForWa,
336 MOS_GPU_NODE_VIDEO,
337 &createOption);
338
339 if (eStatus != MOS_STATUS_SUCCESS)
340 {
341 // use context Video1. It should be valid
342 if (Mos_Solo_IsInUse(m_osInterface))
343 {
344 Mos_Solo_DecodeMapGpuNodeToGpuContex(MOS_GPU_NODE_VIDEO, m_videoContextForWa, false, false);
345 }
346 else
347 {
348 CodecHalDecodeMapGpuNodeToGpuContex(MOS_GPU_NODE_VIDEO, m_videoContextForWa, false);
349 }
350 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnIsGpuContextValid(
351 m_osInterface,
352 m_videoContextForWa));
353 }
354
355 // Do not need to create render context here, it will be created by standard specific decoder
356
357 return eStatus;
358 }
359
360 // Decoder Public Interface Functions
Allocate(CodechalSetting * codecHalSettings)361 MOS_STATUS CodechalDecode::Allocate (CodechalSetting * codecHalSettings)
362 {
363 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
364
365 CODECHAL_DECODE_FUNCTION_ENTER;
366
367 CODECHAL_PUBLIC_CHK_NULL_RETURN(codecHalSettings);
368 CODECHAL_PUBLIC_CHK_NULL_RETURN(m_hwInterface);
369 CODECHAL_PUBLIC_CHK_NULL_RETURN(m_osInterface);
370
371 MOS_TraceEvent(EVENT_CODECHAL_CREATE,
372 EVENT_TYPE_INFO,
373 &codecHalSettings->codecFunction,
374 sizeof(uint32_t),
375 nullptr,
376 0);
377
378 CODECHAL_PUBLIC_CHK_STATUS_RETURN(m_hwInterface->Initialize(codecHalSettings));
379
380 MOS_NULL_RENDERING_FLAGS nullHWAccelerationEnable;
381 nullHWAccelerationEnable.Value = 0;
382
383 #if (_DEBUG || _RELEASE_INTERNAL)
384 if (!m_statusReportDebugInterface)
385 {
386 m_statusReportDebugInterface = MOS_New(CodechalDebugInterface);
387 CODECHAL_PUBLIC_CHK_NULL_RETURN(m_statusReportDebugInterface);
388 CODECHAL_PUBLIC_CHK_STATUS_RETURN(
389 m_statusReportDebugInterface->Initialize(m_hwInterface, codecHalSettings->codecFunction));
390 }
391
392 ReadUserSettingForDebug(
393 m_userSettingPtr,
394 nullHWAccelerationEnable.Value,
395 __MEDIA_USER_FEATURE_VALUE_NULL_HW_ACCELERATION_ENABLE,
396 MediaUserSetting::Group::Device);
397
398 m_useNullHw[MOS_GPU_CONTEXT_VIDEO] =
399 (nullHWAccelerationEnable.CodecGlobal || nullHWAccelerationEnable.CtxVideo);
400 m_useNullHw[MOS_GPU_CONTEXT_VIDEO2] =
401 (nullHWAccelerationEnable.CodecGlobal || nullHWAccelerationEnable.CtxVideo2);
402 m_useNullHw[MOS_GPU_CONTEXT_VIDEO3] =
403 (nullHWAccelerationEnable.CodecGlobal || nullHWAccelerationEnable.CtxVideo3);
404 m_useNullHw[MOS_GPU_CONTEXT_VDBOX2_VIDEO] =
405 (nullHWAccelerationEnable.CodecGlobal || nullHWAccelerationEnable.CtxVDBox2Video);
406 m_useNullHw[MOS_GPU_CONTEXT_VDBOX2_VIDEO2] =
407 (nullHWAccelerationEnable.CodecGlobal || nullHWAccelerationEnable.CtxVDBox2Video2);
408 m_useNullHw[MOS_GPU_CONTEXT_VDBOX2_VIDEO3] =
409 (nullHWAccelerationEnable.CodecGlobal || nullHWAccelerationEnable.CtxVDBox2Video3);
410 m_useNullHw[MOS_GPU_CONTEXT_RENDER] =
411 (nullHWAccelerationEnable.CodecGlobal || nullHWAccelerationEnable.CtxRender);
412 m_useNullHw[MOS_GPU_CONTEXT_RENDER2] =
413 (nullHWAccelerationEnable.CodecGlobal || nullHWAccelerationEnable.CtxRender2);
414 #endif // _DEBUG || _RELEASE_INTERNAL
415
416 m_standard = codecHalSettings->standard;
417 m_mode = codecHalSettings->mode;
418 m_disableDecodeSyncLock = codecHalSettings->disableDecodeSyncLock ? true : false;
419 m_disableLockForTranscode = MEDIA_IS_WA(m_waTable, WaDisableLockForTranscodePerf);
420
421 // register cp params via codechal_Setting
422 m_cpInterface->RegisterParams(codecHalSettings->GetCpParams());
423
424 {
425 MOS_USER_FEATURE_VALUE_DATA userFeatureData;
426 MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
427 userFeatureData.u32Data = MOS_STATUS_REPORT_DEFAULT;
428 userFeatureData.i32DataFlag = MOS_USER_FEATURE_VALUE_DATA_FLAG_CUSTOM_DEFAULT_VALUE_TYPE;
429 MOS_UserFeature_ReadValue_ID(
430 nullptr,
431 __MEDIA_USER_FEATURE_VALUE_STATUS_REPORTING_ENABLE_ID,
432 &userFeatureData,
433 m_osInterface->pOsContext);
434 m_statusQueryReportingEnabled = (userFeatureData.u32Data) ? true : false;
435
436 #if (_DEBUG || _RELEASE_INTERNAL)
437 if (m_statusQueryReportingEnabled)
438 {
439 MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
440 MOS_UserFeature_ReadValue_ID(
441 nullptr,
442 __MEDIA_USER_FEATURE_VALUE_STREAM_OUT_ENABLE_ID,
443 &userFeatureData,
444 m_osInterface->pOsContext);
445 m_streamOutEnabled = (userFeatureData.u32Data) ? true : false;
446
447 }
448
449 MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
450 MOS_UserFeature_ReadValue_ID(
451 nullptr,
452 __MEDIA_USER_FEATURE_VALUE_PERF_PROFILER_FE_BE_TIMING,
453 &userFeatureData,
454 m_osInterface->pOsContext);
455 m_perfFEBETimingEnabled = userFeatureData.bData;
456
457 #endif // _DEBUG || _RELEASE_INTERNAL
458 }
459
460 //#if (_DEBUG || _RELEASE_INTERNAL)
461 //#ifdef _MD5_DEBUG_SUPPORTED
462 // {
463 // // For multi-thread decoder case, MD5 kernel will share the same context with hybrid decoder.
464 // // And it will be initialized in decoder worker thread function.
465 // if ((!m_isHybridDecoder || (m_isHybridDecoder && !IsFrameMTEnabled())) &&
466 // m_debugInterface != nullptr)
467 // {
468 // CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHal_DbgInitMD5Context(
469 // m_debugInterface,
470 // nullptr));
471 // if (m_debugInterface->pMD5Context)
472 // {
473 // m_debugInterface->bMD5DDIThreadExecute = true;
474 // }
475 // }
476 // }
477 //#endif // _MD5_DEBUG_SUPPORTED
478 //#endif // _DEBUG || _RELEASE_INTERNAL
479
480 // Set decoder running flag to OS context so that VPP driver can query this flag and use
481 // this flag to decide if disable VPP DNDI feature in VEBOX for power saving.
482 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSetHybridDecoderRunningFlag(
483 m_osInterface,
484 m_isHybridDecoder));
485
486 // eStatus Query reporting
487 if (m_statusQueryReportingEnabled)
488 {
489 uint32_t statusBufferSize = sizeof(CodechalDecodeStatus) * CODECHAL_DECODE_STATUS_NUM + sizeof(uint32_t) * 2;
490
491 CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer(
492 &m_decodeStatusBuf.m_statusBuffer,
493 statusBufferSize,
494 "StatusQueryBuffer"),
495 "Failed to allocate decode eStatus buffer.");
496
497 MOS_LOCK_PARAMS lockFlagsNoOverWrite;
498 MOS_ZeroMemory(&lockFlagsNoOverWrite, sizeof(MOS_LOCK_PARAMS));
499 lockFlagsNoOverWrite.WriteOnly = 1;
500 lockFlagsNoOverWrite.NoOverWrite = 1;
501
502 uint8_t *data = (uint8_t *)m_osInterface->pfnLockResource(
503 m_osInterface,
504 &m_decodeStatusBuf.m_statusBuffer,
505 &lockFlagsNoOverWrite);
506
507 CODECHAL_DECODE_CHK_NULL_RETURN(data);
508 MOS_ZeroMemory(data, statusBufferSize);
509 m_decodeStatusBuf.m_data = (uint32_t *)data;
510 m_decodeStatusBuf.m_decodeStatus = (CodechalDecodeStatus *)(data + sizeof(uint32_t) * 2);
511 m_decodeStatusBuf.m_currIndex = 0;
512 m_decodeStatusBuf.m_firstIndex = 0;
513 m_decodeStatusBuf.m_swStoreData = 1;
514
515 m_decodeStatusBuf.m_storeDataOffset = 0;
516 m_decodeStatusBuf.m_decErrorStatusOffset = CODECHAL_OFFSETOF(CodechalDecodeStatus, m_mmioErrorStatusReg);
517 m_decodeStatusBuf.m_decFrameCrcOffset = CODECHAL_OFFSETOF(CodechalDecodeStatus, m_mmioFrameCrcReg);
518 m_decodeStatusBuf.m_decMBCountOffset = CODECHAL_OFFSETOF(CodechalDecodeStatus, m_mmioMBCountReg);
519 m_decodeStatusBuf.m_csEngineIdOffset = CODECHAL_OFFSETOF(CodechalDecodeStatus, m_mmioCsEngineIdReg);
520 m_decodeStatusBuf.m_hucErrorStatus2MaskOffset = CODECHAL_OFFSETOF(CodechalDecodeStatus, m_hucErrorStatus2);
521 m_decodeStatusBuf.m_hucErrorStatus2RegOffset = CODECHAL_OFFSETOF(CodechalDecodeStatus, m_hucErrorStatus2) + sizeof(uint32_t);
522 m_decodeStatusBuf.m_hucErrorStatusMaskOffset = CODECHAL_OFFSETOF(CodechalDecodeStatus, m_hucErrorStatus);
523 m_decodeStatusBuf.m_hucErrorStatusRegOffset = CODECHAL_OFFSETOF(CodechalDecodeStatus, m_hucErrorStatus) + sizeof(uint32_t);
524
525 // Set IMEM Loaded bit (in DW1) to 1 by default in the first status buffer
526 // Set None Critical Error bit to 1 by default in the first status buffer
527 // These bits will be changed later after storing register
528 if (m_hucInterface)
529 {
530 m_decodeStatusBuf.m_decodeStatus->m_hucErrorStatus = (uint64_t)m_hucInterface->GetHucStatusHevcS2lFailureMask() << 32;
531 m_decodeStatusBuf.m_decodeStatus->m_hucErrorStatus2 = (uint64_t)m_hucInterface->GetHucStatus2ImemLoadedMask() << 32;
532 }
533
534 //if kernels are used update the media state heap with status pointers to keep track of when buffers are done
535 if (m_hwInterface->GetRenderInterface() != nullptr &&
536 m_hwInterface->GetRenderInterface()->m_stateHeapInterface != nullptr)
537 {
538 PMHW_STATE_HEAP_INTERFACE pStateHeapInterface =
539 m_hwInterface->GetRenderInterface()->m_stateHeapInterface;
540
541 CODECHAL_DECODE_CHK_STATUS_RETURN(pStateHeapInterface->pfnSetCmdBufStatusPtr(
542 pStateHeapInterface,
543 m_decodeStatusBuf.m_data));
544 }
545
546 // StreamOut Buffer Allocation
547 if (m_streamOutEnabled)
548 {
549 uint32_t numMacroblocks =
550 (codecHalSettings->height / CODECHAL_MACROBLOCK_HEIGHT) *
551 (codecHalSettings->width / CODECHAL_MACROBLOCK_WIDTH);
552 uint32_t streamOutBufSize = MOS_ALIGN_CEIL(numMacroblocks * CODEC_SIZE_MFX_STREAMOUT_DATA, 64);
553
554 m_streamOutCurrBufIdx = 0;
555
556 for (auto i = 0; i < CODECHAL_DECODE_NUM_STREAM_OUT_BUFFERS; i++)
557 {
558 CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer(
559 &(m_streamOutBuffer[i]),
560 streamOutBufSize,
561 "StreamOutBuffer",
562 true,
563 0),
564 "Failed to allocate streamout buffer.");
565
566 m_streamOutCurrStatusIdx[i] = CODECHAL_DECODE_STATUS_NUM;
567 }
568 }
569 }
570
571 CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer(
572 &m_predicationBuffer,
573 sizeof(uint32_t),
574 "PredicationBuffer",
575 true,
576 0),
577 "Failed to allocate predication buffer.");
578
579 CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer(
580 &m_frameCountTypeBuf,
581 sizeof(uint32_t),
582 "FrameCountBuffer",
583 true,
584 0),
585 "Failed to allocate FrameCountBuffer buffer.");
586
587 CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer(
588 &m_crcBuf,
589 sizeof(uint32_t),
590 "crcBuffer",
591 true,
592 0),
593 "Failed to allocate crcBuffer");
594
595 CODECHAL_DECODE_CHK_STATUS_RETURN(AllocateStandard(codecHalSettings));
596
597 if(!m_isHybridDecoder)
598 {
599 // Create Video Contexts
600 CODECHAL_DECODE_CHK_STATUS_RETURN(CreateGpuContexts(codecHalSettings));
601 // Set Vdbox index in use
602 m_vdboxIndex = (m_videoGpuNode == MOS_GPU_NODE_VIDEO2)? MHW_VDBOX_NODE_2 : MHW_VDBOX_NODE_1;
603
604 // Set FrameCrc reg offset
605 if (m_standard == CODECHAL_HEVC || m_standard == CODECHAL_VP9)
606 {
607 m_hcpFrameCrcRegOffset = m_hcpInterface->GetMmioRegisters(m_vdboxIndex)->hcpFrameCrcRegOffset;
608 }
609 }
610
611 if (!m_mmc)
612 {
613 m_mmc = MOS_New(CodecHalMmcState, m_hwInterface);
614 CODECHAL_DECODE_CHK_NULL_RETURN(m_mmc);
615 }
616
617 if (codecHalSettings->secureMode)
618 {
619 m_secureDecoder = m_osInterface->pfnCreateSecureDecodeInterface(codecHalSettings, m_hwInterface);
620 }
621
622 #ifdef _DECODE_PROCESSING_SUPPORTED
623 m_downsamplingHinted = codecHalSettings->downsamplingHinted ? true : false;
624 if (CodecHalIsEnableFieldScaling(codecHalSettings->codecFunction, m_standard, m_downsamplingHinted))
625 {
626 CODECHAL_DECODE_CHK_NULL_RETURN(m_fieldScalingInterface);
627 CODECHAL_DECODE_CHK_STATUS_RETURN(m_fieldScalingInterface->InitializeKernelState(
628 this,
629 m_hwInterface,
630 m_osInterface));
631 }
632 #endif
633
634 m_renderContextUsesNullHw = m_useNullHw[m_renderContext];
635 if(!m_isHybridDecoder)
636 {
637 m_videoContextUsesNullHw = m_useNullHw[m_videoContext];
638 m_videoContextForWaUsesNullHw = m_useNullHw[m_videoContextForWa];
639
640 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnRegisterBBCompleteNotifyEvent(
641 m_osInterface,
642 m_videoContext));
643 }
644
645 if (!m_perfProfiler)
646 {
647 m_perfProfiler = MediaPerfProfiler::Instance();
648 CODECHAL_DECODE_CHK_NULL_RETURN(m_perfProfiler);
649
650 CODECHAL_DECODE_CHK_STATUS_RETURN(m_perfProfiler->Initialize((void*)this, m_osInterface));
651 }
652
653 return eStatus;
654 }
655
AllocateRefSurfaces(uint32_t allocWidth,uint32_t allocHeight,MOS_FORMAT format)656 MOS_STATUS CodechalDecode::AllocateRefSurfaces(
657 uint32_t allocWidth,
658 uint32_t allocHeight,
659 MOS_FORMAT format)
660 {
661 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
662
663 CODECHAL_DECODE_FUNCTION_ENTER;
664
665 if (allocWidth == 0 || allocHeight == 0)
666 {
667 CODECHAL_DECODE_ASSERTMESSAGE("Invalid Downsampling Reference Frame Width or Height !");
668 return MOS_STATUS_INVALID_PARAMETER;
669 }
670
671 m_refSurfaces = (MOS_SURFACE*)MOS_AllocAndZeroMemory(sizeof(MOS_SURFACE) * m_refFrmCnt);
672 CODECHAL_DECODE_CHK_NULL_RETURN(m_refSurfaces);
673
674 CODECHAL_DEBUG_TOOL(
675 m_downsampledSurfaces = (MOS_SURFACE*)MOS_AllocAndZeroMemory(m_refFrmCnt * sizeof(MOS_SURFACE));
676 )
677
678 for (uint32_t i = 0; i < m_refFrmCnt; i++)
679 {
680 eStatus = AllocateSurface(
681 &m_refSurfaces[i],
682 allocWidth,
683 allocHeight,
684 "DownsamplingRefSurface",
685 format,
686 m_mmc->IsMmcEnabled());
687
688 if (eStatus != MOS_STATUS_SUCCESS)
689 {
690 CODECHAL_DECODE_ASSERTMESSAGE("Failed to allocate decode downsampling reference surface.");
691 DeallocateRefSurfaces();
692 return eStatus;
693 }
694 }
695
696 return MOS_STATUS_SUCCESS;
697 }
698
isSyncFreeNeededForMMCSurface(PMOS_SURFACE surface)699 bool CodechalDecode::isSyncFreeNeededForMMCSurface(PMOS_SURFACE surface)
700 {
701 if (nullptr == surface || nullptr == m_osInterface)
702 {
703 return false;
704 }
705 //Compressed surface aux table update is after resource dealloction, aux table update need wait the WLs complete
706 //the sync deallocation flag will make sure deallocation API return after all surface related WL been completed and resource been destroyed by OS
707 auto *pSkuTable = m_hwInterface->GetSkuTable();
708 GMM_RESOURCE_FLAG gmmFlags;
709 bool hasAuxSurf = false;
710 gmmFlags = (&surface->OsResource)->pGmmResInfo->GetResFlags();
711 hasAuxSurf = (gmmFlags.Gpu.CCS || gmmFlags.Info.MediaCompressed) && gmmFlags.Gpu.UnifiedAuxSurface;
712
713 if (pSkuTable &&
714 MEDIA_IS_SKU(pSkuTable, FtrE2ECompression) && //Compression enabled platform
715 !MEDIA_IS_SKU(pSkuTable, FtrFlatPhysCCS) && //NOT DGPU compression
716 (surface->bCompressible) && ((surface->CompressionMode != MOS_MMC_DISABLED) || hasAuxSurf)) //Compressed enabled surface
717 {
718 return true;
719 }
720
721 return false;
722 }
723
DestroySurface(PMOS_SURFACE surface)724 MOS_STATUS CodechalDecode::DestroySurface(PMOS_SURFACE surface)
725 {
726 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
727 MOS_GFXRES_FREE_FLAGS resFreeFlags = {0};
728
729 CODECHAL_DECODE_FUNCTION_ENTER;
730
731 if (nullptr == surface)
732 {
733 return MOS_STATUS_SUCCESS;
734 }
735
736 if (surface && isSyncFreeNeededForMMCSurface(surface))
737 {
738 resFreeFlags.SynchronousDestroy = 1;
739 CODECHAL_DECODE_NORMALMESSAGE("Set SynchronousDestroy flag for compressed resource\n");
740 }
741
742 m_osInterface->pfnFreeResourceWithFlag(m_osInterface, &surface->OsResource, resFreeFlags.Value);
743 surface = nullptr;
744
745 return eStatus;
746 }
747
RefSurfacesResize(uint32_t frameIdx,uint32_t width,uint32_t height,MOS_FORMAT format)748 MOS_STATUS CodechalDecode::RefSurfacesResize(
749 uint32_t frameIdx,
750 uint32_t width,
751 uint32_t height,
752 MOS_FORMAT format)
753 {
754 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
755 CODECHAL_DECODE_FUNCTION_ENTER;
756
757 if (m_refSurfaces[frameIdx].dwWidth == 0 || m_refSurfaces[frameIdx].dwHeight == 0)
758 {
759 CODECHAL_DECODE_ASSERTMESSAGE("Invalid Downsampling Reference Frame Width or Height !");
760 return MOS_STATUS_INVALID_PARAMETER;
761 }
762
763 DeallocateSpecificRefSurfaces(frameIdx);
764
765 eStatus = AllocateSurface(
766 &m_refSurfaces[frameIdx],
767 width,
768 height,
769 "DownsamplingRefSurface",
770 format,
771 m_mmc->IsMmcEnabled());
772
773 if (eStatus != MOS_STATUS_SUCCESS)
774 {
775 CODECHAL_DECODE_ASSERTMESSAGE("Failed to allocate decode downsampling reference surface.");
776 DeallocateRefSurfaces();
777 return eStatus;
778 }
779
780 return MOS_STATUS_SUCCESS;
781 }
782
DeallocateSpecificRefSurfaces(uint32_t frameIdx)783 void CodechalDecode::DeallocateSpecificRefSurfaces(uint32_t frameIdx)
784 {
785 CODECHAL_DECODE_FUNCTION_ENTER;
786
787 if (m_refSurfaces != nullptr)
788 {
789 if (!Mos_ResourceIsNull(&m_refSurfaces[frameIdx].OsResource))
790 {
791 DestroySurface(&m_refSurfaces[frameIdx]);
792 }
793 }
794 }
795
DeallocateRefSurfaces()796 void CodechalDecode::DeallocateRefSurfaces()
797 {
798 CODECHAL_DECODE_FUNCTION_ENTER;
799
800 if (m_refSurfaces != nullptr && m_refFrmCnt != 0)
801 {
802 CODECHAL_DEBUG_TOOL(
803 MOS_FreeMemAndSetNull(m_downsampledSurfaces);
804 )
805
806 for (uint32_t i = 0; i < m_refFrmCnt; i++)
807 {
808 if (!Mos_ResourceIsNull(&m_refSurfaces[i].OsResource))
809 {
810 DestroySurface(&m_refSurfaces[i]);
811
812 }
813 }
814
815 MOS_FreeMemory(m_refSurfaces);
816 m_refSurfaces = nullptr;
817 }
818 }
819
SetDummyReference()820 MOS_STATUS CodechalDecode::SetDummyReference()
821 {
822 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
823
824 if (MEDIA_IS_WA(m_waTable, WaDummyReference))
825 {
826 // If can't find valid dummy reference, create one or use current decode output surface
827 if (Mos_ResourceIsNull(&m_dummyReference.OsResource))
828 {
829 // If MMC enabled
830 if (m_mmc != nullptr && m_mmc->IsMmcEnabled() &&
831 !m_mmc->IsMmcExtensionEnabled() &&
832 m_decodeParams.m_destSurface->bIsCompressed)
833 {
834 if (m_mode == CODECHAL_DECODE_MODE_HEVCVLD)
835 {
836 eStatus = AllocateSurface(
837 &m_dummyReference,
838 m_decodeParams.m_destSurface->dwWidth,
839 m_decodeParams.m_destSurface->dwHeight,
840 "dummy reference resource",
841 m_decodeParams.m_destSurface->Format,
842 m_decodeParams.m_destSurface->bIsCompressed);
843
844 if (eStatus != MOS_STATUS_SUCCESS)
845 {
846 CODECHAL_DECODE_ASSERTMESSAGE("Failed to create dummy reference!");
847 return eStatus;
848 }
849 else
850 {
851 m_dummyReferenceStatus = CODECHAL_DUMMY_REFERENCE_ALLOCATED;
852 CODECHAL_DECODE_VERBOSEMESSAGE("Dummy reference is created!");
853 }
854 }
855 }
856 else // Use decode output surface as dummy reference
857 {
858 m_dummyReference.OsResource = m_decodeParams.m_destSurface->OsResource;
859 m_dummyReferenceStatus = CODECHAL_DUMMY_REFERENCE_DEST_SURFACE;
860 }
861 }
862 }
863
864 return eStatus;
865 }
866
~CodechalDecode()867 CodechalDecode::~CodechalDecode()
868 {
869 CODECHAL_DECODE_FUNCTION_ENTER;
870
871 if (m_osInterface)
872 {
873 m_osInterface->pfnDeleteSecureDecodeInterface(m_secureDecoder);
874 m_secureDecoder = nullptr;
875 }
876 else
877 {
878 CODECHAL_DECODE_ASSERTMESSAGE("Failed to destroy secureDecoder.");
879 }
880
881 if (m_mmc)
882 {
883 MOS_Delete(m_mmc);
884 m_mmc = nullptr;
885 }
886
887 // Destroy decode histogram
888 if (m_decodeHistogram != nullptr)
889 {
890 MOS_Delete(m_decodeHistogram);
891 m_decodeHistogram = nullptr;
892 }
893 if (m_decodeOutputBuf != nullptr)
894 {
895 MOS_DeleteArray(m_decodeOutputBuf);
896 m_decodeOutputBuf = nullptr;
897 }
898 if (MEDIA_IS_SKU(m_skuTable, FtrVcs2) && (m_videoGpuNode < MOS_GPU_NODE_MAX))
899 {
900 // Destroy decode video node association
901 if (m_osInterface)
902 {
903 m_osInterface->pfnDestroyVideoNodeAssociation(m_osInterface, m_videoGpuNode);
904 }
905 }
906
907 if (m_statusQueryReportingEnabled && m_osInterface)
908 {
909 m_osInterface->pfnUnlockResource(
910 m_osInterface,
911 &(m_decodeStatusBuf.m_statusBuffer));
912
913 m_osInterface->pfnFreeResource(
914 m_osInterface,
915 &(m_decodeStatusBuf.m_statusBuffer));
916
917 if (m_streamOutEnabled)
918 {
919 for (auto i = 0; i < CODECHAL_DECODE_NUM_STREAM_OUT_BUFFERS; i++)
920 {
921 m_osInterface->pfnFreeResource(
922 m_osInterface,
923 &(m_streamOutBuffer[i]));
924 }
925 }
926 }
927
928 if (m_gpuCtxCreatOpt)
929 {
930 MOS_Delete(m_gpuCtxCreatOpt);
931 }
932
933 if (m_osInterface)
934 {
935 m_osInterface->pfnFreeResource(
936 m_osInterface,
937 &m_predicationBuffer);
938
939 m_osInterface->pfnFreeResource(
940 m_osInterface,
941 &m_frameCountTypeBuf);
942
943 m_osInterface->pfnFreeResource(
944 m_osInterface,
945 &m_crcBuf);
946 }
947
948 if (m_pCodechalOcaDumper)
949 {
950 MOS_Delete(m_pCodechalOcaDumper);
951 }
952
953 #if (_DEBUG || _RELEASE_INTERNAL) && (!WDDM_LINUX)
954 m_debugInterface->PackGoldenReferences({m_debugInterface->GetCrcGoldenReference()});
955 m_debugInterface->DumpGoldenReference();
956 #endif
957
958 DeallocateRefSurfaces();
959
960 #ifdef _DECODE_PROCESSING_SUPPORTED
961 if (CodecHalIsEnableFieldScaling(CODECHAL_FUNCTION_DECODE, m_standard, m_downsamplingHinted))
962 {
963 if (m_fieldScalingInterface != nullptr)
964 {
965 MOS_Delete(m_fieldScalingInterface);
966 m_fieldScalingInterface = nullptr;
967 }
968 }
969 #endif
970
971 if (m_perfProfiler)
972 {
973 MediaPerfProfiler::Destroy(m_perfProfiler, (void*)this, m_osInterface);
974 m_perfProfiler = nullptr;
975 }
976
977 if (m_dummyReferenceStatus == CODECHAL_DUMMY_REFERENCE_ALLOCATED &&
978 !Mos_ResourceIsNull(&m_dummyReference.OsResource) &&
979 m_osInterface)
980 {
981 m_osInterface->pfnFreeResource(m_osInterface, &m_dummyReference.OsResource);
982 }
983
984 if (m_hwInterface)
985 {
986 MOS_Delete(m_hwInterface);
987 Codechal::m_hwInterface = nullptr;
988 }
989 }
990
CalcRequestedSpace(uint32_t & requestedSize,uint32_t & additionalSizeNeeded,uint32_t & requestedPatchListSize)991 void CodechalDecode::CalcRequestedSpace(
992 uint32_t &requestedSize,
993 uint32_t &additionalSizeNeeded,
994 uint32_t &requestedPatchListSize)
995 {
996 requestedSize = m_commandBufferSizeNeeded +
997 (m_standardDecodeSizeNeeded * (m_decodeParams.m_numSlices + 1));
998 requestedPatchListSize = m_commandPatchListSizeNeeded +
999 (m_standardDecodePatchListSizeNeeded * (m_decodeParams.m_numSlices + 1));
1000 additionalSizeNeeded = COMMAND_BUFFER_RESERVED_SPACE;
1001 }
1002
VerifySpaceAvailable()1003 MOS_STATUS CodechalDecode::VerifySpaceAvailable ()
1004 {
1005 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1006
1007 CODECHAL_DECODE_FUNCTION_ENTER;
1008
1009 uint32_t requestedSize = 0, additionalSizeNeeded = 0, requestedPatchListSize = 0;
1010 CalcRequestedSpace(requestedSize, additionalSizeNeeded, requestedPatchListSize);
1011
1012 uint32_t primRequestedSize = RequestedSpaceSize(requestedSize);
1013
1014 // Try a maximum of 3 attempts to request the required sizes from OS
1015 // OS could reset the sizes if necessary, therefore, requires to re-verify
1016 for (auto i = 0; i < 3; i++)
1017 {
1018 if (m_osInterface->bUsesPatchList || MEDIA_IS_SKU(m_skuTable, FtrMediaPatchless))
1019 {
1020 eStatus = (MOS_STATUS)m_osInterface->pfnVerifyPatchListSize(
1021 m_osInterface,
1022 requestedPatchListSize);
1023
1024 if (eStatus != MOS_STATUS_SUCCESS)
1025 {
1026 CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->ResizeCommandBufferAndPatchList(
1027 0,
1028 requestedPatchListSize));
1029 }
1030 }
1031
1032 eStatus = (MOS_STATUS)m_osInterface->pfnVerifyCommandBufferSize(
1033 m_osInterface,
1034 primRequestedSize,
1035 0);
1036
1037 if (eStatus == MOS_STATUS_SUCCESS)
1038 {
1039 break;
1040 }
1041 else
1042 {
1043 CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->ResizeCommandBufferAndPatchList(
1044 primRequestedSize + additionalSizeNeeded,
1045 0));
1046 }
1047 }
1048
1049 CODECHAL_DECODE_CHK_STATUS_RETURN(VerifyExtraSpace(requestedSize, additionalSizeNeeded));
1050
1051 return eStatus;
1052 }
1053
EndFrame()1054 MOS_STATUS CodechalDecode::EndFrame ()
1055 {
1056 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1057
1058 CODECHAL_DECODE_FUNCTION_ENTER;
1059
1060 CODECHAL_DEBUG_TOOL(
1061 CodechalDecodeStatusReport * decodeStatusReport;
1062 auto tempSurfNum = m_debugInterface->m_decodeSurfDumpFrameNum; // to handle BB_END data not written case
1063 uint16_t preIndex = m_debugInterface->m_preIndex;
1064 uint32_t numReportsAvailable = (m_decodeStatusBuf.m_currIndex - preIndex) & (CODECHAL_DECODE_STATUS_NUM - 1);
1065 CODECHAL_DECODE_VERBOSEMESSAGE("NumReportsAvailable = %d", numReportsAvailable);
1066
1067 for (uint32_t i = 0; i < numReportsAvailable; i++) {
1068 uint16_t index = (m_debugInterface->m_preIndex + i) % CODECHAL_DECODE_STATUS_NUM;
1069 decodeStatusReport =
1070 &(m_decodeStatusBuf.m_decodeStatus[index].m_decodeStatusReport);
1071
1072 // record SurfDumpFrameNum to handle BB_END data not written case
1073 if (CodecHal_PictureIsFrame(decodeStatusReport->m_currDecodedPic) ||
1074 CodecHal_PictureIsInterlacedFrame(decodeStatusReport->m_currDecodedPic) ||
1075 decodeStatusReport->m_secondField)
1076 {
1077 tempSurfNum++;
1078 }
1079
1080 if (m_standard == CODECHAL_HEVC &&
1081 m_isHybridDecoder &&
1082 (m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDecodeReferenceSurfaces) || m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDecodeOutputSurface)))
1083 {
1084 CODECHAL_DECODE_CHK_STATUS_BREAK(DecodeGetHybridStatus(
1085 m_decodeStatusBuf.m_decodeStatus, index, CODECHAL_STATUS_QUERY_START_FLAG));
1086 }
1087
1088 auto tempFrameNum = m_debugInterface->m_bufferDumpFrameNum;
1089 auto tempPic = m_debugInterface->m_currPic;
1090 auto tempFrameType = m_debugInterface->m_frameType;
1091 m_debugInterface->m_bufferDumpFrameNum = m_debugInterface->m_decodeSurfDumpFrameNum;
1092 m_debugInterface->m_currPic = decodeStatusReport->m_currDecodedPic;
1093 m_debugInterface->m_frameType = decodeStatusReport->m_frameType;
1094 bool olpDump = false;
1095
1096 MOS_SURFACE dstSurface;
1097 if ((CodecHal_PictureIsFrame(decodeStatusReport->m_currDecodedPic) ||
1098 CodecHal_PictureIsInterlacedFrame(decodeStatusReport->m_currDecodedPic) ||
1099 CodecHal_PictureIsField(decodeStatusReport->m_currDecodedPic)) &&
1100 (m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDecodeBltOutput) ||
1101 m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDecodeOutputSurface) ||
1102 m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrStreamOut)))
1103 {
1104 MOS_ZeroMemory(&dstSurface, sizeof(dstSurface));
1105 dstSurface.Format = Format_NV12;
1106 dstSurface.OsResource = decodeStatusReport->m_currDecodedPicRes;
1107 CODECHAL_DECODE_CHK_STATUS_BREAK(CodecHalGetResourceInfo(
1108 m_osInterface,
1109 &dstSurface));
1110
1111 m_debugInterface->DumpBltOutput(
1112 &dstSurface,
1113 CodechalDbgAttr::attrDecodeBltOutput);
1114
1115 CODECHAL_DECODE_CHK_STATUS_BREAK(m_debugInterface->DumpYUVSurface(
1116 &dstSurface,
1117 CodechalDbgAttr::attrDecodeOutputSurface,
1118 "DstSurf"));
1119
1120 if (m_streamOutEnabled)
1121 {
1122 //dump streamout buffer
1123 CODECHAL_DECODE_CHK_STATUS_BREAK(m_debugInterface->DumpBuffer(
1124 decodeStatusReport->m_streamOutBuf,
1125 CodechalDbgAttr::attrStreamOut,
1126 "StreamOut",
1127 dstSurface.dwWidth));
1128 // reset the capture status of the streamout buffer
1129 m_streamOutCurrStatusIdx[decodeStatusReport->m_streamoutIdx] = CODECHAL_DECODE_STATUS_NUM;
1130 }
1131
1132 olpDump = true;
1133 }
1134
1135 MOS_USER_FEATURE_VALUE_DATA userFeatureData;
1136 MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
1137 MOS_UserFeature_ReadValue_ID(
1138 nullptr,
1139 __MEDIA_USER_FEATURE_VALUE_DECOMPRESS_DECODE_OUTPUT_ID,
1140 &userFeatureData,
1141 m_osInterface->pOsContext);
1142 if (userFeatureData.u32Data)
1143 {
1144 CODECHAL_DECODE_VERBOSEMESSAGE("force ve decompress decode output");
1145 MOS_ZeroMemory(&dstSurface, sizeof(dstSurface));
1146 dstSurface.Format = Format_NV12;
1147 dstSurface.OsResource = decodeStatusReport->m_currDecodedPicRes;
1148 CODECHAL_DECODE_CHK_STATUS_BREAK(CodecHalGetResourceInfo(
1149 m_osInterface,
1150 &dstSurface));
1151 MOS_LOCK_PARAMS lockFlags {};
1152 lockFlags.ReadOnly = 1;
1153 lockFlags.TiledAsTiled = 1;
1154 lockFlags.NoDecompress = 0;
1155 m_osInterface->pfnLockResource(m_osInterface, &dstSurface.OsResource, &lockFlags);
1156 m_osInterface->pfnUnlockResource(m_osInterface, &dstSurface.OsResource);
1157 }
1158
1159 if (m_standard == CODECHAL_VC1 &&
1160 decodeStatusReport->m_olpNeeded &&
1161 olpDump &&
1162 m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDecodeOutputSurface))
1163 {
1164 MOS_ZeroMemory(&dstSurface, sizeof(dstSurface));
1165 dstSurface.Format = Format_NV12;
1166 dstSurface.OsResource = decodeStatusReport->m_deblockedPicResOlp;
1167
1168 CODECHAL_DECODE_CHK_STATUS_BREAK(CodecHalGetResourceInfo(
1169 m_osInterface,
1170 &dstSurface));
1171
1172 CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface(
1173 &dstSurface,
1174 CodechalDbgAttr::attrDecodeOutputSurface,
1175 "OLP_DstSurf"));
1176 }
1177
1178 if ((m_standard == CODECHAL_HEVC || m_standard == CODECHAL_VP9) &&
1179 (decodeStatusReport->m_currSfcOutputPicRes != nullptr) &&
1180 m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrSfcOutputSurface))
1181 {
1182 MOS_ZeroMemory(&dstSurface, sizeof(dstSurface));
1183 dstSurface.Format = Format_NV12;
1184 dstSurface.OsResource = *decodeStatusReport->m_currSfcOutputPicRes;
1185
1186 CODECHAL_DECODE_CHK_STATUS_BREAK(CodecHalGetResourceInfo(
1187 m_osInterface,
1188 &dstSurface));
1189
1190 CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface(
1191 &dstSurface,
1192 CodechalDbgAttr::attrSfcOutputSurface,
1193 "SfcDstSurf"));
1194 }
1195
1196 MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
1197 MOS_UserFeature_ReadValue_ID(
1198 nullptr,
1199 __MEDIA_USER_FEATURE_VALUE_DECOMPRESS_DECODE_SFC_OUTPUT_ID,
1200 &userFeatureData,
1201 m_osInterface->pOsContext);
1202 if (userFeatureData.u32Data)
1203 {
1204 CODECHAL_DECODE_VERBOSEMESSAGE("force ve decompress sfc output");
1205 MOS_ZeroMemory(&dstSurface, sizeof(dstSurface));
1206 dstSurface.Format = Format_NV12;
1207 dstSurface.OsResource = *decodeStatusReport->m_currSfcOutputPicRes;
1208 CODECHAL_DECODE_CHK_STATUS_BREAK(CodecHalGetResourceInfo(
1209 m_osInterface,
1210 &dstSurface));
1211
1212 MOS_LOCK_PARAMS lockFlags {};
1213 lockFlags.ReadOnly = 1;
1214 lockFlags.TiledAsTiled = 1;
1215 lockFlags.NoDecompress = 0;
1216 m_osInterface->pfnLockResource(m_osInterface, &dstSurface.OsResource, &lockFlags);
1217 m_osInterface->pfnUnlockResource(m_osInterface, &dstSurface.OsResource);
1218
1219 }
1220
1221 if (CodecHal_PictureIsFrame(decodeStatusReport->m_currDecodedPic) ||
1222 CodecHal_PictureIsInterlacedFrame(decodeStatusReport->m_currDecodedPic) ||
1223 CodecHal_PictureIsField(decodeStatusReport->m_currDecodedPic))
1224 {
1225 CODECHAL_DECODE_CHK_STATUS_BREAK(m_debugInterface->DeleteCfgLinkNode(m_debugInterface->m_decodeSurfDumpFrameNum));
1226 m_debugInterface->m_decodeSurfDumpFrameNum = tempSurfNum;
1227 }
1228 m_debugInterface->m_bufferDumpFrameNum = tempFrameNum;
1229 m_debugInterface->m_currPic = tempPic;
1230 m_debugInterface->m_frameType = tempFrameType;
1231
1232 if (m_decodeStatusBuf.m_decodeStatus[index].m_hwStoredData == CODECHAL_STATUS_QUERY_END_FLAG)
1233 {
1234 // report the CS Engine ID to user feature
1235 for (auto j = 0; j < CODECHAL_CS_INSTANCE_ID_MAX; j++)
1236 {
1237 CODECHAL_CS_ENGINE_ID csEngineIdValue;
1238 csEngineIdValue.value = m_decodeStatusBuf.m_decodeStatus[index].m_mmioCsEngineIdReg[j];
1239
1240 //validate the user feature value
1241 if (csEngineIdValue.value)
1242 {
1243 CODECHAL_DECODE_ASSERT(csEngineIdValue.fields.ClassId == CODECHAL_CLASS_ID_VIDEO_ENGINE);
1244 CODECHAL_DECODE_ASSERT(csEngineIdValue.fields.InstanceId < CODECHAL_CS_INSTANCE_ID_MAX);
1245 CODECHAL_UPDATE_USED_VDBOX_ID_USER_FEATURE(csEngineIdValue.fields.InstanceId, m_osInterface->pOsContext);
1246 }
1247 }
1248 preIndex = index + 1;
1249 }
1250 }
1251
1252 m_debugInterface->m_preIndex = preIndex;
1253 )
1254
1255 if (m_consecutiveMbErrorConcealmentInUse &&
1256 m_incompletePicture)
1257 {
1258 CODECHAL_DECODE_VERBOSEMESSAGE("Processing incomplete frame MBs");
1259
1260 if (!m_isHybridDecoder)
1261 {
1262 m_osInterface->pfnSetGpuContext(m_osInterface, m_videoContext);
1263 }
1264
1265 m_decodePhantomMbs = true;
1266
1267 CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(DecodePrimitiveLevel(),
1268 "Primitive level decoding failed.");
1269 }
1270
1271 DecodeFrameIndex++;
1272 m_frameNum = DecodeFrameIndex;
1273
1274 m_decodePhantomMbs = false;
1275
1276 return eStatus;
1277 }
1278
Execute(void * params)1279 MOS_STATUS CodechalDecode::Execute(void *params)
1280 {
1281 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1282
1283 PERF_UTILITY_AUTO(__FUNCTION__, PERF_DECODE, PERF_LEVEL_HAL);
1284
1285 CODECHAL_DECODE_FUNCTION_ENTER;
1286
1287 CODECHAL_DECODE_CHK_STATUS_RETURN(Codechal::Execute(params));
1288
1289 CodechalDecodeParams *decodeParams = (CodechalDecodeParams *)params;
1290 m_executeCallIndex = decodeParams->m_executeCallIndex;
1291
1292 // MSDK event handling
1293 Mos_Solo_SetGpuAppTaskEvent(m_osInterface, decodeParams->m_gpuAppTaskEvent);
1294
1295 #if (_DEBUG || _RELEASE_INTERNAL)
1296
1297 MOS_TraceEvent(EVENT_CODEC_DECODE, EVENT_TYPE_START, &m_standard, sizeof(uint32_t), &m_frameNum, sizeof(uint32_t));
1298
1299 #endif // _DEBUG || _RELEASE_INTERNAL
1300
1301 CODECHAL_DEBUG_TOOL(
1302 m_debugInterface->m_bufferDumpFrameNum = m_frameNum;)
1303
1304 if (m_cencBuf!= nullptr)
1305 {
1306 CODECHAL_DECODE_CHK_STATUS_RETURN(Mos_Solo_DisableAubcaptureOptimizations(
1307 m_osInterface,
1308 IsFirstExecuteCall()));
1309 }
1310
1311 #ifdef _DECODE_PROCESSING_SUPPORTED
1312 if (decodeParams->m_refFrameCnt != 0)
1313 {
1314 DecodeProcessingParams *procParams;
1315 uint32_t allocWidth;
1316 uint32_t allocHeight;
1317 MOS_FORMAT format;
1318 uint8_t frameIdx;
1319
1320 CODECHAL_DECODE_CHK_NULL_RETURN(decodeParams->m_picParams);
1321 CODECHAL_DECODE_CHK_NULL_RETURN(decodeParams->m_procParams);
1322
1323 procParams = (DecodeProcessingParams *)decodeParams->m_procParams;
1324 CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(
1325 m_osInterface,
1326 procParams->m_outputSurface));
1327
1328 if (procParams->m_isSourceSurfAllocated)
1329 {
1330 procParams->m_outputSurfaceRegion.m_width = procParams->m_outputSurface->dwWidth;
1331 procParams->m_outputSurfaceRegion.m_height = procParams->m_outputSurface->dwHeight;
1332 frameIdx = 0;
1333
1334 m_refSurfaces = procParams->m_inputSurface;
1335 CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(
1336 m_osInterface,
1337 m_refSurfaces));
1338
1339 procParams->m_inputSurfaceRegion.m_x = 0;
1340 procParams->m_inputSurfaceRegion.m_y = 0;
1341 procParams->m_inputSurfaceRegion.m_width = m_refSurfaces->dwWidth;
1342 procParams->m_inputSurfaceRegion.m_height = m_refSurfaces->dwHeight;
1343 }
1344 else
1345 {
1346 CODECHAL_DECODE_CHK_STATUS_RETURN(CalcDownsamplingParams(
1347 decodeParams->m_picParams, &allocWidth, &allocHeight, &format, &frameIdx));
1348
1349 if (frameIdx >= decodeParams->m_refFrameCnt)
1350 {
1351 CODECHAL_DECODE_ASSERTMESSAGE("Invalid Downsampling Reference Frame Index !");
1352 return MOS_STATUS_INVALID_PARAMETER;
1353 }
1354
1355 if (m_refSurfaces == nullptr)
1356 {
1357 m_refFrmCnt = decodeParams->m_refFrameCnt;
1358 CODECHAL_DECODE_CHK_STATUS_RETURN(AllocateRefSurfaces(allocWidth, allocHeight, format));
1359 }
1360 else
1361 {
1362 PMOS_SURFACE currSurface = &m_refSurfaces[frameIdx];
1363 if (currSurface->dwHeight < allocHeight || currSurface->dwWidth < allocWidth)
1364 {
1365 CODECHAL_DECODE_CHK_STATUS_RETURN(RefSurfacesResize(frameIdx, allocWidth, allocHeight, format));
1366 }
1367 }
1368
1369 procParams->m_inputSurfaceRegion.m_x = 0;
1370 procParams->m_inputSurfaceRegion.m_y = 0;
1371 procParams->m_inputSurfaceRegion.m_width = allocWidth;
1372 procParams->m_inputSurfaceRegion.m_height = allocHeight;
1373
1374 procParams->m_inputSurface = &m_refSurfaces[frameIdx];
1375 }
1376 decodeParams->m_destSurface = &m_refSurfaces[frameIdx];
1377 }
1378 #endif
1379 m_decodeParams = *decodeParams;
1380
1381 CODECHAL_DECODE_CHK_STATUS_RETURN(Mos_Solo_PreProcessDecode(
1382 m_osInterface,
1383 m_decodeParams.m_destSurface));
1384
1385 CODECHAL_DECODE_CHK_STATUS_RETURN(m_cpInterface->UpdateParams(true));
1386
1387 CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(
1388 m_osInterface,
1389 decodeParams->m_destSurface));
1390
1391 if(!m_isHybridDecoder)
1392 {
1393 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSetGpuContext(
1394 m_osInterface,
1395 m_videoContext));
1396 }
1397 if (!m_incompletePicture)
1398 {
1399 m_osInterface->pfnResetOsStates(m_osInterface);
1400 }
1401
1402 CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(SetFrameStates(),
1403 "Decoding initialization failed.");
1404
1405 CODECHAL_DECODE_CHK_STATUS_RETURN(VerifySpaceAvailable());
1406
1407 CODECHAL_DECODE_CHK_STATUS_RETURN(SetDummyReference());
1408
1409 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->SetWatchdogTimerThreshold(m_width, m_height, false));
1410
1411 if ((!m_incompletePicture) && (!m_isHybridDecoder))
1412 {
1413 m_osInterface->pfnIncPerfFrameID(m_osInterface);
1414 m_osInterface->pfnSetPerfTag(
1415 m_osInterface,
1416 (uint16_t)(((m_mode << 4) & 0xF0) | (m_perfType & 0xF)));
1417 m_osInterface->pfnResetPerfBufferID(m_osInterface);
1418 }
1419
1420 CODECHAL_DEBUG_TOOL(
1421
1422 if (decodeParams->m_dataBuffer &&
1423 (m_standard != CODECHAL_JPEG && m_cencBuf == nullptr) &&
1424 !(m_standard == CODECHAL_HEVC && m_isHybridDecoder) &&
1425 !(m_standard == CODECHAL_HEVC && (m_incompletePicture || !IsFirstExecuteCall())))
1426 {
1427 if (m_mode == CODECHAL_DECODE_MODE_MPEG2VLD ||
1428 m_mode == CODECHAL_DECODE_MODE_VC1VLD ||
1429 m_mode == CODECHAL_DECODE_MODE_AVCVLD ||
1430 m_mode == CODECHAL_DECODE_MODE_VP8VLD ||
1431 m_mode == CODECHAL_DECODE_MODE_HEVCVLD ||
1432 m_mode == CODECHAL_DECODE_MODE_VP9VLD)
1433 {
1434 CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
1435 decodeParams->m_dataBuffer,
1436 CodechalDbgAttr::attrDecodeBitstream,
1437 "_DEC",
1438 decodeParams->m_dataSize,
1439 decodeParams->m_dataOffset,
1440 CODECHAL_NUM_MEDIA_STATES
1441 ));
1442 }
1443 else
1444 {
1445 // Dump ResidualDifference
1446 CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
1447 decodeParams->m_dataBuffer,
1448 CodechalDbgAttr::attrResidualDifference,
1449 "_DEC",
1450 decodeParams->m_dataSize));
1451 }
1452 }
1453 )
1454 #ifdef _DECODE_PROCESSING_SUPPORTED
1455 CODECHAL_DEBUG_TOOL(
1456
1457 if (decodeParams->m_procParams)
1458 {
1459 CODECHAL_DECODE_CHK_STATUS_RETURN(DumpProcessingParams(
1460 (DecodeProcessingParams *)decodeParams->m_procParams));
1461 }
1462 )
1463 #endif
1464 for(auto i = 0; i < m_decodePassNum; i++)
1465 {
1466 if (!m_incompletePicture)
1467 {
1468 CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(DecodeStateLevel(),
1469 "State level decoding failed.");
1470 }
1471
1472 CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(DecodePrimitiveLevel(),
1473 "Primitive level decoding failed.");
1474 }
1475
1476 if (m_secureDecoder != nullptr)
1477 {
1478 CODECHAL_DECODE_CHK_STATUS_RETURN(m_secureDecoder->UpdateHuCStreamoutBufferIndex());
1479 }
1480
1481 *decodeParams = m_decodeParams;
1482
1483 if (m_decodeHistogram != nullptr)
1484 {
1485 CODECHAL_DECODE_CHK_STATUS_RETURN(m_decodeHistogram->RenderHistogram(this, m_decodeParams.m_destSurface));
1486 }
1487
1488 //#if (_DEBUG || _RELEASE_INTERNAL)
1489 //#ifdef _MD5_DEBUG_SUPPORTED
1490 // if (CodecHal_PictureIsFrame(m_debugInterface->CurrPic) ||
1491 // CodecHal_PictureIsInterlacedFrame(m_debugInterface->CurrPic) ||
1492 // m_debugInterface->bSecondField ||
1493 // m_isHybridDecoder)
1494 // {
1495 // if (m_debugInterface->pMD5Context != nullptr)
1496 // {
1497 // if (m_debugInterface->bMD5DDIThreadExecute)
1498 // {
1499 // //calculate md5 hash for each RT surface
1500 // CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHal_DbgExecuteMD5Hash(
1501 // m_debugInterface,
1502 // &decodeParams->m_destSurface->OsResource,
1503 // nullptr,
1504 // 0,
1505 // 0));
1506 // }
1507 // }
1508 // }
1509 //#endif // _MD5_DEBUG_SUPPORTED
1510 //#endif // _DEBUG || _RELEASE_INTERNAL
1511
1512 CODECHAL_DEBUG_TOOL(
1513 if (CodecHal_PictureIsFrame(m_debugInterface->m_currPic) ||
1514 CodecHal_PictureIsInterlacedFrame(m_debugInterface->m_currPic) ||
1515 m_debugInterface->m_secondField) {
1516 if (!m_statusQueryReportingEnabled)
1517 {
1518 CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DeleteCfgLinkNode(m_debugInterface->m_bufferDumpFrameNum));
1519 }
1520 })
1521
1522 if (CodecHal_PictureIsFrame(m_crrPic) ||
1523 CodecHal_PictureIsInterlacedFrame(m_crrPic) ||
1524 m_secondField)
1525 {
1526 #if (_DEBUG || _RELEASE_INTERNAL)
1527 if (m_debugInterface->IsHwDebugHooksEnable())
1528 {
1529 CodecHalGetResourceInfo(m_osInterface, decodeParams->m_destSurface);
1530 uint32_t yuvSize = 0;
1531
1532 CheckDecodeOutputBufSize(*decodeParams->m_destSurface);
1533 if (!m_debugInterface->m_swCRC) //HW CRC
1534 {
1535 uint32_t curIdx = (m_decodeStatusBuf.m_currIndex + CODECHAL_DECODE_STATUS_NUM - 1) % CODECHAL_DECODE_STATUS_NUM;
1536 while (true)
1537 {
1538 uint32_t globalHWStoredData = *(m_decodeStatusBuf.m_data);
1539 uint32_t globalCount = m_decodeStatusBuf.m_swStoreData - globalHWStoredData;
1540 uint32_t localCount = m_decodeStatusBuf.m_decodeStatus[curIdx].m_swStoredData - globalHWStoredData;
1541 if (localCount == 0 || localCount > globalCount) //Decode OK
1542 {
1543 m_debugInterface->CaptureGoldenReference(m_decodeOutputBuf, yuvSize, m_decodeStatusBuf.m_decodeStatus[curIdx].m_mmioFrameCrcReg);
1544 break;
1545 }
1546 MosUtilities::MosSleep(1);
1547 }
1548 }
1549 else //sw crc
1550 {
1551 m_debugInterface->DumpYUVSurfaceToBuffer(decodeParams->m_destSurface,
1552 m_decodeOutputBuf,
1553 yuvSize);
1554 m_debugInterface->CaptureGoldenReference(m_decodeOutputBuf, yuvSize, 0);
1555 std::vector<MOS_RESOURCE> vRes = {m_crcBuf};
1556 m_debugInterface->DetectCorruptionSw(vRes, &m_frameCountTypeBuf, m_decodeOutputBuf, yuvSize, m_frameNum);
1557 }
1558 }
1559 #endif
1560 }
1561
1562 CODECHAL_DECODE_CHK_STATUS_RETURN(Mos_Solo_PostProcessDecode(m_osInterface, m_decodeParams.m_destSurface));
1563
1564 #if (_DEBUG || _RELEASE_INTERNAL)
1565
1566 MOS_TraceEvent(EVENT_CODEC_DECODE, EVENT_TYPE_END, &eStatus, sizeof(eStatus), nullptr, 0);
1567
1568 #endif // _DEBUG || _RELEASE_INTERNAL
1569
1570 return eStatus;
1571 }
1572
StartStatusReport(PMOS_COMMAND_BUFFER cmdBuffer)1573 MOS_STATUS CodechalDecode::StartStatusReport(
1574 PMOS_COMMAND_BUFFER cmdBuffer)
1575 {
1576 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1577
1578 CODECHAL_DECODE_FUNCTION_ENTER;
1579
1580 CODECHAL_DECODE_CHK_NULL_RETURN(cmdBuffer);
1581
1582 uint32_t offset =
1583 (m_decodeStatusBuf.m_currIndex * sizeof(CodechalDecodeStatus)) +
1584 m_decodeStatusBuf.m_storeDataOffset +
1585 sizeof(uint32_t) * 2;
1586
1587 MHW_MI_STORE_DATA_PARAMS params;
1588 params.pOsResource = &m_decodeStatusBuf.m_statusBuffer;
1589 params.dwResourceOffset = offset;
1590 params.dwValue = CODECHAL_STATUS_QUERY_START_FLAG;
1591
1592 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreDataImmCmd(
1593 cmdBuffer,
1594 ¶ms));
1595
1596 CODECHAL_DECODE_CHK_STATUS_RETURN(m_perfProfiler->AddPerfCollectStartCmd((void *)this, m_osInterface, m_miInterface, cmdBuffer));
1597 CODECHAL_DECODE_CHK_STATUS_RETURN(NullHW::StartPredicate(m_osInterface, m_miInterface, cmdBuffer));
1598
1599 return eStatus;
1600 }
1601
StopExecutionAtFrame(CodechalHwInterface * hwInterface,PMOS_RESOURCE statusBuffer,PMOS_COMMAND_BUFFER pCmdBuffer,uint32_t numFrame)1602 MOS_STATUS StopExecutionAtFrame(CodechalHwInterface *hwInterface, PMOS_RESOURCE statusBuffer, PMOS_COMMAND_BUFFER pCmdBuffer, uint32_t numFrame)
1603 {
1604 CODECHAL_DECODE_ASSERTMESSAGE("Will stop to frame: %d!!!", numFrame);
1605
1606 CODECHAL_DECODE_CHK_STATUS_RETURN(hwInterface->SendHwSemaphoreWaitCmd(
1607 statusBuffer,
1608 0x7f7f7f7f,
1609 MHW_MI_SAD_EQUAL_SDD,
1610 pCmdBuffer));
1611 return MOS_STATUS_SUCCESS;
1612 }
1613
EndStatusReport(CodechalDecodeStatusReport & decodeStatusReport,PMOS_COMMAND_BUFFER cmdBuffer)1614 MOS_STATUS CodechalDecode::EndStatusReport(
1615 CodechalDecodeStatusReport &decodeStatusReport,
1616 PMOS_COMMAND_BUFFER cmdBuffer)
1617 {
1618 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1619
1620 CODECHAL_DECODE_FUNCTION_ENTER;
1621
1622 CODECHAL_DECODE_CHK_COND_RETURN((m_vdboxIndex > m_mfxInterface->GetMaxVdboxIndex()),
1623 "ERROR - vdbox index exceed the maximum");
1624 auto mmioRegistersMfx = m_hwInterface->SelectVdboxAndGetMmioRegister(m_vdboxIndex, cmdBuffer);
1625 auto mmioRegistersHcp = m_hcpInterface ? m_hcpInterface->GetMmioRegisters(m_vdboxIndex) : nullptr;
1626
1627 CODECHAL_DECODE_CHK_STATUS_RETURN(NullHW::StopPredicate(m_osInterface, m_miInterface, cmdBuffer));
1628
1629 uint32_t currIndex = m_decodeStatusBuf.m_currIndex;
1630 //Error Status report
1631 uint32_t errStatusOffset =
1632 currIndex * sizeof(CodechalDecodeStatus) +
1633 m_decodeStatusBuf.m_decErrorStatusOffset +
1634 sizeof(uint32_t) * 2;
1635
1636 MHW_MI_STORE_REGISTER_MEM_PARAMS regParams;
1637 MOS_ZeroMemory(®Params, sizeof(regParams));
1638
1639 regParams.presStoreBuffer = &m_decodeStatusBuf.m_statusBuffer;
1640 regParams.dwOffset = errStatusOffset;
1641 regParams.dwRegister = ((m_standard == CODECHAL_HEVC || m_standard == CODECHAL_VP9) && mmioRegistersHcp) ?
1642 mmioRegistersHcp->hcpCabacStatusRegOffset : mmioRegistersMfx->mfxErrorFlagsRegOffset;
1643 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreRegisterMemCmd(
1644 cmdBuffer,
1645 ®Params));
1646
1647 //Frame CRC
1648 if (m_reportFrameCrc)
1649 {
1650 uint32_t frameCrcOffset =
1651 currIndex * sizeof(CodechalDecodeStatus) +
1652 m_decodeStatusBuf.m_decFrameCrcOffset +
1653 sizeof(uint32_t) * 2;
1654
1655 regParams.presStoreBuffer = &m_decodeStatusBuf.m_statusBuffer;
1656 regParams.dwOffset = frameCrcOffset;
1657 if (m_standard == CODECHAL_AVC || m_standard == CODECHAL_VC1 || m_standard == CODECHAL_MPEG2 || m_standard == CODECHAL_JPEG)
1658 {
1659 regParams.dwRegister = mmioRegistersMfx->mfxFrameCrcRegOffset;
1660 }
1661 else if(m_standard == CODECHAL_HEVC || m_standard == CODECHAL_VP9)
1662 {
1663 CODECHAL_DECODE_CHK_NULL_RETURN(mmioRegistersHcp);
1664 regParams.dwRegister = mmioRegistersHcp->hcpFrameCrcRegOffset;
1665 }
1666
1667 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreRegisterMemCmd(
1668 cmdBuffer,
1669 ®Params));
1670 }
1671
1672 //MB Count
1673 uint32_t mbCountOffset =
1674 currIndex * sizeof(CodechalDecodeStatus) +
1675 m_decodeStatusBuf.m_decMBCountOffset +
1676 sizeof(uint32_t) * 2;
1677
1678 regParams.presStoreBuffer = &m_decodeStatusBuf.m_statusBuffer;
1679 regParams.dwOffset = mbCountOffset;
1680 regParams.dwRegister = ((m_standard == CODECHAL_HEVC || m_standard == CODECHAL_VP9) && mmioRegistersHcp) ?
1681 mmioRegistersHcp->hcpDecStatusRegOffset : mmioRegistersMfx->mfxMBCountRegOffset;
1682 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreRegisterMemCmd(
1683 cmdBuffer,
1684 ®Params));
1685
1686 // First copy all the SW data in to the eStatus buffer
1687 m_decodeStatusBuf.m_decodeStatus[currIndex].m_swStoredData = m_decodeStatusBuf.m_swStoreData;
1688 m_decodeStatusBuf.m_decodeStatus[currIndex].m_decodeStatusReport = decodeStatusReport;
1689
1690 uint32_t storeDataOffset =
1691 currIndex * sizeof(CodechalDecodeStatus) +
1692 m_decodeStatusBuf.m_storeDataOffset +
1693 sizeof(uint32_t) * 2;
1694
1695 MHW_MI_STORE_DATA_PARAMS dataParams;
1696 dataParams.pOsResource = &m_decodeStatusBuf.m_statusBuffer;
1697 dataParams.dwResourceOffset = storeDataOffset;
1698 dataParams.dwValue = CODECHAL_STATUS_QUERY_END_FLAG;
1699
1700 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreDataImmCmd(
1701 cmdBuffer,
1702 &dataParams));
1703
1704 m_decodeStatusBuf.m_currIndex = (m_decodeStatusBuf.m_currIndex + 1) % CODECHAL_DECODE_STATUS_NUM;
1705
1706 CodechalDecodeStatus *decodeStatus = &m_decodeStatusBuf.m_decodeStatus[m_decodeStatusBuf.m_currIndex];
1707 MOS_ZeroMemory(decodeStatus, sizeof(CodechalDecodeStatus));
1708
1709 CODECHAL_DECODE_CHK_STATUS_RETURN(m_perfProfiler->AddPerfCollectEndCmd((void*)this, m_osInterface, m_miInterface, cmdBuffer));
1710 if (!m_osInterface->bEnableKmdMediaFrameTracking && m_osInterface->bInlineCodecStatusUpdate)
1711 {
1712 MHW_MI_FLUSH_DW_PARAMS flushDwParams;
1713 // Send MI_FLUSH with protection bit off, which will FORCE exit protected mode for MFX
1714 MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
1715 flushDwParams.bVideoPipelineCacheInvalidate = true;
1716 flushDwParams.pOsResource = &m_decodeStatusBuf.m_statusBuffer;
1717 flushDwParams.dwDataDW1 = m_decodeStatusBuf.m_swStoreData;
1718 MHW_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(
1719 cmdBuffer,
1720 &flushDwParams));
1721 }
1722
1723 #if (_DEBUG || _RELEASE_INTERNAL)
1724 if (m_debugInterface->GetStopFrameNumber() == m_frameNum)
1725 {
1726 StopExecutionAtFrame(m_hwInterface, &GetDecodeStatusBuf()->m_statusBuffer, cmdBuffer, m_frameNum); //Hang at specific frame.
1727 }
1728 #endif
1729
1730 return eStatus;
1731 }
1732
ResetStatusReport(bool nullHwInUse)1733 MOS_STATUS CodechalDecode::ResetStatusReport(
1734 bool nullHwInUse)
1735 {
1736 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1737
1738 CODECHAL_DECODE_FUNCTION_ENTER;
1739
1740 if (!m_osInterface->bEnableKmdMediaFrameTracking &&
1741 !m_osInterface->bInlineCodecStatusUpdate)
1742 {
1743 MOS_COMMAND_BUFFER cmdBuffer;
1744 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(
1745 m_osInterface,
1746 &cmdBuffer,
1747 0));
1748
1749 // initialize command buffer attributes
1750 cmdBuffer.Attributes.bTurboMode = m_hwInterface->m_turboMode;
1751
1752 CODECHAL_DECODE_CHK_STATUS_RETURN(SendPrologWithFrameTracking(
1753 &cmdBuffer,
1754 false));
1755
1756 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(
1757 &cmdBuffer,
1758 nullptr));
1759
1760 m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
1761
1762 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(
1763 m_osInterface,
1764 &cmdBuffer,
1765 nullHwInUse));
1766 }
1767
1768 m_decodeStatusBuf.m_swStoreData++;
1769
1770 return eStatus;
1771 }
1772
GetStatusReport(void * status,uint16_t numStatus)1773 MOS_STATUS CodechalDecode::GetStatusReport(
1774 void *status,
1775 uint16_t numStatus)
1776 {
1777 uint16_t reportsGenerated = 0;
1778 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1779
1780 CODECHAL_DECODE_FUNCTION_ENTER;
1781
1782 CODECHAL_DECODE_CHK_NULL_RETURN(status);
1783 CodechalDecodeStatusReport *codecStatus = (CodechalDecodeStatusReport *)status;
1784
1785 uint32_t numReportsAvailable =
1786 (m_decodeStatusBuf.m_currIndex - m_decodeStatusBuf.m_firstIndex) &
1787 (CODECHAL_DECODE_STATUS_NUM - 1);
1788 uint32_t globalHWStoredData = *(m_decodeStatusBuf.m_data);
1789 uint32_t globalCount = m_decodeStatusBuf.m_swStoreData - globalHWStoredData;
1790
1791 CODECHAL_DECODE_VERBOSEMESSAGE(" numStatus = %d, numReportsAvailable = %d.",
1792 numStatus, numReportsAvailable);
1793 CODECHAL_DECODE_VERBOSEMESSAGE(" HWStoreData = %d, globalCount = %d",
1794 globalHWStoredData, globalCount);
1795
1796 if (numReportsAvailable < numStatus)
1797 {
1798 for (auto i = numReportsAvailable ; i < numStatus && i < CODECHAL_DECODE_STATUS_NUM ; i ++)
1799 {
1800 // These buffers are not yet received by driver. Just don't report anything back.
1801 codecStatus[i].m_codecStatus = CODECHAL_STATUS_UNAVAILABLE;
1802 }
1803
1804 numStatus = (uint16_t)numReportsAvailable;
1805 }
1806
1807 if (numReportsAvailable == 0)
1808 {
1809 CODECHAL_DECODE_ASSERTMESSAGE("No reports available, m_currIndex = %d, m_firstIndex = %d",
1810 m_decodeStatusBuf.m_currIndex,
1811 m_decodeStatusBuf.m_firstIndex);
1812 return eStatus;
1813 }
1814
1815 if (m_videoContextUsesNullHw ||
1816 m_videoContextForWaUsesNullHw ||
1817 m_renderContextUsesNullHw)
1818 {
1819 for (auto j = 0 ; j < numStatus ; j++)
1820 {
1821 uint32_t i = (m_decodeStatusBuf.m_firstIndex + numStatus - j - 1) & (CODECHAL_DECODE_STATUS_NUM - 1);
1822 codecStatus[j] = m_decodeStatusBuf.m_decodeStatus[i].m_decodeStatusReport;
1823 codecStatus[j].m_codecStatus = CODECHAL_STATUS_SUCCESSFUL;
1824 reportsGenerated++;
1825 }
1826
1827 m_decodeStatusBuf.m_firstIndex =
1828 (m_decodeStatusBuf.m_firstIndex + reportsGenerated) % CODECHAL_DECODE_STATUS_NUM;
1829
1830 return eStatus;
1831 }
1832
1833 // Report eStatus in reverse temporal order
1834 for (auto j = 0; j < numStatus; j ++)
1835 {
1836 uint32_t i = (m_decodeStatusBuf.m_firstIndex + numStatus - j - 1) & (CODECHAL_DECODE_STATUS_NUM - 1);
1837 CodechalDecodeStatusReport decodeStatusReport = m_decodeStatusBuf.m_decodeStatus[i].m_decodeStatusReport;
1838 uint32_t localCount = m_decodeStatusBuf.m_decodeStatus[i].m_swStoredData - globalHWStoredData;
1839
1840 if (m_isHybridDecoder)
1841 {
1842 codecStatus[j] = decodeStatusReport;
1843 // Consider the decode finished if the event dosen't present.
1844 CODECHAL_DECODE_CHK_STATUS_RETURN(DecodeGetHybridStatus(
1845 m_decodeStatusBuf.m_decodeStatus, i, CODECHAL_STATUS_QUERY_END_FLAG));
1846
1847 if (m_decodeStatusBuf.m_decodeStatus[i].m_hwStoredData == CODECHAL_STATUS_QUERY_END_FLAG)
1848 {
1849 codecStatus[j].m_codecStatus = CODECHAL_STATUS_SUCCESSFUL;
1850 reportsGenerated ++;
1851 }
1852 else
1853 {
1854 codecStatus[j].m_codecStatus = CODECHAL_STATUS_INCOMPLETE;
1855 }
1856 }
1857 else
1858 {
1859 if (localCount == 0 || localCount > globalCount)
1860 {
1861 codecStatus[j] = decodeStatusReport;
1862
1863 // HW execution of these commands is complete.
1864 if (m_osInterface->pfnIsGPUHung(m_osInterface))
1865 {
1866 codecStatus[j].m_codecStatus = CODECHAL_STATUS_INCOMPLETE;
1867 }
1868 else if (m_decodeStatusBuf.m_decodeStatus[i].m_hwStoredData == CODECHAL_STATUS_QUERY_END_FLAG)
1869 {
1870 // No problem in execution
1871 codecStatus[j].m_codecStatus = CODECHAL_STATUS_SUCCESSFUL;
1872
1873 if (m_standard == CODECHAL_HEVC || m_standard == CODECHAL_VP9)
1874 {
1875 if ((m_decodeStatusBuf.m_decodeStatus[i].m_mmioErrorStatusReg &
1876 m_hcpInterface->GetHcpCabacErrorFlagsMask()) != 0
1877 && ((m_decodeStatusBuf.m_decodeStatus[i].m_mmioMBCountReg & 0xFFFC0000) >> 18) != 0)
1878 {
1879 codecStatus[j].m_codecStatus = CODECHAL_STATUS_ERROR;
1880 codecStatus[j].m_numMbsAffected =
1881 (m_decodeStatusBuf.m_decodeStatus[i].m_mmioMBCountReg & 0xFFFC0000) >> 18;
1882 }
1883
1884 if (m_reportFrameCrc)
1885 {
1886 codecStatus[j].m_frameCrc = m_decodeStatusBuf.m_decodeStatus[i].m_mmioFrameCrcReg;
1887 CODECHAL_DECODE_NORMALMESSAGE("HCP CRC:: %d\n", codecStatus[j].m_frameCrc);
1888 }
1889 }
1890 else
1891 {
1892 // Check to see if decoding error occurs
1893 if (m_standard != CODECHAL_JPEG)
1894 {
1895 if ((m_decodeStatusBuf.m_decodeStatus[i].m_mmioErrorStatusReg &
1896 m_mfxInterface->GetMfxErrorFlagsMask()) != 0)
1897 {
1898 codecStatus[j].m_codecStatus = CODECHAL_STATUS_ERROR;
1899 }
1900 //MB Count bit[15:0] is error concealment MB count for none JPEG decoder.
1901 codecStatus[j].m_numMbsAffected =
1902 m_decodeStatusBuf.m_decodeStatus[i].m_mmioMBCountReg & 0xFFFF;
1903 }
1904 if (m_standard == CODECHAL_AVC)
1905 {
1906 codecStatus[j].m_frameCrc = m_decodeStatusBuf.m_decodeStatus[i].m_mmioFrameCrcReg;
1907 }
1908 }
1909 }
1910 else if (m_decodeStatusBuf.m_decodeStatus[i].m_hwStoredData == CODECHAL_STATUS_QUERY_SKIPPED)
1911 {
1912 // In the case of AVC PR3.0 it is possible to drop a batch buffer execution
1913 CODECHAL_DECODE_NORMALMESSAGE("Decode skipped.");
1914 codecStatus[j].m_codecStatus = CODECHAL_STATUS_SUCCESSFUL;
1915 }
1916 else
1917 {
1918 // BB_END data not written. Media reset might have occurred.
1919 CODECHAL_DECODE_NORMALMESSAGE("Media reset may have occured.");
1920 codecStatus[j].m_codecStatus = CODECHAL_STATUS_RESET;
1921 }
1922
1923 if (m_standard == CODECHAL_HEVC)
1924 {
1925 // Print HuC_Status and HuC_Status2 registers
1926 CODECHAL_DECODE_VERBOSEMESSAGE("Index = %d", i);
1927 CODECHAL_DECODE_VERBOSEMESSAGE("HUC_STATUS register = 0x%x",
1928 m_decodeStatusBuf.m_decodeStatus[i].m_hucErrorStatus >> 32);
1929 CODECHAL_DECODE_VERBOSEMESSAGE("HUC_STATUS2 register = 0x%x",
1930 m_decodeStatusBuf.m_decodeStatus[i].m_hucErrorStatus2 >> 32);
1931 }
1932
1933 CODECHAL_DECODE_VERBOSEMESSAGE("Incrementing reports generated to %d.",
1934 (reportsGenerated + 1));
1935 reportsGenerated ++;
1936 }
1937 else
1938 {
1939 CODECHAL_DECODE_VERBOSEMESSAGE("status buffer %d is INCOMPLETE.", j);
1940 codecStatus[j] = decodeStatusReport;
1941 codecStatus[j].m_codecStatus = CODECHAL_STATUS_INCOMPLETE;
1942 if(m_osInterface->bInlineCodecStatusUpdate)
1943 {
1944 // In Linux/Android, inline decode status reporting is enabled.
1945 // If still received CODECHAL_STATUS_INCOMPLETE,
1946 // it will be treat as GPU Hang. so need generate a report.
1947 reportsGenerated ++;
1948 }
1949 }
1950 }
1951 }
1952
1953 m_decodeStatusBuf.m_firstIndex =
1954 (m_decodeStatusBuf.m_firstIndex + reportsGenerated) % CODECHAL_DECODE_STATUS_NUM;
1955 CODECHAL_DECODE_VERBOSEMESSAGE("m_firstIndex now becomes %d.", m_decodeStatusBuf.m_firstIndex);
1956
1957 return eStatus;
1958 }
1959
CheckDecodeOutputBufSize(MOS_SURFACE & dstSurface)1960 MOS_STATUS CodechalDecode::CheckDecodeOutputBufSize(MOS_SURFACE &dstSurface)
1961 {
1962 uint32_t size = (uint32_t)dstSurface.OsResource.pGmmResInfo->GetSizeMainSurface();
1963 //Realloc if m_decodeOutputBufSize < gmm query size in case of resolution change.
1964 if (m_decodeOutputBufSize < size)
1965 {
1966 if(m_decodeOutputBuf != nullptr)
1967 {
1968 MOS_DeleteArray(m_decodeOutputBuf);
1969 m_decodeOutputBuf = MOS_NewArray(uint8_t, size);
1970 }
1971 else
1972 {
1973 m_decodeOutputBuf = MOS_NewArray(uint8_t, size);
1974 }
1975 m_decodeOutputBufSize = size;
1976 }
1977
1978 return MOS_STATUS_SUCCESS;
1979 }
AllocateDecodeOutputBuf()1980 MOS_STATUS CodechalDecode::AllocateDecodeOutputBuf()
1981 {
1982 if (m_decodeOutputBuf == nullptr)
1983 {
1984 m_decodeOutputBuf = MOS_NewArray(uint8_t, m_decodeOutputBufSize);
1985 }
1986 return MOS_STATUS_SUCCESS;
1987 }
1988
SendPrologWithFrameTracking(PMOS_COMMAND_BUFFER cmdBuffer,bool frameTrackingRequested)1989 MOS_STATUS CodechalDecode::SendPrologWithFrameTracking(
1990 PMOS_COMMAND_BUFFER cmdBuffer,
1991 bool frameTrackingRequested)
1992 {
1993 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1994
1995 CODECHAL_DECODE_FUNCTION_ENTER;
1996
1997 CODECHAL_DECODE_CHK_NULL_RETURN(cmdBuffer);
1998
1999 MOS_GPU_CONTEXT gpuContext = m_osInterface->pfnGetGpuContext(m_osInterface);
2000
2001 // Send Start Marker command
2002 if (m_decodeParams.m_setMarkerEnabled)
2003 {
2004 CODECHAL_DECODE_CHK_STATUS_RETURN(SendMarkerCommand(cmdBuffer, MOS_RCS_ENGINE_USED(gpuContext)));
2005 }
2006
2007 if (frameTrackingRequested)
2008 {
2009 // initialize command buffer attributes
2010 cmdBuffer->Attributes.bTurboMode = m_hwInterface->m_turboMode;
2011 cmdBuffer->Attributes.bMediaPreemptionEnabled = MOS_RCS_ENGINE_USED(gpuContext) ?
2012 m_hwInterface->GetRenderInterface()->IsPreemptionEnabled() : 0;
2013 cmdBuffer->Attributes.bEnableMediaFrameTracking = true;
2014 cmdBuffer->Attributes.resMediaFrameTrackingSurface = &m_decodeStatusBuf.m_statusBuffer;
2015 cmdBuffer->Attributes.dwMediaFrameTrackingTag = m_decodeStatusBuf.m_swStoreData;
2016 // Set media frame tracking address offset(the offset from the decoder status buffer page, refer to CodecHalDecode_Initialize)
2017 cmdBuffer->Attributes.dwMediaFrameTrackingAddrOffset = 0;
2018 }
2019
2020 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mmc->SendPrologCmd(m_miInterface, cmdBuffer, gpuContext));
2021
2022 MHW_GENERIC_PROLOG_PARAMS genericPrologParams;
2023 MOS_ZeroMemory(&genericPrologParams, sizeof(genericPrologParams));
2024 genericPrologParams.pOsInterface = m_osInterface;
2025 genericPrologParams.pvMiInterface = m_miInterface;
2026 genericPrologParams.bMmcEnabled = m_mmc->IsMmcEnabled();
2027
2028 CODECHAL_DECODE_CHK_STATUS_RETURN(Mhw_SendGenericPrologCmd(
2029 cmdBuffer,
2030 &genericPrologParams));
2031
2032 // Send predication command
2033 if (m_decodeParams.m_predicationEnabled)
2034 {
2035 CODECHAL_DECODE_CHK_STATUS_RETURN(SendPredicationCommand(
2036 cmdBuffer));
2037 }
2038
2039 return eStatus;
2040 }
2041
SendPredicationCommand(PMOS_COMMAND_BUFFER cmdBuffer)2042 MOS_STATUS CodechalDecode::SendPredicationCommand(
2043 PMOS_COMMAND_BUFFER cmdBuffer)
2044 {
2045 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2046
2047 CODECHAL_DECODE_FUNCTION_ENTER;
2048
2049 CODECHAL_DECODE_CHK_NULL_RETURN(cmdBuffer);
2050 CODECHAL_DECODE_CHK_NULL_RETURN(m_miInterface);
2051
2052 MHW_MI_CONDITIONAL_BATCH_BUFFER_END_PARAMS condBBEndParams;
2053 MOS_ZeroMemory(&condBBEndParams, sizeof(condBBEndParams));
2054
2055 // Skip current frame if presPredication is not equal to zero
2056 if (m_decodeParams.m_predicationNotEqualZero)
2057 {
2058 auto mmioRegistersMfx = m_hwInterface->SelectVdboxAndGetMmioRegister(m_vdboxIndex, cmdBuffer);
2059 MHW_MI_FLUSH_DW_PARAMS flushDwParams;
2060 MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
2061 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(cmdBuffer, &flushDwParams));
2062
2063 // load presPredication to general purpose register0
2064 MHW_MI_STORE_REGISTER_MEM_PARAMS loadRegisterMemParams;
2065 MOS_ZeroMemory(&loadRegisterMemParams, sizeof(loadRegisterMemParams));
2066 loadRegisterMemParams.presStoreBuffer = m_decodeParams.m_presPredication;
2067 loadRegisterMemParams.dwOffset = (uint32_t)m_decodeParams.m_predicationResOffset;
2068 loadRegisterMemParams.dwRegister = mmioRegistersMfx->generalPurposeRegister0LoOffset;
2069 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiLoadRegisterMemCmd(
2070 cmdBuffer,
2071 &loadRegisterMemParams));
2072 MHW_MI_LOAD_REGISTER_IMM_PARAMS loadRegisterImmParams;
2073 MOS_ZeroMemory(&loadRegisterImmParams, sizeof(loadRegisterImmParams));
2074 loadRegisterImmParams.dwData = 0;
2075 loadRegisterImmParams.dwRegister = mmioRegistersMfx->generalPurposeRegister0HiOffset;
2076 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiLoadRegisterImmCmd(
2077 cmdBuffer,
2078 &loadRegisterImmParams));
2079
2080 // load 0 to general purpose register4
2081 MOS_ZeroMemory(&loadRegisterImmParams, sizeof(loadRegisterImmParams));
2082 loadRegisterImmParams.dwData = 0;
2083 loadRegisterImmParams.dwRegister = mmioRegistersMfx->generalPurposeRegister4LoOffset;
2084 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiLoadRegisterImmCmd(
2085 cmdBuffer,
2086 &loadRegisterImmParams));
2087 MOS_ZeroMemory(&loadRegisterImmParams, sizeof(loadRegisterImmParams));
2088 loadRegisterImmParams.dwData = 0;
2089 loadRegisterImmParams.dwRegister = mmioRegistersMfx->generalPurposeRegister4HiOffset;
2090 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiLoadRegisterImmCmd(
2091 cmdBuffer,
2092 &loadRegisterImmParams));
2093
2094 //perform the add operation
2095 MHW_MI_MATH_PARAMS miMathParams;
2096 MHW_MI_ALU_PARAMS miAluParams[4];
2097 MOS_ZeroMemory(&miMathParams, sizeof(miMathParams));
2098 MOS_ZeroMemory(&miAluParams, sizeof(miAluParams));
2099 // load srcA, reg0
2100 miAluParams[0].AluOpcode = MHW_MI_ALU_LOAD;
2101 miAluParams[0].Operand1 = MHW_MI_ALU_SRCA;
2102 miAluParams[0].Operand2 = MHW_MI_ALU_GPREG0;
2103 // load srcB, reg4
2104 miAluParams[1].AluOpcode = MHW_MI_ALU_LOAD;
2105 miAluParams[1].Operand1 = MHW_MI_ALU_SRCB;
2106 miAluParams[1].Operand2 = MHW_MI_ALU_GPREG4;
2107 // add srcA, srcB
2108 miAluParams[2].AluOpcode = MHW_MI_ALU_ADD;
2109 miAluParams[2].Operand1 = MHW_MI_ALU_SRCB;
2110 miAluParams[2].Operand2 = MHW_MI_ALU_GPREG4;
2111 // store reg0, ZF
2112 miAluParams[3].AluOpcode = MHW_MI_ALU_STORE;
2113 miAluParams[3].Operand1 = MHW_MI_ALU_GPREG0;
2114 miAluParams[3].Operand2 = MHW_MI_ALU_ZF;
2115 miMathParams.pAluPayload = miAluParams;
2116 miMathParams.dwNumAluParams = 4; // four ALU commands needed for this substract opertaion. see following ALU commands.
2117 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiMathCmd(
2118 cmdBuffer,
2119 &miMathParams));
2120
2121 // if zero, the zero flag will be 0xFFFFFFFF, else zero flag will be 0x0.
2122 MHW_MI_STORE_REGISTER_MEM_PARAMS storeRegParams;
2123 MOS_ZeroMemory(&storeRegParams, sizeof(storeRegParams));
2124 storeRegParams.presStoreBuffer = &m_predicationBuffer;
2125 storeRegParams.dwOffset = 0;
2126 storeRegParams.dwRegister = mmioRegistersMfx->generalPurposeRegister0LoOffset;
2127 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreRegisterMemCmd(
2128 cmdBuffer,
2129 &storeRegParams));
2130
2131 condBBEndParams.presSemaphoreBuffer = &m_predicationBuffer;
2132 condBBEndParams.dwOffset = 0;
2133 condBBEndParams.dwValue = 0;
2134 condBBEndParams.bDisableCompareMask = true;
2135 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiConditionalBatchBufferEndCmd(
2136 cmdBuffer,
2137 &condBBEndParams));
2138
2139 *m_decodeParams.m_tempPredicationBuffer = &m_predicationBuffer;
2140 }
2141 else
2142 {
2143 // Skip current frame if presPredication is equal to zero
2144 condBBEndParams.presSemaphoreBuffer = m_decodeParams.m_presPredication;
2145 condBBEndParams.dwOffset = (uint32_t)m_decodeParams.m_predicationResOffset;
2146 condBBEndParams.bDisableCompareMask = true;
2147 condBBEndParams.dwValue = 0;
2148 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiConditionalBatchBufferEndCmd(
2149 cmdBuffer,
2150 &condBBEndParams));
2151 }
2152
2153 return eStatus;
2154 }
2155
SendMarkerCommand(PMOS_COMMAND_BUFFER cmdBuffer,bool isRender)2156 MOS_STATUS CodechalDecode::SendMarkerCommand(
2157 PMOS_COMMAND_BUFFER cmdBuffer,
2158 bool isRender)
2159 {
2160 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2161
2162 CODECHAL_DECODE_FUNCTION_ENTER;
2163
2164 CODECHAL_DECODE_CHK_NULL_RETURN(cmdBuffer);
2165 CODECHAL_DECODE_CHK_NULL_RETURN(m_miInterface);
2166
2167 if (isRender)
2168 {
2169 // Send pipe_control to get the timestamp
2170 MHW_PIPE_CONTROL_PARAMS pipeControlParams;
2171 MOS_ZeroMemory(&pipeControlParams, sizeof(pipeControlParams));
2172 pipeControlParams.presDest = (PMOS_RESOURCE)m_decodeParams.m_presSetMarker;
2173 pipeControlParams.dwResourceOffset = 0;
2174 pipeControlParams.dwPostSyncOp = MHW_FLUSH_WRITE_TIMESTAMP_REG;
2175 pipeControlParams.dwFlushMode = MHW_FLUSH_WRITE_CACHE;
2176
2177 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddPipeControl(cmdBuffer, NULL, &pipeControlParams));
2178 }
2179 else
2180 {
2181 // Send flush_dw to get the timestamp
2182 MHW_MI_FLUSH_DW_PARAMS flushDwParams;
2183 MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
2184 flushDwParams.pOsResource = (PMOS_RESOURCE)m_decodeParams.m_presSetMarker;
2185 flushDwParams.dwResourceOffset = 0;
2186 flushDwParams.postSyncOperation = MHW_FLUSH_WRITE_TIMESTAMP_REG;
2187 flushDwParams.bQWordEnable = 1;
2188
2189 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(cmdBuffer, &flushDwParams));
2190 }
2191
2192 return eStatus;
2193 }
2194
SetCencBatchBuffer(PMOS_COMMAND_BUFFER cmdBuffer)2195 MOS_STATUS CodechalDecode::SetCencBatchBuffer(
2196 PMOS_COMMAND_BUFFER cmdBuffer)
2197 {
2198 CODECHAL_DECODE_CHK_NULL_RETURN(cmdBuffer);
2199
2200 MHW_BATCH_BUFFER batchBuffer;
2201 MOS_ZeroMemory(&batchBuffer, sizeof(MHW_BATCH_BUFFER));
2202 MOS_RESOURCE *resHeap = nullptr;
2203 CODECHAL_DECODE_CHK_NULL_RETURN(resHeap = m_cencBuf->secondLvlBbBlock->GetResource());
2204 batchBuffer.OsResource = *resHeap;
2205 batchBuffer.dwOffset = m_cencBuf->secondLvlBbBlock->GetOffset();
2206 batchBuffer.iSize = m_cencBuf->secondLvlBbBlock->GetSize();
2207 batchBuffer.bSecondLevel = true;
2208 #if (_DEBUG || _RELEASE_INTERNAL)
2209 batchBuffer.iLastCurrent = batchBuffer.iSize;
2210 #endif // (_DEBUG || _RELEASE_INTERNAL)
2211
2212 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferStartCmd(
2213 cmdBuffer,
2214 &batchBuffer));
2215
2216 CODECHAL_DEBUG_TOOL(
2217 CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->Dump2ndLvlBatch(
2218 &batchBuffer,
2219 CODECHAL_NUM_MEDIA_STATES,
2220 "_2ndLvlBatch"));)
2221
2222 // Update GlobalCmdBufId
2223 MHW_MI_STORE_DATA_PARAMS miStoreDataParams;
2224 MOS_ZeroMemory(&miStoreDataParams, sizeof(miStoreDataParams));
2225 miStoreDataParams.pOsResource = m_cencBuf->resTracker;
2226 miStoreDataParams.dwValue = m_cencBuf->trackerId;
2227 CODECHAL_DECODE_VERBOSEMESSAGE("dwCmdBufId = %d", miStoreDataParams.dwValue);
2228 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreDataImmCmd(
2229 cmdBuffer,
2230 &miStoreDataParams));
2231 return MOS_STATUS_SUCCESS;
2232 }
2233
2234 #if USE_CODECHAL_DEBUG_TOOL
2235 #ifdef _DECODE_PROCESSING_SUPPORTED
DumpProcessingParams(DecodeProcessingParams * decProcParams)2236 MOS_STATUS CodechalDecode::DumpProcessingParams(DecodeProcessingParams *decProcParams)
2237 {
2238 CODECHAL_DEBUG_FUNCTION_ENTER;
2239
2240 if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDecodeProcParams))
2241 {
2242 return MOS_STATUS_SUCCESS;
2243 }
2244
2245 CODECHAL_DEBUG_CHK_NULL(decProcParams);
2246 CODECHAL_DEBUG_CHK_NULL(decProcParams->m_inputSurface);
2247 CODECHAL_DEBUG_CHK_NULL(decProcParams->m_outputSurface);
2248
2249 std::ostringstream oss;
2250 oss.setf(std::ios::showbase | std::ios::uppercase);
2251
2252 oss << "Input Surface Resolution: "
2253 << +decProcParams->m_inputSurface->dwWidth << " x " << +decProcParams->m_inputSurface->dwHeight << std::endl;
2254 oss << "Input Region Resolution: "
2255 << +decProcParams->m_inputSurfaceRegion.m_width << " x " << +decProcParams->m_inputSurfaceRegion.m_height << std::endl;
2256 oss << "Input Region Offset: ("
2257 << +decProcParams->m_inputSurfaceRegion.m_x << "," << +decProcParams->m_inputSurfaceRegion.m_y << ")" << std::endl;
2258 oss << "Input Surface Format: "
2259 << (decProcParams->m_inputSurface->Format == Format_NV12 ? "NV12" : "P010" )<< std::endl;
2260 oss << "Output Surface Resolution: "
2261 << +decProcParams->m_outputSurface->dwWidth << " x " << +decProcParams->m_outputSurface->dwHeight << std::endl;
2262 oss << "Output Region Resolution: "
2263 << +decProcParams->m_outputSurfaceRegion.m_width << " x " << +decProcParams->m_outputSurfaceRegion.m_height << std::endl;
2264 oss << "Output Region Offset: ("
2265 << +decProcParams->m_outputSurfaceRegion.m_x << ", " << +decProcParams->m_outputSurfaceRegion.m_y << ")" << std::endl;
2266 oss << "Output Surface Format: "
2267 << (decProcParams->m_outputSurface->Format == Format_NV12 ? "NV12" : "YUY2" )<< std::endl;
2268
2269 const char* filePath = m_debugInterface->CreateFileName(
2270 "_DEC",
2271 CodechalDbgBufferType::bufDecProcParams,
2272 CodechalDbgExtType::txt);
2273
2274 std::ofstream ofs(filePath, std::ios::out);
2275 ofs << oss.str();
2276 ofs.close();
2277
2278 return MOS_STATUS_SUCCESS;
2279 }
2280
2281 #endif
2282 #endif
2283
2284