1 /*
2 * Copyright (c) 2017-2020, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 //!
23 //! \file codechal_decode_downsampling.cpp
24 //! \brief Implements the decode interface extension for field downsampling.
25 //! \details Downsampling in this case is supported by EU kernels.
26 //!
27 #include "codechal_decoder.h"
28 #include "codeckrnheader.h"
29
30 // Construct function of Class MediaWalkerFieldScalingStaticData
MediaWalkerFieldScalingStaticData()31 MediaWalkerFieldScalingStaticData::MediaWalkerFieldScalingStaticData()
32 {
33 CODECHAL_DECODE_FUNCTION_ENTER;
34
35 memset(&m_mediaWalkerData, 0, sizeof(m_mediaWalkerData));
36 m_mediaWalkerData.m_dword07.m_value = 0x7;
37 m_mediaWalkerData.m_dword14.m_nlasEnable = false;
38 }
39
40 // Initialize the static const float variables in class FieldScalingInterface.
41 const float FieldScalingInterface::m_maxScaleRatio = 1.0f;
42 const float FieldScalingInterface::m_minScaleRatio = 0.125f;
43
FieldScalingInterface()44 FieldScalingInterface::FieldScalingInterface()
45 {
46 CODECHAL_DECODE_FUNCTION_ENTER;
47
48 memset(&m_kernelSize, 0, sizeof(m_kernelSize));
49 memset(&m_dshSize, 0, sizeof(m_dshSize));
50 memset(&m_syncObject, 0, sizeof(m_syncObject));
51
52 for (uint8_t i = stateNv12; i < stateMax; i++)
53 {
54 m_kernelBinary[i] = nullptr;
55 m_kernelStates[i] = MHW_KERNEL_STATE();
56 }
57
58 m_kernelUID[stateNv12] = IDR_CODEC_ALLPL2ToNV12iScale;
59 m_kernelUID[stateYuy2] = IDR_CODEC_ALLPL2ToPAiScale;
60
61 m_curbeLength = MediaWalkerFieldScalingStaticData::m_byteSize;
62 }
63
~FieldScalingInterface()64 FieldScalingInterface::~FieldScalingInterface()
65 {
66 CODECHAL_DECODE_FUNCTION_ENTER;
67
68 if (m_mmcState != nullptr)
69 {
70 MOS_Delete(m_mmcState);
71 m_mmcState = nullptr;
72 }
73
74 CODECHAL_DECODE_ASSERT(m_osInterface);
75 if (m_osInterface != nullptr)
76 {
77 m_osInterface->pfnDestroySyncResource(m_osInterface, &m_syncObject);
78 }
79 }
80
InitInterfaceStateHeapSetting(CodechalHwInterface * hwInterface)81 MOS_STATUS FieldScalingInterface::InitInterfaceStateHeapSetting(
82 CodechalHwInterface *hwInterface)
83 {
84 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
85
86 CODECHAL_DECODE_FUNCTION_ENTER;
87
88 MHW_KERNEL_STATE *kernelState;
89 for (auto krnlIdx = 0; krnlIdx < stateMax; krnlIdx++)
90 {
91 kernelState = &m_kernelStates[krnlIdx];
92
93 CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalGetKernelBinaryAndSize(
94 m_kernelBase,
95 m_kernelUID[krnlIdx],
96 &m_kernelBinary[krnlIdx],
97 &m_kernelSize[krnlIdx]));
98
99 kernelState->KernelParams.iCurbeLength = m_curbeLength;
100 kernelState->KernelParams.pBinary = m_kernelBinary[krnlIdx];
101 kernelState->KernelParams.iSize = m_kernelSize[krnlIdx];
102
103 hwInterface->GetStateHeapSettings()->dwIshSize +=
104 MOS_ALIGN_CEIL(
105 kernelState->KernelParams.iSize,
106 (1 << MHW_KERNEL_OFFSET_SHIFT));
107 }
108
109 hwInterface->GetStateHeapSettings()->dwNumSyncTags += m_numSyncTags;
110 hwInterface->GetStateHeapSettings()->dwDshSize += m_initDshSize;
111
112 return eStatus;
113 }
114
SetCurbeFieldScaling(MHW_KERNEL_STATE * kernelState,DecodeProcessingParams * procParams)115 MOS_STATUS FieldScalingInterface::SetCurbeFieldScaling(
116 MHW_KERNEL_STATE *kernelState,
117 DecodeProcessingParams *procParams)
118 {
119 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
120
121 CODECHAL_DECODE_FUNCTION_ENTER;
122
123 CODECHAL_DECODE_CHK_NULL_RETURN(kernelState);
124 CODECHAL_DECODE_CHK_NULL_RETURN(procParams);
125 CODECHAL_DECODE_CHK_NULL_RETURN(procParams->m_inputSurface);
126 CODECHAL_DECODE_CHK_NULL_RETURN(procParams->m_outputSurface);
127
128 MOS_SURFACE *inputSurface = procParams->m_inputSurface;
129 MOS_SURFACE *outputSurface = procParams->m_outputSurface;
130
131 float stepX = (float)procParams->m_inputSurfaceRegion.m_width /
132 (float)(procParams->m_outputSurfaceRegion.m_width * inputSurface->dwWidth);
133 float stepY = (float)procParams->m_inputSurfaceRegion.m_height /
134 (float)(procParams->m_outputSurfaceRegion.m_height * inputSurface->dwHeight);
135
136 MediaWalkerFieldScalingStaticData cmd;
137 cmd.m_mediaWalkerData.m_dword07.m_pointerToInlineParameters = 0xB;
138 cmd.m_mediaWalkerData.m_dword08.m_destinationRectangleWidth = procParams->m_outputSurfaceRegion.m_width;
139 cmd.m_mediaWalkerData.m_dword08.m_destinationRectangleHeight = procParams->m_outputSurfaceRegion.m_height;
140
141 if (outputSurface->Format == Format_NV12)
142 {
143 cmd.m_mediaWalkerData.m_dword10.m_chromaSitingLocation = CODECHAL_CHROMA_SUBSAMPLING_CENTER_LEFT;
144 }
145 else
146 {
147 cmd.m_mediaWalkerData.m_dword10.m_chromaSitingLocation = CODECHAL_CHROMA_SUBSAMPLING_TOP_LEFT;
148 }
149
150 cmd.m_mediaWalkerData.m_dword16.m_horizontalScalingStepRatioLayer0 = stepX;
151 cmd.m_mediaWalkerData.m_dword24.m_verticalScalingStepRatioLayer0 = stepY;
152 cmd.m_mediaWalkerData.m_dword48.m_destXTopLeftLayer0 = 0;
153 cmd.m_mediaWalkerData.m_dword48.m_destYTopLeftLayer0 = 0;
154 cmd.m_mediaWalkerData.m_dword56.m_destXBottomRightLayer0 = procParams->m_outputSurfaceRegion.m_width - 1;
155 cmd.m_mediaWalkerData.m_dword56.m_destYBottomRightLayer0 = procParams->m_outputSurfaceRegion.m_height - 1;
156 cmd.m_mediaWalkerData.m_dword64.m_mainVideoXScalingStepLeft = 1.0F;
157
158 CODECHAL_DECODE_CHK_STATUS_RETURN(kernelState->m_dshRegion.AddData(
159 &cmd.m_mediaWalkerData,
160 kernelState->dwCurbeOffset,
161 cmd.m_byteSize));
162
163 return eStatus;
164 }
165
IsFieldScalingSupported(DecodeProcessingParams * params)166 bool FieldScalingInterface::IsFieldScalingSupported(DecodeProcessingParams *params)
167 {
168 CODECHAL_DECODE_FUNCTION_ENTER;
169
170 if (!params || !params->m_inputSurface || !params->m_outputSurface)
171 {
172 CODECHAL_DECODE_ASSERTMESSAGE("Invalid Parameters");
173 return false;
174 }
175
176 MOS_SURFACE *srcSurface = params->m_inputSurface;
177 MOS_SURFACE *destSurface = params->m_outputSurface;
178
179 // Check input size
180 if (!MOS_WITHIN_RANGE(srcSurface->dwWidth, m_minInputWidth, m_maxInputWidth) ||
181 !MOS_WITHIN_RANGE(srcSurface->dwHeight, m_minInputHeight, m_maxInputHeight))
182 {
183 CODECHAL_DECODE_ASSERTMESSAGE("Unsupported Input Resolution '0x%08x'x'0x%08x' for field scaling.", srcSurface->dwWidth, srcSurface->dwHeight);
184 return false;
185 }
186
187 // Check input format
188 if (srcSurface->Format != Format_NV12)
189 {
190 CODECHAL_DECODE_ASSERTMESSAGE("Unsupported Input Format '0x%08x' for field scaling.", srcSurface->Format);
191 return false;
192 }
193
194 // Check input region rectangles
195 if ((params->m_inputSurfaceRegion.m_width > srcSurface->dwWidth) ||
196 (params->m_inputSurfaceRegion.m_height > srcSurface->dwHeight))
197 {
198 CODECHAL_DECODE_ASSERTMESSAGE("Input region is out of bound for field scaling.");
199 return false;
200 }
201
202 // Check output format
203 if (destSurface->Format != Format_NV12 && destSurface->Format != Format_YUY2)
204 {
205 CODECHAL_DECODE_ASSERTMESSAGE("Unsupported Output Format '0x%08x' for field scaling.", destSurface->Format);
206 return false;
207 }
208
209 // Check output size
210 if (!MOS_WITHIN_RANGE(destSurface->dwWidth, m_minInputWidth, m_maxInputWidth) ||
211 !MOS_WITHIN_RANGE(destSurface->dwHeight, m_minInputHeight, m_maxInputHeight))
212 {
213 CODECHAL_DECODE_ASSERTMESSAGE("Unsupported Output Resolution '0x%08x'x'0x%08x' for field scaling.", destSurface->dwWidth, destSurface->dwHeight);
214 return false;
215 }
216
217 // Check output region rectangles
218 if ((params->m_outputSurfaceRegion.m_width > destSurface->dwWidth) ||
219 (params->m_outputSurfaceRegion.m_height > destSurface->dwHeight))
220 {
221 CODECHAL_DECODE_ASSERTMESSAGE("Output region is out of bound for field scaling.");
222 return false;
223 }
224
225 // Check scaling ratio
226 // Scaling range is [0.125, 1] for both X and Y direction.
227 float scaleX = (float)params->m_outputSurfaceRegion.m_width / (float)params->m_inputSurfaceRegion.m_width;
228 float scaleY = (float)params->m_outputSurfaceRegion.m_height / (float)params->m_inputSurfaceRegion.m_height;
229
230 if (!MOS_WITHIN_RANGE(scaleX, m_minScaleRatio, m_maxScaleRatio) ||
231 !MOS_WITHIN_RANGE(scaleY, m_minScaleRatio, m_maxScaleRatio))
232 {
233 CODECHAL_DECODE_ASSERTMESSAGE("Scaling factor not supported by field scaling.");
234 return false;
235 }
236
237 return true;
238 }
239
InitializeKernelState(CodechalDecode * decoder,CodechalHwInterface * hwInterface,PMOS_INTERFACE osInterface)240 MOS_STATUS FieldScalingInterface::InitializeKernelState(
241 CodechalDecode *decoder,
242 CodechalHwInterface *hwInterface,
243 PMOS_INTERFACE osInterface)
244 {
245 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
246
247 CODECHAL_DECODE_FUNCTION_ENTER;
248
249 CODECHAL_DECODE_CHK_NULL_RETURN(hwInterface);
250 CODECHAL_DECODE_CHK_NULL_RETURN(osInterface);
251 CODECHAL_DECODE_CHK_NULL_RETURN(hwInterface->GetMiInterface());
252 CODECHAL_DECODE_CHK_NULL_RETURN(hwInterface->GetRenderInterface());
253 CODECHAL_DECODE_CHK_NULL_RETURN(hwInterface->GetRenderInterface()->GetHwCaps());
254 CODECHAL_DECODE_CHK_NULL_RETURN(hwInterface->GetRenderInterface()->m_stateHeapInterface);
255
256 this->m_decoder = decoder;
257 m_osInterface = osInterface;
258 m_hwInterface = hwInterface;
259 m_renderInterface = m_hwInterface->GetRenderInterface();
260 m_stateHeapInterface = m_renderInterface->m_stateHeapInterface;
261 m_miInterface = m_hwInterface->GetMiInterface();
262
263 MHW_KERNEL_STATE *kernelState;
264 for (auto krnIdx = 0; krnIdx < stateMax; krnIdx++)
265 {
266 kernelState = &m_kernelStates[krnIdx];
267
268 kernelState->KernelParams.iThreadCount = m_renderInterface->GetHwCaps()->dwMaxThreads;
269 kernelState->KernelParams.iBTCount = numSurfaces;
270 kernelState->KernelParams.iBlockWidth = CODECHAL_MACROBLOCK_WIDTH;
271 kernelState->KernelParams.iBlockHeight = CODECHAL_MACROBLOCK_HEIGHT;
272 kernelState->KernelParams.iIdCount = 1;
273 kernelState->KernelParams.iSamplerCount = m_samplerNum;
274 kernelState->KernelParams.iSamplerLength = m_stateHeapInterface->pStateHeapInterface->GetSizeofCmdSampleState();
275
276 kernelState->dwCurbeOffset = m_stateHeapInterface->pStateHeapInterface->GetSizeofCmdInterfaceDescriptorData();
277 kernelState->dwSamplerOffset =
278 kernelState->dwCurbeOffset +
279 MOS_ALIGN_CEIL(kernelState->KernelParams.iCurbeLength, m_stateHeapInterface->pStateHeapInterface->GetCurbeAlignment());
280 kernelState->dwKernelBinaryOffset = 0;
281
282 MHW_CHK_STATUS_RETURN(m_stateHeapInterface->pfnCalculateSshAndBtSizesRequested(
283 m_stateHeapInterface,
284 kernelState->KernelParams.iBTCount,
285 &kernelState->dwSshSize,
286 &kernelState->dwBindingTableSize));
287
288 m_dshSize[krnIdx] =
289 m_stateHeapInterface->pStateHeapInterface->GetSizeofCmdInterfaceDescriptorData() +
290 MOS_ALIGN_CEIL(kernelState->KernelParams.iCurbeLength, m_stateHeapInterface->pStateHeapInterface->GetCurbeAlignment()) +
291 kernelState->KernelParams.iSamplerLength * m_samplerNum;
292
293 MHW_CHK_STATUS_RETURN(m_hwInterface->MhwInitISH(
294 m_stateHeapInterface,
295 kernelState));
296 }
297
298 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnCreateSyncResource(
299 m_osInterface,
300 &m_syncObject));
301
302 return eStatus;
303 }
304
SetupMediaVfe(PMOS_COMMAND_BUFFER cmdBuffer,MHW_KERNEL_STATE * kernelState)305 MOS_STATUS FieldScalingInterface::SetupMediaVfe(
306 PMOS_COMMAND_BUFFER cmdBuffer,
307 MHW_KERNEL_STATE *kernelState)
308 {
309 MHW_VFE_PARAMS vfeParams = {};
310
311 vfeParams.pKernelState = kernelState;
312 CODECHAL_DECODE_CHK_STATUS_RETURN(m_renderInterface->AddMediaVfeCmd(cmdBuffer, &vfeParams));
313
314 return MOS_STATUS_SUCCESS;
315 }
316
DoFieldScaling(DecodeProcessingParams * procParams,MOS_GPU_CONTEXT renderContext,bool disableDecodeSyncLock,bool disableLockForTranscode)317 MOS_STATUS FieldScalingInterface::DoFieldScaling(
318 DecodeProcessingParams *procParams,
319 MOS_GPU_CONTEXT renderContext,
320 bool disableDecodeSyncLock,
321 bool disableLockForTranscode)
322 {
323 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
324
325 CODECHAL_DECODE_FUNCTION_ENTER;
326
327 CODECHAL_DECODE_CHK_NULL_RETURN(procParams);
328 CODECHAL_DECODE_CHK_NULL_RETURN(procParams->m_inputSurface);
329 CODECHAL_DECODE_CHK_NULL_RETURN(procParams->m_outputSurface);
330 CODECHAL_DECODE_CHK_NULL_RETURN(m_hwInterface->GetMiInterface());
331
332 CODECHAL_DECODE_CHK_STATUS_RETURN(InitMmcState());
333
334 MOS_SYNC_PARAMS syncParams;
335 syncParams = g_cInitSyncParams;
336 syncParams.GpuContext = m_decoder->GetVideoContext();
337 syncParams.presSyncResource = &m_syncObject;
338
339 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineSignal(m_osInterface, &syncParams));
340
341 syncParams = g_cInitSyncParams;
342 syncParams.GpuContext = renderContext;
343 syncParams.presSyncResource = &m_syncObject;
344
345 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineWait(m_osInterface, &syncParams));
346
347 FieldScalingKernelStateIdx kernelStateIdx;
348 if (procParams->m_outputSurface->Format == Format_NV12)
349 {
350 kernelStateIdx = stateNv12;
351 }
352 else if (procParams->m_outputSurface->Format == Format_YUY2)
353 {
354 kernelStateIdx = stateYuy2;
355 }
356 else
357 {
358 return MOS_STATUS_INVALID_PARAMETER;
359 }
360
361 m_osInterface->pfnSetGpuContext(m_osInterface, renderContext);
362 m_osInterface->pfnResetOsStates(m_osInterface);
363
364 MHW_KERNEL_STATE *kernelState = &m_kernelStates[kernelStateIdx];
365
366 CODECHAL_DECODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnRequestSshSpaceForCmdBuf(
367 m_stateHeapInterface,
368 kernelState->KernelParams.iBTCount));
369
370 CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->AssignDshAndSshSpace(
371 m_stateHeapInterface,
372 kernelState,
373 false,
374 m_dshSize[kernelStateIdx],
375 false,
376 m_decoder->GetDecodeStatusBuf()->m_swStoreData));
377
378 // Initialize DSH kernel region
379 MHW_INTERFACE_DESCRIPTOR_PARAMS idParams;
380 memset(&idParams, 0, sizeof(idParams));
381 idParams.pKernelState = kernelState;
382 CODECHAL_DECODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSetInterfaceDescriptor(
383 m_stateHeapInterface,
384 kernelState->KernelParams.iIdCount,
385 &idParams));
386
387 CODECHAL_DECODE_CHK_STATUS_RETURN(SetCurbeFieldScaling(
388 kernelState,
389 procParams));
390
391 MHW_SAMPLER_STATE_PARAM samplerParams[m_samplerNum];
392 memset(&samplerParams[0], 0, sizeof(MHW_SAMPLER_STATE_PARAM) * m_samplerNum);
393 samplerParams[0].bInUse = false;
394 samplerParams[0].pKernelState = kernelState;
395 for (uint32_t index = 1; index < m_samplerNum - 1; index++)
396 {
397 samplerParams[index].bInUse = true;
398 samplerParams[index].pKernelState = kernelState;
399 }
400 CODECHAL_DECODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSetSamplerState(
401 m_stateHeapInterface,
402 nullptr,
403 &samplerParams[0]));
404
405 // Send HW commands (including SSH)
406 MOS_COMMAND_BUFFER cmdBuffer;
407 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
408
409 MHW_PIPE_CONTROL_PARAMS pipeControlParams;
410 memset(&pipeControlParams, 0, sizeof(pipeControlParams));
411
412 // Send command buffer header at the beginning (OS dependent)
413 CODECHAL_DECODE_CHK_STATUS_RETURN(m_decoder->SendPrologWithFrameTracking(
414 &cmdBuffer, true));
415
416 if (m_renderInterface->GetL3CacheConfig()->bL3CachingEnabled)
417 {
418 CODECHAL_DECODE_CHK_STATUS_RETURN(m_renderInterface->SetL3Cache(&cmdBuffer));
419 }
420
421 CODECHAL_DECODE_CHK_STATUS_RETURN(m_renderInterface->EnablePreemption(&cmdBuffer));
422
423 CODECHAL_DECODE_CHK_STATUS_RETURN(m_renderInterface->AddPipelineSelectCmd(&cmdBuffer, false));
424
425 CODECHAL_DECODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSetBindingTable(
426 m_stateHeapInterface,
427 kernelState));
428
429 // Source Surface
430 // Top Field
431 CODECHAL_SURFACE_CODEC_PARAMS surfaceCodecParams;
432 MOS_ZeroMemory(&surfaceCodecParams, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
433 surfaceCodecParams.bIs2DSurface = true;
434 surfaceCodecParams.bUseHalfHeight = true;
435 surfaceCodecParams.bUseUVPlane = true;
436 surfaceCodecParams.psSurface = procParams->m_inputSurface;
437 surfaceCodecParams.dwCacheabilityControl = surfaceCacheabilityControlBitsFromGtt;
438
439 surfaceCodecParams.dwBindingTableOffset = fieldTopSrcY;
440 surfaceCodecParams.dwUVBindingTableOffset = fieldTopSrcUV;
441 surfaceCodecParams.dwVerticalLineStride = 1;
442 surfaceCodecParams.dwVerticalLineStrideOffset = 0;
443
444 surfaceCodecParams.bForceChromaFormat = true;
445 surfaceCodecParams.ChromaType = MHW_GFX3DSTATE_SURFACEFORMAT_R8G8_UNORM;
446
447 PMOS_INTERFACE osInterface = m_osInterface;
448 CodecHalGetResourceInfo(osInterface,surfaceCodecParams.psSurface);
449
450 #ifdef _MMC_SUPPORTED
451 if (m_mmcState)
452 {
453 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mmcState->SetSurfaceParams(&surfaceCodecParams));
454 }
455 #endif
456
457 CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
458 m_hwInterface,
459 &cmdBuffer,
460 &surfaceCodecParams,
461 kernelState));
462
463 // Bottom Field
464 surfaceCodecParams.dwBindingTableOffset = fieldBotSrcY;
465 surfaceCodecParams.dwUVBindingTableOffset = fieldBotSrcUV;
466 surfaceCodecParams.dwVerticalLineStrideOffset = 1;
467
468 CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
469 m_hwInterface,
470 &cmdBuffer,
471 &surfaceCodecParams,
472 kernelState));
473
474 // Destination Surface (NV12 & YUY2, RGB8 support is not yet implemented)
475 MOS_ZeroMemory(&surfaceCodecParams, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
476 surfaceCodecParams.bIs2DSurface = true;
477 surfaceCodecParams.psSurface = procParams->m_outputSurface;
478 surfaceCodecParams.bMediaBlockRW = true;
479 surfaceCodecParams.bIsWritable = true;
480 surfaceCodecParams.dwBindingTableOffset = dstY;
481 surfaceCodecParams.dwUVBindingTableOffset = dstUV;
482 surfaceCodecParams.dwCacheabilityControl = surfaceCacheabilityControlBitsFromGtt;
483
484 if (procParams->m_outputSurface->Format == Format_NV12)
485 {
486 surfaceCodecParams.bUseUVPlane = true;
487 surfaceCodecParams.bForceChromaFormat = true;
488 surfaceCodecParams.ChromaType = MHW_GFX3DSTATE_SURFACEFORMAT_R8G8_UNORM;
489 }
490
491 #ifdef _MMC_SUPPORTED
492 if (m_mmcState)
493 {
494 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mmcState->SetSurfaceParams(&surfaceCodecParams));
495 }
496 #endif
497
498 CodecHalGetResourceInfo(osInterface,surfaceCodecParams.psSurface);
499 CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
500 m_hwInterface,
501 &cmdBuffer,
502 &surfaceCodecParams,
503 kernelState));
504
505 MHW_STATE_BASE_ADDR_PARAMS stateBaseAddrParams;
506 memset(&stateBaseAddrParams, 0, sizeof(stateBaseAddrParams));
507 MOS_RESOURCE *dsh = nullptr, *ish = nullptr;
508 CODECHAL_DECODE_CHK_NULL_RETURN(dsh = kernelState->m_dshRegion.GetResource());
509 CODECHAL_DECODE_CHK_NULL_RETURN(ish = kernelState->m_ishRegion.GetResource());
510 stateBaseAddrParams.presDynamicState = dsh;
511 stateBaseAddrParams.dwDynamicStateSize = kernelState->m_dshRegion.GetHeapSize();
512 stateBaseAddrParams.presInstructionBuffer = ish;
513 stateBaseAddrParams.dwInstructionBufferSize = kernelState->m_ishRegion.GetHeapSize();
514
515 //Function is shared by Gen9 Gen10 Gen11 Gen12, here Gen9 will be used when fetching cache's Index.
516 stateBaseAddrParams.mocs4GeneralState = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_UNCACHED].Gen9.Index;
517 stateBaseAddrParams.mocs4DynamicState = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_UNCACHED].Gen9.Index;
518 stateBaseAddrParams.mocs4SurfaceState = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_UNCACHED].Gen9.Index;
519 stateBaseAddrParams.mocs4IndirectObjectBuffer = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_UNCACHED].Gen9.Index;
520 stateBaseAddrParams.mocs4StatelessDataport = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_UNCACHED].Gen9.Index;
521 CODECHAL_DECODE_CHK_STATUS_RETURN(m_renderInterface->AddStateBaseAddrCmd(&cmdBuffer, &stateBaseAddrParams));
522
523 CODECHAL_DECODE_CHK_STATUS_RETURN(SetupMediaVfe(&cmdBuffer, kernelState));
524
525 MHW_CURBE_LOAD_PARAMS curbeLoadParams;
526 memset(&curbeLoadParams, 0, sizeof(curbeLoadParams));
527 curbeLoadParams.pKernelState = kernelState;
528 CODECHAL_DECODE_CHK_STATUS_RETURN(m_renderInterface->AddMediaCurbeLoadCmd(&cmdBuffer, &curbeLoadParams));
529
530 MHW_ID_LOAD_PARAMS idLoadParams;
531 memset(&idLoadParams, 0, sizeof(idLoadParams));
532 idLoadParams.pKernelState = kernelState;
533 idLoadParams.dwNumKernelsLoaded = 1;
534 CODECHAL_DECODE_CHK_STATUS_RETURN(m_renderInterface->AddMediaIDLoadCmd(&cmdBuffer, &idLoadParams));
535
536 uint32_t resolutionX = MOS_ROUNDUP_DIVIDE(procParams->m_outputSurfaceRegion.m_width, 16);
537 uint32_t resolutionY = MOS_ROUNDUP_DIVIDE(procParams->m_outputSurfaceRegion.m_height, 16);
538
539 CODECHAL_WALKER_CODEC_PARAMS walkerCodecParams;
540 memset(&walkerCodecParams, 0, sizeof(walkerCodecParams));
541 walkerCodecParams.WalkerMode = MHW_WALKER_MODE_DUAL;
542 walkerCodecParams.dwResolutionX = resolutionX;
543 walkerCodecParams.dwResolutionY = resolutionY;
544 walkerCodecParams.bNoDependency = true; // raster scan mode
545
546 MHW_WALKER_PARAMS walkerParams;
547 CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalInitMediaObjectWalkerParams(
548 m_hwInterface,
549 &walkerParams,
550 &walkerCodecParams));
551
552 CODECHAL_DECODE_CHK_STATUS_RETURN(m_renderInterface->AddMediaObjectWalkerCmd(&cmdBuffer, &walkerParams));
553
554 // Check if destination surface needs to be synchronized, before command buffer submission
555 syncParams = g_cInitSyncParams;
556 syncParams.GpuContext = renderContext;
557 syncParams.presSyncResource = &procParams->m_outputSurface->OsResource;
558 syncParams.bReadOnly = false;
559 syncParams.bDisableDecodeSyncLock = disableDecodeSyncLock;
560 syncParams.bDisableLockForTranscode = disableLockForTranscode;
561
562 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnPerformOverlaySync(m_osInterface, &syncParams));
563 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceWait(m_osInterface, &syncParams));
564
565 // Update the resource tag (s/w tag) for On-Demand Sync
566 m_osInterface->pfnSetResourceSyncTag(m_osInterface, &syncParams);
567
568 // Update GPU Sync tag for on demand synchronization
569 if (m_osInterface->bTagResourceSync)
570 {
571 pipeControlParams.dwFlushMode = MHW_FLUSH_WRITE_CACHE;
572 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddPipeControl(&cmdBuffer, nullptr, &pipeControlParams));
573 CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->WriteSyncTagToResource(&cmdBuffer, &syncParams));
574 }
575
576 CODECHAL_DECODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnUpdateGlobalCmdBufId(
577 m_stateHeapInterface));
578
579 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(&cmdBuffer, nullptr));
580
581 m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
582
583 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, m_decoder->GetRenderContextUsesNullHw()));
584
585 if (m_decoder->IsStatusQueryReportingEnabled())
586 {
587 CODECHAL_DECODE_CHK_STATUS_RETURN(m_decoder->ResetStatusReport(m_decoder->GetRenderContextUsesNullHw()));
588 }
589
590 m_osInterface->pfnSetGpuContext(m_osInterface, m_decoder->GetVideoContext());
591
592 return (MOS_STATUS)eStatus;
593 }
594
InitMmcState()595 MOS_STATUS FieldScalingInterface::InitMmcState()
596 {
597 #ifdef _MMC_SUPPORTED
598 if (m_mmcState == nullptr)
599 {
600 m_mmcState = MOS_New(CodecHalMmcState, m_hwInterface);
601 CODECHAL_DECODE_CHK_NULL_RETURN(m_mmcState);
602 }
603 #endif
604 return MOS_STATUS_SUCCESS;
605 }
606