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