1 /*
2 * Copyright (c) 2018-2024, 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 vp_csc_filter.h
24 //! \brief Defines the common interface for CSC
25 //! this file is for the base interface which is shared by all CSC in driver.
26 //!
27
28 #include "vp_csc_filter.h"
29 #include "vp_vebox_cmd_packet_base.h"
30 #include "hw_filter.h"
31 #include "sw_filter_pipe.h"
32 #include "vp_hal_ddi_utils.h"
33
34 namespace vp {
35
36 //!
37 //! \brief Chroma Downsampling and Upsampling for CNL+
38 //!
39 #define VP_VEBOX_CHROMA_UPSAMPLING_420_WITH_DI_TYPE0_HORZ_OFFSET 0
40 #define VP_VEBOX_CHROMA_UPSAMPLING_420_WITH_DI_TYPE1_HORZ_OFFSET 1
41 #define VP_VEBOX_CHROMA_UPSAMPLING_420_WITH_DI_TYPE2_HORZ_OFFSET 0
42 #define VP_VEBOX_CHROMA_UPSAMPLING_420_WITH_DI_TYPE3_HORZ_OFFSET 1
43 #define VP_VEBOX_CHROMA_UPSAMPLING_420_WITH_DI_TYPE4_HORZ_OFFSET 0
44 #define VP_VEBOX_CHROMA_UPSAMPLING_420_WITH_DI_TYPE5_HORZ_OFFSET 1
45 #define VP_VEBOX_CHROMA_UPSAMPLING_420_WITH_DI_TYPE0_VERT_OFFSET 2
46 #define VP_VEBOX_CHROMA_UPSAMPLING_420_WITH_DI_TYPE1_VERT_OFFSET 2
47 #define VP_VEBOX_CHROMA_UPSAMPLING_420_WITH_DI_TYPE2_VERT_OFFSET 0
48 #define VP_VEBOX_CHROMA_UPSAMPLING_420_WITH_DI_TYPE3_VERT_OFFSET 0
49 #define VP_VEBOX_CHROMA_UPSAMPLING_420_WITH_DI_TYPE4_VERT_OFFSET 4
50 #define VP_VEBOX_CHROMA_UPSAMPLING_420_WITH_DI_TYPE5_VERT_OFFSET 4
51 #define VP_VEBOX_CHROMA_UPSAMPLING_420_WITHOUT_DI_TYPE0_HORZ_OFFSET 0
52 #define VP_VEBOX_CHROMA_UPSAMPLING_420_WITHOUT_DI_TYPE1_HORZ_OFFSET 1
53 #define VP_VEBOX_CHROMA_UPSAMPLING_420_WITHOUT_DI_TYPE2_HORZ_OFFSET 0
54 #define VP_VEBOX_CHROMA_UPSAMPLING_420_WITHOUT_DI_TYPE3_HORZ_OFFSET 1
55 #define VP_VEBOX_CHROMA_UPSAMPLING_420_WITHOUT_DI_TYPE4_HORZ_OFFSET 0
56 #define VP_VEBOX_CHROMA_UPSAMPLING_420_WITHOUT_DI_TYPE5_HORZ_OFFSET 1
57 #define VP_VEBOX_CHROMA_UPSAMPLING_420_WITHOUT_DI_TYPE0_VERT_OFFSET 1
58 #define VP_VEBOX_CHROMA_UPSAMPLING_420_WITHOUT_DI_TYPE1_VERT_OFFSET 1
59 #define VP_VEBOX_CHROMA_UPSAMPLING_420_WITHOUT_DI_TYPE2_VERT_OFFSET 0
60 #define VP_VEBOX_CHROMA_UPSAMPLING_420_WITHOUT_DI_TYPE3_VERT_OFFSET 0
61 #define VP_VEBOX_CHROMA_UPSAMPLING_420_WITHOUT_DI_TYPE4_VERT_OFFSET 2
62 #define VP_VEBOX_CHROMA_UPSAMPLING_420_WITHOUT_DI_TYPE5_VERT_OFFSET 2
63 #define VP_VEBOX_CHROMA_UPSAMPLING_422_TYPE2_HORZ_OFFSET 0
64 #define VP_VEBOX_CHROMA_UPSAMPLING_422_TYPE3_HORZ_OFFSET 1
65 #define VP_VEBOX_CHROMA_UPSAMPLING_422_TYPE2_VERT_OFFSET 0
66 #define VP_VEBOX_CHROMA_UPSAMPLING_422_TYPE3_VERT_OFFSET 0
67 #define VP_VEBOX_CHROMA_DOWNSAMPLING_420_TYPE0_HORZ_OFFSET 0
68 #define VP_VEBOX_CHROMA_DOWNSAMPLING_420_TYPE1_HORZ_OFFSET 1
69 #define VP_VEBOX_CHROMA_DOWNSAMPLING_420_TYPE2_HORZ_OFFSET 0
70 #define VP_VEBOX_CHROMA_DOWNSAMPLING_420_TYPE3_HORZ_OFFSET 1
71 #define VP_VEBOX_CHROMA_DOWNSAMPLING_420_TYPE4_HORZ_OFFSET 0
72 #define VP_VEBOX_CHROMA_DOWNSAMPLING_420_TYPE5_HORZ_OFFSET 1
73 #define VP_VEBOX_CHROMA_DOWNSAMPLING_420_TYPE0_VERT_OFFSET 1
74 #define VP_VEBOX_CHROMA_DOWNSAMPLING_420_TYPE1_VERT_OFFSET 1
75 #define VP_VEBOX_CHROMA_DOWNSAMPLING_420_TYPE2_VERT_OFFSET 0
76 #define VP_VEBOX_CHROMA_DOWNSAMPLING_420_TYPE3_VERT_OFFSET 0
77 #define VP_VEBOX_CHROMA_DOWNSAMPLING_420_TYPE4_VERT_OFFSET 2
78 #define VP_VEBOX_CHROMA_DOWNSAMPLING_420_TYPE5_VERT_OFFSET 2
79 #define VP_VEBOX_CHROMA_DOWNSAMPLING_422_TYPE2_HORZ_OFFSET 0
80 #define VP_VEBOX_CHROMA_DOWNSAMPLING_422_TYPE3_HORZ_OFFSET 1
81 #define VP_VEBOX_CHROMA_DOWNSAMPLING_422_TYPE2_VERT_OFFSET 0
82 #define VP_VEBOX_CHROMA_DOWNSAMPLING_422_TYPE3_VERT_OFFSET 0
83
84 MOS_FORMAT GetSfcInputFormat(VP_EXECUTE_CAPS &executeCaps, MOS_FORMAT inputFormat, VPHAL_CSPACE colorSpaceOutput, MOS_FORMAT outputFormat);
85 VPHAL_CSPACE GetDemosaicOutputColorSpace(VPHAL_CSPACE colorSpace);
86 bool IsBeCscNeededForAlphaFill(MOS_FORMAT formatInput, MOS_FORMAT formatOutput, PVPHAL_ALPHA_PARAMS compAlpha);
87
VpCscFilter(PVP_MHWINTERFACE vpMhwInterface)88 VpCscFilter::VpCscFilter(PVP_MHWINTERFACE vpMhwInterface) :
89 VpFilter(vpMhwInterface)
90 {
91 }
92
Init()93 MOS_STATUS VpCscFilter::Init()
94 {
95 VP_FUNC_CALL();
96
97 return MOS_STATUS_SUCCESS;
98 }
99
Prepare()100 MOS_STATUS VpCscFilter::Prepare()
101 {
102 VP_FUNC_CALL();
103
104 return MOS_STATUS_SUCCESS;
105 }
106
Destroy()107 MOS_STATUS VpCscFilter::Destroy()
108 {
109 VP_FUNC_CALL();
110
111 if (m_sfcCSCParams)
112 {
113 MOS_FreeMemory(m_sfcCSCParams);
114 m_sfcCSCParams = nullptr;
115 }
116
117 if (m_veboxCSCParams)
118 {
119 MOS_FreeMemory(m_veboxCSCParams);
120 m_veboxCSCParams = nullptr;
121 }
122
123 return MOS_STATUS_SUCCESS;
124 }
125
SetExecuteEngineCaps(FeatureParamCsc & cscParams,VP_EXECUTE_CAPS vpExecuteCaps)126 MOS_STATUS VpCscFilter::SetExecuteEngineCaps(
127 FeatureParamCsc &cscParams,
128 VP_EXECUTE_CAPS vpExecuteCaps)
129 {
130 VP_FUNC_CALL();
131
132 m_cscParams = cscParams;
133 m_executeCaps = vpExecuteCaps;
134
135 return MOS_STATUS_SUCCESS;
136 }
137
CalculateEngineParams()138 MOS_STATUS VpCscFilter::CalculateEngineParams()
139 {
140 VP_FUNC_CALL();
141
142 if (FeatureTypeCscOnSfc == m_cscParams.type)
143 {
144 VP_RENDER_CHK_STATUS_RETURN(CalculateSfcEngineParams());
145 }
146 else if (FeatureTypeCscOnVebox == m_cscParams.type)
147 {
148 VP_RENDER_CHK_STATUS_RETURN(CalculateVeboxEngineParams());
149 }
150 else if (FeatureTypeCscOnRender == m_cscParams.type)
151 {
152 // place hold for Render solution
153 VP_PUBLIC_ASSERTMESSAGE("No function support CSC in Render path now");
154 return MOS_STATUS_UNIMPLEMENTED;
155 }
156 else
157 {
158 VP_PUBLIC_ASSERTMESSAGE("Error call, No function support CSC with such config");
159 return MOS_STATUS_INVALID_PARAMETER;
160 }
161
162 return MOS_STATUS_SUCCESS;
163 }
164
GetSfcInputColorSpace(VP_EXECUTE_CAPS & executeCaps,VPHAL_CSPACE inputColorSpace,VPHAL_CSPACE colorSpaceOutput,MOS_FORMAT outputFormat)165 VPHAL_CSPACE GetSfcInputColorSpace(VP_EXECUTE_CAPS &executeCaps, VPHAL_CSPACE inputColorSpace, VPHAL_CSPACE colorSpaceOutput, MOS_FORMAT outputFormat)
166 {
167 VP_FUNC_CALL();
168
169 if (executeCaps.b3DlutOutput)
170 {
171 if (IS_RGB64_FLOAT_FORMAT(outputFormat)) // SFC output FP16, BT2020->BT709
172 {
173 return CSpace_BT2020_RGB;
174 }
175 else
176 {
177 return IS_COLOR_SPACE_BT2020(colorSpaceOutput) ? CSpace_BT2020_RGB : CSpace_sRGB;
178 }
179 }
180
181 // return sRGB as colorspace as Vebox will do Bt202 to sRGB Gamut switch
182 if (executeCaps.bIECP && executeCaps.bCGC && executeCaps.bBt2020ToRGB)
183 {
184 return CSpace_sRGB;
185 }
186
187 if (executeCaps.bDemosaicInUse)
188 {
189 return GetDemosaicOutputColorSpace(colorSpaceOutput);
190 }
191 return inputColorSpace;
192 }
193
IsDitheringNeeded(MOS_FORMAT formatInput,MOS_FORMAT formatOutput)194 bool VpCscFilter::IsDitheringNeeded(MOS_FORMAT formatInput, MOS_FORMAT formatOutput)
195 {
196 uint32_t inputBitDepth = VpHalDDIUtils::GetSurfaceBitDepth(formatInput);
197 if (inputBitDepth == 0)
198 {
199 VP_PUBLIC_ASSERTMESSAGE("Unknown Input format %d for bit depth, return false", formatInput);
200 return false;
201 }
202 uint32_t outputBitDepth = VpHalDDIUtils::GetSurfaceBitDepth(formatOutput);
203 if (outputBitDepth == 0)
204 {
205 VP_PUBLIC_ASSERTMESSAGE("Unknown Output format %d for bit depth, return false", formatOutput);
206 return false;
207 }
208 if (inputBitDepth > outputBitDepth)
209 {
210 VP_RENDER_NORMALMESSAGE("inputFormat = %d, inputBitDepth = %d, outputFormat = %d, outputBitDepth = %d, return true",
211 formatInput,
212 inputBitDepth,
213 formatOutput,
214 outputBitDepth);
215 return true;
216 }
217 else
218 {
219 VP_RENDER_NORMALMESSAGE("inputFormat = %d, inputBitDepth = %d, outputFormat = %d, outputBitDepth = %d, return false",
220 formatInput,
221 inputBitDepth,
222 formatOutput,
223 outputBitDepth);
224 return false;
225 }
226 }
227
CalculateSfcEngineParams()228 MOS_STATUS VpCscFilter::CalculateSfcEngineParams()
229 {
230 VP_FUNC_CALL();
231
232 if (!m_executeCaps.bSFC)
233 {
234 VP_PUBLIC_ASSERTMESSAGE("Error call, function only support SFC CSC");
235 return MOS_STATUS_INVALID_PARAMETER;
236 }
237
238 if (!m_sfcCSCParams)
239 {
240 m_sfcCSCParams = (PSFC_CSC_PARAMS)MOS_AllocAndZeroMemory(sizeof(SFC_CSC_PARAMS));
241
242 if (m_sfcCSCParams == nullptr)
243 {
244 VP_PUBLIC_ASSERTMESSAGE("sfc CSC Pamas buffer allocate failed, return nullpointer");
245 return MOS_STATUS_NO_SPACE;
246 }
247 }
248 else
249 {
250 MOS_ZeroMemory(m_sfcCSCParams, sizeof(SFC_CSC_PARAMS));
251 }
252
253 m_sfcCSCParams->bIEFEnable = (m_cscParams.pIEFParams &&
254 m_cscParams.pIEFParams->bEnabled &&
255 m_cscParams.pIEFParams->fIEFFactor > 0.0F) ? true : false;
256
257 if (m_sfcCSCParams->bIEFEnable)
258 {
259 m_sfcCSCParams->iefParams = m_cscParams.pIEFParams;
260 }
261
262 m_sfcCSCParams->inputColorSpace = m_cscParams.input.colorSpace;
263
264 // IsDitheringNeeded should be called before input format being updated by GetSfcInputFormat
265 m_sfcCSCParams->isDitheringNeeded = IsDitheringNeeded(m_cscParams.formatInput, m_cscParams.formatOutput);
266
267 m_sfcCSCParams->inputColorSpace = GetSfcInputColorSpace(m_executeCaps, m_cscParams.input.colorSpace, m_cscParams.output.colorSpace, m_cscParams.formatOutput);
268
269 m_cscParams.formatInput = GetSfcInputFormat(m_executeCaps, m_cscParams.formatInput, m_cscParams.output.colorSpace, m_cscParams.formatOutput);
270 m_sfcCSCParams->inputFormat = m_cscParams.formatInput;
271 m_sfcCSCParams->outputFormat = m_cscParams.formatOutput;
272 m_sfcCSCParams->isFullRgbG10P709 = m_cscParams.isFullRgbG10P709;
273 m_sfcCSCParams->isDemosaicNeeded = m_executeCaps.bDemosaicInUse;
274
275 // No need to check m_cscParams.pAlphaParams as CalculateVeboxEngineParams does, as alpha is done by scaling filter on SFC.
276 if (m_sfcCSCParams->inputColorSpace != m_cscParams.output.colorSpace && !(IS_RGB64_FLOAT_FORMAT(m_sfcCSCParams->outputFormat) && m_sfcCSCParams->isFullRgbG10P709))
277 {
278 m_sfcCSCParams->bCSCEnabled = true;
279 }
280
281 if (IS_RGB_CSPACE(m_sfcCSCParams->inputColorSpace) || IS_COLOR_SPACE_BT2020_RGB(m_sfcCSCParams->inputColorSpace))
282 {
283 m_sfcCSCParams->isInputColorSpaceRGB = true;
284 }
285 else
286 {
287 m_sfcCSCParams->isInputColorSpaceRGB = false;
288 }
289
290 // Set Chromasting Params
291 VP_RENDER_CHK_STATUS_RETURN(SetSfcChromaParams(m_executeCaps));
292
293 return MOS_STATUS_SUCCESS;
294 }
295
CalculateVeboxEngineParams()296 MOS_STATUS VpCscFilter::CalculateVeboxEngineParams()
297 {
298 VP_FUNC_CALL();
299
300 if (!m_executeCaps.bVebox)
301 {
302 VP_PUBLIC_ASSERTMESSAGE("Error call, function only support Vebox CSC");
303 return MOS_STATUS_INVALID_PARAMETER;
304 }
305
306 if (!m_veboxCSCParams)
307 {
308 m_veboxCSCParams = (PVEBOX_CSC_PARAMS)MOS_AllocAndZeroMemory(sizeof(VEBOX_CSC_PARAMS));
309
310 if (m_veboxCSCParams == nullptr)
311 {
312 VP_PUBLIC_ASSERTMESSAGE("sfc CSC Pamas buffer allocate failed, return nullpointer");
313 return MOS_STATUS_NO_SPACE;
314 }
315 }
316 else
317 {
318 MOS_ZeroMemory(m_veboxCSCParams, sizeof(VEBOX_CSC_PARAMS));
319 }
320
321 bool isBeCscNeededForAlphaFill = IsBeCscNeededForAlphaFill(
322 m_cscParams.formatInput, m_cscParams.formatOutput, m_cscParams.pAlphaParams);
323
324 m_veboxCSCParams->inputColorSpace = m_cscParams.input.colorSpace;
325 m_veboxCSCParams->outputColorSpace = m_cscParams.output.colorSpace;
326 m_veboxCSCParams->inputFormat = m_cscParams.formatInput;
327 m_veboxCSCParams->outputFormat = m_cscParams.formatOutput;
328
329 m_veboxCSCParams->bCSCEnabled = (m_cscParams.input.colorSpace != m_cscParams.output.colorSpace || isBeCscNeededForAlphaFill);
330 m_veboxCSCParams->alphaParams = m_cscParams.pAlphaParams;
331
332 VP_RENDER_CHK_STATUS_RETURN(UpdateChromaSiting(m_executeCaps));
333
334 VP_RENDER_CHK_STATUS_RETURN(SetVeboxCUSChromaParams(m_executeCaps));
335 VP_RENDER_CHK_STATUS_RETURN(SetVeboxCDSChromaParams(m_executeCaps));
336
337 return MOS_STATUS_SUCCESS;
338 }
339
SetSfcChromaParams(VP_EXECUTE_CAPS vpExecuteCaps)340 MOS_STATUS VpCscFilter::SetSfcChromaParams(
341 VP_EXECUTE_CAPS vpExecuteCaps)
342 {
343 VP_FUNC_CALL();
344
345 VP_RENDER_CHK_NULL_RETURN(m_sfcCSCParams);
346
347 // Update chroma sitting according to updated input format.
348 VP_RENDER_CHK_STATUS_RETURN(UpdateChromaSiting(vpExecuteCaps));
349
350 m_sfcCSCParams->sfcSrcChromaSiting = m_cscParams.input.chromaSiting;
351
352 // Setup General params
353 // Set chroma subsampling type according to the Vebox output, but
354 // when Vebox is bypassed, set it according to the source surface format.
355 // VDBOX SFC doesn't use 8 tap chroma filtering for all input format.
356
357 if (vpExecuteCaps.bVebox)
358 {
359 if (VpHalDDIUtils::GetSurfaceColorPack(m_sfcCSCParams->inputFormat) == VPHAL_COLORPACK_444)
360 {
361 m_sfcCSCParams->b8tapChromafiltering = true;
362 }
363 else
364 {
365 m_sfcCSCParams->b8tapChromafiltering = false;
366 }
367 }
368 else
369 {
370 m_sfcCSCParams->b8tapChromafiltering = false;
371 }
372
373 m_sfcCSCParams->chromaDownSamplingHorizontalCoef = (m_cscParams.output.chromaSiting & MHW_CHROMA_SITING_HORZ_CENTER) ? MEDIASTATE_SFC_CHROMA_DOWNSAMPLING_COEF_4_OVER_8 :
374 ((m_cscParams.output.chromaSiting & MHW_CHROMA_SITING_HORZ_RIGHT) ? MEDIASTATE_SFC_CHROMA_DOWNSAMPLING_COEF_8_OVER_8 :
375 MEDIASTATE_SFC_CHROMA_DOWNSAMPLING_COEF_0_OVER_8);
376 m_sfcCSCParams->chromaDownSamplingVerticalCoef = (m_cscParams.output.chromaSiting & MHW_CHROMA_SITING_VERT_CENTER) ? MEDIASTATE_SFC_CHROMA_DOWNSAMPLING_COEF_4_OVER_8 :
377 ((m_cscParams.output.chromaSiting & MHW_CHROMA_SITING_VERT_BOTTOM) ? MEDIASTATE_SFC_CHROMA_DOWNSAMPLING_COEF_8_OVER_8 :
378 MEDIASTATE_SFC_CHROMA_DOWNSAMPLING_COEF_0_OVER_8);
379
380 m_sfcCSCParams->bChromaUpSamplingEnable = IsChromaUpSamplingNeeded();
381
382 return MOS_STATUS_SUCCESS;
383 }
384
SetVeboxCUSChromaParams(VP_EXECUTE_CAPS vpExecuteCaps)385 MOS_STATUS VpCscFilter::SetVeboxCUSChromaParams(VP_EXECUTE_CAPS vpExecuteCaps)
386 {
387 VP_FUNC_CALL();
388
389 VP_RENDER_CHK_NULL_RETURN(m_veboxCSCParams);
390
391 VPHAL_COLORPACK srcColorPack;
392 bool bNeedUpSampling = vpExecuteCaps.bIECP || m_veboxCSCParams->bCSCEnabled ||
393 (vpExecuteCaps.b3DlutOutput && !vpExecuteCaps.bHDR3DLUT);
394 bool bDIEnabled = vpExecuteCaps.bDI;
395
396 if (Format_None != m_cscParams.formatforCUS)
397 {
398 srcColorPack = VpHalDDIUtils::GetSurfaceColorPack(m_cscParams.formatforCUS);
399 }
400 else
401 {
402 srcColorPack = VpHalDDIUtils::GetSurfaceColorPack(m_cscParams.formatInput);
403 }
404
405 // Init CUS as disabled
406 m_veboxCSCParams->bypassCUS = true;
407
408 if (bNeedUpSampling)
409 {
410 // Type 0
411 if ((m_cscParams.input.chromaSiting & MHW_CHROMA_SITING_HORZ_LEFT) &&
412 (m_cscParams.input.chromaSiting & MHW_CHROMA_SITING_VERT_CENTER))
413 {
414 if (srcColorPack == VPHAL_COLORPACK_420)
415 {
416 m_veboxCSCParams->bypassCUS = false;
417 if (bDIEnabled)
418 {
419 m_veboxCSCParams->chromaUpSamplingHorizontalCoef = VP_VEBOX_CHROMA_UPSAMPLING_420_WITH_DI_TYPE0_HORZ_OFFSET;
420 m_veboxCSCParams->chromaUpSamplingVerticalCoef = VP_VEBOX_CHROMA_UPSAMPLING_420_WITH_DI_TYPE0_VERT_OFFSET;
421 }
422 else
423 {
424 m_veboxCSCParams->chromaUpSamplingHorizontalCoef = VP_VEBOX_CHROMA_UPSAMPLING_420_WITHOUT_DI_TYPE0_HORZ_OFFSET;
425 m_veboxCSCParams->chromaUpSamplingVerticalCoef = VP_VEBOX_CHROMA_UPSAMPLING_420_WITHOUT_DI_TYPE0_VERT_OFFSET;
426 }
427 }
428 }
429 // Type 1
430 else if ((m_cscParams.input.chromaSiting & MHW_CHROMA_SITING_HORZ_CENTER) &&
431 (m_cscParams.input.chromaSiting & MHW_CHROMA_SITING_VERT_CENTER))
432 {
433 if (srcColorPack == VPHAL_COLORPACK_420)
434 {
435 m_veboxCSCParams->bypassCUS = false;
436 if (bDIEnabled)
437 {
438 m_veboxCSCParams->chromaUpSamplingHorizontalCoef = VP_VEBOX_CHROMA_UPSAMPLING_420_WITH_DI_TYPE1_HORZ_OFFSET;
439 m_veboxCSCParams->chromaUpSamplingVerticalCoef = VP_VEBOX_CHROMA_UPSAMPLING_420_WITH_DI_TYPE1_VERT_OFFSET;
440 }
441 else
442 {
443 m_veboxCSCParams->chromaUpSamplingHorizontalCoef = VP_VEBOX_CHROMA_UPSAMPLING_420_WITHOUT_DI_TYPE1_HORZ_OFFSET;
444 m_veboxCSCParams->chromaUpSamplingVerticalCoef = VP_VEBOX_CHROMA_UPSAMPLING_420_WITHOUT_DI_TYPE1_VERT_OFFSET;
445 }
446 }
447 }
448 // Type 2
449 else if ((m_cscParams.input.chromaSiting & MHW_CHROMA_SITING_HORZ_LEFT) &&
450 (m_cscParams.input.chromaSiting & MHW_CHROMA_SITING_VERT_TOP))
451 {
452 if (srcColorPack == VPHAL_COLORPACK_420)
453 {
454 m_veboxCSCParams->bypassCUS = false;
455 if (bDIEnabled)
456 {
457 m_veboxCSCParams->chromaUpSamplingHorizontalCoef = VP_VEBOX_CHROMA_UPSAMPLING_420_WITH_DI_TYPE2_HORZ_OFFSET;
458 m_veboxCSCParams->chromaUpSamplingVerticalCoef = VP_VEBOX_CHROMA_UPSAMPLING_420_WITH_DI_TYPE2_VERT_OFFSET;
459 }
460 else
461 {
462 m_veboxCSCParams->chromaUpSamplingHorizontalCoef = VP_VEBOX_CHROMA_UPSAMPLING_420_WITHOUT_DI_TYPE2_HORZ_OFFSET;
463 m_veboxCSCParams->chromaUpSamplingVerticalCoef = VP_VEBOX_CHROMA_UPSAMPLING_420_WITHOUT_DI_TYPE2_VERT_OFFSET;
464 }
465 }
466 else if (srcColorPack == VPHAL_COLORPACK_422)
467 {
468 m_veboxCSCParams->bypassCUS = false;
469 m_veboxCSCParams->chromaUpSamplingHorizontalCoef = VP_VEBOX_CHROMA_UPSAMPLING_422_TYPE2_HORZ_OFFSET;
470 m_veboxCSCParams->chromaUpSamplingVerticalCoef = VP_VEBOX_CHROMA_UPSAMPLING_422_TYPE2_VERT_OFFSET;
471 }
472 }
473 // Type 3
474 else if ((m_cscParams.input.chromaSiting & MHW_CHROMA_SITING_HORZ_CENTER) &&
475 (m_cscParams.input.chromaSiting & MHW_CHROMA_SITING_VERT_TOP))
476 {
477 if (srcColorPack == VPHAL_COLORPACK_420)
478 {
479 m_veboxCSCParams->bypassCUS = false;
480 if (bDIEnabled)
481 {
482 m_veboxCSCParams->chromaUpSamplingHorizontalCoef = VP_VEBOX_CHROMA_UPSAMPLING_420_WITH_DI_TYPE3_HORZ_OFFSET;
483 m_veboxCSCParams->chromaUpSamplingVerticalCoef = VP_VEBOX_CHROMA_UPSAMPLING_420_WITH_DI_TYPE3_VERT_OFFSET;
484 }
485 else
486 {
487 m_veboxCSCParams->chromaUpSamplingHorizontalCoef = VP_VEBOX_CHROMA_UPSAMPLING_420_WITHOUT_DI_TYPE3_HORZ_OFFSET;
488 m_veboxCSCParams->chromaUpSamplingVerticalCoef = VP_VEBOX_CHROMA_UPSAMPLING_420_WITHOUT_DI_TYPE3_VERT_OFFSET;
489 }
490 }
491 else if (srcColorPack == VPHAL_COLORPACK_422)
492 {
493 m_veboxCSCParams->bypassCUS = false;
494 m_veboxCSCParams->chromaUpSamplingHorizontalCoef = VP_VEBOX_CHROMA_UPSAMPLING_422_TYPE3_HORZ_OFFSET;
495 m_veboxCSCParams->chromaUpSamplingVerticalCoef = VP_VEBOX_CHROMA_UPSAMPLING_422_TYPE3_VERT_OFFSET;
496 }
497 }
498 // Type 4
499 else if ((m_cscParams.input.chromaSiting & MHW_CHROMA_SITING_HORZ_LEFT) &&
500 (m_cscParams.input.chromaSiting & MHW_CHROMA_SITING_VERT_BOTTOM))
501 {
502 if (srcColorPack == VPHAL_COLORPACK_420)
503 {
504 m_veboxCSCParams->bypassCUS = false;
505 if (bDIEnabled)
506 {
507 m_veboxCSCParams->chromaUpSamplingHorizontalCoef = VP_VEBOX_CHROMA_UPSAMPLING_420_WITH_DI_TYPE4_HORZ_OFFSET;
508 m_veboxCSCParams->chromaUpSamplingVerticalCoef = VP_VEBOX_CHROMA_UPSAMPLING_420_WITH_DI_TYPE4_VERT_OFFSET;
509 }
510 else
511 {
512 m_veboxCSCParams->chromaUpSamplingHorizontalCoef = VP_VEBOX_CHROMA_UPSAMPLING_420_WITHOUT_DI_TYPE4_HORZ_OFFSET;
513 m_veboxCSCParams->chromaUpSamplingVerticalCoef = VP_VEBOX_CHROMA_UPSAMPLING_420_WITHOUT_DI_TYPE4_VERT_OFFSET;
514 }
515 }
516 }
517 // Type 5
518 else if ((m_cscParams.input.chromaSiting & MHW_CHROMA_SITING_HORZ_CENTER) &&
519 (m_cscParams.input.chromaSiting & MHW_CHROMA_SITING_VERT_BOTTOM))
520 {
521 if (srcColorPack == VPHAL_COLORPACK_420)
522 {
523 m_veboxCSCParams->bypassCUS = false;
524 if (bDIEnabled)
525 {
526 m_veboxCSCParams->chromaUpSamplingHorizontalCoef = VP_VEBOX_CHROMA_UPSAMPLING_420_WITH_DI_TYPE5_HORZ_OFFSET;
527 m_veboxCSCParams->chromaUpSamplingVerticalCoef = VP_VEBOX_CHROMA_UPSAMPLING_420_WITH_DI_TYPE5_VERT_OFFSET;
528 }
529 else
530 {
531 m_veboxCSCParams->chromaUpSamplingHorizontalCoef = VP_VEBOX_CHROMA_UPSAMPLING_420_WITHOUT_DI_TYPE5_HORZ_OFFSET;
532 m_veboxCSCParams->chromaUpSamplingVerticalCoef = VP_VEBOX_CHROMA_UPSAMPLING_420_WITHOUT_DI_TYPE5_VERT_OFFSET;
533 }
534 }
535 }
536 }
537
538 VP_RENDER_NORMALMESSAGE("bypassCUS %d, chromaUpSamplingHorizontalCoef %d, chromaUpSamplingVerticalCoef %d",
539 m_veboxCSCParams->bypassCUS, m_veboxCSCParams->chromaUpSamplingHorizontalCoef, m_veboxCSCParams->chromaUpSamplingVerticalCoef);
540
541 return MOS_STATUS_SUCCESS;
542 }
543
SetVeboxCDSChromaParams(VP_EXECUTE_CAPS vpExecuteCaps)544 MOS_STATUS VpCscFilter::SetVeboxCDSChromaParams(VP_EXECUTE_CAPS vpExecuteCaps)
545 {
546 VP_FUNC_CALL();
547
548 bool bNeedDownSampling = false;
549
550 VPHAL_COLORPACK dstColorPack = VpHalDDIUtils::GetSurfaceColorPack(m_cscParams.formatOutput);
551
552 // Only VEBOX output, we use VEO to do downsampling.
553 // Else, we use SFC/FC path to do downscaling.
554 // if VEBOX intermediate buffer format is non_YUY2 on DI case, enable downsampling as center-left
555 if (vpExecuteCaps.bDI && (m_cscParams.formatOutput != Format_YUY2 || vpExecuteCaps.bIECP))
556 {
557 bNeedDownSampling = true;
558 }
559 else
560 {
561 bNeedDownSampling = vpExecuteCaps.bVebox && !vpExecuteCaps.bSFC && !vpExecuteCaps.bForceCscToRender;
562 }
563
564 // Init as CDS disabled
565 m_veboxCSCParams->bypassCDS = true;
566
567 if (bNeedDownSampling)
568 {
569 // Type 0
570 if ((m_cscParams.output.chromaSiting & MHW_CHROMA_SITING_HORZ_LEFT) &&
571 (m_cscParams.output.chromaSiting & MHW_CHROMA_SITING_VERT_CENTER))
572 {
573 if (dstColorPack == VPHAL_COLORPACK_420)
574 {
575 m_veboxCSCParams->bypassCDS = false;
576 m_veboxCSCParams->chromaDownSamplingHorizontalCoef = VP_VEBOX_CHROMA_DOWNSAMPLING_420_TYPE0_HORZ_OFFSET;
577 m_veboxCSCParams->chromaDownSamplingVerticalCoef = VP_VEBOX_CHROMA_DOWNSAMPLING_420_TYPE0_VERT_OFFSET;
578 }
579 }
580 // Type 1
581 else if ((m_cscParams.output.chromaSiting & MHW_CHROMA_SITING_HORZ_CENTER) &&
582 (m_cscParams.output.chromaSiting & MHW_CHROMA_SITING_VERT_CENTER))
583 {
584 if (dstColorPack == VPHAL_COLORPACK_420)
585 {
586 m_veboxCSCParams->bypassCDS = false;
587 m_veboxCSCParams->chromaDownSamplingHorizontalCoef = VP_VEBOX_CHROMA_DOWNSAMPLING_420_TYPE1_HORZ_OFFSET;
588 m_veboxCSCParams->chromaDownSamplingVerticalCoef = VP_VEBOX_CHROMA_DOWNSAMPLING_420_TYPE1_VERT_OFFSET;
589 }
590 }
591 // Type 2
592 else if ((m_cscParams.output.chromaSiting & MHW_CHROMA_SITING_HORZ_LEFT) &&
593 (m_cscParams.output.chromaSiting & MHW_CHROMA_SITING_VERT_TOP))
594 {
595 if (dstColorPack == VPHAL_COLORPACK_420)
596 {
597 m_veboxCSCParams->bypassCDS = false;
598 m_veboxCSCParams->chromaDownSamplingHorizontalCoef = VP_VEBOX_CHROMA_DOWNSAMPLING_420_TYPE2_HORZ_OFFSET;
599 m_veboxCSCParams->chromaDownSamplingVerticalCoef = VP_VEBOX_CHROMA_DOWNSAMPLING_420_TYPE2_VERT_OFFSET;
600 }
601 else if (dstColorPack == VPHAL_COLORPACK_422)
602 {
603 m_veboxCSCParams->bypassCDS = false;
604 m_veboxCSCParams->chromaDownSamplingHorizontalCoef = VP_VEBOX_CHROMA_DOWNSAMPLING_422_TYPE2_HORZ_OFFSET;
605 m_veboxCSCParams->chromaDownSamplingVerticalCoef = VP_VEBOX_CHROMA_DOWNSAMPLING_422_TYPE2_VERT_OFFSET;
606 }
607 }
608 // Type 3
609 else if ((m_cscParams.output.chromaSiting & MHW_CHROMA_SITING_HORZ_CENTER) &&
610 (m_cscParams.output.chromaSiting & MHW_CHROMA_SITING_VERT_TOP))
611 {
612 if (dstColorPack == VPHAL_COLORPACK_420)
613 {
614 m_veboxCSCParams->bypassCDS = false;
615 m_veboxCSCParams->chromaDownSamplingHorizontalCoef = VP_VEBOX_CHROMA_DOWNSAMPLING_420_TYPE3_HORZ_OFFSET;
616 m_veboxCSCParams->chromaDownSamplingVerticalCoef = VP_VEBOX_CHROMA_DOWNSAMPLING_420_TYPE3_VERT_OFFSET;
617 }
618 else if (dstColorPack == VPHAL_COLORPACK_422)
619 {
620 m_veboxCSCParams->bypassCDS = false;
621 m_veboxCSCParams->chromaDownSamplingHorizontalCoef = VP_VEBOX_CHROMA_DOWNSAMPLING_422_TYPE3_HORZ_OFFSET;
622 m_veboxCSCParams->chromaDownSamplingVerticalCoef = VP_VEBOX_CHROMA_DOWNSAMPLING_422_TYPE3_VERT_OFFSET;
623 }
624 }
625 // Type 4
626 else if ((m_cscParams.output.chromaSiting & MHW_CHROMA_SITING_HORZ_LEFT) &&
627 (m_cscParams.output.chromaSiting & MHW_CHROMA_SITING_VERT_BOTTOM))
628 {
629 if (dstColorPack == VPHAL_COLORPACK_420)
630 {
631 m_veboxCSCParams->bypassCDS = false;
632 m_veboxCSCParams->chromaDownSamplingHorizontalCoef = VP_VEBOX_CHROMA_DOWNSAMPLING_420_TYPE4_HORZ_OFFSET;
633 m_veboxCSCParams->chromaDownSamplingVerticalCoef = VP_VEBOX_CHROMA_DOWNSAMPLING_420_TYPE4_VERT_OFFSET;
634 }
635 }
636 // Type 5
637 else if ((m_cscParams.output.chromaSiting & MHW_CHROMA_SITING_HORZ_CENTER) &&
638 (m_cscParams.output.chromaSiting & MHW_CHROMA_SITING_VERT_BOTTOM))
639 {
640 if (dstColorPack == VPHAL_COLORPACK_420)
641 {
642 m_veboxCSCParams->bypassCDS = false;
643 m_veboxCSCParams->chromaDownSamplingHorizontalCoef = VP_VEBOX_CHROMA_DOWNSAMPLING_420_TYPE5_HORZ_OFFSET;
644 m_veboxCSCParams->chromaDownSamplingVerticalCoef = VP_VEBOX_CHROMA_DOWNSAMPLING_420_TYPE5_VERT_OFFSET;
645 }
646 }
647 }
648
649 VP_RENDER_NORMALMESSAGE("bypassCDS %d, chromaDownSamplingHorizontalCoef %d, chromaDownSamplingVerticalCoef %d",
650 m_veboxCSCParams->bypassCDS, m_veboxCSCParams->chromaDownSamplingHorizontalCoef, m_veboxCSCParams->chromaDownSamplingVerticalCoef);
651
652 return MOS_STATUS_SUCCESS;
653 }
654
UpdateChromaSiting(VP_EXECUTE_CAPS vpExecuteCaps)655 MOS_STATUS VpCscFilter::UpdateChromaSiting(VP_EXECUTE_CAPS vpExecuteCaps)
656 {
657 VP_FUNC_CALL();
658
659 // For VDBOX input, just using the chroma siting input directly.
660 if (!vpExecuteCaps.bVebox)
661 {
662 return MOS_STATUS_SUCCESS;
663 }
664
665 if (MHW_CHROMA_SITING_NONE == m_cscParams.input.chromaSiting)
666 {
667 m_cscParams.input.chromaSiting = (CHROMA_SITING_HORZ_LEFT | CHROMA_SITING_VERT_CENTER);
668 }
669 switch (VpHalDDIUtils::GetSurfaceColorPack(m_cscParams.formatInput))
670 {
671 case VPHAL_COLORPACK_422:
672 m_cscParams.input.chromaSiting = (m_cscParams.input.chromaSiting & 0x7) | CHROMA_SITING_VERT_TOP;
673 break;
674 case VPHAL_COLORPACK_444:
675 m_cscParams.input.chromaSiting = CHROMA_SITING_HORZ_LEFT | CHROMA_SITING_VERT_TOP;
676 break;
677 default:
678 break;
679 }
680
681 if (MHW_CHROMA_SITING_NONE == m_cscParams.output.chromaSiting)
682 {
683 m_cscParams.output.chromaSiting = (CHROMA_SITING_HORZ_LEFT | CHROMA_SITING_VERT_CENTER);
684 }
685 switch (VpHalDDIUtils::GetSurfaceColorPack(m_cscParams.formatOutput))
686 {
687 case VPHAL_COLORPACK_422:
688 m_cscParams.output.chromaSiting = (m_cscParams.output.chromaSiting & 0x7) | CHROMA_SITING_VERT_TOP;
689 break;
690 case VPHAL_COLORPACK_444:
691 m_cscParams.output.chromaSiting = CHROMA_SITING_HORZ_LEFT | CHROMA_SITING_VERT_TOP;
692 break;
693 default:
694 break;
695 }
696
697 return MOS_STATUS_SUCCESS;
698 }
699
IsChromaUpSamplingNeeded()700 bool VpCscFilter::IsChromaUpSamplingNeeded()
701 {
702 VP_FUNC_CALL();
703
704 bool bChromaUpSampling = false;
705 VPHAL_COLORPACK srcColorPack, dstColorPack;
706
707 srcColorPack = VpHalDDIUtils::GetSurfaceColorPack(m_cscParams.formatInput);
708 dstColorPack = VpHalDDIUtils::GetSurfaceColorPack(m_cscParams.formatOutput);
709
710 if ((srcColorPack == VPHAL_COLORPACK_420 &&
711 (dstColorPack == VPHAL_COLORPACK_422 || dstColorPack == VPHAL_COLORPACK_444)) ||
712 (srcColorPack == VPHAL_COLORPACK_422 && dstColorPack == VPHAL_COLORPACK_444))
713 {
714 bChromaUpSampling = true;
715 }
716
717 VP_PUBLIC_NORMALMESSAGE("formatInput %d, formatOutput %d, srcColorPack %d, dstColorPack %d, bChromaUpSampling %d",
718 m_cscParams.formatInput, m_cscParams.formatOutput, srcColorPack, dstColorPack, bChromaUpSampling ? 1 : 0);
719
720 return bChromaUpSampling;
721 }
722
723 /****************************************************************************************************/
724 /* HwFilter Csc Parameter */
725 /****************************************************************************************************/
Create(HW_FILTER_CSC_PARAM & param,FeatureType featureType)726 HwFilterParameter *HwFilterCscParameter::Create(HW_FILTER_CSC_PARAM ¶m, FeatureType featureType)
727 {
728 VP_FUNC_CALL();
729
730 HwFilterCscParameter *p = MOS_New(HwFilterCscParameter, featureType);
731 if (p)
732 {
733 if (MOS_FAILED(p->Initialize(param)))
734 {
735 MOS_Delete(p);
736 return nullptr;
737 }
738 }
739 return p;
740 }
741
HwFilterCscParameter(FeatureType featureType)742 HwFilterCscParameter::HwFilterCscParameter(FeatureType featureType) : HwFilterParameter(featureType)
743 {
744 }
745
~HwFilterCscParameter()746 HwFilterCscParameter::~HwFilterCscParameter()
747 {
748 }
749
ConfigParams(HwFilter & hwFilter)750 MOS_STATUS HwFilterCscParameter::ConfigParams(HwFilter &hwFilter)
751 {
752 VP_FUNC_CALL();
753
754 return hwFilter.ConfigParam(m_Params);
755 }
756
Initialize(HW_FILTER_CSC_PARAM & param)757 MOS_STATUS HwFilterCscParameter::Initialize(HW_FILTER_CSC_PARAM ¶m)
758 {
759 VP_FUNC_CALL();
760
761 m_Params = param;
762 return MOS_STATUS_SUCCESS;
763 }
764
765 /****************************************************************************************************/
766 /* Packet Sfc Csc Parameter */
767 /****************************************************************************************************/
Create(HW_FILTER_CSC_PARAM & param)768 VpPacketParameter *VpSfcCscParameter::Create(HW_FILTER_CSC_PARAM ¶m)
769 {
770 VP_FUNC_CALL();
771
772 if (nullptr == param.pPacketParamFactory)
773 {
774 return nullptr;
775 }
776 VpSfcCscParameter *p = dynamic_cast<VpSfcCscParameter *>(param.pPacketParamFactory->GetPacketParameter(param.pHwInterface));
777 if (p)
778 {
779 if (MOS_FAILED(p->Initialize(param)))
780 {
781 VpPacketParameter *pParam = p;
782 param.pPacketParamFactory->ReturnPacketParameter(pParam);
783 return nullptr;
784 }
785 }
786 return p;
787 }
788
VpSfcCscParameter(PVP_MHWINTERFACE pHwInterface,PacketParamFactoryBase * packetParamFactory)789 VpSfcCscParameter::VpSfcCscParameter(PVP_MHWINTERFACE pHwInterface, PacketParamFactoryBase *packetParamFactory) :
790 VpPacketParameter(packetParamFactory), m_CscFilter(pHwInterface)
791 {
792 }
~VpSfcCscParameter()793 VpSfcCscParameter::~VpSfcCscParameter() {}
794
SetPacketParam(VpCmdPacket * _packet)795 bool VpSfcCscParameter::SetPacketParam(VpCmdPacket *_packet)
796 {
797 VP_FUNC_CALL();
798
799 SFC_CSC_PARAMS *params = m_CscFilter.GetSfcParams();
800 if (nullptr == params)
801 {
802 VP_PUBLIC_ASSERTMESSAGE("Failed to get sfc csc params");
803 return false;
804 }
805
806 VpVeboxCmdPacketBase *packet = dynamic_cast<VpVeboxCmdPacketBase *>(_packet);
807 if (packet)
808 {
809 return MOS_SUCCEEDED(packet->SetSfcCSCParams(params));
810 }
811
812 VP_PUBLIC_ASSERTMESSAGE("Invalid packet for sfc csc");
813 return false;
814 }
815
Initialize(HW_FILTER_CSC_PARAM & params)816 MOS_STATUS VpSfcCscParameter::Initialize(HW_FILTER_CSC_PARAM ¶ms)
817 {
818 VP_FUNC_CALL();
819
820 VP_PUBLIC_CHK_STATUS_RETURN(m_CscFilter.Init());
821 VP_PUBLIC_CHK_STATUS_RETURN(m_CscFilter.SetExecuteEngineCaps(params.cscParams, params.vpExecuteCaps));
822 VP_PUBLIC_CHK_STATUS_RETURN(m_CscFilter.CalculateEngineParams());
823 return MOS_STATUS_SUCCESS;
824 }
825
826 /****************************************************************************************************/
827 /* Policy Sfc Csc Handler */
828 /****************************************************************************************************/
PolicySfcCscHandler(VP_HW_CAPS & hwCaps)829 PolicySfcCscHandler::PolicySfcCscHandler(VP_HW_CAPS &hwCaps) : PolicyFeatureHandler(hwCaps)
830 {
831 m_Type = FeatureTypeCscOnSfc;
832 }
~PolicySfcCscHandler()833 PolicySfcCscHandler::~PolicySfcCscHandler()
834 {
835 }
836
IsFeatureEnabled(VP_EXECUTE_CAPS vpExecuteCaps)837 bool PolicySfcCscHandler::IsFeatureEnabled(VP_EXECUTE_CAPS vpExecuteCaps)
838 {
839 VP_FUNC_CALL();
840
841 return vpExecuteCaps.bSfcCsc;
842 }
843
CreateHwFilterParam(VP_EXECUTE_CAPS vpExecuteCaps,SwFilterPipe & swFilterPipe,PVP_MHWINTERFACE pHwInterface)844 HwFilterParameter *PolicySfcCscHandler::CreateHwFilterParam(VP_EXECUTE_CAPS vpExecuteCaps, SwFilterPipe &swFilterPipe, PVP_MHWINTERFACE pHwInterface)
845 {
846 VP_FUNC_CALL();
847
848 if (IsFeatureEnabled(vpExecuteCaps))
849 {
850 if (SwFilterPipeType1To1 != swFilterPipe.GetSwFilterPipeType())
851 {
852 VP_PUBLIC_ASSERTMESSAGE("Invalid parameter! Sfc only support 1To1 swFilterPipe!");
853 return nullptr;
854 }
855
856 SwFilterCsc *swFilter = dynamic_cast<SwFilterCsc *>(swFilterPipe.GetSwFilter(true, 0, FeatureTypeCscOnSfc));
857
858 if (nullptr == swFilter)
859 {
860 VP_PUBLIC_ASSERTMESSAGE("Invalid parameter! Feature enabled in vpExecuteCaps but no swFilter exists!");
861 return nullptr;
862 }
863
864 FeatureParamCsc ¶m = swFilter->GetSwFilterParams();
865
866 HW_FILTER_CSC_PARAM paramCsc = {};
867 paramCsc.type = m_Type;
868 paramCsc.pHwInterface = pHwInterface;
869 paramCsc.vpExecuteCaps = vpExecuteCaps;
870 paramCsc.pPacketParamFactory = &m_PacketParamFactory;
871 paramCsc.cscParams = param;
872 paramCsc.pfnCreatePacketParam = PolicySfcCscHandler::CreatePacketParam;
873
874 HwFilterParameter *pHwFilterParam = GetHwFeatureParameterFromPool();
875
876 if (pHwFilterParam)
877 {
878 if (MOS_FAILED(((HwFilterCscParameter*)pHwFilterParam)->Initialize(paramCsc)))
879 {
880 ReleaseHwFeatureParameter(pHwFilterParam);
881 }
882 }
883 else
884 {
885 pHwFilterParam = HwFilterCscParameter::Create(paramCsc, m_Type);
886 }
887
888 return pHwFilterParam;
889 }
890 else
891 {
892 return nullptr;
893 }
894 }
895
UpdateFeaturePipe(VP_EXECUTE_CAPS caps,SwFilter & feature,SwFilterPipe & featurePipe,SwFilterPipe & executePipe,bool isInputPipe,int index)896 MOS_STATUS PolicySfcCscHandler::UpdateFeaturePipe(VP_EXECUTE_CAPS caps, SwFilter &feature, SwFilterPipe &featurePipe, SwFilterPipe &executePipe, bool isInputPipe, int index)
897 {
898 VP_FUNC_CALL();
899
900 SwFilterCsc *featureCsc = dynamic_cast<SwFilterCsc *>(&feature);
901 VP_PUBLIC_CHK_NULL_RETURN(featureCsc);
902
903 if (caps.b1stPassOfSfc2PassScaling || caps.bForceCscToRender)
904 {
905 SwFilterCsc *filter2ndPass = featureCsc;
906 SwFilterCsc *filter1ndPass = (SwFilterCsc *)feature.Clone();
907
908 VP_PUBLIC_CHK_NULL_RETURN(filter1ndPass);
909 VP_PUBLIC_CHK_NULL_RETURN(filter2ndPass);
910
911 filter1ndPass->GetFilterEngineCaps() = filter2ndPass->GetFilterEngineCaps();
912 filter1ndPass->SetFeatureType(filter2ndPass->GetFeatureType());
913
914 FeatureParamCsc ¶ms2ndPass = filter2ndPass->GetSwFilterParams();
915 FeatureParamCsc ¶ms1stPass = filter1ndPass->GetSwFilterParams();
916
917 // No csc in 1st pass.
918 params1stPass.formatOutput = params1stPass.formatInput;
919 params1stPass.output = params1stPass.input;
920 if (caps.b1stPassOfSfc2PassScaling)
921 {
922 params1stPass.pIEFParams = nullptr;
923 }
924 else
925 {
926 // 2nd pass is render. Do IEF in first pass as it is not supported in 3D sampler.
927 params1stPass.pIEFParams = params2ndPass.pIEFParams;
928 params2ndPass.pIEFParams = nullptr;
929 }
930 params1stPass.pAlphaParams = nullptr;
931
932 // Clear engine caps for filter in 2nd pass.
933 filter2ndPass->SetFeatureType(FeatureTypeCsc);
934 filter2ndPass->GetFilterEngineCaps().usedForNextPass = 1;
935
936 if (caps.bForceCscToRender)
937 {
938 // Switch to render engine for csc filter.
939 VP_PUBLIC_NORMALMESSAGE("Force csc to render case. VeboxNeeded: %d -> 0, SfcNeeded: %d -> %d, RenderNeeded: %d -> 1",
940 filter2ndPass->GetFilterEngineCaps().VeboxNeeded,
941 filter2ndPass->GetFilterEngineCaps().SfcNeeded,
942 caps.b1stPassOfSfc2PassScaling,
943 filter2ndPass->GetFilterEngineCaps().RenderNeeded);
944 filter2ndPass->GetFilterEngineCaps().bEnabled = 1;
945 filter2ndPass->GetFilterEngineCaps().VeboxNeeded = 0;
946 filter2ndPass->GetFilterEngineCaps().SfcNeeded = caps.b1stPassOfSfc2PassScaling;
947 filter2ndPass->GetFilterEngineCaps().RenderNeeded = 1;
948 filter2ndPass->GetFilterEngineCaps().fcSupported = 1;
949 }
950
951 executePipe.AddSwFilterUnordered(filter1ndPass, isInputPipe, index);
952 }
953 else
954 {
955 return PolicyFeatureHandler::UpdateFeaturePipe(caps, feature, featurePipe, executePipe, isInputPipe, index);
956 }
957
958 return MOS_STATUS_SUCCESS;
959 }
960
961 /****************************************************************************************************/
962 /* Vebox Csc Parameter */
963 /****************************************************************************************************/
Create(HW_FILTER_CSC_PARAM & param)964 VpPacketParameter* VpVeboxCscParameter::Create(HW_FILTER_CSC_PARAM& param)
965 {
966 VP_FUNC_CALL();
967
968 if (nullptr == param.pPacketParamFactory)
969 {
970 return nullptr;
971 }
972 VpVeboxCscParameter* p = dynamic_cast<VpVeboxCscParameter*>(param.pPacketParamFactory->GetPacketParameter(param.pHwInterface));
973 if (p)
974 {
975 if (MOS_FAILED(p->Initialize(param)))
976 {
977 VpPacketParameter* pParam = p;
978 param.pPacketParamFactory->ReturnPacketParameter(pParam);
979 return nullptr;
980 }
981 }
982 return p;
983 }
VpVeboxCscParameter(PVP_MHWINTERFACE pHwInterface,PacketParamFactoryBase * packetParamFactory)984 VpVeboxCscParameter::VpVeboxCscParameter(PVP_MHWINTERFACE pHwInterface, PacketParamFactoryBase* packetParamFactory) :
985 VpPacketParameter(packetParamFactory), m_CscFilter(pHwInterface)
986 {
987 }
~VpVeboxCscParameter()988 VpVeboxCscParameter::~VpVeboxCscParameter()
989 {
990 }
SetPacketParam(VpCmdPacket * pPacket)991 bool VpVeboxCscParameter::SetPacketParam(VpCmdPacket* pPacket)
992 {
993 VP_FUNC_CALL();
994
995 VEBOX_CSC_PARAMS *params = m_CscFilter.GetVeboxParams();
996 if (nullptr == params)
997 {
998 VP_PUBLIC_ASSERTMESSAGE("Failed to get vebox be csc params");
999 return false;
1000 }
1001
1002 VpVeboxCmdPacketBase *packet = dynamic_cast<VpVeboxCmdPacketBase *>(pPacket);
1003 if (packet)
1004 {
1005 return MOS_SUCCEEDED(packet->SetVeboxBeCSCParams(params));
1006 }
1007
1008 VP_PUBLIC_ASSERTMESSAGE("Invalid packet for vebox be csc");
1009 return false;
1010 }
Initialize(HW_FILTER_CSC_PARAM & params)1011 MOS_STATUS VpVeboxCscParameter::Initialize(HW_FILTER_CSC_PARAM& params)
1012 {
1013 VP_FUNC_CALL();
1014
1015 VP_PUBLIC_CHK_STATUS_RETURN(m_CscFilter.Init());
1016 VP_PUBLIC_CHK_STATUS_RETURN(m_CscFilter.SetExecuteEngineCaps(params.cscParams, params.vpExecuteCaps));
1017 VP_PUBLIC_CHK_STATUS_RETURN(m_CscFilter.CalculateEngineParams());
1018 return MOS_STATUS_SUCCESS;
1019 }
PolicyVeboxCscHandler(VP_HW_CAPS & hwCaps)1020 PolicyVeboxCscHandler::PolicyVeboxCscHandler(VP_HW_CAPS &hwCaps) : PolicyFeatureHandler(hwCaps)
1021 {
1022 m_Type = FeatureTypeCscOnVebox;
1023 }
~PolicyVeboxCscHandler()1024 PolicyVeboxCscHandler::~PolicyVeboxCscHandler()
1025 {
1026 }
IsFeatureEnabled(VP_EXECUTE_CAPS vpExecuteCaps)1027 bool PolicyVeboxCscHandler::IsFeatureEnabled(VP_EXECUTE_CAPS vpExecuteCaps)
1028 {
1029 VP_FUNC_CALL();
1030
1031 return vpExecuteCaps.bBeCSC;
1032 }
CreateHwFilterParam(VP_EXECUTE_CAPS vpExecuteCaps,SwFilterPipe & swFilterPipe,PVP_MHWINTERFACE pHwInterface)1033 HwFilterParameter* PolicyVeboxCscHandler::CreateHwFilterParam(VP_EXECUTE_CAPS vpExecuteCaps, SwFilterPipe& swFilterPipe, PVP_MHWINTERFACE pHwInterface)
1034 {
1035 VP_FUNC_CALL();
1036
1037 if (IsFeatureEnabled(vpExecuteCaps))
1038 {
1039 if (SwFilterPipeType1To1 != swFilterPipe.GetSwFilterPipeType())
1040 {
1041 VP_PUBLIC_ASSERTMESSAGE("Invalid parameter! Sfc only support 1To1 swFilterPipe!");
1042 return nullptr;
1043 }
1044
1045 SwFilterCsc *swFilter = dynamic_cast<SwFilterCsc *>(swFilterPipe.GetSwFilter(true, 0, FeatureTypeCscOnVebox));
1046
1047 if (nullptr == swFilter)
1048 {
1049 VP_PUBLIC_ASSERTMESSAGE("Invalid parameter! Feature enabled in vpExecuteCaps but no swFilter exists!");
1050 return nullptr;
1051 }
1052
1053 FeatureParamCsc ¶m = swFilter->GetSwFilterParams();
1054
1055 HW_FILTER_CSC_PARAM paramCsc = {};
1056 paramCsc.type = m_Type;
1057 paramCsc.pHwInterface = pHwInterface;
1058 paramCsc.vpExecuteCaps = vpExecuteCaps;
1059 paramCsc.pPacketParamFactory = &m_PacketParamFactory;
1060 paramCsc.cscParams = param;
1061 paramCsc.pfnCreatePacketParam = PolicyVeboxCscHandler::CreatePacketParam;
1062
1063 HwFilterParameter *pHwFilterParam = GetHwFeatureParameterFromPool();
1064
1065 if (pHwFilterParam)
1066 {
1067 if (MOS_FAILED(((HwFilterCscParameter*)pHwFilterParam)->Initialize(paramCsc)))
1068 {
1069 ReleaseHwFeatureParameter(pHwFilterParam);
1070 }
1071 }
1072 else
1073 {
1074 pHwFilterParam = HwFilterCscParameter::Create(paramCsc, m_Type);
1075 }
1076
1077 return pHwFilterParam;
1078 }
1079 else
1080 {
1081 return nullptr;
1082 }
1083 }
1084
UpdateFeaturePipe(VP_EXECUTE_CAPS caps,SwFilter & feature,SwFilterPipe & featurePipe,SwFilterPipe & executePipe,bool isInputPipe,int index)1085 MOS_STATUS PolicyVeboxCscHandler::UpdateFeaturePipe(VP_EXECUTE_CAPS caps, SwFilter &feature, SwFilterPipe &featurePipe, SwFilterPipe &executePipe, bool isInputPipe, int index)
1086 {
1087 VP_FUNC_CALL();
1088
1089 SwFilterCsc *featureCsc = dynamic_cast<SwFilterCsc *>(&feature);
1090 VP_PUBLIC_CHK_NULL_RETURN(featureCsc);
1091
1092 if (!featureCsc->GetFilterEngineCaps().VeboxNeeded || caps.bForceCscToRender)
1093 {
1094 SwFilterCsc *filter2ndPass = featureCsc;
1095 SwFilterCsc *filter1ndPass = (SwFilterCsc *)feature.Clone();
1096
1097 VP_PUBLIC_CHK_NULL_RETURN(filter1ndPass);
1098 VP_PUBLIC_CHK_NULL_RETURN(filter2ndPass);
1099
1100 filter1ndPass->GetFilterEngineCaps() = filter2ndPass->GetFilterEngineCaps();
1101
1102 if (!filter1ndPass->GetFilterEngineCaps().VeboxNeeded)
1103 {
1104 VP_PUBLIC_NORMALMESSAGE("VeboxNeeded being false. Just do chroma sitting in current pass");
1105 filter1ndPass->GetFilterEngineCaps().VeboxNeeded = 1;
1106 }
1107
1108 filter1ndPass->SetFeatureType(filter2ndPass->GetFeatureType());
1109
1110 FeatureParamCsc ¶ms2ndPass = filter2ndPass->GetSwFilterParams();
1111 FeatureParamCsc ¶ms1stPass = filter1ndPass->GetSwFilterParams();
1112
1113 // No csc in 1st pass.
1114 params1stPass.formatOutput = params1stPass.formatInput;
1115 params1stPass.output = params1stPass.input;
1116
1117 // vebox + render no IEF Params
1118 params1stPass.pIEFParams = nullptr;
1119 params2ndPass.pIEFParams = nullptr;
1120
1121 params1stPass.pAlphaParams = nullptr;
1122
1123 // Clear engine caps for filter in 2nd pass.
1124 filter2ndPass->SetFeatureType(FeatureTypeCsc);
1125 filter2ndPass->GetFilterEngineCaps().usedForNextPass = 1;
1126
1127 if (caps.bForceCscToRender)
1128 {
1129 // Switch to render engine for csc filter.
1130 VP_PUBLIC_NORMALMESSAGE("Force csc to render case. VeboxNeeded: %d -> 0, RenderNeeded: %d -> 1",
1131 filter2ndPass->GetFilterEngineCaps().VeboxNeeded,
1132 filter2ndPass->GetFilterEngineCaps().RenderNeeded);
1133 filter2ndPass->GetFilterEngineCaps().bEnabled = 1;
1134 filter2ndPass->GetFilterEngineCaps().VeboxNeeded = 0;
1135 filter2ndPass->GetFilterEngineCaps().RenderNeeded = 1;
1136 filter2ndPass->GetFilterEngineCaps().fcSupported = 1;
1137 }
1138 else
1139 {
1140 VP_PUBLIC_NORMALMESSAGE("VeboxNeeded being false.Keep engine caps for next pass no change. enable %d, SfcNeeded %d, RenderNeeded %d",
1141 filter2ndPass->GetFilterEngineCaps().bEnabled,
1142 filter2ndPass->GetFilterEngineCaps().SfcNeeded,
1143 filter2ndPass->GetFilterEngineCaps().RenderNeeded);
1144 }
1145
1146 executePipe.AddSwFilterUnordered(filter1ndPass, isInputPipe, index);
1147 }
1148 else
1149 {
1150 return PolicyFeatureHandler::UpdateFeaturePipe(caps, feature, featurePipe, executePipe, isInputPipe, index);
1151 }
1152
1153 return MOS_STATUS_SUCCESS;
1154 }
1155 }
1156