1 /*
2 * Copyright (c) 2017-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_decode_sfc_hevc_g12.cpp
24 //! \brief    Implements the decode interface extension for CSC and scaling via SFC for HEVC decoder for G12+ platform.
25 //! \details  Downsampling in this case is supported by the SFC fixed function HW unit.
26 //!
27 
28 #include "codechal_decode_sfc_hevc_g12.h"
29 #include "mos_os_cp_interface_specific.h"
30 
CodechalHevcSfcStateG12()31 CodechalHevcSfcStateG12::CodechalHevcSfcStateG12()
32 {
33     CODECHAL_HW_FUNCTION_ENTER;
34 }
35 
~CodechalHevcSfcStateG12()36 CodechalHevcSfcStateG12::~CodechalHevcSfcStateG12()
37 {
38     CODECHAL_HW_FUNCTION_ENTER;
39 
40     // Free AVS Line Buffer
41     if (m_resAvsLineBuffers)
42     {
43         for (int i = 0; i < m_numBuffersAllocated; i++)
44         {
45             m_osInterface->pfnFreeResource(m_osInterface, m_resAvsLineBuffers + i);
46         }
47         MOS_FreeMemory(m_resAvsLineBuffers);
48         m_resAvsLineBuffers = nullptr;
49     }
50     // Free SFD Line Buffer
51     if (m_resSfdLineBuffers)
52     {
53         for (int i = 0; i < m_numBuffersAllocated; i++)
54         {
55             m_osInterface->pfnFreeResource(m_osInterface, m_resSfdLineBuffers + i);
56         }
57         MOS_FreeMemory(m_resSfdLineBuffers);
58         m_resSfdLineBuffers = nullptr;
59     }
60     // Free AVS Line Tile Buffer
61     m_osInterface->pfnFreeResource(m_osInterface, &m_resAvsLineTileBuffer);
62     // Free SFD Line Tile Buffer
63     m_osInterface->pfnFreeResource(m_osInterface, &m_resSfdLineTileBuffer);
64 }
65 
AllocateResources()66 MOS_STATUS CodechalHevcSfcStateG12::AllocateResources()
67 {
68     if (m_numBuffersAllocated < m_numPipe)
69     {
70         // Allocate AVS line buffer for input row store
71         if (m_resAvsLineBuffers)
72         {
73             for (int i = 0; i < m_numBuffersAllocated; i++)
74             {
75                 m_osInterface->pfnFreeResource(m_osInterface, m_resAvsLineBuffers + i);
76             }
77             MOS_FreeMemory(m_resAvsLineBuffers);
78             m_resAvsLineBuffers = nullptr;
79         }
80         if (m_resAvsLineBuffers == nullptr)
81         {
82             m_resAvsLineBuffers = (MOS_RESOURCE *)MOS_AllocAndZeroMemory(sizeof(MOS_RESOURCE) * m_numPipe);
83             CODECHAL_HW_CHK_NULL_RETURN(m_resAvsLineBuffers);
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 = MOS_ROUNDUP_DIVIDE(m_inputFrameWidth, 8) * 6 * MHW_SFC_CACHELINE_SIZE;
91             allocParams.pBufName = "SfcAvsLineBuffer";
92 
93             for (int i = 0; i < m_numPipe; i++)
94             {
95                 CODECHAL_HW_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource(
96                     m_osInterface,
97                     &allocParams,
98                     m_resAvsLineBuffers + i));
99             }
100         }
101 
102         // Allocate SFD line buffer for output row store, needed for 420
103         if (m_resSfdLineBuffers)
104         {
105             for (int i = 0; i < m_numBuffersAllocated; i++)
106             {
107                 m_osInterface->pfnFreeResource(m_osInterface, m_resSfdLineBuffers + i);
108             }
109             MOS_FreeMemory(m_resSfdLineBuffers);
110             m_resSfdLineBuffers = nullptr;
111         }
112         if (m_resSfdLineBuffers == nullptr)
113         {
114             m_resSfdLineBuffers = (MOS_RESOURCE *)MOS_AllocAndZeroMemory(sizeof(MOS_RESOURCE) * m_numPipe);
115             CODECHAL_HW_CHK_NULL_RETURN(m_resSfdLineBuffers);
116 
117             MOS_ALLOC_GFXRES_PARAMS allocParams;
118             MOS_ZeroMemory(&allocParams, sizeof(MOS_ALLOC_GFXRES_PARAMS));
119             allocParams.Type = MOS_GFXRES_BUFFER;
120             allocParams.TileType = MOS_TILE_LINEAR;
121             allocParams.Format = Format_Buffer;
122             allocParams.dwBytes = MOS_ROUNDUP_DIVIDE(m_outputSurfaceRegion.m_width, 10) * MHW_SFC_CACHELINE_SIZE;
123             allocParams.pBufName = "SfcSfdLineBuffer";
124 
125             for (int i = 0; i < m_numPipe; i++)
126             {
127                 CODECHAL_HW_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource(
128                     m_osInterface,
129                     &allocParams,
130                     m_resSfdLineBuffers + i));
131             }
132         }
133         m_numBuffersAllocated = m_numPipe;
134     }
135 
136     // Allocate IEF line buffer - no IEF for HCP SFC
137 
138     // Allocate AVS line tile buffer for input column store
139     if (Mos_ResourceIsNull(&m_resAvsLineTileBuffer))
140     {
141         MOS_ALLOC_GFXRES_PARAMS allocParams;
142         MOS_ZeroMemory(&allocParams, sizeof(MOS_ALLOC_GFXRES_PARAMS));
143         allocParams.Type     = MOS_GFXRES_BUFFER;
144         allocParams.TileType = MOS_TILE_LINEAR;
145         allocParams.Format   = Format_Buffer;
146         allocParams.dwBytes  = MOS_ROUNDUP_DIVIDE(m_inputFrameHeight, 8) * 6 * MHW_SFC_CACHELINE_SIZE * 2; //double for safe
147         allocParams.pBufName = "SfcAvsLineTileBuffer";
148 
149         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource(
150             m_osInterface,
151             &allocParams,
152             &m_resAvsLineTileBuffer));
153     }
154     // Allocate SFD line tile buffer for output column store
155     if (Mos_ResourceIsNull(&m_resSfdLineTileBuffer))
156     {
157         MOS_ALLOC_GFXRES_PARAMS allocParams;
158         MOS_ZeroMemory(&allocParams, sizeof(MOS_ALLOC_GFXRES_PARAMS));
159         allocParams.Type     = MOS_GFXRES_BUFFER;
160         allocParams.TileType = MOS_TILE_LINEAR;
161         allocParams.Format   = Format_Buffer;
162         allocParams.dwBytes  = MOS_ROUNDUP_DIVIDE(m_outputSurfaceRegion.m_width, 10) * MHW_SFC_CACHELINE_SIZE * 2; //double for safe
163         allocParams.pBufName = "SfcSfdLineTileBuffer";
164 
165         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource(
166             m_osInterface,
167             &allocParams,
168             &m_resSfdLineTileBuffer));
169     }
170 
171     //Initialize AVS parameters, try to do once
172     if (m_scaling && !m_avsParams.piYCoefsX)
173     {
174         m_avsParams.Format = Format_None;
175         m_avsParams.fScaleX = 0.0F;
176         m_avsParams.fScaleY = 0.0F;
177         m_avsParams.piYCoefsX = nullptr;
178 
179         uint32_t ycoeffTableSize = POLYPHASE_Y_COEFFICIENT_TABLE_SIZE_G9;
180         uint32_t uvcoeffTableSize = POLYPHASE_UV_COEFFICIENT_TABLE_SIZE_G9;
181 
182         int32_t size = (ycoeffTableSize + uvcoeffTableSize) * 2;
183 
184         uint8_t *ptr = (uint8_t*)MOS_AllocAndZeroMemory(size);
185         CODECHAL_DECODE_CHK_NULL_RETURN(ptr);
186 
187         m_avsParams.piYCoefsX = (int32_t *)ptr;
188 
189         ptr += ycoeffTableSize;
190         m_avsParams.piUVCoefsX = (int32_t *)ptr;
191 
192         ptr += uvcoeffTableSize;
193         m_avsParams.piYCoefsY = (int32_t *)ptr;
194 
195         ptr += ycoeffTableSize;
196         m_avsParams.piUVCoefsY = (int32_t *)ptr;
197     }
198 
199     return MOS_STATUS_SUCCESS;
200 }
201 
CheckAndInitialize(DecodeProcessingParams * decProcessingParams,PCODEC_HEVC_PIC_PARAMS hevcPicParams,PCODECHAL_DECODE_SCALABILITY_STATE scalabilityState,PMOS_SURFACE histogramSurface)202 MOS_STATUS CodechalHevcSfcStateG12::CheckAndInitialize(
203     DecodeProcessingParams             *decProcessingParams,
204     PCODEC_HEVC_PIC_PARAMS              hevcPicParams,
205     PCODECHAL_DECODE_SCALABILITY_STATE  scalabilityState,
206     PMOS_SURFACE                        histogramSurface)
207 {
208     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
209 
210     CODECHAL_HW_FUNCTION_ENTER;
211 
212     if (decProcessingParams)
213     {
214         if (IsSfcOutputSupported(decProcessingParams, MhwSfcInterfaceG12::SFC_PIPE_MODE_HCP))
215         {
216             m_sfcPipeOut        = true;
217             m_hevcPicParams     = hevcPicParams;
218             m_scalabilityState  = static_cast<PCODECHAL_DECODE_SCALABILITY_STATE_G12>(scalabilityState);
219             m_histogramSurface  = histogramSurface;
220             m_numPipe           = m_scalabilityState ? m_scalabilityState->ucScalablePipeNum : 1;
221 
222             // Set the input region as the HCP output frame region
223             m_inputFrameWidth                                = m_hevcPicParams->PicWidthInMinCbsY << (m_hevcPicParams->log2_min_luma_coding_block_size_minus3 + 3);
224             m_inputFrameHeight                               = m_hevcPicParams->PicHeightInMinCbsY << (m_hevcPicParams->log2_min_luma_coding_block_size_minus3 + 3);
225             decProcessingParams->m_inputSurfaceRegion.m_x = 0;
226             decProcessingParams->m_inputSurfaceRegion.m_y = 0;
227             // Honor the region width from the setting of API instead of overriding.
228             if (decProcessingParams->m_inputSurfaceRegion.m_width == 0 || decProcessingParams->m_inputSurfaceRegion.m_width > m_inputFrameWidth)
229             {
230                 decProcessingParams->m_inputSurfaceRegion.m_width = m_inputFrameWidth;
231             }
232             // Honor the region height from the setting of API instead of overriding.
233             if (decProcessingParams->m_inputSurfaceRegion.m_height == 0 || decProcessingParams->m_inputSurfaceRegion.m_height > m_inputFrameHeight)
234             {
235                 decProcessingParams->m_inputSurfaceRegion.m_height = m_inputFrameHeight;
236             }
237 
238             CODECHAL_HW_CHK_STATUS_RETURN(Initialize(decProcessingParams, MhwSfcInterfaceG12::SFC_PIPE_MODE_HCP));
239 
240             if(m_decoder)
241             {
242                 m_decoder->SetVdSfcSupportedFlag(true);
243             }
244         }
245         else
246         {
247             if(m_decoder)
248             {
249                 m_decoder->SetVdSfcSupportedFlag(false);
250             }
251         }
252     }
253 
254     return eStatus;
255 }
256 
IsSfcFormatSupported(MOS_FORMAT inputFormat,MOS_FORMAT outputFormat)257 bool CodechalHevcSfcStateG12::IsSfcFormatSupported(
258     MOS_FORMAT                  inputFormat,
259     MOS_FORMAT                  outputFormat)
260 {
261     if ((inputFormat != Format_NV12) &&
262         (inputFormat != Format_400P) &&
263         (inputFormat != Format_IMC3) &&
264         (inputFormat != Format_422H) &&
265         (inputFormat != Format_444P) &&
266         (inputFormat != Format_P010) &&
267         (inputFormat != Format_YUY2) &&
268         (inputFormat != Format_AYUV) &&
269         (inputFormat != Format_Y210) &&
270         (inputFormat != Format_Y410) &&
271         (inputFormat != Format_P016) &&
272         (inputFormat != Format_Y216) &&
273         (inputFormat != Format_Y416))
274     {
275         CODECHAL_DECODE_ASSERTMESSAGE("Unsupported Input Format '0x%08x' for SFC.", inputFormat);
276         return false;
277     }
278 
279     if ((outputFormat != Format_A8R8G8B8) &&
280         (outputFormat != Format_NV12) &&
281         (outputFormat != Format_P010) &&
282         (outputFormat != Format_YUY2) &&
283         (outputFormat != Format_AYUV) &&
284         (outputFormat != Format_P016) &&
285         (outputFormat != Format_Y210) &&
286         (outputFormat != Format_Y216) &&
287         (outputFormat != Format_Y410) &&
288         (outputFormat != Format_Y416))
289     {
290         CODECHAL_DECODE_ASSERTMESSAGE("Unsupported Output Format '0x%08x' for SFC.", outputFormat);
291         return false;
292     }
293 
294     return true;
295 }
296 
UpdateInputInfo(PMHW_SFC_STATE_PARAMS sfcStateParams)297 MOS_STATUS CodechalHevcSfcStateG12::UpdateInputInfo(
298     PMHW_SFC_STATE_PARAMS   sfcStateParams)
299 {
300     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
301 
302     CODECHAL_HW_FUNCTION_ENTER;
303 
304     CODECHAL_HW_CHK_NULL_RETURN(m_hevcPicParams);
305     CODECHAL_HW_CHK_NULL_RETURN(sfcStateParams);
306 
307     PMHW_SFC_STATE_PARAMS_G12 sfcStateParamsG12 = static_cast<PMHW_SFC_STATE_PARAMS_G12>(sfcStateParams);
308 
309     uint32_t  lcuSize = 1 << (m_hevcPicParams->log2_diff_max_min_luma_coding_block_size +
310         m_hevcPicParams->log2_min_luma_coding_block_size_minus3 + 3);
311 
312     sfcStateParamsG12->sfcPipeMode                = MhwSfcInterfaceG12::SFC_PIPE_MODE_HCP;
313     sfcStateParamsG12->dwAVSFilterMode            = MEDIASTATE_SFC_AVS_FILTER_8x8;
314     sfcStateParamsG12->dwVDVEInputOrderingMode    = (16 == lcuSize) ? MhwSfcInterfaceG12::LCU_16_16_HEVC :
315         (32 == lcuSize) ? MhwSfcInterfaceG12::LCU_32_32_HEVC : MhwSfcInterfaceG12::LCU_64_64_HEVC;
316     sfcStateParamsG12->dwInputChromaSubSampling   = (HCP_CHROMA_FORMAT_YUV444 == m_hevcPicParams->chroma_format_idc) ? 4 : m_hevcPicParams->chroma_format_idc;
317     sfcStateParamsG12->dwInputFrameWidth          = m_inputFrameWidth;
318     sfcStateParamsG12->dwInputFrameHeight         = m_inputFrameHeight;
319     if (m_sfcOutputSurface->Format == Format_NV12 ||
320         m_sfcOutputSurface->Format == Format_P010 ||
321         m_sfcOutputSurface->Format == Format_P016)
322     {
323         sfcStateParams->dwChromaDownSamplingHorizontalCoef = (m_chromaSiting & MHW_CHROMA_SITING_HORZ_CENTER) ? MEDIASTATE_SFC_CHROMA_DOWNSAMPLING_COEF_4_OVER_8 : ((m_chromaSiting & MHW_CHROMA_SITING_HORZ_RIGHT) ? MEDIASTATE_SFC_CHROMA_DOWNSAMPLING_COEF_8_OVER_8 : MEDIASTATE_SFC_CHROMA_DOWNSAMPLING_COEF_0_OVER_8);
324         sfcStateParams->dwChromaDownSamplingVerticalCoef = (m_chromaSiting & MHW_CHROMA_SITING_VERT_CENTER) ? MEDIASTATE_SFC_CHROMA_DOWNSAMPLING_COEF_4_OVER_8 : ((m_chromaSiting & MHW_CHROMA_SITING_VERT_BOTTOM) ? MEDIASTATE_SFC_CHROMA_DOWNSAMPLING_COEF_8_OVER_8 : MEDIASTATE_SFC_CHROMA_DOWNSAMPLING_COEF_0_OVER_8);
325     }
326     else if (m_sfcOutputSurface->Format == Format_YUY2 ||
327         m_sfcOutputSurface->Format == Format_Y210 ||
328         m_sfcOutputSurface->Format == Format_Y216)
329     {
330         sfcStateParams->dwChromaDownSamplingHorizontalCoef = (m_chromaSiting & MHW_CHROMA_SITING_HORZ_CENTER) ? MEDIASTATE_SFC_CHROMA_DOWNSAMPLING_COEF_4_OVER_8 : ((m_chromaSiting & MHW_CHROMA_SITING_HORZ_RIGHT) ? MEDIASTATE_SFC_CHROMA_DOWNSAMPLING_COEF_8_OVER_8 : MEDIASTATE_SFC_CHROMA_DOWNSAMPLING_COEF_0_OVER_8);
331         sfcStateParams->dwChromaDownSamplingVerticalCoef = 0;
332     }
333     else
334     {
335         sfcStateParamsG12->dwChromaDownSamplingHorizontalCoef = 0;
336         sfcStateParamsG12->dwChromaDownSamplingVerticalCoef = 0;
337     }
338 
339     sfcStateParamsG12->inputBitDepth              = 0;
340     if (m_inputSurface)
341     {
342         if (m_inputSurface->Format == Format_P010 ||
343             m_inputSurface->Format == Format_Y210 ||
344             m_inputSurface->Format == Format_Y410)
345         {
346             sfcStateParamsG12->inputBitDepth = 1;
347         }
348         else if (m_inputSurface->Format == Format_P016 ||
349                  m_inputSurface->Format == Format_Y216 ||
350                  m_inputSurface->Format == Format_Y416)
351         {
352             sfcStateParamsG12->inputBitDepth = 2;
353         }
354     }
355 
356     // Scalability parameters
357     if (CodecHalDecodeScalabilityIsScalableMode(m_scalabilityState))
358     {
359         CODECHAL_DECODE_SFC_SCALABILITY_PARAMS  sfcScalaParams;
360 
361         MOS_ZeroMemory(&sfcScalaParams, sizeof(sfcScalaParams));
362         CODECHAL_HW_CHK_STATUS_RETURN(CodecHalDecodeScalability_SetSfcState(
363             m_scalabilityState,
364             m_hevcPicParams,
365             &m_inputSurfaceRegion,
366             &m_outputSurfaceRegion,
367             &sfcScalaParams));
368         sfcStateParamsG12->engineMode   = sfcScalaParams.engineMode;
369         sfcStateParamsG12->tileType     = sfcScalaParams.tileType;
370         sfcStateParamsG12->srcStartX    = sfcScalaParams.srcStartX;
371         sfcStateParamsG12->srcEndX      = sfcScalaParams.srcEndX;
372         sfcStateParamsG12->dstStartX    = sfcScalaParams.dstStartX;
373         sfcStateParamsG12->dstEndX      = sfcScalaParams.dstEndX;
374 
375         if (m_scalabilityState->bIsRtMode)
376         {
377             m_curPipe = m_scalabilityState->u8RtCurPipe;
378         }
379         else if (CodecHalDecodeScalabilityIsBEPhaseG12(m_scalabilityState))
380         {
381             m_curPipe = m_scalabilityState->HcpDecPhase - CODECHAL_HCP_DECODE_PHASE_BE0;
382         }
383         else
384         {
385             m_curPipe = 0;
386         }
387     }
388 
389     // Histogram stream out
390     sfcStateParamsG12->histogramSurface = m_histogramSurface;
391 
392     return eStatus;
393 }
394 
AddSfcCommands(PMOS_COMMAND_BUFFER cmdBuffer)395 MOS_STATUS CodechalHevcSfcStateG12::AddSfcCommands(
396     PMOS_COMMAND_BUFFER             cmdBuffer)
397 {
398     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
399 
400     MEDIA_WA_TABLE *m_waTable = m_osInterface->pfnGetWaTable(m_osInterface);
401     MHW_CHK_NULL_RETURN(m_waTable);
402 
403     CODECHAL_HW_FUNCTION_ENTER;
404 
405     CODECHAL_HW_CHK_NULL_RETURN(cmdBuffer);
406 
407     if (m_sfcPipeOut == false)
408     {
409         return eStatus;
410     }
411 
412     MHW_SFC_LOCK_PARAMS sfcLockParams;
413     MOS_ZeroMemory(&sfcLockParams, sizeof(sfcLockParams));
414 
415     sfcLockParams.sfcPipeMode = m_sfcPipeMode;
416     sfcLockParams.bOutputToMemory = ((MhwSfcInterface::SFC_PIPE_MODE_VEBOX != m_sfcPipeMode) && !m_jpegInUse);
417 
418     MHW_SFC_STATE_PARAMS_G12 sfcStateParams;
419     MOS_ZeroMemory(&sfcStateParams, sizeof(sfcStateParams));
420     MHW_SFC_OUT_SURFACE_PARAMS sfcOutSurfaceParams;
421     MOS_ZeroMemory(&sfcOutSurfaceParams, sizeof(sfcOutSurfaceParams));
422     CODECHAL_HW_CHK_STATUS_RETURN(SetSfcStateParams(&sfcStateParams, &sfcOutSurfaceParams));
423 
424     CODECHAL_HW_CHK_STATUS_RETURN(m_sfcInterface->AddSfcLock(cmdBuffer, &sfcLockParams));
425     //insert 2 dummy VD_CONTROL_STATE packets with data=0 after every HCP_SFC_LOCK
426     if (MEDIA_IS_WA(m_waTable, Wa_14010222001))
427     {
428         MHW_MI_VD_CONTROL_STATE_PARAMS vdCtrlParam;
429         MOS_ZeroMemory(&vdCtrlParam, sizeof(MHW_MI_VD_CONTROL_STATE_PARAMS));
430         for (int i = 0; i < 2; i++)
431         {
432             CODECHAL_HW_CHK_STATUS_RETURN(static_cast<MhwMiInterfaceG12 *>(m_miInterface)->AddMiVdControlStateCmd(cmdBuffer, &vdCtrlParam));
433         }
434     }
435     CODECHAL_HW_CHK_STATUS_RETURN(m_sfcInterface->AddSfcState(cmdBuffer, &sfcStateParams, &sfcOutSurfaceParams));
436 
437     if (m_scaling)
438     {
439         CODECHAL_HW_CHK_STATUS_RETURN(SetSfcAvsStateParams());
440         CODECHAL_HW_CHK_STATUS_RETURN(m_sfcInterface->AddSfcAvsState(cmdBuffer, &m_avsState));
441         CODECHAL_HW_CHK_STATUS_RETURN(m_sfcInterface->AddSfcAvsLumaTable(cmdBuffer, &m_lumaTable));
442         CODECHAL_HW_CHK_STATUS_RETURN(m_sfcInterface->AddSfcAvsChromaTable(cmdBuffer, &m_chromaTable));
443     }
444 
445     if (m_csc)
446     {
447         MHW_SFC_IEF_STATE_PARAMS sfcIefStateParams;
448         MOS_ZeroMemory(&sfcIefStateParams, sizeof(sfcIefStateParams));
449         CODECHAL_HW_CHK_STATUS_RETURN(SetSfcIefStateParams(&sfcIefStateParams));
450         CODECHAL_HW_CHK_STATUS_RETURN(m_sfcInterface->AddSfcIefState(cmdBuffer, &sfcIefStateParams));
451     }
452 
453     CODECHAL_HW_CHK_STATUS_RETURN(m_sfcInterface->AddSfcFrameStart(cmdBuffer, m_sfcPipeMode));
454 
455     return eStatus;
456 }
457 
SetSfcStateParams(PMHW_SFC_STATE_PARAMS sfcStateParams,PMHW_SFC_OUT_SURFACE_PARAMS outSurfaceParams)458 MOS_STATUS CodechalHevcSfcStateG12::SetSfcStateParams(
459     PMHW_SFC_STATE_PARAMS               sfcStateParams,
460     PMHW_SFC_OUT_SURFACE_PARAMS         outSurfaceParams)
461 {
462     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
463 
464     CODECHAL_HW_FUNCTION_ENTER;
465 
466     CODECHAL_HW_CHK_STATUS_RETURN(CodechalSfcState::SetSfcStateParams(sfcStateParams, outSurfaceParams));
467 
468     PMHW_SFC_STATE_PARAMS_G12 sfcStateParamsG12 = static_cast<PMHW_SFC_STATE_PARAMS_G12>(sfcStateParams);
469     sfcStateParamsG12->pOsResAVSLineBuffer = m_resAvsLineBuffers + m_curPipe;
470     sfcStateParamsG12->resSfdLineBuffer = m_resSfdLineBuffers + m_curPipe;
471     sfcStateParamsG12->resAvsLineTileBuffer = &m_resAvsLineTileBuffer;
472     sfcStateParamsG12->resSfdLineTileBuffer = &m_resSfdLineTileBuffer;
473 
474     // Force output frame size same as output region size
475     sfcStateParamsG12->dwOutputFrameWidth = sfcStateParamsG12->dwScaledRegionWidth;
476     sfcStateParamsG12->dwOutputFrameHeight = sfcStateParamsG12->dwScaledRegionHeight;
477 
478     if (m_mmcEnabled)
479     {
480         MOS_MEMCOMP_STATE mmcMode   = MOS_MEMCOMP_DISABLED;
481         CODECHAL_HW_CHK_STATUS_RETURN(m_osInterface->pfnGetMemoryCompressionMode(m_osInterface, &m_sfcOutputSurface->OsResource, &mmcMode));
482         sfcStateParams->bMMCEnable  = (mmcMode != MOS_MEMCOMP_DISABLED) ? true : false;
483         sfcStateParams->MMCMode     = (mmcMode == MOS_MEMCOMP_RC) ? MOS_MMC_RC : MOS_MMC_MC;
484         CODECHAL_HW_CHK_STATUS_RETURN(m_osInterface->pfnGetMemoryCompressionFormat(
485             m_osInterface, &m_sfcOutputSurface->OsResource, &outSurfaceParams->dwCompressionFormat));
486     }
487 
488     return eStatus;
489 }
490 
SetSfcAvsStateParams()491 MOS_STATUS CodechalHevcSfcStateG12::SetSfcAvsStateParams()
492 {
493     CODECHAL_HW_FUNCTION_ENTER;
494 
495     CODECHAL_HW_CHK_STATUS_RETURN(CodechalSfcState::SetSfcAvsStateParams());
496 
497     PMHW_SFC_AVS_STATE mhwSfcAvsState = &m_avsState;
498 
499     if (HCP_CHROMA_FORMAT_YUV444 == m_hevcPicParams->chroma_format_idc) // 444
500     {
501         mhwSfcAvsState->dwInputHorizontalSiting = 0;
502         mhwSfcAvsState->dwInputVerticalSitting = 0;
503     }
504     else if (HCP_CHROMA_FORMAT_YUV422 == m_hevcPicParams->chroma_format_idc) // 422
505     {
506         mhwSfcAvsState->dwInputHorizontalSiting = (m_chromaSiting & MHW_CHROMA_SITING_HORZ_CENTER) ? SFC_AVS_INPUT_SITING_COEF_4_OVER_8 : ((m_chromaSiting & MHW_CHROMA_SITING_HORZ_RIGHT) ? SFC_AVS_INPUT_SITING_COEF_8_OVER_8 : SFC_AVS_INPUT_SITING_COEF_0_OVER_8);
507         mhwSfcAvsState->dwInputVerticalSitting = 0;
508     }
509     else // 420
510     {
511         mhwSfcAvsState->dwInputHorizontalSiting = (m_chromaSiting & MHW_CHROMA_SITING_HORZ_CENTER) ? SFC_AVS_INPUT_SITING_COEF_4_OVER_8 : ((m_chromaSiting & MHW_CHROMA_SITING_HORZ_RIGHT) ? SFC_AVS_INPUT_SITING_COEF_8_OVER_8 : SFC_AVS_INPUT_SITING_COEF_0_OVER_8);
512         mhwSfcAvsState->dwInputVerticalSitting = (m_chromaSiting & MHW_CHROMA_SITING_VERT_CENTER) ? SFC_AVS_INPUT_SITING_COEF_4_OVER_8 : ((m_chromaSiting & MHW_CHROMA_SITING_VERT_BOTTOM) ? SFC_AVS_INPUT_SITING_COEF_8_OVER_8 : SFC_AVS_INPUT_SITING_COEF_0_OVER_8);
513     }
514 
515     return MOS_STATUS_SUCCESS;
516 }
517