1 /*
2 * Copyright (c) 2019-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 //!
24 //! \file policy.cpp
25 //! \brief Defines the common interface for vp features manager
26 //! \details The vp manager is further sub-divided by vp type
27 //! this file is for the base interface which is shared by all components.
28 //!
29 #include "policy.h"
30 #include "vp_obj_factories.h"
31 #include "vp_feature_manager.h"
32 #include "vp_platform_interface.h"
33 #include "sw_filter_handle.h"
34 #include "vp_cgc_filter.h"
35 #include "vp_user_feature_control.h"
36
37
38 namespace vp
39 {
40 /****************************************************************************************************/
41 /* Policy */
42 /****************************************************************************************************/
43
Policy(VpInterface & vpInterface)44 Policy::Policy(VpInterface &vpInterface) : m_vpInterface(vpInterface)
45 {
46 }
47
~Policy()48 Policy::~Policy()
49 {
50 UnregisterFeatures();
51 }
52
UpdateVpHwCapsBasedOnSku(VP_HW_CAPS & vpHwCaps)53 MOS_STATUS Policy::UpdateVpHwCapsBasedOnSku(VP_HW_CAPS &vpHwCaps)
54 {
55 return MOS_STATUS_SUCCESS;
56 }
57
Initialize()58 MOS_STATUS Policy::Initialize()
59 {
60 VP_FUNC_CALL();
61
62 VpPlatformInterface *vpPlatformInterface = (VpPlatformInterface *)m_vpInterface.GetHwInterface()->m_vpPlatformInterface;
63 VP_PUBLIC_CHK_NULL_RETURN(vpPlatformInterface);
64 VP_PUBLIC_CHK_STATUS_RETURN(vpPlatformInterface->InitVpHwCaps(m_hwCaps));
65 //update caps
66 UpdateVpHwCapsBasedOnSku(m_hwCaps);
67 VP_PUBLIC_CHK_STATUS_RETURN(RegisterFeatures());
68 m_initialized = true;
69 return MOS_STATUS_SUCCESS;
70 }
71
IsVeboxSfcFormatSupported(MOS_FORMAT formatInput,MOS_FORMAT formatOutput)72 bool Policy::IsVeboxSfcFormatSupported(MOS_FORMAT formatInput, MOS_FORMAT formatOutput)
73 {
74 VP_FUNC_CALL();
75
76 if (!m_initialized)
77 {
78 return false;
79 }
80 if (m_hwCaps.m_sfcHwEntry[formatInput].inputSupported &&
81 m_hwCaps.m_sfcHwEntry[formatOutput].outputSupported)
82 {
83 return true;
84 }
85 else
86 {
87 return false;
88 }
89 }
90
IsAlphaEnabled(FeatureParamScaling * scalingParams)91 bool Policy::IsAlphaEnabled(FeatureParamScaling* scalingParams)
92 {
93 VP_FUNC_CALL();
94
95 if (scalingParams == nullptr)
96 {
97 return false;
98 }
99
100 return scalingParams->pCompAlpha != nullptr;
101 }
102
IsColorfillEnabled(FeatureParamScaling * scalingParams)103 bool Policy::IsColorfillEnabled(FeatureParamScaling* scalingParams)
104 {
105 VP_FUNC_CALL();
106
107 if (scalingParams == nullptr)
108 {
109 return false;
110 }
111
112 bool isColorFill = false;
113 isColorFill = (scalingParams->pColorFillParams &&
114 (!scalingParams->pColorFillParams->bDisableColorfillinSFC) &&
115 (scalingParams->pColorFillParams->bOnePixelBiasinSFC ?
116 (!RECT1_CONTAINS_RECT2_ONEPIXELBIAS(scalingParams->input.rcDst, scalingParams->output.rcDst)):
117 (!RECT1_CONTAINS_RECT2(scalingParams->input.rcDst, scalingParams->output.rcDst))))
118 ? true
119 : false;
120
121 return isColorFill;
122 }
123
RegisterFeatures()124 MOS_STATUS Policy::RegisterFeatures()
125 {
126 VP_FUNC_CALL();
127
128 UnregisterFeatures();
129
130 // Vebox/Sfc features.
131 PolicyFeatureHandler *p = MOS_New(PolicySfcCscHandler, m_hwCaps);
132 VP_PUBLIC_CHK_NULL_RETURN(p);
133 m_VeboxSfcFeatureHandlers.insert(std::make_pair(FeatureTypeCscOnSfc, p));
134
135 p = MOS_New(PolicySfcRotMirHandler, m_hwCaps);
136 VP_PUBLIC_CHK_NULL_RETURN(p);
137 m_VeboxSfcFeatureHandlers.insert(std::make_pair(FeatureTypeRotMirOnSfc, p));
138
139 p = MOS_New(PolicySfcScalingHandler, m_hwCaps);
140 VP_PUBLIC_CHK_NULL_RETURN(p);
141 m_VeboxSfcFeatureHandlers.insert(std::make_pair(FeatureTypeScalingOnSfc, p));
142
143 p = MOS_New(PolicyVeboxDnHandler, m_hwCaps);
144 VP_PUBLIC_CHK_NULL_RETURN(p);
145 m_VeboxSfcFeatureHandlers.insert(std::make_pair(FeatureTypeDnOnVebox, p));
146
147 p = MOS_New(PolicyRenderDnHVSCalHandler, m_hwCaps);
148 VP_PUBLIC_CHK_NULL_RETURN(p);
149 m_RenderFeatureHandlers.insert(std::make_pair(FeatureTypeDnHVSCalOnRender, p));
150
151 p = MOS_New(PolicyVeboxCscHandler, m_hwCaps);
152 VP_PUBLIC_CHK_NULL_RETURN(p);
153 m_VeboxSfcFeatureHandlers.insert(std::make_pair(FeatureTypeCscOnVebox, p));
154
155 p = MOS_New(PolicyVeboxSteHandler, m_hwCaps);
156 VP_PUBLIC_CHK_NULL_RETURN(p);
157 m_VeboxSfcFeatureHandlers.insert(std::make_pair(FeatureTypeSteOnVebox, p));
158
159 p = MOS_New(PolicyVeboxTccHandler, m_hwCaps);
160 VP_PUBLIC_CHK_NULL_RETURN(p);
161 m_VeboxSfcFeatureHandlers.insert(std::make_pair(FeatureTypeTccOnVebox, p));
162
163 p = MOS_New(PolicyVeboxProcampHandler, m_hwCaps);
164 VP_PUBLIC_CHK_NULL_RETURN(p);
165 m_VeboxSfcFeatureHandlers.insert(std::make_pair(FeatureTypeProcampOnVebox, p));
166
167 p = MOS_New(PolicyVeboxHdrHandler, m_hwCaps);
168 VP_PUBLIC_CHK_NULL_RETURN(p);
169 m_VeboxSfcFeatureHandlers.insert(std::make_pair(FeatureTypeHdrOnVebox, p));
170
171 p = MOS_New(PolicyRenderHdr3DLutCalHandler, m_hwCaps);
172 VP_PUBLIC_CHK_NULL_RETURN(p);
173 m_RenderFeatureHandlers.insert(std::make_pair(FeatureTypeHdr3DLutCalOnRender, p));
174
175 p = MOS_New(PolicyRenderHdrHandler, m_hwCaps);
176 VP_PUBLIC_CHK_NULL_RETURN(p);
177 m_RenderFeatureHandlers.insert(std::make_pair(FeatureTypeHdrOnRender, p));
178
179 p = MOS_New(PolicyDiHandler, m_hwCaps);
180 VP_PUBLIC_CHK_NULL_RETURN(p);
181 m_VeboxSfcFeatureHandlers.insert(std::make_pair(FeatureTypeDiOnVebox, p));
182
183 p = MOS_New(PolicySfcColorFillHandler, m_hwCaps);
184 VP_PUBLIC_CHK_NULL_RETURN(p);
185 m_VeboxSfcFeatureHandlers.insert(std::make_pair(FeatureTypeColorFillOnSfc, p));
186
187 p = MOS_New(PolicySfcAlphaHandler, m_hwCaps);
188 VP_PUBLIC_CHK_NULL_RETURN(p);
189 m_VeboxSfcFeatureHandlers.insert(std::make_pair(FeatureTypeAlphaOnSfc, p));
190
191 VP_PUBLIC_CHK_STATUS_RETURN(RegisterFcFeatures());
192
193 p = MOS_New(PolicyVeboxCgcHandler, m_hwCaps);
194 VP_PUBLIC_CHK_NULL_RETURN(p);
195 m_VeboxSfcFeatureHandlers.insert(std::make_pair(FeatureTypeCgcOnVebox, p));
196
197 // Next step to add a table to trace all SW features based on platforms
198 m_featurePool.push_back(FeatureTypeCsc);
199 m_featurePool.push_back(FeatureTypeScaling);
200 m_featurePool.push_back(FeatureTypeRotMir);
201 m_featurePool.push_back(FeatureTypeDn);
202 m_featurePool.push_back(FeatureTypeSte);
203 m_featurePool.push_back(FeatureTypeTcc);
204 m_featurePool.push_back(FeatureTypeProcamp);
205 m_featurePool.push_back(FeatureTypeHdr);
206 m_featurePool.push_back(FeatureTypeDi);
207 m_featurePool.push_back(FeatureTypeFc);
208 m_featurePool.push_back(FeatureTypeLumakey);
209 m_featurePool.push_back(FeatureTypeBlending);
210 m_featurePool.push_back(FeatureTypeColorFill);
211 m_featurePool.push_back(FeatureTypeAlpha);
212 m_featurePool.push_back(FeatureTypeCgc);
213
214 return MOS_STATUS_SUCCESS;
215 }
216
UnregisterFeatures()217 void Policy::UnregisterFeatures()
218 {
219 while (!m_VeboxSfcFeatureHandlers.empty())
220 {
221 std::map<FeatureType, PolicyFeatureHandler*>::iterator it = m_VeboxSfcFeatureHandlers.begin();
222 MOS_Delete(it->second);
223 m_VeboxSfcFeatureHandlers.erase(it);
224 }
225
226 while (!m_RenderFeatureHandlers.empty())
227 {
228 std::map<FeatureType, PolicyFeatureHandler*>::iterator it = m_RenderFeatureHandlers.begin();
229 MOS_Delete(it->second);
230 m_RenderFeatureHandlers.erase(it);
231 }
232
233 m_featurePool.clear();
234 }
235
RegisterFcFeatures()236 MOS_STATUS Policy::RegisterFcFeatures()
237 {
238 VP_PUBLIC_CHK_NULL_RETURN(m_vpInterface.GetHwInterface())
239 VpUserFeatureControl *vpUserFeatureControl = m_vpInterface.GetHwInterface()->m_userFeatureControl;
240 VP_PUBLIC_CHK_NULL_RETURN(vpUserFeatureControl);
241 bool enableL0FC = vpUserFeatureControl->EnableL0FC();
242
243 //Legacy Fc and L0 FC switching will be done in the wrapper handler class
244 //It will use Legacy FC if vpUserFeatureControl->EnableL0FC() is not true, which means specific platform not support L0 FC
245 //It will fall back to legacy FC when vp execute caps show bLegacyFC is true, which means some formats L0 FC not supported yet
246 //In the future, after all caps formats added for L0 FC, the wrapper will be removed and only register specific L0/Legacy FC handler
247 PolicyFeatureHandler *p = MOS_New(PolicyFcWrapHandler, m_hwCaps, enableL0FC);
248 VP_PUBLIC_CHK_NULL_RETURN(p);
249 m_RenderFeatureHandlers.insert(std::make_pair(FeatureTypeFcOnRender, p));
250
251 p = MOS_New(PolicyFcFeatureWrapHandler, m_hwCaps, enableL0FC);
252 VP_PUBLIC_CHK_NULL_RETURN(p);
253 m_RenderFeatureHandlers.insert(std::make_pair(FeatureTypeLumakeyOnRender, p));
254
255 p = MOS_New(PolicyFcFeatureWrapHandler, m_hwCaps, enableL0FC);
256 VP_PUBLIC_CHK_NULL_RETURN(p);
257 m_RenderFeatureHandlers.insert(std::make_pair(FeatureTypeBlendingOnRender, p));
258
259 p = MOS_New(PolicyFcFeatureWrapHandler, m_hwCaps, enableL0FC);
260 VP_PUBLIC_CHK_NULL_RETURN(p);
261 m_RenderFeatureHandlers.insert(std::make_pair(FeatureTypeColorFillOnRender, p));
262
263 p = MOS_New(PolicyFcFeatureWrapHandler, m_hwCaps, enableL0FC);
264 VP_PUBLIC_CHK_NULL_RETURN(p);
265 m_RenderFeatureHandlers.insert(std::make_pair(FeatureTypeAlphaOnRender, p));
266
267 p = MOS_New(PolicyFcFeatureWrapHandler, m_hwCaps, enableL0FC);
268 VP_PUBLIC_CHK_NULL_RETURN(p);
269 m_RenderFeatureHandlers.insert(std::make_pair(FeatureTypeCscOnRender, p));
270
271 p = MOS_New(PolicyFcFeatureWrapHandler, m_hwCaps, enableL0FC);
272 VP_PUBLIC_CHK_NULL_RETURN(p);
273 m_RenderFeatureHandlers.insert(std::make_pair(FeatureTypeScalingOnRender, p));
274
275 p = MOS_New(PolicyFcFeatureWrapHandler, m_hwCaps, enableL0FC);
276 VP_PUBLIC_CHK_NULL_RETURN(p);
277 m_RenderFeatureHandlers.insert(std::make_pair(FeatureTypeRotMirOnRender, p));
278
279 p = MOS_New(PolicyFcFeatureWrapHandler, m_hwCaps, enableL0FC);
280 VP_PUBLIC_CHK_NULL_RETURN(p);
281 m_RenderFeatureHandlers.insert(std::make_pair(FeatureTypeDiOnRender, p));
282
283 p = MOS_New(PolicyFcFeatureWrapHandler, m_hwCaps, enableL0FC);
284 VP_PUBLIC_CHK_NULL_RETURN(p);
285 m_RenderFeatureHandlers.insert(std::make_pair(FeatureTypeProcampOnRender, p));
286
287 #if (_DEBUG || _RELEASE_INTERNAL)
288 VpFeatureReport *vpFeatureReport = m_vpInterface.GetHwInterface()->m_reporting;
289 if (vpFeatureReport)
290 {
291 vpFeatureReport->GetFeatures().isL0FC = enableL0FC;
292 }
293 #endif
294
295 return MOS_STATUS_SUCCESS;
296 }
297
298 /* Enable SwFilterPipe */
299
CreateHwFilter(SwFilterPipe & subSwFilterPipe,HwFilter * & pFilter)300 MOS_STATUS Policy::CreateHwFilter(SwFilterPipe &subSwFilterPipe, HwFilter *&pFilter)
301 {
302 VP_FUNC_CALL();
303
304 if (subSwFilterPipe.IsEmpty())
305 {
306 pFilter = nullptr;
307 return MOS_STATUS_SUCCESS;
308 }
309
310 HW_FILTER_PARAMS param = {};
311
312 MT_LOG(MT_VP_FEATURE_GRAPH_SETUPEXECUTESWFILTER_START, MT_NORMAL);
313 VP_PUBLIC_NORMALMESSAGE("Feature Graph: Setup ExecutePipe Start");
314 MOS_STATUS status = GetHwFilterParam(subSwFilterPipe, param);
315
316 if (MOS_FAILED(status))
317 {
318 VP_PUBLIC_ASSERTMESSAGE("Create HW Filter Failed, Return Error");
319 MT_ERR2(MT_VP_HAL_POLICY, MT_ERROR_CODE, status, MT_CODE_LINE, __LINE__);
320 return status;
321 }
322
323 pFilter = m_vpInterface.GetHwFilterFactory().Create(param);
324
325 ReleaseHwFilterParam(param);
326
327 if (!pFilter)
328 {
329 VP_PUBLIC_ASSERTMESSAGE("Create HW Filter Failed, Return Error");
330 MT_ERR2(MT_VP_HAL_POLICY, MT_ERROR_CODE, MOS_STATUS_UNIMPLEMENTED, MT_CODE_LINE, __LINE__);
331 if (m_vpInterface.GetHwInterface()->m_userFeatureControl->Is3DLutKernelOnly())
332 {
333 VP_PUBLIC_NORMALMESSAGE("Bypass This Workload due to 3dlut kenrel test, Return True");
334 return MOS_STATUS_SUCCESS;
335 }
336 return MOS_STATUS_UNIMPLEMENTED;
337 }
338 MT_LOG(MT_VP_FEATURE_GRAPH_SETUPEXECUTESWFILTER_END, MT_NORMAL);
339 VP_PUBLIC_NORMALMESSAGE("Feature Graph: Setup ExecutePipe End");
340 return MOS_STATUS_SUCCESS;
341 }
342
GetHwFilterParam(SwFilterPipe & subSwFilterPipe,HW_FILTER_PARAMS & params)343 MOS_STATUS Policy::GetHwFilterParam(SwFilterPipe& subSwFilterPipe, HW_FILTER_PARAMS& params)
344 {
345 VP_FUNC_CALL();
346
347 MOS_STATUS status = MOS_STATUS_SUCCESS;
348
349 params.Type = EngineTypeInvalid;
350
351 // Create and clear executedFilters.
352 if (params.executedFilters)
353 {
354 params.executedFilters->Clean();
355 }
356 else
357 {
358 status = m_vpInterface.GetSwFilterPipeFactory().Create(params.executedFilters);
359
360 if (status != MOS_STATUS_SUCCESS)
361 {
362 m_vpInterface.GetSwFilterPipeFactory().Destory(params.executedFilters);
363 VP_PUBLIC_ASSERTMESSAGE("Create Executed Filter Failed, Return Error");
364 MT_ERR2(MT_VP_HAL_POLICY, MT_ERROR_CODE, status, MT_CODE_LINE, __LINE__);
365 return status;
366 }
367 }
368
369 params.executedFilters->SetExePipeFlag(true);
370
371 status = GetExecuteCaps(subSwFilterPipe, params);
372
373 if (status != MOS_STATUS_SUCCESS)
374 {
375 m_vpInterface.GetSwFilterPipeFactory().Destory(params.executedFilters);
376 VP_PUBLIC_ASSERTMESSAGE("Create Executed Filter Failed, Return Error");
377 MT_ERR2(MT_VP_HAL_POLICY, MT_ERROR_CODE, status, MT_CODE_LINE, __LINE__);
378 return status;
379 }
380
381 return MOS_STATUS_SUCCESS;
382 }
383
GetExecuteCaps(SwFilterPipe & subSwFilterPipe,HW_FILTER_PARAMS & params)384 MOS_STATUS Policy::GetExecuteCaps(SwFilterPipe& subSwFilterPipe, HW_FILTER_PARAMS& params)
385 {
386 VP_FUNC_CALL();
387
388 VP_EngineEntry engineCapsCombinedAllPipes = {};
389 SwFilterSubPipe* pipe = nullptr;
390 uint32_t index = 0;
391 uint32_t inputSurfCount = subSwFilterPipe.GetSurfaceCount(true);
392 uint32_t outputSurfCount = subSwFilterPipe.GetSurfaceCount(false);
393
394 VP_PUBLIC_NORMALMESSAGE("Only Support primary layer for advanced processing");
395
396 engineCapsCombinedAllPipes.value = 0;
397
398 for (index = 0; index < inputSurfCount; ++index)
399 {
400 VP_PUBLIC_CHK_STATUS_RETURN(BuildExecutionEngines(subSwFilterPipe, true, index, engineCapsCombinedAllPipes));
401 }
402
403 VP_PUBLIC_CHK_STATUS_RETURN(UpdateExecuteEngineCapsForCrossPipeFeatures(subSwFilterPipe, engineCapsCombinedAllPipes));
404
405 for (index = 0; index < outputSurfCount; ++index)
406 {
407 VP_PUBLIC_CHK_STATUS_RETURN(BuildExecutionEngines(subSwFilterPipe, false, index, engineCapsCombinedAllPipes));
408 }
409
410 VP_PUBLIC_CHK_STATUS_RETURN(BuildFilters(subSwFilterPipe, params));
411
412 return MOS_STATUS_SUCCESS;
413 }
414
GetExecutionCapsForSingleFeature(FeatureType featureType,SwFilterSubPipe & swFilterPipe,VP_EngineEntry & engineCapsCombined)415 MOS_STATUS Policy::GetExecutionCapsForSingleFeature(FeatureType featureType, SwFilterSubPipe& swFilterPipe, VP_EngineEntry& engineCapsCombined)
416 {
417 VP_FUNC_CALL();
418
419 SwFilter* feature = swFilterPipe.GetSwFilter(featureType);
420 SwFilter* di = nullptr;
421 SwFilter* hdr = nullptr;
422 SwFilter* cgc = nullptr;
423 SwFilter* scaling = nullptr;
424 VPHAL_CSPACE cscInputColorSpaceCheck = CSpace_None;
425
426 auto getDeinterlaceExecutionCaps = [&](SwFilter *_di)
427 {
428 bool forceDIToRender = false;
429 VP_PUBLIC_CHK_NULL_RETURN(_di);
430 scaling = scaling ? scaling : dynamic_cast<SwFilterScaling*>(swFilterPipe.GetSwFilter(FeatureType(FeatureTypeScaling)));
431 if (scaling)
432 {
433 // No need check HDR for DI case.
434 VP_PUBLIC_CHK_STATUS_RETURN(GetScalingExecutionCaps(scaling, false, true));
435 forceDIToRender = scaling->GetFilterEngineCaps().RenderNeeded && scaling->GetFilterEngineCaps().sfcNotSupported;
436 }
437 return GetDeinterlaceExecutionCaps(_di, forceDIToRender);
438 };
439
440 if (!feature)
441 {
442 VP_PUBLIC_VERBOSEMESSAGE("Feature %d is not enabled in current pipe", featureType);
443 return MOS_STATUS_SUCCESS;
444 }
445 else
446 {
447 VP_PUBLIC_NORMALMESSAGE("Feature %d is enabled in current pipe", featureType);
448 }
449
450 // Always clean engine caps before Query. For next step, need to add new caps variable in swFilter
451 // for forcing engine case.
452 // feature->GetFilterEngineCaps().value = 0;
453
454 switch (featureType)
455 {
456 case FeatureTypeCsc:
457 hdr = swFilterPipe.GetSwFilter(FeatureTypeHdr);
458 di = swFilterPipe.GetSwFilter(FeatureTypeDi);
459 cgc = dynamic_cast<SwFilterCgc *>(swFilterPipe.GetSwFilter(FeatureType(FeatureTypeCgc)));
460 cscInputColorSpaceCheck = (&((SwFilterCsc *)feature)->GetSwFilterParams())->input.colorSpace;
461 if (hdr)
462 {
463 VP_PUBLIC_CHK_STATUS_RETURN(GetCSCExecutionCapsHdr(hdr, feature));
464 }
465 else if (IS_COLOR_SPACE_BT2020_YUV(cscInputColorSpaceCheck) && cgc)
466 {
467 VP_PUBLIC_CHK_STATUS_RETURN(GetCSCExecutionCapsBT2020ToRGB(cgc, feature));
468 }
469 else if (di)
470 {
471 VP_PUBLIC_CHK_STATUS_RETURN(getDeinterlaceExecutionCaps(di));
472
473 VP_EngineEntry *diEngine = &di->GetFilterEngineCaps();
474 if (diEngine->bEnabled && diEngine->VeboxNeeded)
475 {
476 VP_PUBLIC_CHK_STATUS_RETURN(GetCSCExecutionCapsDi(feature));
477 }
478 else
479 {
480 VP_PUBLIC_CHK_STATUS_RETURN(GetCSCExecutionCaps(feature, false));
481 }
482 }
483 else
484 {
485 VP_PUBLIC_CHK_STATUS_RETURN(GetCSCExecutionCaps(feature, false));
486 }
487 break;
488 case FeatureTypeScaling:
489 hdr = dynamic_cast<SwFilterHdr *>(swFilterPipe.GetSwFilter(FeatureType(FeatureTypeHdr)));
490 if (hdr)
491 {
492 VP_PUBLIC_CHK_STATUS_RETURN(GetScalingExecutionCapsHdr(feature));
493 }
494 else
495 {
496 di = swFilterPipe.GetSwFilter(FeatureTypeDi);
497 VP_PUBLIC_CHK_STATUS_RETURN(GetScalingExecutionCaps(feature, di != nullptr));
498 }
499 break;
500 case FeatureTypeRotMir:
501 VP_PUBLIC_CHK_STATUS_RETURN(GetRotationExecutionCaps(feature));
502 break;
503 case FeatureTypeDn:
504 VP_PUBLIC_CHK_STATUS_RETURN(GetDenoiseExecutionCaps(feature));
505 break;
506 case FeatureTypeSte:
507 VP_PUBLIC_CHK_STATUS_RETURN(GetSteExecutionCaps(feature));
508 break;
509 case FeatureTypeTcc:
510 VP_PUBLIC_CHK_STATUS_RETURN(GetTccExecutionCaps(feature));
511 break;
512 case FeatureTypeProcamp:
513 VP_PUBLIC_CHK_STATUS_RETURN(GetProcampExecutionCaps(feature));
514 break;
515 case FeatureTypeHdr:
516 VP_PUBLIC_CHK_STATUS_RETURN(GetHdrExecutionCaps(feature));
517 break;
518 case FeatureTypeDi:
519 VP_PUBLIC_CHK_STATUS_RETURN(getDeinterlaceExecutionCaps(feature));
520 break;
521 case FeatureTypeLumakey:
522 VP_PUBLIC_CHK_STATUS_RETURN(GetLumakeyExecutionCaps(feature));
523 break;
524 case FeatureTypeBlending:
525 VP_PUBLIC_CHK_STATUS_RETURN(GetBlendingExecutionCaps(feature));
526 break;
527 case FeatureTypeColorFill:
528 VP_PUBLIC_CHK_STATUS_RETURN(GetColorFillExecutionCaps(feature));
529 break;
530 case FeatureTypeAlpha:
531 VP_PUBLIC_CHK_STATUS_RETURN(GetAlphaExecutionCaps(feature));
532 break;
533 case FeatureTypeCgc:
534 VP_PUBLIC_CHK_STATUS_RETURN(GetCgcExecutionCaps(feature));
535 break;
536 default:
537 VP_PUBLIC_CHK_STATUS_RETURN(GetExecutionCaps(feature));
538 VP_PUBLIC_ASSERTMESSAGE("Feature is not supported by driver, bypass it");
539 break;
540 }
541
542 VP_EngineEntry& engineCaps = feature->GetFilterEngineCaps();
543
544 if (engineCaps.value == 0)
545 {
546 // Return success after all feature enabled and fully switched to APO path.
547 VP_PUBLIC_NORMALMESSAGE("No engine being assigned for feature %d. Will bypass it.", featureType);
548 }
549
550 engineCapsCombined.value |= engineCaps.value;
551
552 MT_LOG7(MT_VP_HAL_POLICY_GET_EXTCAPS4FTR, MT_NORMAL, MT_VP_HAL_FEATUERTYPE, featureType, MT_VP_HAL_ENGINECAPS, int64_t(engineCaps.value),
553 MT_VP_HAL_ENGINECAPS_EN, int64_t(engineCaps.bEnabled), MT_VP_HAL_ENGINECAPS_VE_NEEDED, int64_t(engineCaps.VeboxNeeded),
554 MT_VP_HAL_ENGINECAPS_SFC_NEEDED, int64_t(engineCaps.SfcNeeded), MT_VP_HAL_ENGINECAPS_RENDER_NEEDED, int64_t(engineCaps.RenderNeeded),
555 MT_VP_HAL_ENGINECAPS_FC_SUPPORT, int64_t(engineCaps.fcSupported));
556
557 return MOS_STATUS_SUCCESS;
558 }
559
UpdateExecuteEngineCapsForHDR(SwFilterPipe & swFilterPipe,VP_EngineEntry & engineCapsCombinedAllPipes)560 MOS_STATUS Policy::UpdateExecuteEngineCapsForHDR(SwFilterPipe &swFilterPipe, VP_EngineEntry &engineCapsCombinedAllPipes)
561 {
562 VP_FUNC_CALL();
563
564 uint32_t pipeCount = swFilterPipe.GetSurfaceCount(true);
565 std::vector<SwFilterHdr *> hdrFilters;
566 bool isHdrKernelNeeded = false;
567 auto outputSurf = swFilterPipe.GetSurface(false, 0);
568 VP_PUBLIC_CHK_NULL_RETURN(outputSurf);
569
570 if (1 == pipeCount)
571 {
572 return MOS_STATUS_SUCCESS;
573 }
574
575 // Multi-layer S2H or H2H case.
576 if (pipeCount > 1 && IS_COLOR_SPACE_BT2020(outputSurf->ColorSpace))
577 {
578 VP_PUBLIC_NORMALMESSAGE("multi-layer H2H or S2H, use HDR kernel.");
579 isHdrKernelNeeded = true;
580 }
581
582 for (uint32_t i = 0; i < pipeCount; ++i)
583 {
584 auto filter = (SwFilterHdr *)swFilterPipe.GetSwFilter(true, i, FeatureTypeHdr);
585 if (nullptr == filter)
586 {
587 continue;
588 }
589
590 if (!filter->GetFilterEngineCaps().bEnabled)
591 {
592 continue;
593 }
594
595 hdrFilters.push_back(filter);
596 }
597
598 if (!isHdrKernelNeeded)
599 {
600 // 1 H2S layer, use vebox 3DLut + fc or HDR kernel based on hdrKernelNeeded flag on hdr filter.
601 if (hdrFilters.size() <= 1)
602 {
603 return MOS_STATUS_SUCCESS;
604 }
605 VP_PUBLIC_NORMALMESSAGE("multi-layer H2S, use HDR kernel.");
606 isHdrKernelNeeded = true;
607 }
608
609 if (isHdrKernelNeeded)
610 {
611 for (auto filter : hdrFilters)
612 {
613 auto &engineCaps = filter->GetFilterEngineCaps();
614 if (!filter->GetFilterEngineCaps().hdrKernelNeeded)
615 {
616 engineCaps.VeboxNeeded = 0;
617 engineCaps.RenderNeeded = 1;
618 engineCaps.hdrKernelNeeded = 1;
619 engineCaps.hdrKernelSupported = 1;
620 VP_PUBLIC_NORMALMESSAGE("Update HDR filter to use HDR kernel.");
621 PrintFeatureExecutionCaps(__FUNCTION__, engineCaps);
622 }
623 }
624 engineCapsCombinedAllPipes.RenderNeeded = 1;
625 engineCapsCombinedAllPipes.hdrKernelNeeded = 1;
626 engineCapsCombinedAllPipes.hdrKernelSupported = 1;
627
628 for (uint32_t i = 0; i < pipeCount; ++i)
629 {
630 SwFilterSubPipe *pipe = nullptr;
631 pipe = swFilterPipe.GetSwFilterSubPipe(true, i);
632 // All layers will be processed by hdr kernel if hdr kernel being used. The features not supported by hdr kernel in all pipes will be filtered out.
633 VP_PUBLIC_CHK_STATUS_RETURN(FilterFeatureCombinationForHDRKernel(pipe));
634
635 }
636 }
637
638 return MOS_STATUS_SUCCESS;
639 }
640
UpdateExecuteEngineCapsForCrossPipeFeatures(SwFilterPipe & swFilterPipe,VP_EngineEntry & engineCapsCombinedAllPipes)641 MOS_STATUS Policy::UpdateExecuteEngineCapsForCrossPipeFeatures(SwFilterPipe &swFilterPipe, VP_EngineEntry &engineCapsCombinedAllPipes)
642 {
643 VP_FUNC_CALL();
644
645 VP_PUBLIC_CHK_STATUS_RETURN(UpdateExecuteEngineCapsForHDR(swFilterPipe, engineCapsCombinedAllPipes));
646 return MOS_STATUS_SUCCESS;
647 }
648
BuildExecutionEngines(SwFilterPipe & swFilterPipe,bool isInputPipe,uint32_t index,VP_EngineEntry & engineCapsCombinedAllPipes)649 MOS_STATUS Policy::BuildExecutionEngines(SwFilterPipe &swFilterPipe, bool isInputPipe, uint32_t index, VP_EngineEntry &engineCapsCombinedAllPipes)
650 {
651 VP_FUNC_CALL();
652
653 SwFilterSubPipe *pipe = nullptr;
654 SwFilter * feature = nullptr;
655 pipe = swFilterPipe.GetSwFilterSubPipe(isInputPipe, index);
656 VP_EngineEntry engineCapsCombined = {};
657
658 engineCapsCombined.value = 0;
659
660 VP_PUBLIC_NORMALMESSAGE("isInputPipe %d, index %d", (isInputPipe ? 1 : 0), index);
661
662 if (pipe)
663 {
664 for (auto filterID : m_featurePool)
665 {
666 VP_PUBLIC_CHK_STATUS_RETURN(GetExecutionCapsForSingleFeature(filterID, *pipe, engineCapsCombined));
667 }
668 engineCapsCombinedAllPipes.value |= engineCapsCombined.value;
669 VP_PUBLIC_CHK_STATUS_RETURN(FilterFeatureCombination(swFilterPipe, isInputPipe, index, engineCapsCombined, engineCapsCombinedAllPipes));
670 }
671 return MOS_STATUS_SUCCESS;
672 }
673
Update3DLutoutputColorAndFormat(FeatureParamCsc * cscParams,FeatureParamHdr * hdrParams,MOS_FORMAT Format,VPHAL_CSPACE CSpace)674 MOS_STATUS Policy::Update3DLutoutputColorAndFormat(FeatureParamCsc *cscParams, FeatureParamHdr *hdrParams, MOS_FORMAT Format, VPHAL_CSPACE CSpace)
675 {
676 // For vebox + render, e.g. BT2020 P010->SRGB, if not correct the format here, since forceCscToRender being enabled, outputFormat in csc filter of
677 // first pass will be set to P010 in PolicyVeboxCscHandler::UpdateFeaturePipe(). It will cause the wrong format being used for intermediate surface
678 // in VpResourceManager::GetIntermediaOutputSurfaceColorAndFormat().
679 // For vebox + sfc, GetSfcInputFormat in VpCscFilter::CalculateSfcEngineParams() will ensure the right format being used, although the format
680 // in csc will be overwritten in params.executedFilters->Update() in Policy::BuildExecuteFilter.
681 hdrParams->formatOutput = Format;
682 hdrParams->dstColorSpace = CSpace;
683 cscParams->formatInput = Format;
684 cscParams->input.colorSpace = CSpace;
685
686 return MOS_STATUS_SUCCESS;
687 }
688
GetCSCExecutionCapsHdr(SwFilter * HDR,SwFilter * CSC)689 MOS_STATUS Policy::GetCSCExecutionCapsHdr(SwFilter *HDR, SwFilter *CSC)
690 {
691 VP_FUNC_CALL();
692
693 SwFilterHdr *hdr = nullptr;
694 SwFilterCsc *csc = nullptr;
695 FeatureParamHdr *hdrParams = nullptr;
696 FeatureParamCsc *cscParams = nullptr;
697 VP_EngineEntry *cscEngine = nullptr;
698
699 VP_PUBLIC_CHK_NULL_RETURN(HDR);
700 VP_PUBLIC_CHK_NULL_RETURN(CSC);
701 hdr = (SwFilterHdr *)HDR;
702 csc = (SwFilterCsc *)CSC;
703
704 hdrParams = &hdr->GetSwFilterParams();
705 cscParams = &csc->GetSwFilterParams();
706 cscEngine = &csc->GetFilterEngineCaps();
707
708 // Clean usedForNextPass flag.
709 if (cscEngine->usedForNextPass)
710 {
711 cscEngine->usedForNextPass = false;
712 }
713 if (cscEngine->value != 0)
714 {
715 VP_PUBLIC_NORMALMESSAGE("CSC Feature Already been processed, Skip further process");
716
717 PrintFeatureExecutionCaps(__FUNCTION__, *cscEngine);
718 return MOS_STATUS_SUCCESS;
719 }
720
721 MOS_FORMAT hdrFormat = Format_Any;
722 VPHAL_CSPACE hdrCSpace = CSpace_Any;
723 if (cscParams->isFullRgbG10P709 && IS_RGB64_FLOAT_FORMAT(cscParams->formatOutput))
724 {
725 hdrCSpace = CSpace_BT2020_RGB;
726 hdrFormat = Format_A16B16G16R16;
727 }
728 else
729 {
730 hdrCSpace = IS_COLOR_SPACE_BT2020(cscParams->output.colorSpace) ? CSpace_BT2020_RGB : CSpace_sRGB;
731 hdrFormat = IS_COLOR_SPACE_BT2020(cscParams->output.colorSpace) ? Format_R10G10B10A2 : Format_A8R8G8B8;
732 }
733 VP_PUBLIC_CHK_STATUS_RETURN(Update3DLutoutputColorAndFormat(cscParams, hdrParams, hdrFormat, hdrCSpace));
734
735 if (m_hwCaps.m_sfcHwEntry[hdrFormat].inputSupported &&
736 m_hwCaps.m_sfcHwEntry[cscParams->formatOutput].outputSupported &&
737 m_hwCaps.m_sfcHwEntry[hdrFormat].cscSupported)
738 {
739 if (hdrFormat == cscParams->formatOutput && hdrCSpace == cscParams->output.colorSpace)
740 {
741 VP_PUBLIC_NORMALMESSAGE("Skip CSC for HDR case.");
742 cscEngine->forceEnableForSfc = 1;
743 cscEngine->forceEnableForHdrKernel = 1;
744 }
745 else
746 {
747 cscEngine->bEnabled = 1;
748 cscEngine->SfcNeeded = 1;
749 cscEngine->RenderNeeded = 1;
750 cscEngine->fcSupported = 1;
751 cscEngine->hdrKernelSupported = 1;
752 }
753 }
754 else
755 {
756 VP_PUBLIC_ASSERTMESSAGE("Post CSC for HDR not supported by SFC");
757 return MOS_STATUS_INVALID_PARAMETER;
758 }
759
760 return MOS_STATUS_SUCCESS;
761 }
762
GetCSCExecutionCapsDi(SwFilter * feature)763 MOS_STATUS Policy::GetCSCExecutionCapsDi(SwFilter* feature)
764 {
765 VP_FUNC_CALL();
766
767 VP_PUBLIC_CHK_NULL_RETURN(feature);
768
769 SwFilterCsc* csc = dynamic_cast<SwFilterCsc*>(feature);
770 VP_PUBLIC_CHK_NULL_RETURN(csc);
771 auto userFeatureControl = m_vpInterface.GetHwInterface()->m_userFeatureControl;
772 bool disableSfc = userFeatureControl->IsSfcDisabled();
773
774 VP_PUBLIC_CHK_STATUS_RETURN(GetCSCExecutionCaps(feature, false));
775
776 VP_EngineEntry *cscEngine = &csc->GetFilterEngineCaps();
777 VP_PUBLIC_CHK_NULL_RETURN(cscEngine);
778 if (!disableSfc && (cscEngine->bEnabled && (cscEngine->SfcNeeded || cscEngine->VeboxNeeded)) ||
779 !cscEngine->bEnabled && cscEngine->forceEnableForSfc)
780 {
781 cscEngine->bEnabled = 1;
782 cscEngine->SfcNeeded = 1;
783 cscEngine->VeboxNeeded = 0;
784 cscEngine->RenderNeeded = 0;
785 }
786 else
787 {
788 cscEngine->bEnabled = 1;
789 cscEngine->SfcNeeded = 0;
790 cscEngine->VeboxNeeded = 0;
791 cscEngine->RenderNeeded = 1;
792 cscEngine->fcSupported = 1;
793 }
794
795 PrintFeatureExecutionCaps(__FUNCTION__, *cscEngine);
796 return MOS_STATUS_SUCCESS;
797 }
798
799
GetCSCExecutionCapsBT2020ToRGB(SwFilter * cgc,SwFilter * csc)800 MOS_STATUS Policy::GetCSCExecutionCapsBT2020ToRGB(SwFilter *cgc, SwFilter *csc)
801 {
802 VP_FUNC_CALL();
803 VP_PUBLIC_CHK_NULL_RETURN(csc);
804 VP_PUBLIC_CHK_NULL_RETURN(cgc);
805 VP_PUBLIC_CHK_NULL_RETURN(m_vpInterface.GetHwInterface());
806 VP_PUBLIC_CHK_NULL_RETURN(m_vpInterface.GetHwInterface()->m_userFeatureControl);
807 auto userFeatureControl = m_vpInterface.GetHwInterface()->m_userFeatureControl;
808 bool disableVeboxOutput = userFeatureControl->IsVeboxOutputDisabled();
809 bool disableSfc = userFeatureControl->IsSfcDisabled();
810 MOS_FORMAT midFormat = Format_A8R8G8B8;
811
812 if (!((SwFilterCgc *)cgc)->IsBt2020ToRGBEnabled())
813 {
814 VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_UNIMPLEMENTED);
815 }
816
817 FeatureParamCsc *cscParams = &((SwFilterCsc *)csc)->GetSwFilterParams();
818
819 VP_EngineEntry *cscEngine = &((SwFilterCsc *)csc)->GetFilterEngineCaps();
820
821 FeatureParamCgc *cgcParams = &((SwFilterCgc *)cgc)->GetSwFilterParams();
822
823 // Clean usedForNextPass flag.
824 if (cscEngine->usedForNextPass)
825 {
826 cscEngine->usedForNextPass = false;
827 }
828 if (cscEngine->value != 0)
829 {
830 VP_PUBLIC_NORMALMESSAGE("CSC Feature Already been processed, Skip further process");
831
832 PrintFeatureExecutionCaps(__FUNCTION__, *cscEngine);
833 return MOS_STATUS_SUCCESS;
834 }
835
836 if (m_hwCaps.m_sfcHwEntry[midFormat].cscSupported &&
837 m_hwCaps.m_sfcHwEntry[cscParams->formatOutput].outputSupported &&
838 m_hwCaps.m_sfcHwEntry[midFormat].inputSupported)
839 {
840 // Vebox GC + SFC/Render. The csc parameter below if for sfc or render.
841 cgcParams->formatOutput = midFormat;
842 cgcParams->dstColorSpace = CSpace_sRGB;
843 cscParams->formatforCUS = cscParams->formatInput;
844 cscParams->formatInput = cgcParams->formatOutput;
845 cscParams->input.colorSpace = cgcParams->dstColorSpace;
846
847 cscEngine->bEnabled = 1;
848 if (disableSfc)
849 {
850 cscEngine->SfcNeeded = 0;
851 }
852 else
853 {
854 cscEngine->SfcNeeded = 1;
855 }
856 cscEngine->VeboxNeeded = 0;
857 cscEngine->RenderNeeded = 1;
858 cscEngine->fcSupported = 1;
859 }
860 else
861 {
862 PrintFeatureExecutionCaps(__FUNCTION__, *cscEngine);
863 VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_INVALID_PARAMETER);
864 }
865
866 PrintFeatureExecutionCaps(__FUNCTION__, *cscEngine);
867 return MOS_STATUS_SUCCESS;
868 }
869
IsDemosaicValidOutputFormat(MOS_FORMAT format)870 bool Policy::IsDemosaicValidOutputFormat(MOS_FORMAT format)
871 {
872 return (format == Format_R10G10B10A2 || format == Format_A8R8G8B8);
873 }
874
IsBeCscNeededForAlphaFill(MOS_FORMAT formatInput,MOS_FORMAT formatOutput,PVPHAL_ALPHA_PARAMS compAlpha)875 bool IsBeCscNeededForAlphaFill(MOS_FORMAT formatInput, MOS_FORMAT formatOutput, PVPHAL_ALPHA_PARAMS compAlpha)
876 {
877 if (nullptr == compAlpha)
878 {
879 VP_PUBLIC_NORMALMESSAGE("No alpha setting exists.");
880 return false;
881 }
882
883 if (!IS_ALPHA_FORMAT(formatOutput))
884 {
885 VP_PUBLIC_NORMALMESSAGE("Alpha setting can be ignored for non-alpha output format.");
886 return false;
887 }
888
889 if (VPHAL_ALPHA_FILL_MODE_SOURCE_STREAM == compAlpha->AlphaMode)
890 {
891 VP_PUBLIC_NORMALMESSAGE("No need BeCsc for VPHAL_ALPHA_FILL_MODE_SOURCE_STREAM when output from vebox.");
892 return false;
893 }
894
895 if (VPHAL_ALPHA_FILL_MODE_OPAQUE == compAlpha->AlphaMode && !IS_ALPHA_FORMAT(formatInput))
896 {
897 // In such case, vebox will fill the alpha field with 0xff by default.
898 VP_PUBLIC_NORMALMESSAGE("No need BeCsc for VPHAL_ALPHA_FILL_MODE_OPAQUE with non-alpha input format.");
899 return false;
900 }
901
902 return true;
903 }
904
IsAlphaSettingSupportedBySfc(MOS_FORMAT formatInput,MOS_FORMAT formatOutput,PVPHAL_ALPHA_PARAMS compAlpha)905 bool Policy::IsAlphaSettingSupportedBySfc(MOS_FORMAT formatInput, MOS_FORMAT formatOutput, PVPHAL_ALPHA_PARAMS compAlpha)
906 {
907 if (!IS_ALPHA_FORMAT(formatOutput))
908 {
909 VP_PUBLIC_NORMALMESSAGE("Alpha setting can be ignored for non-alpha output format.");
910 return true;
911 }
912
913 if (compAlpha && VPHAL_ALPHA_FILL_MODE_SOURCE_STREAM == compAlpha->AlphaMode)
914 {
915 if (IS_ALPHA_FORMAT(formatInput))
916 {
917 VP_PUBLIC_NORMALMESSAGE("VPHAL_ALPHA_FILL_MODE_SOURCE_STREAM is not supported by SFC.");
918 if (Format_Y410 == formatOutput)
919 {
920 // Y410 is also not supported by FC Save_444Scale16_SrcY410 kernel for Alpha Source Mode.
921 // Ignore Alpha Source Mode if sfc/render being needed.
922 VP_PUBLIC_NORMALMESSAGE("Ignore VPHAL_ALPHA_FILL_MODE_SOURCE_STREAM for Y410.");
923 return true;
924 }
925 return false;
926 }
927 else
928 {
929 VP_PUBLIC_NORMALMESSAGE("VPHAL_ALPHA_FILL_MODE_SOURCE_STREAM can be ignored since no alpha info in input surface.");
930 return true;
931 }
932 }
933 else if (compAlpha && VPHAL_ALPHA_FILL_MODE_BACKGROUND == compAlpha->AlphaMode)
934 {
935 if (IS_ALPHA_FORMAT_RGB8(formatOutput) || IS_ALPHA_FORMAT_RGB10(formatOutput))
936 {
937 VP_PUBLIC_NORMALMESSAGE("VPHAL_ALPHA_FILL_MODE_BACKGROUND is supported by SFC for RGB8 and RGB10.");
938 return true;
939 }
940 else
941 {
942 VP_PUBLIC_NORMALMESSAGE("VPHAL_ALPHA_FILL_MODE_BACKGROUND is not supported for format %d.", formatOutput);
943 if (Format_Y410 == formatOutput)
944 {
945 // Y410 is also not supported by FC Save_444Scale16_SrcY410 kernel for Alpha Background Mode.
946 // Ignore Alpha Background Mode if sfc/render being needed.
947 VP_PUBLIC_NORMALMESSAGE("Ignore VPHAL_ALPHA_FILL_MODE_BACKGROUND for Y410.");
948 return true;
949 }
950 return false;
951 }
952 }
953
954 if (compAlpha)
955 {
956 VP_PUBLIC_NORMALMESSAGE("true for AlphaMode %d.", compAlpha->AlphaMode);
957 }
958 else
959 {
960 VP_PUBLIC_NORMALMESSAGE("compAlpha == nullptr. Just return true");
961 }
962
963 return true;
964 }
965
IsAlphaSettingSupportedByVebox(MOS_FORMAT formatInput,MOS_FORMAT formatOutput,PVPHAL_ALPHA_PARAMS compAlpha)966 bool Policy::IsAlphaSettingSupportedByVebox(MOS_FORMAT formatInput, MOS_FORMAT formatOutput, PVPHAL_ALPHA_PARAMS compAlpha)
967 {
968 if (!IS_ALPHA_FORMAT(formatOutput))
969 {
970 VP_PUBLIC_NORMALMESSAGE("Alpha setting can be ignored for non-alpha output format.");
971 return true;
972 }
973
974 if (compAlpha && VPHAL_ALPHA_FILL_MODE_BACKGROUND == compAlpha->AlphaMode)
975 {
976 VP_PUBLIC_NORMALMESSAGE("Alpha Background Mode is not supported by Vebox.");
977 return false;
978 }
979 else
980 {
981 if (compAlpha)
982 {
983 VP_PUBLIC_NORMALMESSAGE("true for AlphaMode %d.", compAlpha->AlphaMode);
984 }
985 else
986 {
987 VP_PUBLIC_NORMALMESSAGE("compAlpha == nullptr. Just return true");
988 }
989 return true;
990 }
991 }
992
GetCSCExecutionCaps(SwFilter * feature,bool isCamPipeWithBayerInput)993 MOS_STATUS Policy::GetCSCExecutionCaps(SwFilter* feature, bool isCamPipeWithBayerInput)
994 {
995 VP_FUNC_CALL();
996 VP_PUBLIC_CHK_NULL_RETURN(feature);
997 VP_PUBLIC_CHK_NULL_RETURN(m_vpInterface.GetHwInterface());
998 VP_PUBLIC_CHK_NULL_RETURN(m_vpInterface.GetHwInterface()->m_userFeatureControl);
999
1000 auto userFeatureControl = m_vpInterface.GetHwInterface()->m_userFeatureControl;
1001 bool disableVeboxOutput = userFeatureControl->IsVeboxOutputDisabled();
1002 bool disableSfc = userFeatureControl->IsSfcDisabled();
1003 bool veboxTypeH = userFeatureControl->IsVeboxTypeHMode();
1004 SwFilterCsc* csc = (SwFilterCsc*)feature;
1005
1006 FeatureParamCsc *cscParams = &csc->GetSwFilterParams();
1007
1008 MOS_FORMAT midFormat = Format_Any;
1009
1010 VP_EngineEntry *cscEngine = &csc->GetFilterEngineCaps();
1011
1012 cscEngine->isBayerInputInUse = false;
1013 // Clean usedForNextPass flag.
1014 if (cscEngine->usedForNextPass)
1015 {
1016 cscEngine->usedForNextPass = false;
1017 }
1018 if (cscEngine->value != 0)
1019 {
1020 VP_PUBLIC_NORMALMESSAGE("CSC Feature Already been processed, Skip further process");
1021
1022 PrintFeatureExecutionCaps(__FUNCTION__, *cscEngine);
1023 return MOS_STATUS_SUCCESS;
1024 }
1025
1026 if (cscParams->formatInput == Format_422H ||
1027 cscParams->formatInput == Format_422V)
1028 {
1029 //422H and 422V input not supported by L0 FC yet. Will remove the restriction after they are enabled
1030 cscEngine->forceLegacyFC = true;
1031 }
1032
1033 bool isAlphaSettingSupportedBySfc =
1034 IsAlphaSettingSupportedBySfc(cscParams->formatInput, cscParams->formatOutput, cscParams->pAlphaParams);
1035 bool isAlphaSettingSupportedByVebox =
1036 IsAlphaSettingSupportedByVebox(cscParams->formatInput, cscParams->formatOutput, cscParams->pAlphaParams);
1037
1038 if (cscParams->formatInput == cscParams->formatOutput &&
1039 cscParams->input.colorSpace == cscParams->output.colorSpace &&
1040 cscParams->input.chromaSiting == cscParams->output.chromaSiting &&
1041 nullptr == cscParams->pIEFParams &&
1042 isAlphaSettingSupportedByVebox)
1043 {
1044 bool veboxSupported = m_hwCaps.m_veboxHwEntry[cscParams->formatInput].inputSupported;
1045 bool sfcSupported = veboxSupported && m_hwCaps.m_sfcHwEntry[cscParams->formatInput].inputSupported;
1046
1047 if (!veboxSupported)
1048 {
1049 VP_PUBLIC_NORMALMESSAGE("Format %d not supported by vebox. Force to render.", cscParams->formatInput);
1050 cscEngine->bEnabled = 1;
1051 cscEngine->SfcNeeded = 0;
1052 cscEngine->VeboxNeeded = 0;
1053 cscEngine->RenderNeeded = 1;
1054 cscEngine->fcSupported = 1;
1055 cscEngine->sfcNotSupported = 1;
1056 }
1057 else if (disableVeboxOutput)
1058 {
1059 VP_PUBLIC_NORMALMESSAGE("Non-csc cases with vebox output disabled. Still keep csc filter to avoid output from vebox.");
1060 cscEngine->bEnabled = 1;
1061 cscEngine->SfcNeeded = (disableSfc || !sfcSupported) ? 0 : 1;
1062 cscEngine->VeboxNeeded = 0;
1063 cscEngine->RenderNeeded = 1;
1064 cscEngine->fcSupported = 1;
1065 }
1066 else if (IsBeCscNeededForAlphaFill(cscParams->formatInput, cscParams->formatOutput, cscParams->pAlphaParams))
1067 {
1068 VP_PUBLIC_NORMALMESSAGE("BeCsc is needed by Alpha when output from vebox. Keep csc filter.");
1069 cscEngine->bEnabled = 1;
1070 cscEngine->SfcNeeded = disableSfc ? 0 : 1;
1071 cscEngine->RenderNeeded = 1;
1072 cscEngine->fcSupported = 1;
1073 if (veboxTypeH)
1074 {
1075 cscEngine->VeboxNeeded = 0;
1076 VP_PUBLIC_NORMALMESSAGE("Not use vebox to do csc for veboxTypeH.");
1077 }
1078 else
1079 {
1080 cscEngine->VeboxNeeded = 1;
1081 }
1082 }
1083 else
1084 {
1085 // for non-csc cases, all engine supported
1086 cscEngine->bEnabled = 0;
1087 cscEngine->SfcNeeded = 0;
1088 cscEngine->VeboxNeeded = 0;
1089 cscEngine->RenderNeeded = 0;
1090 if (sfcSupported && !disableSfc)
1091 {
1092 cscEngine->forceEnableForSfc = 1;
1093 }
1094 else
1095 {
1096 cscEngine->sfcNotSupported = 1;
1097 }
1098 }
1099
1100 PrintFeatureExecutionCaps(__FUNCTION__, *cscEngine);
1101 return MOS_STATUS_SUCCESS;
1102 }
1103
1104 if (IS_COLOR_SPACE_BT2020_YUV(cscParams->input.colorSpace))
1105 {
1106 if ((cscParams->output.colorSpace == CSpace_BT601) ||
1107 (cscParams->output.colorSpace == CSpace_BT709) ||
1108 (cscParams->output.colorSpace == CSpace_BT601_FullRange) ||
1109 (cscParams->output.colorSpace == CSpace_BT709_FullRange) ||
1110 (cscParams->output.colorSpace == CSpace_stRGB) ||
1111 (cscParams->output.colorSpace == CSpace_sRGB))
1112 {
1113 // Should not come here for BT2020 support.
1114 VP_PUBLIC_ASSERTMESSAGE("not support BT2020 input.");
1115 return MOS_STATUS_UNIMPLEMENTED;
1116 }
1117 }
1118
1119 cscEngine->bEnabled = 1;
1120 cscEngine->RenderNeeded = 1;
1121 cscEngine->fcSupported = 1;
1122
1123 // SFC CSC enabling check
1124 if (!disableSfc &&
1125 m_hwCaps.m_sfcHwEntry[cscParams->formatInput].inputSupported &&
1126 (m_hwCaps.m_sfcHwEntry[cscParams->formatOutput].outputSupported &
1127 VpGetFormatTileSupport(cscParams->output.tileMode)) &&
1128 m_hwCaps.m_sfcHwEntry[cscParams->formatInput].cscSupported &&
1129 isAlphaSettingSupportedBySfc)
1130 {
1131 cscEngine->SfcNeeded = 1;
1132 }
1133
1134 if (disableVeboxOutput)
1135 {
1136 // If vebox output disabled, then such mega feature like CSC will not take effect in Vebox.
1137 // then CSC will must be assign to SFC/Render path for execution.
1138 VP_PUBLIC_NORMALMESSAGE("Force to use sfc or render for csc.");
1139 }
1140 else
1141 {
1142 if (!cscParams->pIEFParams &&
1143 m_hwCaps.m_veboxHwEntry[cscParams->formatInput].inputSupported &&
1144 (m_hwCaps.m_veboxHwEntry[cscParams->formatOutput].outputSupported ||
1145 (isCamPipeWithBayerInput && IsDemosaicValidOutputFormat(cscParams->formatOutput))) &&
1146 m_hwCaps.m_veboxHwEntry[cscParams->formatInput].iecp &&
1147 m_hwCaps.m_veboxHwEntry[cscParams->formatInput].backEndCscSupported &&
1148 isAlphaSettingSupportedByVebox)
1149 {
1150 cscEngine->VeboxNeeded = 1;
1151 }
1152 }
1153
1154 PrintFeatureExecutionCaps(__FUNCTION__, *cscEngine);
1155 return MOS_STATUS_SUCCESS;
1156 }
1157
GetScalingExecutionCapsHdr(SwFilter * feature)1158 MOS_STATUS Policy::GetScalingExecutionCapsHdr(SwFilter *feature)
1159 {
1160 VP_FUNC_CALL();
1161 VP_PUBLIC_CHK_STATUS_RETURN(GetScalingExecutionCaps(feature, true, false));
1162 return MOS_STATUS_SUCCESS;
1163 }
1164
GetScalingExecutionCaps(SwFilter * feature,bool isDIEnabled)1165 MOS_STATUS Policy::GetScalingExecutionCaps(SwFilter *feature, bool isDIEnabled)
1166 {
1167 VP_FUNC_CALL();
1168 VP_PUBLIC_CHK_STATUS_RETURN(GetScalingExecutionCaps(feature, false, isDIEnabled));
1169 return MOS_STATUS_SUCCESS;
1170 }
1171
GetScalingExecutionCaps(SwFilter * feature,bool isHdrEnabled,bool isDIEnabled)1172 MOS_STATUS Policy::GetScalingExecutionCaps(SwFilter *feature, bool isHdrEnabled, bool isDIEnabled)
1173 {
1174 VP_FUNC_CALL();
1175
1176 uint32_t dwSurfaceWidth = 0, dwSurfaceHeight = 0;
1177 uint32_t dwOutputSurfaceWidth = 0, dwOutputSurfaceHeight = 0;
1178 uint32_t veboxMinWidth = 0, veboxMaxWidth = 0;
1179 uint32_t veboxMinHeight = 0, veboxMaxHeight = 0;
1180 uint32_t dwSfcInputMinWidth = 0, dwSfcMaxWidth = 0;
1181 uint32_t dwSfcInputMinHeight = 0, dwSfcMaxHeight = 0;
1182 uint32_t dwSfcOutputMinWidth = 0, dwSfcOutputMinHeight = 0;
1183 uint32_t dwDstMinHeight = 0;
1184 float fScaleMin = 0, fScaleMax = 0;
1185 float fScaleMin2Pass = 0, fScaleMax2Pass = 0;
1186 float fScaleX = 0, fScaleY = 0;
1187
1188 VP_PUBLIC_CHK_NULL_RETURN(feature);
1189 VP_PUBLIC_CHK_NULL_RETURN(m_vpInterface.GetHwInterface());
1190 VP_PUBLIC_CHK_NULL_RETURN(m_vpInterface.GetHwInterface()->m_userFeatureControl);
1191
1192 auto userFeatureControl = m_vpInterface.GetHwInterface()->m_userFeatureControl;
1193 bool disableSfc = userFeatureControl->IsSfcDisabled();
1194 SwFilterScaling* scaling = (SwFilterScaling*)feature;
1195 FeatureParamScaling *scalingParams = &scaling->GetSwFilterParams();
1196 VP_EngineEntry *scalingEngine = &scaling->GetFilterEngineCaps();
1197 bool isAlphaSettingSupportedBySfc =
1198 IsAlphaSettingSupportedBySfc(scalingParams->formatInput, scalingParams->formatOutput, scalingParams->pCompAlpha);
1199 bool isAlphaSettingSupportedByVebox =
1200 IsAlphaSettingSupportedByVebox(scalingParams->formatInput, scalingParams->formatOutput, scalingParams->pCompAlpha);
1201
1202 if (scalingParams->formatOutput == Format_422H)
1203 {
1204 VP_PUBLIC_ASSERTMESSAGE("Scaling not support 422H format output.");
1205 return MOS_STATUS_UNIMPLEMENTED;
1206 }
1207
1208 // Clean usedForNextPass flag.
1209 if (scalingEngine->usedForNextPass)
1210 {
1211 scalingEngine->usedForNextPass = false;
1212 }
1213
1214 if (scalingEngine->value != 0)
1215 {
1216 VP_PUBLIC_NORMALMESSAGE("Scaling Feature Already been processed, Skip further process");
1217
1218 PrintFeatureExecutionCaps(__FUNCTION__, *scalingEngine);
1219 return MOS_STATUS_SUCCESS;
1220 }
1221
1222 //For BT2020 color fill, fall back to legacy FC.
1223 //Legacy FC and L0 FC both not support BT2020 as target Cspace ColorFill, Legacy FC will do wrong color
1224 //Will remove restriction after L0 FC enabled BT2020 target color fill
1225 if (IS_COLOR_SPACE_BT2020(scalingParams->csc.colorSpaceOutput) &&
1226 scalingParams->pColorFillParams != nullptr &&
1227 (scalingParams->input.rcDst.left > scalingParams->output.rcDst.left ||
1228 scalingParams->input.rcDst.right < scalingParams->output.rcDst.right ||
1229 scalingParams->input.rcDst.top > scalingParams->output.rcDst.top ||
1230 scalingParams->input.rcDst.bottom < scalingParams->output.rcDst.bottom))
1231 {
1232 scalingEngine->forceLegacyFC = true;
1233 }
1234
1235 // For AVS sampler not enabled case, HQ/Fast scaling should go to SFC.
1236 // And Ief should only be done by SFC.
1237 if (!m_hwCaps.m_rules.isAvsSamplerSupported &&
1238 scalingParams->scalingPreference != VPHAL_SCALING_PREFER_SFC)
1239 {
1240 VP_PUBLIC_NORMALMESSAGE("Force scalingPreference from %d to SFC", scalingParams->scalingPreference);
1241 scalingParams->scalingPreference = VPHAL_SCALING_PREFER_SFC;
1242 }
1243
1244 if (userFeatureControl->IsSFCLinearOutputByTileConvertEnabled() &&
1245 scalingParams->output.dwWidth <= 1152 &&
1246 scalingParams->output.dwPitch != 128 &&
1247 scalingParams->output.dwPitch != 256 &&
1248 (scalingParams->output.dwPitch % 1024) !=0 &&
1249 !(scalingParams->formatOutput == Format_RGBP ||
1250 scalingParams->formatOutput == Format_BGRP ||
1251 scalingParams->formatOutput == Format_R8G8B8) &&
1252 scalingParams->output.tileMode == MOS_TILE_LINEAR_GMM)
1253 {
1254 scalingEngine->enableSFCLinearOutputByTileConvert = true;
1255 VP_PUBLIC_NORMALMESSAGE("enable sfcLinearOutputByTileConvert, output width %d, output pitch %d, output tilemode %d", scalingParams->output.dwWidth, scalingParams->output.dwPitch, scalingParams->output.tileMode);
1256 }
1257 dwSurfaceWidth = scalingParams->input.dwWidth;
1258 dwSurfaceHeight = scalingParams->input.dwHeight;
1259 dwOutputSurfaceWidth = scalingParams->output.dwWidth;
1260 dwOutputSurfaceHeight = scalingParams->output.dwHeight;
1261
1262 // Region of the input frame which needs to be processed by SFC
1263 uint32_t dwSourceRegionHeight = MOS_ALIGN_FLOOR(
1264 MOS_MIN((uint32_t)(scalingParams->input.rcSrc.bottom - scalingParams->input.rcSrc.top), dwSurfaceHeight),
1265 m_hwCaps.m_sfcHwEntry[scalingParams->formatInput].verticalAlignUnit);
1266 uint32_t dwSourceRegionWidth = MOS_ALIGN_FLOOR(
1267 MOS_MIN((uint32_t)(scalingParams->input.rcSrc.right - scalingParams->input.rcSrc.left), dwSurfaceWidth),
1268 m_hwCaps.m_sfcHwEntry[scalingParams->formatInput].horizontalAlignUnit);
1269
1270 // Size of the Output Region over the Render Target
1271 uint32_t dwOutputRegionHeight = MOS_ALIGN_CEIL(
1272 (uint32_t)(scalingParams->input.rcDst.bottom - scalingParams->input.rcDst.top),
1273 m_hwCaps.m_sfcHwEntry[scalingParams->formatOutput].verticalAlignUnit);
1274 uint32_t dwOutputRegionWidth = MOS_ALIGN_CEIL(
1275 (uint32_t)(scalingParams->input.rcDst.right - scalingParams->input.rcDst.left),
1276 m_hwCaps.m_sfcHwEntry[scalingParams->formatOutput].horizontalAlignUnit);
1277
1278 if (!m_hwCaps.m_veboxHwEntry[scalingParams->formatInput].inputSupported)
1279 {
1280 // For non-scaling cases with vebox unsupported format, will force to use fc.
1281 scalingEngine->bEnabled = (dwOutputRegionHeight != dwSourceRegionHeight ||
1282 dwOutputRegionWidth != dwSourceRegionWidth);
1283 scalingEngine->SfcNeeded = 0;
1284 scalingEngine->VeboxNeeded = 0;
1285 scalingEngine->RenderNeeded = 1;
1286 scalingEngine->fcSupported = 1;
1287 scalingEngine->hdrKernelSupported = 1;
1288 scalingEngine->forceEnableForSfc = 0;
1289 scalingEngine->forceEnableForFc = 1;
1290 scalingEngine->veboxNotSupported = 1;
1291
1292 PrintFeatureExecutionCaps(__FUNCTION__, *scalingEngine);
1293 return MOS_STATUS_SUCCESS;
1294 }
1295
1296 veboxMinWidth = m_hwCaps.m_veboxHwEntry[scalingParams->formatInput].minWidth;
1297 veboxMaxWidth = m_hwCaps.m_veboxHwEntry[scalingParams->formatInput].maxWidth;
1298 veboxMinHeight = m_hwCaps.m_veboxHwEntry[scalingParams->formatInput].minHeight;
1299 veboxMaxHeight = m_hwCaps.m_veboxHwEntry[scalingParams->formatInput].maxHeight;
1300 dwSfcInputMinWidth = m_hwCaps.m_sfcHwEntry[scalingParams->formatInput].inputMinResolution;
1301 dwSfcMaxWidth = m_hwCaps.m_sfcHwEntry[scalingParams->formatInput].maxResolution;
1302 dwSfcInputMinHeight = m_hwCaps.m_sfcHwEntry[scalingParams->formatInput].inputMinResolution;
1303 dwSfcMaxHeight = m_hwCaps.m_sfcHwEntry[scalingParams->formatInput].maxResolution;
1304 dwSfcOutputMinWidth = m_hwCaps.m_sfcHwEntry[scalingParams->formatOutput].outputMinResolution;
1305 dwSfcOutputMinHeight = m_hwCaps.m_sfcHwEntry[scalingParams->formatOutput].outputMinResolution;
1306 fScaleMin = m_hwCaps.m_sfcHwEntry[scalingParams->formatInput].minScalingRatio;
1307 fScaleMax = m_hwCaps.m_sfcHwEntry[scalingParams->formatInput].maxScalingRatio;
1308 if (m_hwCaps.m_rules.sfcMultiPassSupport.scaling.enable)
1309 {
1310 fScaleMin2Pass = fScaleMin * m_hwCaps.m_rules.sfcMultiPassSupport.scaling.downScaling.minRatioEnlarged;
1311 fScaleMax2Pass = fScaleMax * m_hwCaps.m_rules.sfcMultiPassSupport.scaling.upScaling.maxRatioEnlarged;
1312 }
1313
1314 if (scalingParams->interlacedScalingType == ISCALING_FIELD_TO_INTERLEAVED)
1315 {
1316 dwDstMinHeight = dwSfcOutputMinHeight * 2;
1317 }
1318 else
1319 {
1320 dwDstMinHeight = dwSfcOutputMinHeight;
1321 }
1322
1323 if (OUT_OF_BOUNDS(dwSurfaceWidth, veboxMinWidth, veboxMaxWidth) ||
1324 OUT_OF_BOUNDS(dwSurfaceHeight, veboxMinHeight, veboxMaxHeight))
1325 {
1326 // For non-scaling cases with vebox unsupported format, will force to use fc.
1327 scalingEngine->bEnabled = (dwOutputRegionHeight != dwSourceRegionHeight ||
1328 dwOutputRegionWidth != dwSourceRegionWidth);
1329 scalingEngine->SfcNeeded = 0;
1330 scalingEngine->VeboxNeeded = 0;
1331 scalingEngine->forceEnableForSfc = 0;
1332 scalingEngine->RenderNeeded = 1;
1333 scalingEngine->fcSupported = 1;
1334 scalingEngine->hdrKernelSupported = 1;
1335 scalingEngine->forceEnableForFc = 1;
1336 scalingEngine->veboxNotSupported = 1;
1337
1338 VP_PUBLIC_NORMALMESSAGE("The surface resolution (%d x %d) is not supported by vebox (%d x %d) ~ (%d x %d).",
1339 dwSurfaceWidth, dwSurfaceHeight, veboxMinWidth, veboxMinHeight, veboxMaxWidth, veboxMaxHeight);
1340
1341 PrintFeatureExecutionCaps(__FUNCTION__, *scalingEngine);
1342 return MOS_STATUS_SUCCESS;
1343 }
1344
1345 // Calculate the scaling ratio
1346 // Both source region and scaled region are pre-rotated
1347 // Need to take Interlace scaling into consideration next step
1348 fScaleX = (float)dwOutputRegionWidth / (float)dwSourceRegionWidth;
1349 fScaleY = (float)dwOutputRegionHeight / (float)dwSourceRegionHeight;
1350
1351 auto isSfcIscalingNotSupported = [&]()
1352 {
1353 return ISCALING_INTERLEAVED_TO_INTERLEAVED == scalingParams->interlacedScalingType &&
1354 (scalingParams->input.rcSrc.left != 0 ||
1355 scalingParams->input.rcSrc.top != 0 ||
1356 scalingParams->input.rcDst.left != 0 ||
1357 scalingParams->input.rcDst.top != 0 ||
1358 scalingParams->rotation.rotationNeeded);
1359 };
1360
1361 if (fScaleX == 1.0f && fScaleY == 1.0f &&
1362 // Only support vebox crop from left-top, which is to align with legacy path.
1363 0 == scalingParams->input.rcSrc.left && 0 == scalingParams->input.rcSrc.top &&
1364 SAME_SIZE_RECT(scalingParams->input.rcDst, scalingParams->output.rcDst) &&
1365 // If alpha is not supported by vebox, which should go SFC pipe.
1366 isAlphaSettingSupportedByVebox &&
1367 // If Colorfill enabled, which should go SFC pipe.
1368 !IsColorfillEnabled(scalingParams) &&
1369 scalingParams->interlacedScalingType != ISCALING_INTERLEAVED_TO_FIELD &&
1370 scalingParams->interlacedScalingType != ISCALING_FIELD_TO_INTERLEAVED)
1371 {
1372 if (OUT_OF_BOUNDS(dwSurfaceWidth, dwSfcInputMinWidth, dwSfcMaxWidth) ||
1373 OUT_OF_BOUNDS(dwSurfaceHeight, dwSfcInputMinHeight, dwSfcMaxHeight))
1374 {
1375 // for non-Scaling cases, all engine supported
1376 scalingEngine->bEnabled = 0;
1377 scalingEngine->SfcNeeded = 0;
1378 scalingEngine->VeboxNeeded = 0;
1379 scalingEngine->RenderNeeded = 0;
1380 scalingEngine->forceEnableForSfc = 0;
1381 scalingEngine->forceEnableForFc = 1;
1382 scalingEngine->fcSupported = 1;
1383 scalingEngine->hdrKernelSupported = 1;
1384 scalingEngine->sfcNotSupported = 1;
1385 VP_PUBLIC_NORMALMESSAGE("The surface resolution (%d x %d) is not supported by sfc (%d x %d) ~ (%d x %d).",
1386 dwSurfaceWidth, dwSurfaceHeight, dwSfcInputMinWidth, dwSfcInputMinHeight, dwSfcMaxWidth, dwSfcMaxHeight);
1387 }
1388 else if (isSfcIscalingNotSupported())
1389 {
1390 scalingEngine->bEnabled = 1;
1391 scalingEngine->SfcNeeded = 0;
1392 scalingEngine->VeboxNeeded = 0;
1393 scalingEngine->RenderNeeded = 1;
1394 scalingEngine->fcSupported = 1;
1395 scalingEngine->sfcNotSupported = 1;
1396 VP_PUBLIC_NORMALMESSAGE("Interlaced scaling cannot support offset, rotate or mirror by SFC pipe, fallback to FC.");
1397 }
1398 else if (scalingParams->input.rcDst.left > 0 ||
1399 scalingParams->input.rcDst.top > 0)
1400 {
1401 // for dst left and top non zero cases, should go SFC or Render Pipe
1402 scalingEngine->bEnabled = 1;
1403 scalingEngine->SfcNeeded = !disableSfc && isAlphaSettingSupportedBySfc;
1404 scalingEngine->VeboxNeeded = 0;
1405 scalingEngine->RenderNeeded = 1;
1406 scalingEngine->fcSupported = 1;
1407 scalingEngine->hdrKernelSupported = 1;
1408 VP_PUBLIC_NORMALMESSAGE("The dst left and top non zero is not supported by vebox ");
1409 }
1410 else
1411 {
1412 // for non-Scaling cases, all engine supported
1413 scalingEngine->bEnabled = 0;
1414 scalingEngine->SfcNeeded = 0;
1415 scalingEngine->VeboxNeeded = 0;
1416 scalingEngine->RenderNeeded = 0;
1417 scalingEngine->forceEnableForSfc = isAlphaSettingSupportedBySfc;
1418 scalingEngine->forceEnableForFc = 1;
1419 scalingEngine->fcSupported = 1;
1420 scalingEngine->hdrKernelSupported = 1;
1421 scalingEngine->sfcNotSupported = disableSfc || !isAlphaSettingSupportedBySfc;
1422 }
1423
1424 PrintFeatureExecutionCaps(__FUNCTION__, *scalingEngine);
1425 return MOS_STATUS_SUCCESS;
1426 }
1427
1428 if (disableSfc)
1429 {
1430 scalingEngine->bEnabled = 1;
1431 scalingEngine->RenderNeeded = 1;
1432 scalingEngine->fcSupported = 1;
1433 scalingEngine->hdrKernelSupported = 1;
1434 scalingEngine->SfcNeeded = 0;
1435 // Set sfcNotSupported to 1 to avoid SFC being selected without scaling filter.
1436 scalingEngine->sfcNotSupported = 1;
1437 VP_PUBLIC_NORMALMESSAGE("Force scaling to FC. disableSfc %d", disableSfc);
1438 PrintFeatureExecutionCaps(__FUNCTION__, *scalingEngine);
1439 return MOS_STATUS_SUCCESS;
1440 }
1441
1442 // SFC Scaling enabling check
1443 if (m_hwCaps.m_sfcHwEntry[scalingParams->formatInput].inputSupported &&
1444 (m_hwCaps.m_sfcHwEntry[scalingParams->formatOutput].outputSupported & VpGetFormatTileSupport(scalingParams->output.tileMode) ) &&
1445 m_hwCaps.m_sfcHwEntry[scalingParams->formatInput].scalingSupported)
1446 {
1447 if (!(OUT_OF_BOUNDS(dwSurfaceWidth, dwSfcInputMinWidth, dwSfcMaxWidth) ||
1448 OUT_OF_BOUNDS(dwSurfaceHeight, dwSfcInputMinHeight, dwSfcMaxHeight) ||
1449 OUT_OF_BOUNDS(dwSourceRegionWidth, dwSfcInputMinWidth, dwSfcMaxWidth) ||
1450 OUT_OF_BOUNDS(dwSourceRegionHeight, dwSfcInputMinHeight, dwSfcMaxHeight) ||
1451 OUT_OF_BOUNDS(dwOutputRegionWidth, dwSfcOutputMinWidth, dwSfcMaxWidth) ||
1452 OUT_OF_BOUNDS(dwOutputRegionHeight, dwSfcOutputMinHeight, dwSfcMaxHeight) ||
1453 OUT_OF_BOUNDS(dwOutputSurfaceWidth, dwSfcOutputMinWidth, dwSfcMaxWidth) ||
1454 OUT_OF_BOUNDS(dwOutputSurfaceHeight, dwDstMinHeight, dwSfcMaxHeight)))
1455 {
1456 if ((m_hwCaps.m_rules.sfcMultiPassSupport.scaling.enable &&
1457 (OUT_OF_BOUNDS(fScaleX, fScaleMin2Pass, fScaleMax2Pass) ||
1458 OUT_OF_BOUNDS(fScaleY, fScaleMin2Pass, fScaleMax2Pass))) ||
1459 ((!m_hwCaps.m_rules.sfcMultiPassSupport.scaling.enable ||
1460 isHdrEnabled) && // Ve HDR + (8, 16] && [1/16, 1/8) scaling on render, not use 2 Pass SFC for scaling,
1461 (OUT_OF_BOUNDS(fScaleX, fScaleMin, fScaleMax) || // since A10R10G10B10/ARGB8 cannot be used as the input of vebox when global IECP being enabled.
1462 OUT_OF_BOUNDS(fScaleY, fScaleMin, fScaleMax))) ||
1463 (scalingParams->scalingPreference == VPHAL_SCALING_PREFER_COMP))
1464 {
1465 // Render Pipe, need to add more conditions next step for multiple SFC mode
1466 // if Render didn't have AVS but Scaling quality mode needed
1467 scalingEngine->bEnabled = 1;
1468 scalingEngine->RenderNeeded = 1;
1469 scalingEngine->fcSupported = 1;
1470 scalingEngine->hdrKernelSupported = 1;
1471 scalingEngine->SfcNeeded = 0;
1472 // Set sfcNotSupported to 1 to avoid SFC being selected without scaling filter.
1473 scalingEngine->sfcNotSupported = 1;
1474 VP_PUBLIC_NORMALMESSAGE("Fc selected. fScaleX %f, fScaleY %f, scalingPreference %d",
1475 fScaleX, fScaleY, scalingParams->scalingPreference);
1476 }
1477 else if (isSfcIscalingNotSupported())
1478 {
1479 scalingEngine->bEnabled = 1;
1480 scalingEngine->RenderNeeded = 1;
1481 scalingEngine->fcSupported = 1;
1482 scalingEngine->SfcNeeded = 0;
1483 scalingEngine->sfcNotSupported = 1;
1484 VP_PUBLIC_NORMALMESSAGE("Interlaced scaling cannot support offset, rotate or mirror by SFC pipe, fallback to FC.");
1485 }
1486 // SFC feasible
1487 else
1488 {
1489 bool sfc2PassScalingNeededX = OUT_OF_BOUNDS(fScaleX, fScaleMin, fScaleMax);
1490 bool sfc2PassScalingNeededY = OUT_OF_BOUNDS(fScaleY, fScaleMin, fScaleMax);
1491 bool multiPassNeeded= sfc2PassScalingNeededX || sfc2PassScalingNeededY;
1492
1493 scalingEngine->bEnabled = 1;
1494
1495 if (multiPassNeeded && isDIEnabled)
1496 {
1497 scalingEngine->RenderNeeded = 1;
1498 scalingEngine->fcSupported = 1;
1499 // Set sfcNotSupported to 1 to avoid SFC being selected without scaling filter.
1500 scalingEngine->sfcNotSupported = 1;
1501 VP_PUBLIC_NORMALMESSAGE("2 pass scaling + DI switch to render path.");
1502 }
1503 else if (!m_hwCaps.m_rules.isAvsSamplerSupported && scalingParams->isPrimary && isAlphaSettingSupportedBySfc)
1504 {
1505 // For primary layer, force to use sfc for better quailty.
1506 scalingEngine->SfcNeeded = 1;
1507 scalingEngine->sfc2PassScalingNeededX = sfc2PassScalingNeededX ? 1 : 0;
1508 scalingEngine->sfc2PassScalingNeededY = sfc2PassScalingNeededY ? 1 : 0;
1509 scalingEngine->multiPassNeeded = multiPassNeeded;
1510
1511 if (1 == fScaleX && 1 == fScaleY)
1512 {
1513 VP_PUBLIC_NORMALMESSAGE("Fc can be selected for scale ratio being 1 case on primary, e.g. crop only case.");
1514 scalingEngine->RenderNeeded = 1;
1515 scalingEngine->fcSupported = 1;
1516 scalingEngine->hdrKernelSupported = 1;
1517 }
1518 else
1519 {
1520 scalingEngine->hdrKernelSupported = 1;
1521 }
1522 }
1523 else
1524 {
1525 scalingEngine->RenderNeeded = 1;
1526 scalingEngine->fcSupported = 1;
1527 scalingEngine->hdrKernelSupported = 1;
1528 // For non-primary layer, only consider sfc for non-2-pass case.
1529 if (!sfc2PassScalingNeededX && !sfc2PassScalingNeededY)
1530 {
1531 scalingEngine->SfcNeeded = isAlphaSettingSupportedBySfc;
1532 }
1533 else
1534 {
1535 // Set sfcNotSupported to 1 to avoid SFC being selected without scaling filter.
1536 scalingEngine->sfcNotSupported = 1;
1537 }
1538 }
1539 }
1540 }
1541 else
1542 {
1543 scalingEngine->bEnabled = 1;
1544 scalingEngine->RenderNeeded = 1;
1545 scalingEngine->fcSupported = 1;
1546 scalingEngine->hdrKernelSupported = 1;
1547 scalingEngine->SfcNeeded = 0;
1548 // Set sfcNotSupported to 1 to avoid SFC being selected without scaling filter.
1549 scalingEngine->sfcNotSupported = 1;
1550 VP_PUBLIC_NORMALMESSAGE("Scaling parameters are not supported by SFC. Switch to Render.");
1551 }
1552 }
1553 else
1554 {
1555 scalingEngine->bEnabled = 1;
1556 scalingEngine->RenderNeeded = 1;
1557 scalingEngine->fcSupported = 1;
1558 scalingEngine->hdrKernelSupported = 1;
1559 scalingEngine->SfcNeeded = 0;
1560 VP_PUBLIC_NORMALMESSAGE("Format is not supported by SFC. Switch to Render.");
1561 }
1562
1563 PrintFeatureExecutionCaps(__FUNCTION__, *scalingEngine);
1564 return MOS_STATUS_SUCCESS;
1565 }
1566
IsSfcRotationSupported(FeatureParamRotMir * rotationParams)1567 bool Policy::IsSfcRotationSupported(FeatureParamRotMir *rotationParams)
1568 {
1569 VP_FUNC_CALL();
1570
1571 bool isSfcRotationSupported = false;
1572 if (m_hwCaps.m_sfcHwEntry[rotationParams->formatInput].inputSupported &&
1573 m_hwCaps.m_sfcHwEntry[rotationParams->formatOutput].outputSupported)
1574 {
1575 if (VPHAL_ROTATION_IDENTITY == rotationParams->rotation)
1576 {
1577 isSfcRotationSupported = true;
1578 }
1579 else if (VPHAL_MIRROR_HORIZONTAL == rotationParams->rotation)
1580 {
1581 if (m_hwCaps.m_sfcHwEntry[rotationParams->formatInput].mirrorSupported)
1582 {
1583 isSfcRotationSupported = true;
1584 }
1585 }
1586 else if (rotationParams->rotation <= VPHAL_ROTATION_270)
1587 {
1588 // Rotation w/o mirror case
1589 if (m_hwCaps.m_sfcHwEntry[rotationParams->formatInput].rotationSupported &&
1590 rotationParams->surfInfo.tileOutput == MOS_TILE_Y)
1591 {
1592 isSfcRotationSupported = true;
1593 }
1594 }
1595 else
1596 {
1597 // Rotation w/ mirror case
1598 if (m_hwCaps.m_sfcHwEntry[rotationParams->formatInput].mirrorSupported &&
1599 m_hwCaps.m_sfcHwEntry[rotationParams->formatInput].rotationSupported &&
1600 rotationParams->surfInfo.tileOutput == MOS_TILE_Y)
1601 {
1602 isSfcRotationSupported = true;
1603 }
1604 }
1605 }
1606
1607 VP_PUBLIC_NORMALMESSAGE("Is rotation supported by sfc: %d", isSfcRotationSupported ? 1 : 0);
1608 return isSfcRotationSupported;
1609 }
1610
GetRotationExecutionCaps(SwFilter * feature)1611 MOS_STATUS Policy::GetRotationExecutionCaps(SwFilter* feature)
1612 {
1613 VP_FUNC_CALL();
1614
1615 VP_PUBLIC_CHK_NULL_RETURN(feature);
1616 VP_PUBLIC_CHK_NULL_RETURN(m_vpInterface.GetHwInterface());
1617 VP_PUBLIC_CHK_NULL_RETURN(m_vpInterface.GetHwInterface()->m_userFeatureControl);
1618
1619 auto userFeatureControl = m_vpInterface.GetHwInterface()->m_userFeatureControl;
1620 bool disableSfc = userFeatureControl->IsSfcDisabled();
1621 SwFilterRotMir* rotation = (SwFilterRotMir*)feature;
1622 FeatureParamRotMir *rotationParams = &rotation->GetSwFilterParams();
1623 VP_EngineEntry *rotationEngine = &rotation->GetFilterEngineCaps();
1624
1625 // Clean usedForNextPass flag.
1626 if (rotationEngine->usedForNextPass)
1627 {
1628 rotationEngine->usedForNextPass = false;
1629 }
1630 if (rotationEngine->value != 0)
1631 {
1632 VP_PUBLIC_NORMALMESSAGE("Scaling Feature Already been processed, Skip further process");
1633
1634 PrintFeatureExecutionCaps(__FUNCTION__, *rotationEngine);
1635 return MOS_STATUS_SUCCESS;
1636 }
1637
1638 if (rotationParams->rotation == VPHAL_ROTATION_IDENTITY)
1639 {
1640 // for non-rotation cases, all engine supported
1641 rotationEngine->bEnabled = 0;
1642 rotationEngine->VeboxNeeded = 0;
1643 rotationEngine->SfcNeeded = 0;
1644 rotationEngine->RenderNeeded = 0;
1645 rotationEngine->forceEnableForSfc = 1;
1646 rotationEngine->forceEnableForHdrKernel = 1;
1647 PrintFeatureExecutionCaps(__FUNCTION__, *rotationEngine);
1648 return MOS_STATUS_SUCCESS;
1649 }
1650
1651 rotationEngine->bEnabled = 1;
1652 rotationEngine->RenderNeeded = 1;
1653 rotationEngine->fcSupported = 1;
1654 rotationEngine->hdrKernelSupported = 1;
1655
1656 if (disableSfc)
1657 {
1658 VP_PUBLIC_NORMALMESSAGE("Force rotation to FC. disableSfc %d", disableSfc);
1659 PrintFeatureExecutionCaps(__FUNCTION__, *rotationEngine);
1660 return MOS_STATUS_SUCCESS;
1661 }
1662
1663 rotationEngine->SfcNeeded = IsSfcRotationSupported(rotationParams);
1664
1665 PrintFeatureExecutionCaps(__FUNCTION__, *rotationEngine);
1666 return MOS_STATUS_SUCCESS;
1667 }
1668
GetDenoiseExecutionCaps(SwFilter * feature)1669 MOS_STATUS Policy::GetDenoiseExecutionCaps(SwFilter* feature)
1670 {
1671 VP_FUNC_CALL();
1672 VP_PUBLIC_CHK_NULL_RETURN(feature);
1673
1674 SwFilterDenoise* denoise = dynamic_cast<SwFilterDenoise*>(feature);
1675 VP_PUBLIC_CHK_NULL_RETURN(denoise);
1676
1677 FeatureParamDenoise& denoiseParams = denoise->GetSwFilterParams();
1678 VP_EngineEntry& denoiseEngine = denoise->GetFilterEngineCaps();
1679 MOS_FORMAT inputformat = denoiseParams.formatInput;
1680
1681 // MOS_FORMAT is [-14,103], cannot use -14~-1 as index for m_veboxHwEntry
1682 if (inputformat < 0)
1683 {
1684 inputformat = Format_Any;
1685 }
1686
1687 uint32_t widthAlignUint = m_hwCaps.m_veboxHwEntry[inputformat].horizontalAlignUnit;
1688 uint32_t heightAlignUnit = m_hwCaps.m_veboxHwEntry[inputformat].verticalAlignUnit;
1689
1690 if (denoiseEngine.value != 0)
1691 {
1692 VP_PUBLIC_NORMALMESSAGE("Scaling Feature Already been processed, Skip further process");
1693 PrintFeatureExecutionCaps(__FUNCTION__, denoiseEngine);
1694 return MOS_STATUS_SUCCESS;
1695 }
1696
1697 if (m_hwCaps.m_veboxHwEntry[inputformat].denoiseSupported)
1698 {
1699 if (denoiseParams.denoiseParams.bEnableHVSDenoise)
1700 {
1701 denoiseParams.stage = DN_STAGE_HVS_KERNEL;
1702 denoiseEngine.bEnabled = 1;
1703 denoiseEngine.isolated = 1;
1704 denoiseEngine.RenderNeeded = 1;
1705 denoise->SetRenderTargetType(RenderTargetType::RenderTargetTypeParameter);
1706 VP_PUBLIC_NORMALMESSAGE("DN_STAGE_HVS_KERNEL");
1707 }
1708 else
1709 {
1710 denoiseParams.stage = DN_STAGE_DEFAULT;
1711 widthAlignUint = MOS_ALIGN_CEIL(m_hwCaps.m_veboxHwEntry[inputformat].horizontalAlignUnit, 2);
1712
1713 if (inputformat == Format_NV12 ||
1714 inputformat == Format_P010 ||
1715 inputformat == Format_P016)
1716 {
1717 heightAlignUnit = MOS_ALIGN_CEIL(m_hwCaps.m_veboxHwEntry[inputformat].verticalAlignUnit, 4);
1718 }
1719 else
1720 {
1721 heightAlignUnit = MOS_ALIGN_CEIL(m_hwCaps.m_veboxHwEntry[inputformat].verticalAlignUnit, 2);
1722 }
1723
1724 if (MOS_IS_ALIGNED(MOS_MIN(denoiseParams.heightInput, denoiseParams.srcBottom), heightAlignUnit))
1725 {
1726 denoiseEngine.bEnabled = 1;
1727 denoiseEngine.VeboxNeeded = 1;
1728 }
1729 else
1730 {
1731 VP_PUBLIC_NORMALMESSAGE("Denoise Feature is disabled since min of heightInput (%d) and srcBottom (%d) not being %d aligned.", denoiseParams.heightInput, denoiseParams.srcBottom, heightAlignUnit);
1732 }
1733 }
1734 }
1735
1736 denoiseParams.widthAlignUnitInput = widthAlignUint;
1737 denoiseParams.heightAlignUnitInput = heightAlignUnit;
1738
1739 PrintFeatureExecutionCaps(__FUNCTION__, denoiseEngine);
1740 return MOS_STATUS_SUCCESS;
1741 }
1742
GetDeinterlaceExecutionCaps(SwFilter * feature,bool forceDIToRender)1743 MOS_STATUS Policy::GetDeinterlaceExecutionCaps(SwFilter* feature, bool forceDIToRender)
1744 {
1745 VP_FUNC_CALL();
1746 VP_PUBLIC_CHK_NULL_RETURN(feature);
1747
1748 SwFilterDeinterlace *swFilterDi = dynamic_cast<SwFilterDeinterlace*>(feature);
1749 VP_PUBLIC_CHK_NULL_RETURN(swFilterDi);
1750 VP_PUBLIC_CHK_NULL_RETURN(m_vpInterface.GetHwInterface());
1751 VP_PUBLIC_CHK_NULL_RETURN(m_vpInterface.GetHwInterface()->m_userFeatureControl);
1752 auto userFeatureControl = m_vpInterface.GetHwInterface()->m_userFeatureControl;
1753 bool disableVeboxOutput = userFeatureControl->IsVeboxOutputDisabled();
1754 bool disableSfc = userFeatureControl->IsSfcDisabled();
1755
1756 FeatureParamDeinterlace &diParams = swFilterDi->GetSwFilterParams();
1757 VP_EngineEntry &diEngine = swFilterDi->GetFilterEngineCaps();
1758 MOS_FORMAT inputformat = diParams.formatInput;
1759
1760 // MOS_FORMAT is [-14,103], cannot use -14~-1 as index for m_veboxHwEntry
1761 if (inputformat < 0)
1762 {
1763 inputformat = Format_Any;
1764 }
1765
1766 if (diEngine.value != 0)
1767 {
1768 VP_PUBLIC_NORMALMESSAGE("DI Feature Already been processed, Skip further process.");
1769 PrintFeatureExecutionCaps(__FUNCTION__, diEngine);
1770 return MOS_STATUS_SUCCESS;
1771 }
1772
1773 if (!m_hwCaps.m_veboxHwEntry[inputformat].deinterlaceSupported)
1774 {
1775 diEngine.bEnabled = 1;
1776 diEngine.RenderNeeded = 1;
1777 diEngine.fcSupported = 1;
1778 diEngine.VeboxNeeded = 0;
1779 PrintFeatureExecutionCaps(__FUNCTION__, diEngine);
1780 return MOS_STATUS_SUCCESS;
1781 }
1782
1783 if (nullptr == diParams.diParams ||
1784 (!MOS_IS_ALIGNED(MOS_MIN((uint32_t)diParams.heightInput, (uint32_t)diParams.rcSrc.bottom), 4) &&
1785 (diParams.formatInput == Format_P010 ||
1786 diParams.formatInput == Format_P016 ||
1787 diParams.formatInput == Format_NV12)))
1788 {
1789 diEngine.bEnabled = 0;
1790 diEngine.RenderNeeded = 0;
1791 diEngine.fcSupported = 0;
1792 diEngine.VeboxNeeded = 0;
1793 PrintFeatureExecutionCaps(__FUNCTION__, diEngine);
1794 return MOS_STATUS_SUCCESS;
1795 }
1796
1797 if (forceDIToRender && diParams.diParams)
1798 {
1799 diEngine.bEnabled = 1;
1800 diEngine.RenderNeeded = 1;
1801 diEngine.fcSupported = 1;
1802 diEngine.VeboxNeeded = 0;
1803 VP_PUBLIC_NORMALMESSAGE("force to render for 2 pass scaling + DI.");
1804 PrintFeatureExecutionCaps(__FUNCTION__, diEngine);
1805 return MOS_STATUS_SUCCESS;
1806 }
1807
1808 if (m_vpInterface.GetResourceManager()->IsRefValid() &&
1809 m_vpInterface.GetResourceManager()->IsSameSamples())
1810 {
1811 diEngine.bypassVeboxFeatures = 1;
1812 diEngine.diProcess2ndField = 1;
1813 }
1814 else
1815 {
1816 if (diParams.diParams->DIMode == DI_MODE_BOB)
1817 {
1818 diEngine.bEnabled = 1;
1819 diEngine.RenderNeeded = 1;
1820 diEngine.fcSupported = 1;
1821
1822 // to align with case design, if disableSfc == 1, force di to render
1823 if (disableSfc)
1824 {
1825 diEngine.VeboxNeeded = 0;
1826 VP_PUBLIC_NORMALMESSAGE("Force DI to render.");
1827 }
1828 else
1829 {
1830 diEngine.VeboxNeeded = 1;
1831 }
1832 }
1833 else
1834 {
1835 diEngine.bEnabled = 1;
1836 diEngine.RenderNeeded = 0;
1837 diEngine.fcSupported = 0;
1838 diEngine.VeboxNeeded = 1;
1839 }
1840 }
1841
1842 PrintFeatureExecutionCaps(__FUNCTION__, diEngine);
1843 VP_PUBLIC_NORMALMESSAGE("Di mode = %d", diParams.diParams->DIMode);
1844 return MOS_STATUS_SUCCESS;
1845 }
1846
GetSteExecutionCaps(SwFilter * feature)1847 MOS_STATUS Policy::GetSteExecutionCaps(SwFilter* feature)
1848 {
1849 VP_FUNC_CALL();
1850 VP_PUBLIC_CHK_NULL_RETURN(feature);
1851
1852 SwFilterSte* steFilter = dynamic_cast<SwFilterSte*>(feature);
1853 VP_PUBLIC_CHK_NULL_RETURN(steFilter);
1854
1855 FeatureParamSte& steParams = steFilter->GetSwFilterParams();
1856 VP_EngineEntry& steEngine = steFilter->GetFilterEngineCaps();
1857 MOS_FORMAT inputformat = steParams.formatInput;
1858
1859 // MOS_FORMAT is [-14,103], cannot use -14~-1 as index for m_veboxHwEntry
1860 if (inputformat < 0)
1861 {
1862 inputformat = Format_Any;
1863 }
1864
1865 if (steEngine.value != 0)
1866 {
1867 VP_PUBLIC_NORMALMESSAGE("ACE Feature Already been processed, Skip further process");
1868 PrintFeatureExecutionCaps(__FUNCTION__, steEngine);
1869 return MOS_STATUS_SUCCESS;
1870 }
1871
1872 if (m_hwCaps.m_veboxHwEntry[inputformat].steSupported &&
1873 m_hwCaps.m_veboxHwEntry[inputformat].inputSupported &&
1874 m_hwCaps.m_veboxHwEntry[inputformat].iecp)
1875 {
1876 steEngine.bEnabled = 1;
1877 steEngine.VeboxNeeded = 1;
1878 steEngine.VeboxIECPNeeded = 1;
1879 }
1880
1881 PrintFeatureExecutionCaps(__FUNCTION__, steEngine);
1882 return MOS_STATUS_SUCCESS;
1883 }
1884
GetTccExecutionCaps(SwFilter * feature)1885 MOS_STATUS Policy::GetTccExecutionCaps(SwFilter* feature)
1886 {
1887 VP_FUNC_CALL();
1888 VP_PUBLIC_CHK_NULL_RETURN(feature);
1889
1890 SwFilterTcc* tccFilter = dynamic_cast<SwFilterTcc*>(feature);
1891 VP_PUBLIC_CHK_NULL_RETURN(tccFilter);
1892
1893 FeatureParamTcc& tccParams = tccFilter->GetSwFilterParams();
1894 VP_EngineEntry& tccEngine = tccFilter->GetFilterEngineCaps();
1895 MOS_FORMAT inputformat = tccParams.formatInput;
1896
1897 // MOS_FORMAT is [-14,103], cannot use -14~-1 as index for m_veboxHwEntry
1898 if (inputformat < 0)
1899 {
1900 inputformat = Format_Any;
1901 }
1902
1903 if (tccEngine.value != 0)
1904 {
1905 VP_PUBLIC_NORMALMESSAGE("TCC Feature Already been processed, Skip further process");
1906 PrintFeatureExecutionCaps(__FUNCTION__, tccEngine);
1907 return MOS_STATUS_SUCCESS;
1908 }
1909
1910 if (m_hwCaps.m_veboxHwEntry[inputformat].inputSupported &&
1911 m_hwCaps.m_veboxHwEntry[inputformat].iecp &&
1912 m_hwCaps.m_veboxHwEntry[inputformat].tccSupported)
1913 {
1914 tccEngine.bEnabled = 1;
1915 tccEngine.VeboxNeeded = 1;
1916 tccEngine.VeboxIECPNeeded = 1;
1917 }
1918
1919 PrintFeatureExecutionCaps(__FUNCTION__, tccEngine);
1920 return MOS_STATUS_SUCCESS;
1921 }
1922
GetProcampExecutionCaps(SwFilter * feature)1923 MOS_STATUS Policy::GetProcampExecutionCaps(SwFilter* feature)
1924 {
1925 VP_FUNC_CALL();
1926 VP_PUBLIC_CHK_NULL_RETURN(feature);
1927
1928 SwFilterProcamp* procampFilter = dynamic_cast<SwFilterProcamp*>(feature);
1929 VP_PUBLIC_CHK_NULL_RETURN(procampFilter);
1930 VP_PUBLIC_CHK_NULL_RETURN(m_vpInterface.GetHwInterface());
1931 VP_PUBLIC_CHK_NULL_RETURN(m_vpInterface.GetHwInterface()->m_userFeatureControl);
1932
1933 auto userFeatureControl = m_vpInterface.GetHwInterface()->m_userFeatureControl;
1934 FeatureParamProcamp& procampParams = procampFilter->GetSwFilterParams();
1935 VP_EngineEntry& procampEngine = procampFilter->GetFilterEngineCaps();
1936 MOS_FORMAT inputformat = procampParams.formatInput;
1937
1938 // MOS_FORMAT is [-14,103], cannot use -14~-1 as index for m_veboxHwEntry
1939 if (inputformat < 0)
1940 {
1941 inputformat = Format_Any;
1942 }
1943
1944 if (procampEngine.value != 0)
1945 {
1946 VP_PUBLIC_NORMALMESSAGE("Procamp Feature Already been processed, Skip further process");
1947 PrintFeatureExecutionCaps(__FUNCTION__, procampEngine);
1948 return MOS_STATUS_SUCCESS;
1949 }
1950
1951 procampEngine.bEnabled = 1;
1952 procampEngine.RenderNeeded = 1;
1953 procampEngine.fcSupported = 1;
1954
1955 if (m_hwCaps.m_veboxHwEntry[inputformat].inputSupported &&
1956 m_hwCaps.m_veboxHwEntry[inputformat].iecp)
1957 {
1958 procampEngine.VeboxNeeded = 1;
1959 procampEngine.VeboxIECPNeeded = 1;
1960 }
1961
1962 PrintFeatureExecutionCaps(__FUNCTION__, procampEngine);
1963 return MOS_STATUS_SUCCESS;
1964 }
1965
GetHdrExecutionCaps(SwFilter * feature)1966 MOS_STATUS Policy::GetHdrExecutionCaps(SwFilter *feature)
1967 {
1968 VP_FUNC_CALL();
1969 VP_PUBLIC_CHK_NULL_RETURN(feature);
1970 VP_PUBLIC_CHK_NULL_RETURN(m_vpInterface.GetHwInterface());
1971 VP_PUBLIC_CHK_NULL_RETURN(m_vpInterface.GetHwInterface()->m_userFeatureControl);
1972
1973 SwFilterHdr *hdrFilter = dynamic_cast<SwFilterHdr *>(feature);
1974 VP_PUBLIC_CHK_NULL_RETURN(hdrFilter);
1975
1976 FeatureParamHdr *hdrParams = &hdrFilter->GetSwFilterParams();
1977
1978 VP_EngineEntry *pHDREngine = &hdrFilter->GetFilterEngineCaps();
1979 MOS_FORMAT inputformat = hdrParams->formatInput;
1980 uint32_t dwSurfaceWidth = 0, dwSurfaceHeight = 0;
1981 uint32_t veboxMinWidth = 0, veboxMaxWidth = 0;
1982 uint32_t veboxMinHeight = 0, veboxMaxHeight = 0;
1983 auto userFeatureControl = m_vpInterface.GetHwInterface()->m_userFeatureControl;
1984 bool disableVeboxOutput = userFeatureControl->IsVeboxOutputDisabled();
1985 bool disableSfc = userFeatureControl->IsSfcDisabled();
1986
1987 // MOS_FORMAT is [-14,103], cannot use -14~-1 as index for m_veboxHwEntry
1988 if (inputformat < 0)
1989 {
1990 inputformat = Format_Any;
1991 }
1992
1993 if (pHDREngine->value != 0)
1994 {
1995 VP_PUBLIC_NORMALMESSAGE("HDR Feature Already been processed, Skip further process");
1996 if (HDR_STAGE_VEBOX_3DLUT_UPDATE == hdrParams->stage)
1997 {
1998 VP_PUBLIC_NORMALMESSAGE("HDR_STAGE_VEBOX_3DLUT_UPDATE");
1999 }
2000 PrintFeatureExecutionCaps(__FUNCTION__, *pHDREngine);
2001 return MOS_STATUS_SUCCESS;
2002 }
2003
2004 veboxMinWidth = m_hwCaps.m_veboxHwEntry[hdrParams->formatInput].minWidth;
2005 veboxMaxWidth = m_hwCaps.m_veboxHwEntry[hdrParams->formatInput].maxWidth;
2006 veboxMinHeight = m_hwCaps.m_veboxHwEntry[hdrParams->formatInput].minHeight;
2007 veboxMaxHeight = m_hwCaps.m_veboxHwEntry[hdrParams->formatInput].maxHeight;
2008
2009
2010 if (disableVeboxOutput && disableSfc ||
2011 OUT_OF_BOUNDS(hdrParams->widthInput, veboxMinWidth, veboxMaxWidth) ||
2012 OUT_OF_BOUNDS(hdrParams->heightInput, veboxMinHeight, veboxMaxHeight) ||
2013 !m_hwCaps.m_veboxHwEntry[hdrParams->formatInput].inputSupported ||
2014 !m_hwCaps.m_veboxHwEntry[hdrParams->formatInput].hdrSupported)
2015 {
2016 pHDREngine->bEnabled = 1;
2017 pHDREngine->VeboxNeeded = 0;
2018 pHDREngine->RenderNeeded = 1;
2019 pHDREngine->hdrKernelNeeded = 1;
2020 pHDREngine->hdrKernelSupported = 1;
2021 VP_PUBLIC_NORMALMESSAGE("Hdr render is selected. Input Resolution %dx%d, Input Format %d",
2022 hdrParams->widthInput, hdrParams->heightInput, hdrParams->formatInput);
2023 PrintFeatureExecutionCaps(__FUNCTION__, *pHDREngine);
2024 return MOS_STATUS_SUCCESS;
2025 }
2026
2027 if (IsHDR33LutSizeSupported() && (hdrParams->hdrMode == VPHAL_HDR_MODE_H2H))
2028 {
2029 hdrParams->lutSize = LUT33_SEG_SIZE;
2030 pHDREngine->isHdr33LutSizeEnabled = true;
2031 VP_RENDER_NORMALMESSAGE("3DLut table is used 33 lutsize.");
2032 }
2033 else
2034 {
2035 hdrParams->lutSize = LUT65_SEG_SIZE;
2036 pHDREngine->isHdr33LutSizeEnabled = false;
2037 VP_RENDER_NORMALMESSAGE("3DLut table is used 65 lutsize.");
2038 }
2039
2040 pHDREngine->is1K1DLutSurfaceInUse = m_hwCaps.m_rules.is1K1DLutSurfaceInUse;
2041 if (hdrParams->external3DLutParams && userFeatureControl->IsExternal3DLutSupport())
2042 {
2043 hdrParams->stage = HDR_STAGE_VEBOX_EXTERNAL_3DLUT;
2044 pHDREngine->bEnabled = 1;
2045 pHDREngine->VeboxNeeded = 1;
2046 if (hdrParams->formatOutput == Format_A8B8G8R8 || hdrParams->formatOutput == Format_A8R8G8B8)
2047 {
2048 pHDREngine->VeboxARGBOut = 1;
2049 }
2050 else if (hdrParams->formatOutput == Format_B10G10R10A2 || hdrParams->formatOutput == Format_R10G10B10A2)
2051 {
2052 pHDREngine->VeboxARGB10bitOutput = 1;
2053 }
2054 VP_PUBLIC_NORMALMESSAGE("3DLUT table setup by API, use HDR_STAGE_VEBOX_EXTERNAL_3DLUT.");
2055 return MOS_STATUS_SUCCESS;
2056 }
2057 else if (Is3DLutKernelSupported())
2058 {
2059 if (userFeatureControl->Is3DLutKernelOnly())
2060 {
2061 hdrParams->is3DLutKernelOnly = true;
2062 }
2063
2064 if (hdrParams->uiMaxContentLevelLum != m_savedMaxCLL || hdrParams->uiMaxDisplayLum != m_savedMaxDLL ||
2065 hdrParams->hdrMode != m_savedHdrMode)
2066 {
2067 m_savedMaxCLL = hdrParams->uiMaxContentLevelLum;
2068 m_savedMaxDLL = hdrParams->uiMaxDisplayLum;
2069 m_savedHdrMode = hdrParams->hdrMode;
2070
2071 hdrParams->stage = HDR_STAGE_3DLUT_KERNEL;
2072 pHDREngine->bEnabled = 1;
2073 pHDREngine->isolated = 1;
2074 pHDREngine->RenderNeeded = 1;
2075 hdrFilter->SetRenderTargetType(RenderTargetType::RenderTargetTypeParameter);
2076 VP_PUBLIC_NORMALMESSAGE("HDR_STAGE_3DLUT_KERNEL");
2077 // For next stage, will be updated during UpdateFeaturePipe.
2078 }
2079 else
2080 {
2081 hdrParams->stage = HDR_STAGE_VEBOX_3DLUT_NO_UPDATE;
2082 pHDREngine->bEnabled = 1;
2083 pHDREngine->VeboxNeeded = 1;
2084 hdrFilter->SetRenderTargetType(RenderTargetType::RenderTargetTypeSurface);
2085 if (hdrParams->formatOutput == Format_A8B8G8R8 || hdrParams->formatOutput == Format_A8R8G8B8)
2086 {
2087 pHDREngine->VeboxARGBOut = 1;
2088 }
2089 else if (hdrParams->formatOutput == Format_B10G10R10A2 || hdrParams->formatOutput == Format_R10G10B10A2)
2090 {
2091 pHDREngine->VeboxARGB10bitOutput = 1;
2092 }
2093 VP_PUBLIC_NORMALMESSAGE("HDR_STAGE_VEBOX_3DLUT_NO_UPDATE");
2094 }
2095 }
2096 else
2097 {
2098 hdrParams->stage = HDR_STAGE_DEFAULT;
2099 pHDREngine->bEnabled = 1;
2100 pHDREngine->VeboxNeeded = 1;
2101 if (hdrParams->formatOutput == Format_A8B8G8R8 || hdrParams->formatOutput == Format_A8R8G8B8)
2102 {
2103 pHDREngine->VeboxARGBOut = 1;
2104 }
2105 else if (hdrParams->formatOutput == Format_B10G10R10A2 || hdrParams->formatOutput == Format_R10G10B10A2)
2106 {
2107 pHDREngine->VeboxARGB10bitOutput = 1;
2108 }
2109 VP_PUBLIC_NORMALMESSAGE("HDR_STAGE_DEFAULT");
2110 }
2111
2112 PrintFeatureExecutionCaps(__FUNCTION__, *pHDREngine);
2113 return MOS_STATUS_SUCCESS;
2114 }
2115
GetColorFillExecutionCaps(SwFilter * feature)2116 MOS_STATUS Policy::GetColorFillExecutionCaps(SwFilter* feature)
2117 {
2118 VP_FUNC_CALL();
2119 VP_PUBLIC_CHK_NULL_RETURN(feature);
2120
2121 SwFilterColorFill* filter = dynamic_cast<SwFilterColorFill*>(feature);
2122 VP_PUBLIC_CHK_NULL_RETURN(filter);
2123 VP_PUBLIC_CHK_NULL_RETURN(m_vpInterface.GetHwInterface());
2124 VP_PUBLIC_CHK_NULL_RETURN(m_vpInterface.GetHwInterface()->m_userFeatureControl);
2125
2126 auto userFeatureControl = m_vpInterface.GetHwInterface()->m_userFeatureControl;
2127 bool disableSfc = userFeatureControl->IsSfcDisabled();
2128 FeatureParamColorFill& params = filter->GetSwFilterParams();
2129 VP_EngineEntry& engine = filter->GetFilterEngineCaps();
2130 MOS_FORMAT inputformat = params.formatInput;
2131
2132 // MOS_FORMAT is [-14,103], cannot use -14~-1 as index for m_veboxHwEntry
2133 if (inputformat < 0)
2134 {
2135 inputformat = Format_Any;
2136 }
2137
2138 if (engine.value != 0)
2139 {
2140 VP_PUBLIC_NORMALMESSAGE("ColorFill Feature Already been processed, Skip further process");
2141 PrintFeatureExecutionCaps(__FUNCTION__, engine);
2142 return MOS_STATUS_SUCCESS;
2143 }
2144
2145 engine.bEnabled = 1;
2146 engine.RenderNeeded = 1;
2147 engine.fcSupported = 1;
2148 // For disableSfc case, sfc will be filtered in SwFilterColorFill::GetCombinedFilterEngineCaps
2149 // with scaling setting.
2150 engine.SfcNeeded = !disableSfc; // For SFC, the parameter in scaling is used.
2151
2152 PrintFeatureExecutionCaps(__FUNCTION__, engine);
2153 return MOS_STATUS_SUCCESS;
2154 }
2155
GetAlphaExecutionCaps(SwFilter * feature)2156 MOS_STATUS Policy::GetAlphaExecutionCaps(SwFilter* feature)
2157 {
2158 VP_FUNC_CALL();
2159 VP_PUBLIC_CHK_NULL_RETURN(feature);
2160
2161 SwFilterAlpha* filter = dynamic_cast<SwFilterAlpha*>(feature);
2162 VP_PUBLIC_CHK_NULL_RETURN(filter);
2163 VP_PUBLIC_CHK_NULL_RETURN(m_vpInterface.GetHwInterface());
2164 VP_PUBLIC_CHK_NULL_RETURN(m_vpInterface.GetHwInterface()->m_userFeatureControl);
2165
2166 auto userFeatureControl = m_vpInterface.GetHwInterface()->m_userFeatureControl;
2167 bool disableSfc = userFeatureControl->IsSfcDisabled();
2168 FeatureParamAlpha& params = filter->GetSwFilterParams();
2169 VP_EngineEntry& engine = filter->GetFilterEngineCaps();
2170 MOS_FORMAT inputformat = params.formatInput;
2171
2172 // MOS_FORMAT is [-14,103], cannot use -14~-1 as index for m_veboxHwEntry
2173 if (inputformat < 0)
2174 {
2175 inputformat = Format_Any;
2176 }
2177
2178 if (engine.value != 0)
2179 {
2180 VP_PUBLIC_NORMALMESSAGE("Alpha Feature Already been processed, Skip further process");
2181 PrintFeatureExecutionCaps(__FUNCTION__, engine);
2182 return MOS_STATUS_SUCCESS;
2183 }
2184 engine.bEnabled = 1;
2185 engine.RenderNeeded = 1;
2186 engine.fcSupported = 1;
2187
2188 // For Vebox, the alpha parameter in csc is used.
2189 engine.VeboxNeeded = IsAlphaSettingSupportedByVebox(params.formatInput, params.formatOutput, params.compAlpha);
2190
2191 if (disableSfc)
2192 {
2193 engine.SfcNeeded = false;
2194 }
2195 else
2196 {
2197 // For SFC, the alpha parameter in scaling is used.
2198 engine.SfcNeeded = IsAlphaSettingSupportedBySfc(params.formatInput, params.formatOutput, params.compAlpha);
2199 }
2200
2201 PrintFeatureExecutionCaps(__FUNCTION__, engine);
2202 return MOS_STATUS_SUCCESS;
2203 }
2204
GetLumakeyExecutionCaps(SwFilter * feature)2205 MOS_STATUS Policy::GetLumakeyExecutionCaps(SwFilter* feature)
2206 {
2207 VP_FUNC_CALL();
2208 VP_PUBLIC_CHK_NULL_RETURN(feature);
2209
2210 SwFilterLumakey* filter = dynamic_cast<SwFilterLumakey*>(feature);
2211 VP_PUBLIC_CHK_NULL_RETURN(filter);
2212
2213 FeatureParamLumakey& params = filter->GetSwFilterParams();
2214 VP_EngineEntry& engine = filter->GetFilterEngineCaps();
2215 MOS_FORMAT inputformat = params.formatInput;
2216
2217 // MOS_FORMAT is [-14,103], cannot use -14~-1 as index for m_veboxHwEntry
2218 if (inputformat < 0)
2219 {
2220 inputformat = Format_Any;
2221 }
2222
2223 if (engine.value != 0)
2224 {
2225 VP_PUBLIC_NORMALMESSAGE("Lumakey Feature Already been processed, Skip further process");
2226 PrintFeatureExecutionCaps(__FUNCTION__, engine);
2227 return MOS_STATUS_SUCCESS;
2228 }
2229
2230 engine.bEnabled = 1;
2231 engine.RenderNeeded = 1;
2232 engine.fcSupported = 1;
2233
2234 PrintFeatureExecutionCaps(__FUNCTION__, engine);
2235 return MOS_STATUS_SUCCESS;
2236 }
2237
GetBlendingExecutionCaps(SwFilter * feature)2238 MOS_STATUS Policy::GetBlendingExecutionCaps(SwFilter* feature)
2239 {
2240 VP_FUNC_CALL();
2241 VP_PUBLIC_CHK_NULL_RETURN(feature);
2242
2243 SwFilterBlending* filter = dynamic_cast<SwFilterBlending*>(feature);
2244 VP_PUBLIC_CHK_NULL_RETURN(filter);
2245
2246 FeatureParamBlending& params = filter->GetSwFilterParams();
2247 VP_EngineEntry& engine = filter->GetFilterEngineCaps();
2248 MOS_FORMAT inputformat = params.formatInput;
2249
2250 // MOS_FORMAT is [-14,103], cannot use -14~-1 as index for m_veboxHwEntry
2251 if (inputformat < 0)
2252 {
2253 inputformat = Format_Any;
2254 }
2255
2256 if (engine.value != 0)
2257 {
2258 VP_PUBLIC_NORMALMESSAGE("Blending Feature Already been processed, Skip further process");
2259 PrintFeatureExecutionCaps(__FUNCTION__, engine);
2260 return MOS_STATUS_SUCCESS;
2261 }
2262
2263 engine.bEnabled = 1;
2264 engine.RenderNeeded = 1;
2265 engine.fcSupported = 1;
2266
2267 PrintFeatureExecutionCaps(__FUNCTION__, engine);
2268 return MOS_STATUS_SUCCESS;
2269 }
2270
GetCgcExecutionCaps(SwFilter * feature)2271 MOS_STATUS Policy::GetCgcExecutionCaps(SwFilter* feature)
2272 {
2273 VP_FUNC_CALL();
2274 VP_PUBLIC_CHK_NULL_RETURN(feature);
2275
2276 SwFilterCgc* cgcFilter = dynamic_cast<SwFilterCgc*>(feature);
2277 VP_PUBLIC_CHK_NULL_RETURN(cgcFilter);
2278
2279 FeatureParamCgc& cgcParams = cgcFilter->GetSwFilterParams();
2280 VP_EngineEntry& cgcEngine = cgcFilter->GetFilterEngineCaps();
2281 MOS_FORMAT inputformat = cgcParams.formatInput;
2282
2283 // MOS_FORMAT is [-14,103], cannot use -14~-1 as index for m_veboxHwEntry
2284 if (inputformat < 0)
2285 {
2286 inputformat = Format_Any;
2287 }
2288
2289 if (cgcEngine.value != 0)
2290 {
2291 VP_PUBLIC_NORMALMESSAGE("CGC Feature Already been processed, Skip further process");
2292 PrintFeatureExecutionCaps(__FUNCTION__, cgcEngine);
2293 return MOS_STATUS_SUCCESS;
2294 }
2295
2296 if (m_hwCaps.m_veboxHwEntry[inputformat].inputSupported &&
2297 m_hwCaps.m_veboxHwEntry[inputformat].iecp &&
2298 m_hwCaps.m_veboxHwEntry[inputformat].cgcSupported)
2299 {
2300 cgcEngine.bEnabled = 1;
2301 cgcEngine.VeboxNeeded = 1;
2302 cgcEngine.VeboxIECPNeeded = 1;
2303 cgcEngine.bt2020ToRGB = cgcParams.bBt2020ToRGB;
2304 }
2305
2306 PrintFeatureExecutionCaps(__FUNCTION__, cgcEngine);
2307 return MOS_STATUS_SUCCESS;
2308 }
2309
GetExecutionCaps(SwFilter * feature)2310 MOS_STATUS Policy::GetExecutionCaps(SwFilter* feature)
2311 {
2312 VP_FUNC_CALL();
2313
2314 VP_PUBLIC_CHK_NULL_RETURN(feature);
2315
2316 VP_EngineEntry &defaultEngine = feature->GetFilterEngineCaps();
2317 defaultEngine.value = 0;
2318
2319 PrintFeatureExecutionCaps(__FUNCTION__, defaultEngine);
2320 return MOS_STATUS_SUCCESS;
2321 }
2322
InitExecuteCaps(VP_EXECUTE_CAPS & caps,VP_EngineEntry & engineCapsInputPipe,VP_EngineEntry & engineCapsOutputPipe)2323 MOS_STATUS Policy::InitExecuteCaps(VP_EXECUTE_CAPS &caps, VP_EngineEntry &engineCapsInputPipe, VP_EngineEntry &engineCapsOutputPipe)
2324 {
2325 caps.value = 0;
2326
2327 if (0 == engineCapsInputPipe.value)
2328 {
2329 caps.bOutputPipeFeatureInuse = engineCapsOutputPipe.bEnabled;
2330 // For color fill w/o input surface case, engineCapsOutputPipe.fcOnlyFeatureExists should be set.
2331 if (0 == engineCapsOutputPipe.value || engineCapsOutputPipe.nonFcFeatureExists || !engineCapsOutputPipe.fcOnlyFeatureExists)
2332 {
2333 caps.bVebox = true;
2334 caps.bIECP = engineCapsOutputPipe.VeboxIECPNeeded;
2335 caps.bSFC = engineCapsOutputPipe.nonVeboxFeatureExists;
2336 }
2337 else
2338 {
2339 caps.bRender = 1;
2340 caps.bComposite = 1;
2341 }
2342 }
2343 else if (engineCapsInputPipe.isolated)
2344 {
2345 caps.bTemperalInputInuse = engineCapsInputPipe.bTemperalInputInuse;
2346 if (engineCapsInputPipe.VeboxNeeded != 0 || engineCapsInputPipe.SfcNeeded != 0)
2347 {
2348 caps.bVebox = true;
2349 caps.bIECP = engineCapsInputPipe.VeboxIECPNeeded;
2350 caps.bSFC = engineCapsInputPipe.SfcNeeded != 0;
2351 }
2352 else if (engineCapsInputPipe.RenderNeeded)
2353 {
2354 caps.bRender = 1;
2355
2356 if (engineCapsInputPipe.isOutputPipeNeeded)
2357 {
2358 caps.bOutputPipeFeatureInuse = true;
2359 }
2360 }
2361 else
2362 {
2363 // No valid engine selected.
2364 VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_INVALID_PARAMETER);
2365 }
2366 }
2367 else if (engineCapsInputPipe.hdrKernelNeeded)
2368 {
2369 caps.bRender = 1;
2370 caps.bRenderHdr = engineCapsInputPipe.hdrKernelNeeded;
2371 caps.bOutputPipeFeatureInuse = true;
2372 }
2373 else if (engineCapsInputPipe.nonFcFeatureExists)
2374 {
2375 VP_EngineEntry engineCaps = engineCapsInputPipe;
2376 bool multiPassNeeded = false;
2377 if (!engineCaps.fcOnlyFeatureExists && !engineCapsOutputPipe.fcOnlyFeatureExists &&
2378 !engineCaps.multiPassNeeded)
2379 {
2380 caps.bOutputPipeFeatureInuse = true;
2381 engineCaps.value |= engineCapsOutputPipe.value;
2382 }
2383 caps.bVebox = true;
2384 caps.bIECP = engineCaps.VeboxIECPNeeded;
2385 caps.bDiProcess2ndField = engineCaps.diProcess2ndField;
2386 caps.bTemperalInputInuse = engineCaps.bTemperalInputInuse;
2387 caps.b1K1DLutInUse = engineCaps.is1K1DLutSurfaceInUse;
2388 caps.bDemosaicInUse = engineCaps.isBayerInputInUse;
2389
2390 if (engineCaps.fcOnlyFeatureExists)
2391 {
2392 // For vebox/sfc+render case, use 2nd workload (render) to do csc for better performance
2393 // in most VP common cases, e.g. NV12->RGB, to save the memory bandwidth.
2394 caps.bForceCscToRender = true;
2395 // Force procamp to render if both enable Lumaykey and procamp on the same layer
2396 // Lumaykey should be top-priority
2397 if (engineCaps.outputWithLumaKey)
2398 {
2399 caps.bForceProcampToRender = true;
2400 }
2401 else
2402 {
2403 // For vebox/sfc+render case, use 2nd workload (render) to do Procamp,
2404 // especially for the scenario including Lumakey feature, which will ensure the Procamp can be done after Lumakey.
2405 caps.bForceProcampToRender = false;
2406 }
2407 // For vebox + render with features, which can be done on both sfc and render,
2408 // and sfc is not must have, sfc should not be selected and those features should be done on render.
2409 caps.bSFC = engineCaps.nonVeboxFeatureExists && engineCaps.sfcOnlyFeatureExists;
2410 // For L0 FC not supported formats, fallback to legacy FC
2411 caps.bFallbackLegacyFC = engineCaps.forceLegacyFC;
2412
2413 }
2414 else
2415 {
2416 caps.bSFC = !engineCapsOutputPipe.sfcNotSupported && engineCaps.nonVeboxFeatureExists;
2417 }
2418 }
2419 else if (engineCapsInputPipe.forceBypassWorkload)
2420 {
2421 caps.bVebox = 0;
2422 caps.bSFC = 0;
2423 caps.bRender = 0;
2424 caps.forceBypassWorkload = 1;
2425 }
2426 else
2427 {
2428 if (!engineCapsInputPipe.fcSupported)
2429 {
2430 // Should be only fc feature here.
2431 VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_INVALID_PARAMETER);
2432 }
2433 VP_EngineEntry engineCaps = engineCapsInputPipe;
2434 engineCaps.value |= engineCapsOutputPipe.value;
2435 caps.bOutputPipeFeatureInuse = true;
2436 // Fc cases.
2437 if (!engineCaps.fcOnlyFeatureExists && !engineCaps.veboxNotSupported)
2438 {
2439 // If all feature can support both vebox/sfc and fc.
2440 caps.bVebox = true;
2441 caps.bIECP = engineCapsInputPipe.VeboxIECPNeeded;
2442 caps.bSFC = engineCapsInputPipe.nonVeboxFeatureExists;
2443 }
2444 else
2445 {
2446 caps.bRender = 1;
2447 caps.bComposite = 1;
2448 }
2449
2450 caps.bDiProcess2ndField = engineCaps.diProcess2ndField;
2451 caps.bTemperalInputInuse = engineCaps.bTemperalInputInuse;
2452 caps.b1K1DLutInUse = engineCaps.is1K1DLutSurfaceInUse;
2453 caps.bFallbackLegacyFC = engineCaps.forceLegacyFC;
2454 }
2455 if (caps.bSFC && engineCapsInputPipe.enableSFCLinearOutputByTileConvert)
2456 {
2457 caps.enableSFCLinearOutputByTileConvert = engineCapsInputPipe.enableSFCLinearOutputByTileConvert;
2458 }
2459 VP_PUBLIC_NORMALMESSAGE("Execute Caps, value 0x%llx (bVebox %d, bSFC %d, bRender %d, bComposite %d, bOutputPipeFeatureInuse %d, bIECP %d, bForceCscToRender %d, bDiProcess2ndField %d)",
2460 caps.value, caps.bVebox, caps.bSFC, caps.bRender, caps.bComposite, caps.bOutputPipeFeatureInuse, caps.bIECP,
2461 caps.bForceCscToRender, caps.bDiProcess2ndField);
2462 PrintFeatureExecutionCaps("engineCapsInputPipe", engineCapsInputPipe);
2463 PrintFeatureExecutionCaps("engineCapsOutputPipe", engineCapsOutputPipe);
2464
2465 MT_LOG7(MT_VP_HAL_POLICY_INIT_EXECCAPS, MT_NORMAL, MT_VP_HAL_EXECCAPS, (int64_t)caps.value, MT_VP_HAL_EXECCAPS_VE, (int64_t)caps.bVebox, MT_VP_HAL_EXECCAPS_SFC, (int64_t)caps.bSFC, MT_VP_HAL_EXECCAPS_RENDER,
2466 (int64_t)caps.bRender, MT_VP_HAL_EXECCAPS_COMP, (int64_t)caps.bComposite, MT_VP_HAL_EXECCAPS_OUTPIPE_FTRINUSE, (int64_t)caps.bOutputPipeFeatureInuse, MT_VP_HAL_EXECCAPS_IECP, (int64_t)caps.bIECP);
2467 MT_LOG7(MT_VP_HAL_POLICY_GET_INPIPECAPS, MT_NORMAL, MT_VP_HAL_ENGINECAPS, (int64_t)engineCapsInputPipe.value, MT_VP_HAL_ENGINECAPS_EN, (int64_t)engineCapsInputPipe.bEnabled, MT_VP_HAL_ENGINECAPS_VE_NEEDED,
2468 (int64_t)engineCapsInputPipe.VeboxNeeded, MT_VP_HAL_ENGINECAPS_SFC_NEEDED, (int64_t)engineCapsInputPipe.SfcNeeded, MT_VP_HAL_ENGINECAPS_RENDER_NEEDED, (int64_t)engineCapsInputPipe.RenderNeeded, MT_VP_HAL_ENGINECAPS_FC_SUPPORT, (int64_t)engineCapsInputPipe.fcSupported, MT_VP_HAL_ENGINECAPS_ISOLATED, (int64_t)engineCapsInputPipe.isolated);
2469 MT_LOG7(MT_VP_HAL_POLICY_GET_OUTPIPECAPS, MT_NORMAL, MT_VP_HAL_ENGINECAPS, (int64_t)engineCapsOutputPipe.value, MT_VP_HAL_ENGINECAPS_EN, (int64_t)engineCapsOutputPipe.bEnabled, MT_VP_HAL_ENGINECAPS_VE_NEEDED, (int64_t)engineCapsOutputPipe.VeboxNeeded, MT_VP_HAL_ENGINECAPS_SFC_NEEDED, (int64_t)engineCapsOutputPipe.SfcNeeded, MT_VP_HAL_ENGINECAPS_RENDER_NEEDED, (int64_t)engineCapsOutputPipe.RenderNeeded,
2470 MT_VP_HAL_ENGINECAPS_FC_SUPPORT, (int64_t)engineCapsOutputPipe.fcSupported, MT_VP_HAL_ENGINECAPS_ISOLATED, (int64_t)engineCapsOutputPipe.isolated);
2471
2472 return MOS_STATUS_SUCCESS;
2473 }
2474
GetOutputPipeEngineCaps(SwFilterPipe & featurePipe,VP_EngineEntry & engineCapsOutputPipe,SwFilterSubPipe * inputPipeSelected)2475 MOS_STATUS Policy::GetOutputPipeEngineCaps(SwFilterPipe& featurePipe, VP_EngineEntry &engineCapsOutputPipe, SwFilterSubPipe *inputPipeSelected)
2476 {
2477 SwFilterSubPipe *featureSubPipe = featurePipe.GetSwFilterSubPipe(false, 0);
2478 VP_PUBLIC_CHK_NULL_RETURN(featureSubPipe);
2479
2480 engineCapsOutputPipe.value = 0;
2481
2482 for (auto featureType : m_featurePool)
2483 {
2484 SwFilter *swFilter = featureSubPipe->GetSwFilter(featureType);
2485
2486 if (nullptr == swFilter)
2487 {
2488 continue;
2489 }
2490
2491 VP_EngineEntry engineCaps = swFilter->GetCombinedFilterEngineCaps(inputPipeSelected);
2492
2493 if (!engineCaps.bEnabled)
2494 {
2495 continue;
2496 }
2497
2498 if (engineCaps.isolated || !engineCaps.RenderNeeded || !engineCaps.fcSupported)
2499 {
2500 // No support for non-fc supported feature in current stage.
2501 // Will add it if needed.
2502 VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_INVALID_PARAMETER);
2503 }
2504
2505 if (!engineCaps.SfcNeeded && !engineCaps.VeboxNeeded && !engineCaps.bypassIfVeboxSfcInUse)
2506 {
2507 engineCapsOutputPipe.fcOnlyFeatureExists = true;
2508 }
2509 engineCapsOutputPipe.value |= engineCaps.value;
2510 engineCapsOutputPipe.nonVeboxFeatureExists |= (!engineCaps.VeboxNeeded && !engineCaps.bypassIfVeboxSfcInUse);
2511 }
2512
2513 PrintFeatureExecutionCaps(__FUNCTION__, engineCapsOutputPipe);
2514 MT_LOG7(MT_VP_HAL_POLICY_GET_OUTPIPECAPS, MT_NORMAL, MT_VP_HAL_ENGINECAPS, (int64_t)engineCapsOutputPipe.value, MT_VP_HAL_ENGINECAPS_EN, (int64_t)engineCapsOutputPipe.bEnabled,
2515 MT_VP_HAL_ENGINECAPS_VE_NEEDED, (int64_t)engineCapsOutputPipe.VeboxNeeded, MT_VP_HAL_ENGINECAPS_SFC_NEEDED, (int64_t)engineCapsOutputPipe.SfcNeeded,
2516 MT_VP_HAL_ENGINECAPS_RENDER_NEEDED, (int64_t)engineCapsOutputPipe.RenderNeeded, MT_VP_HAL_ENGINECAPS_FC_SUPPORT, (int64_t)engineCapsOutputPipe.fcSupported,
2517 MT_VP_HAL_ENGINECAPS_ISOLATED, (int64_t)engineCapsOutputPipe.isolated);
2518
2519 return MOS_STATUS_SUCCESS;
2520 }
2521
IsExcludedFeatureForHdr(FeatureType feature)2522 bool Policy::IsExcludedFeatureForHdr(FeatureType feature)
2523 {
2524 return (FeatureTypeTcc == feature ||
2525 FeatureTypeSte == feature ||
2526 FeatureTypeProcamp == feature);
2527 }
2528
IsIsolateFeatureOutputPipeNeeded(SwFilterSubPipe * featureSubPipe,SwFilter * swFilter)2529 bool Policy::IsIsolateFeatureOutputPipeNeeded(SwFilterSubPipe *featureSubPipe, SwFilter *swFilter)
2530 {
2531 if (RenderTargetTypeSurface == swFilter->GetRenderTargetType())
2532 {
2533 bool isIsolateFeatureOutputPipeNeeded = true;
2534 for (auto featureType : m_featurePool)
2535 {
2536 SwFilter *curSwFilter = featureSubPipe->GetSwFilter(featureType);
2537 if (nullptr != curSwFilter)
2538 {
2539 VP_EngineEntry caps = curSwFilter->GetFilterEngineCaps();
2540 if (caps.bEnabled == true && featureType != swFilter->GetFeatureType())
2541 {
2542 auto renderTargetType = curSwFilter->GetRenderTargetType();
2543 if (renderTargetType == RenderTargetTypeSurface)
2544 {
2545 isIsolateFeatureOutputPipeNeeded = false;
2546 break;
2547 }
2548 }
2549 }
2550 }
2551 return isIsolateFeatureOutputPipeNeeded;
2552 }
2553 else
2554 {
2555 return false;
2556 }
2557 }
2558
GetInputPipeEngineCaps(SwFilterPipe & featurePipe,VP_EngineEntry & engineCapsInputPipe,SwFilterSubPipe * & singlePipeSelected,bool & isSingleSubPipe,uint32_t & selectedPipeIndex)2559 MOS_STATUS Policy::GetInputPipeEngineCaps(SwFilterPipe& featurePipe, VP_EngineEntry &engineCapsInputPipe,
2560 SwFilterSubPipe *&singlePipeSelected, bool &isSingleSubPipe, uint32_t &selectedPipeIndex)
2561 {
2562 // Priority for selecting features to be processed in current workload.
2563 // 1. Features with isolated flag. One isolated feature can only be processed without any other features involved.
2564 // 2. Features without fc supported flag.
2565 // 3. For single layer, select vebox, if all vebox == 1
2566 // select sfc, if all sfc/vebox == 1 and sfc == 1/vebox == 0 exists
2567 // For multi layer, select FC
2568 // Add support for ordered pipe later.
2569 isSingleSubPipe = featurePipe.GetSurfaceCount(true) <= 1;
2570 singlePipeSelected = isSingleSubPipe ? featurePipe.GetSwFilterSubPipe(true, 0) : nullptr;
2571 selectedPipeIndex = 0;
2572
2573 VP_EngineEntry engineCapsIsolated = {}; // Input pipe engine caps for isolated feature exists case.
2574 VP_EngineEntry engineCapsForVeboxSfc = {}; // Input pipe engine caps for non-fc feature exists case.
2575 VP_EngineEntry engineCapsForFc = {}; // Input pipe engine caps for fc supported by all features cases.
2576 VP_EngineEntry engineCapsForHdrKernel = {0}; // Input pipe engine caps for hdr kernel supported by all features cases.
2577 for (uint32_t pipeIndex = 0; pipeIndex < featurePipe.GetSurfaceCount(true); ++pipeIndex)
2578 {
2579 SwFilterSubPipe *featureSubPipe = featurePipe.GetSwFilterSubPipe(true, pipeIndex);
2580 VP_PUBLIC_CHK_NULL_RETURN(featureSubPipe);
2581
2582 bool isSfcNeeded = false;
2583 engineCapsForVeboxSfc.value = 0;
2584
2585 for (auto featureType : m_featurePool)
2586 {
2587 SwFilter *swFilter = featureSubPipe->GetSwFilter(featureType);
2588 if (nullptr == swFilter)
2589 {
2590 continue;
2591 }
2592
2593 VP_EngineEntry &engineCaps = swFilter->GetFilterEngineCaps();
2594
2595 if (!engineCaps.bEnabled)
2596 {
2597 // Some features need to be bypassed with requirement on workload, e.g. 2nd field for DI.
2598 if (engineCaps.bypassVeboxFeatures || engineCaps.diProcess2ndField)
2599 {
2600 isSingleSubPipe = true;
2601 selectedPipeIndex = pipeIndex;
2602 singlePipeSelected = featureSubPipe;
2603 engineCapsForVeboxSfc.value |= engineCaps.value;
2604 engineCapsForFc.value |= engineCaps.value;
2605 }
2606 if (engineCaps.sfcNotSupported)
2607 {
2608 // sfc cannot be selected. Resolution limit is checked with scaling filter, even scaling
2609 // feature itself not being enabled.
2610 engineCapsForVeboxSfc.sfcNotSupported = engineCaps.sfcNotSupported;
2611 engineCapsForFc.sfcNotSupported = engineCaps.sfcNotSupported;
2612 VP_PUBLIC_NORMALMESSAGE("sfcNotSupported flag is set.");
2613 }
2614 if (engineCaps.veboxNotSupported)
2615 {
2616 // vebox cannot be selected. Resolution limit is checked with scaling filter, even scaling
2617 // feature itself not being enabled.
2618 engineCapsForVeboxSfc.veboxNotSupported = engineCaps.veboxNotSupported;
2619 engineCapsForFc.veboxNotSupported = engineCaps.veboxNotSupported;
2620 VP_PUBLIC_NORMALMESSAGE("veboxNotSupported flag is set.");
2621 }
2622 if (engineCaps.forceBypassWorkload)
2623 {
2624 engineCapsInputPipe.forceBypassWorkload = engineCaps.forceBypassWorkload;
2625 VP_PUBLIC_NORMALMESSAGE("Set engineCapsInputPipe forceDisableForVebox true.");
2626 }
2627 continue;
2628 }
2629
2630 if (engineCaps.isolated)
2631 {
2632 // 1. Process feature with isolated flag firstly.
2633 isSingleSubPipe = true;
2634 selectedPipeIndex = pipeIndex;
2635 singlePipeSelected = featureSubPipe;
2636 engineCapsIsolated = engineCaps;
2637 engineCapsIsolated.isOutputPipeNeeded = IsIsolateFeatureOutputPipeNeeded(featureSubPipe, swFilter);
2638 break;
2639 }
2640 else if (!engineCaps.fcSupported)
2641 {
2642 // 2. Process non-fc features by vebox/sfc.
2643 if (engineCaps.RenderNeeded && !engineCaps.hdrKernelNeeded)
2644 {
2645 // Non-FC render feature should be isolated.
2646 VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_INVALID_PARAMETER);
2647 }
2648
2649 if (engineCaps.hdrKernelSupported)
2650 {
2651 engineCapsForHdrKernel.value |= engineCaps.value;
2652 }
2653
2654 if (engineCaps.hdrKernelNeeded)
2655 {
2656 VP_PUBLIC_NORMALMESSAGE("HDR kernel is needed.");
2657 }
2658 else
2659 {
2660 if (!engineCaps.SfcNeeded && !engineCaps.VeboxNeeded)
2661 {
2662 VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_INVALID_PARAMETER)
2663 }
2664 if (engineCaps.sfcNotSupported)
2665 {
2666 // sfc cannot be selected. Resolution limit is checked with scaling filter, even scaling
2667 // feature itself not being enabled.
2668 engineCapsForVeboxSfc.sfcNotSupported = engineCaps.sfcNotSupported;
2669 engineCapsForFc.sfcNotSupported = engineCaps.sfcNotSupported;
2670 VP_PUBLIC_NORMALMESSAGE("sfcNotSupported flag is set.");
2671 }
2672
2673 if ((engineCaps.SfcNeeded && !engineCaps.RenderNeeded && !engineCaps.VeboxNeeded))
2674 {
2675 engineCapsForVeboxSfc.sfcOnlyFeatureExists = 1;
2676 }
2677
2678 isSingleSubPipe = true;
2679 selectedPipeIndex = pipeIndex;
2680 singlePipeSelected = featureSubPipe;
2681 engineCapsForVeboxSfc.value |= engineCaps.value;
2682 engineCapsForVeboxSfc.nonFcFeatureExists = true;
2683 engineCapsForVeboxSfc.nonVeboxFeatureExists |= !engineCaps.VeboxNeeded;
2684
2685 SwFilter *lumakey = featureSubPipe->GetSwFilter(FeatureTypeLumakey);
2686 if (lumakey && lumakey->GetFilterEngineCaps().bEnabled)
2687 {
2688 engineCapsForVeboxSfc.outputWithLumaKey = true;
2689 VP_PUBLIC_NORMALMESSAGE("outputWithLumaKey flag is set.");
2690 }
2691 else
2692 {
2693 engineCapsForVeboxSfc.outputWithLumaKey = false;
2694 }
2695 }
2696 }
2697 else
2698 {
2699 if (engineCaps.hdrKernelSupported)
2700 {
2701 engineCapsForHdrKernel.value |= engineCaps.value;
2702 }
2703
2704 if (engineCaps.hdrKernelNeeded)
2705 {
2706 VP_PUBLIC_ASSERTMESSAGE("hdrKernelNeeded and fcSupported should not be set at same time.");
2707 VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_INVALID_PARAMETER)
2708 }
2709
2710 // 3. Process features support FC.
2711 if (engineCaps.SfcNeeded || engineCaps.VeboxNeeded)
2712 {
2713 engineCapsForVeboxSfc.value |= engineCaps.value;
2714 engineCapsForVeboxSfc.nonVeboxFeatureExists |= !engineCaps.VeboxNeeded;
2715 }
2716 else
2717 {
2718 // Set fcOnlyFeatureExists flag for engineCapsForVeboxSfc to indicate that
2719 // not all features in input pipe can be processed by vebox/sfc and
2720 // features in output pipe cannot be combined to vebox/sfc workload.
2721 engineCapsForVeboxSfc.fcOnlyFeatureExists = true;
2722 engineCapsForFc.fcOnlyFeatureExists = true;
2723 }
2724 if (engineCaps.sfcNotSupported)
2725 {
2726 // sfc cannot be selected. Resolution limit is checked with scaling filter, even scaling
2727 // feature itself not being enabled.
2728 engineCapsForVeboxSfc.sfcNotSupported = engineCaps.sfcNotSupported;
2729 engineCapsForFc.sfcNotSupported = engineCaps.sfcNotSupported;
2730 VP_PUBLIC_NORMALMESSAGE("sfcNotSupported flag is set.");
2731 }
2732
2733 engineCapsForFc.value |= engineCaps.value;
2734 engineCapsForFc.nonVeboxFeatureExists |= !engineCaps.VeboxNeeded;
2735 }
2736 }
2737
2738 if (isSingleSubPipe)
2739 {
2740 break;
2741 }
2742 }
2743
2744 // For multi-layer case or color fill case, force to set fcOnlyFeatureExists flag.
2745 engineCapsForFc.fcOnlyFeatureExists = engineCapsForFc.fcOnlyFeatureExists ||
2746 featurePipe.GetSurfaceCount(true) > 1 ||
2747 featurePipe.GetSurfaceCount(true) == 0 ||
2748 engineCapsForFc.nonVeboxFeatureExists && engineCapsForFc.sfcNotSupported;
2749
2750 if (engineCapsForVeboxSfc.nonVeboxFeatureExists && engineCapsForVeboxSfc.sfcNotSupported)
2751 {
2752 VP_PUBLIC_NORMALMESSAGE("Clear nonVeboxFeatureExists flag to avoid sfc being selected, since sfcNotSupported == 1.");
2753 engineCapsForVeboxSfc.nonVeboxFeatureExists = 0;
2754 }
2755
2756 // If want to disable vebox/sfc output to output surface with color fill directly for multilayer case,
2757 // fcOnlyFeatureExists need be set for vebox sfc for multi layer case here.
2758 engineCapsForVeboxSfc.fcOnlyFeatureExists = engineCapsForFc.fcOnlyFeatureExists;
2759
2760 if (engineCapsIsolated.isolated)
2761 {
2762 VP_PUBLIC_NORMALMESSAGE("engineCapsIsolated selected.");
2763 engineCapsInputPipe = engineCapsIsolated;
2764 }
2765 else if (engineCapsForHdrKernel.hdrKernelNeeded)
2766 {
2767 VP_PUBLIC_NORMALMESSAGE("engineCapsForHdrKernel selected.");
2768 engineCapsInputPipe = engineCapsForHdrKernel;
2769 }
2770 else if (engineCapsForVeboxSfc.nonFcFeatureExists)
2771 {
2772 VP_PUBLIC_NORMALMESSAGE("engineCapsForVeboxSfc selected.");
2773 engineCapsInputPipe = engineCapsForVeboxSfc;
2774 }
2775 else if (engineCapsInputPipe.forceBypassWorkload)
2776 {
2777 VP_PUBLIC_NORMALMESSAGE("Still use engineCapsInputPipe forceBypassWorkload set true.");
2778 }
2779 else
2780 {
2781 VP_PUBLIC_NORMALMESSAGE("engineCapsForFc selected.");
2782 if (0 == engineCapsForFc.bEnabled)
2783 {
2784 engineCapsForFc.fcSupported = true;
2785 // Decision on choosing between vebox/sfc and render will be made in InitExecuteCaps.
2786 VP_PUBLIC_NORMALMESSAGE("Surface copy with no feature enabled. Force set fcSupported flag.");
2787 }
2788 engineCapsInputPipe = engineCapsForFc;
2789 }
2790
2791 PrintFeatureExecutionCaps(__FUNCTION__, engineCapsInputPipe);
2792 MT_LOG7(MT_VP_HAL_POLICY_GET_INPIPECAPS, MT_NORMAL, MT_VP_HAL_ENGINECAPS, (int64_t)engineCapsInputPipe.value,
2793 MT_VP_HAL_ENGINECAPS_EN, (int64_t)engineCapsInputPipe.bEnabled, MT_VP_HAL_ENGINECAPS_VE_NEEDED, (int64_t)engineCapsInputPipe.VeboxNeeded,
2794 MT_VP_HAL_ENGINECAPS_SFC_NEEDED, (int64_t)engineCapsInputPipe.SfcNeeded, MT_VP_HAL_ENGINECAPS_RENDER_NEEDED, (int64_t)engineCapsInputPipe.RenderNeeded,
2795 MT_VP_HAL_ENGINECAPS_FC_SUPPORT, (int64_t)engineCapsInputPipe.fcSupported, MT_VP_HAL_ENGINECAPS_ISOLATED, (int64_t)engineCapsInputPipe.isolated);
2796
2797 return MOS_STATUS_SUCCESS;
2798 }
2799
BypassVeboxFeatures(SwFilterSubPipe * featureSubPipe,VP_EngineEntry & engineCaps)2800 MOS_STATUS Policy::BypassVeboxFeatures(SwFilterSubPipe *featureSubPipe, VP_EngineEntry &engineCaps)
2801 {
2802 VP_PUBLIC_CHK_NULL_RETURN(featureSubPipe);
2803
2804 for (auto filterID : m_featurePool)
2805 {
2806 SwFilter *feature = featureSubPipe->GetSwFilter(FeatureType(filterID));
2807
2808 if (nullptr == feature)
2809 {
2810 continue;
2811 }
2812
2813 if (feature->GetFilterEngineCaps().VeboxNeeded)
2814 {
2815 // Disable vebox features and avoid it run into render path.
2816 feature->GetFilterEngineCaps().VeboxNeeded = 0;
2817 feature->GetFilterEngineCaps().RenderNeeded = 0;
2818 feature->GetFilterEngineCaps().bEnabled = feature->GetFilterEngineCaps().SfcNeeded;
2819 }
2820 }
2821
2822 engineCaps.nonVeboxFeatureExists = true;
2823 VP_PUBLIC_NORMALMESSAGE("Set nonVeboxFeatureExists to 1 for BypassVeboxFeatures.");
2824
2825 return MOS_STATUS_SUCCESS;
2826 }
2827
BuildExecuteCaps(SwFilterPipe & featurePipe,VP_EXECUTE_CAPS & caps,VP_EngineEntry & engineCapsInputPipe,VP_EngineEntry & engineCapsOutputPipe,bool & isSingleSubPipe,uint32_t & selectedPipeIndex)2828 MOS_STATUS Policy::BuildExecuteCaps(SwFilterPipe& featurePipe, VP_EXECUTE_CAPS &caps, VP_EngineEntry &engineCapsInputPipe, VP_EngineEntry &engineCapsOutputPipe,
2829 bool &isSingleSubPipe, uint32_t &selectedPipeIndex)
2830 {
2831 SwFilterSubPipe *singlePipeSelected = nullptr;
2832
2833 caps.value = 0;
2834 engineCapsOutputPipe.value = 0;
2835 engineCapsInputPipe.value = 0;
2836 isSingleSubPipe = false;
2837 selectedPipeIndex = 0;
2838
2839 VP_PUBLIC_CHK_STATUS_RETURN(GetInputPipeEngineCaps(featurePipe, engineCapsInputPipe,
2840 singlePipeSelected, isSingleSubPipe, selectedPipeIndex));
2841 VP_PUBLIC_CHK_STATUS_RETURN(GetOutputPipeEngineCaps(featurePipe, engineCapsOutputPipe, singlePipeSelected));
2842
2843 if (engineCapsInputPipe.bypassVeboxFeatures)
2844 {
2845 if (engineCapsInputPipe.isolated)
2846 {
2847 // isolated feature case should not come here.
2848 VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_INVALID_PARAMETER);
2849 }
2850 VP_PUBLIC_CHK_STATUS_RETURN(BypassVeboxFeatures(singlePipeSelected, engineCapsInputPipe));
2851 }
2852
2853 VP_PUBLIC_CHK_STATUS_RETURN(InitExecuteCaps(caps, engineCapsInputPipe, engineCapsOutputPipe));
2854
2855 return MOS_STATUS_SUCCESS;
2856 }
2857
BuildFilters(SwFilterPipe & featurePipe,HW_FILTER_PARAMS & params)2858 MOS_STATUS Policy::BuildFilters(SwFilterPipe& featurePipe, HW_FILTER_PARAMS& params)
2859 {
2860 VP_FUNC_CALL();
2861
2862 VP_EngineEntry engineCaps = {};
2863 VP_EXECUTE_CAPS caps = {};
2864 VP_EngineEntry engineCapsInputPipe = {};
2865 VP_EngineEntry engineCapsOutputPipe = {};
2866 bool isSingleSubPipe = false;
2867 uint32_t selectedPipeIndex = 0;
2868
2869 VP_PUBLIC_CHK_STATUS_RETURN(BuildExecuteCaps(featurePipe, caps, engineCapsInputPipe, engineCapsOutputPipe, isSingleSubPipe, selectedPipeIndex));
2870
2871 std::vector<int> layerIndexes;
2872 VP_PUBLIC_CHK_STATUS_RETURN(LayerSelectForProcess(layerIndexes, featurePipe, isSingleSubPipe, selectedPipeIndex, caps));
2873
2874 if (IsVeboxSecurePathEnabled(featurePipe, caps))
2875 {
2876 // Process Vebox Secure workload
2877 VP_PUBLIC_CHK_STATUS_RETURN(BuildVeboxSecureFilters(featurePipe, caps, params));
2878
2879 VP_PUBLIC_CHK_STATUS_RETURN(SetupFilterResource(featurePipe, layerIndexes, caps, params));
2880
2881 VP_PUBLIC_CHK_STATUS_RETURN(BuildExecuteHwFilter(caps, params));
2882 return MOS_STATUS_SUCCESS;
2883 }
2884
2885 // Set feature types with engine for selected features
2886 VP_PUBLIC_CHK_STATUS_RETURN(UpdateFeatureTypeWithEngine(layerIndexes, featurePipe, caps, engineCapsInputPipe.isolated, caps.bOutputPipeFeatureInuse/*engineCapsOutputPipe.bEnabled*/));
2887
2888 VP_PUBLIC_CHK_STATUS_RETURN(BuildExecuteFilter(featurePipe, layerIndexes, caps, params));
2889 VP_PUBLIC_CHK_STATUS_RETURN(featurePipe.ResetSecureFlag());
2890
2891 /* Place Holder for Resource Manager to manage intermedia surface or HW needed surface in policy*/
2892
2893 return MOS_STATUS_SUCCESS;
2894 }
2895
FilterFeatureCombination(SwFilterPipe & swFilterPipe,bool isInputPipe,uint32_t index,VP_EngineEntry & engineCapsCombined,VP_EngineEntry & engineCapsCombinedAllPipes)2896 MOS_STATUS Policy::FilterFeatureCombination(SwFilterPipe &swFilterPipe, bool isInputPipe, uint32_t index, VP_EngineEntry &engineCapsCombined, VP_EngineEntry &engineCapsCombinedAllPipes)
2897 {
2898 VP_FUNC_CALL();
2899
2900 SwFilterSubPipe *pipe = nullptr;
2901 pipe = swFilterPipe.GetSwFilterSubPipe(isInputPipe, index);
2902 VP_PUBLIC_CHK_NULL_RETURN(pipe);
2903
2904 // Filter out vebox/sfc only features.
2905 if (engineCapsCombined.veboxNotSupported)
2906 {
2907 for (auto filterID : m_featurePool)
2908 {
2909 auto feature = pipe->GetSwFilter(FeatureType(filterID));
2910 if (feature && feature->GetFilterEngineCaps().bEnabled &&
2911 (feature->GetFilterEngineCaps().VeboxNeeded ||
2912 feature->GetFilterEngineCaps().SfcNeeded) &&
2913 !feature->GetFilterEngineCaps().RenderNeeded)
2914 {
2915 feature->GetFilterEngineCaps().bEnabled = 0;
2916 feature->GetFilterEngineCaps().VeboxNeeded = 0;
2917 feature->GetFilterEngineCaps().SfcNeeded = 0;
2918 feature->GetFilterEngineCaps().forceEnableForSfc = 0;
2919 VP_PUBLIC_NORMALMESSAGE("Disable feature 0x%x since vebox cannot be used.", filterID);
2920 PrintFeatureExecutionCaps("Disable feature since vebox cannot be used", feature->GetFilterEngineCaps());
2921 }
2922 }
2923 }
2924 else if (engineCapsCombined.forceBypassWorkload)
2925 {
2926 for (auto filterID : m_featurePool)
2927 {
2928 auto feature = pipe->GetSwFilter(FeatureType(filterID));
2929 if (feature && feature->GetFilterEngineCaps().bEnabled)
2930 {
2931 feature->GetFilterEngineCaps().bEnabled = 0;
2932 feature->GetFilterEngineCaps().VeboxNeeded = 0;
2933 feature->GetFilterEngineCaps().SfcNeeded = 0;
2934 feature->GetFilterEngineCaps().RenderNeeded = 0;
2935 feature->GetFilterEngineCaps() = {0};
2936 feature->GetFilterEngineCaps().forceBypassWorkload = 1;
2937 VP_PUBLIC_NORMALMESSAGE("Disable feature 0x%x because of bypass this workload.", filterID);
2938 PrintFeatureExecutionCaps("Disable feature because of bypass this workload.", feature->GetFilterEngineCaps());
2939 }
2940 }
2941 }
2942
2943 // For DI on render with scaling case, force to do scaling on render.
2944 if (engineCapsCombined.SfcNeeded)
2945 {
2946 auto di = pipe->GetSwFilter(FeatureType(FeatureTypeDi));
2947
2948 if (di && di->GetFilterEngineCaps().bEnabled &&
2949 !di->GetFilterEngineCaps().VeboxNeeded && di->GetFilterEngineCaps().RenderNeeded)
2950 {
2951 for (auto filterID : m_featurePool)
2952 {
2953 auto feature = pipe->GetSwFilter(FeatureType(filterID));
2954 if (nullptr == feature || !feature->GetFilterEngineCaps().bEnabled)
2955 {
2956 continue;
2957 }
2958 if (FeatureType(filterID) == FeatureTypeScaling &&
2959 feature->GetFilterEngineCaps().SfcNeeded &&
2960 !feature->GetFilterEngineCaps().RenderNeeded &&
2961 !m_hwCaps.m_rules.isAvsSamplerSupported)
2962 {
2963 feature->GetFilterEngineCaps().SfcNeeded = 0;
2964 feature->GetFilterEngineCaps().RenderNeeded = 1;
2965 feature->GetFilterEngineCaps().fcSupported = 1;
2966 PrintFeatureExecutionCaps("Update scaling caps for render DI", feature->GetFilterEngineCaps());
2967 }
2968 else if (!feature->GetFilterEngineCaps().VeboxNeeded &&
2969 feature->GetFilterEngineCaps().SfcNeeded &&
2970 feature->GetFilterEngineCaps().RenderNeeded)
2971 {
2972 feature->GetFilterEngineCaps().SfcNeeded = 0;
2973 VP_PUBLIC_NORMALMESSAGE("Force feature 0x%x to render for render DI", filterID);
2974 MT_LOG2(MT_VP_HAL_POLICY_FLITER_FTR_COMBINE, MT_NORMAL, MT_VP_HAL_FEATUERTYPE, filterID, MT_VP_HAL_EXECCAPS_FORCE_DI2RENDER, (int64_t)feature->GetFilterEngineCaps().RenderNeeded);
2975 auto engineCaps = feature->GetFilterEngineCaps();
2976 PrintFeatureExecutionCaps("Force feature to render for render DI", engineCaps);
2977 MT_LOG7(MT_VP_HAL_POLICY_FLITER_FTR_COMBINE, MT_NORMAL, MT_VP_HAL_FEATUERTYPE, filterID, MT_VP_HAL_ENGINECAPS, (int64_t)engineCaps.value, MT_VP_HAL_ENGINECAPS_EN, (int64_t)engineCaps.bEnabled,
2978 MT_VP_HAL_ENGINECAPS_VE_NEEDED, (int64_t)engineCaps.VeboxNeeded, MT_VP_HAL_ENGINECAPS_SFC_NEEDED, (int64_t)engineCaps.SfcNeeded,
2979 MT_VP_HAL_ENGINECAPS_RENDER_NEEDED, (int64_t)engineCaps.RenderNeeded, MT_VP_HAL_ENGINECAPS_FC_SUPPORT, (int64_t)engineCaps.fcSupported);
2980 }
2981 }
2982 }
2983 }
2984
2985 if (engineCapsCombinedAllPipes.hdrKernelNeeded)
2986 {
2987 VP_PUBLIC_CHK_STATUS_RETURN(FilterFeatureCombinationForHDRKernel(pipe));
2988 }
2989 else
2990 {
2991 auto hdr = pipe->GetSwFilter(FeatureTypeHdr);
2992
2993 if (nullptr != hdr)
2994 {
2995 for (auto filterID : m_featurePool)
2996 {
2997 if (IsExcludedFeatureForHdr(filterID))
2998 {
2999 auto feature = pipe->GetSwFilter(FeatureType(filterID));
3000 if (feature && feature->GetFilterEngineCaps().bEnabled)
3001 {
3002 feature->GetFilterEngineCaps().bEnabled = false;
3003 VP_PUBLIC_NORMALMESSAGE("Disable feature 0x%x for HDR.", filterID);
3004 PrintFeatureExecutionCaps("Disable feature for HDR", feature->GetFilterEngineCaps());
3005 }
3006 }
3007
3008 if (filterID == FeatureTypeCsc)
3009 {
3010 SwFilterCsc *feature = (SwFilterCsc *)pipe->GetSwFilter(FeatureType(filterID));
3011 if (feature)
3012 {
3013 auto ¶ms = feature->GetSwFilterParams();
3014 params.pIEFParams = nullptr;
3015 PrintFeatureExecutionCaps("Disable IEF for HDR", feature->GetFilterEngineCaps());
3016 }
3017 }
3018 }
3019 }
3020 }
3021
3022 return MOS_STATUS_SUCCESS;
3023 }
3024
FilterFeatureCombinationForHDRKernel(SwFilterSubPipe * pipe)3025 MOS_STATUS Policy::FilterFeatureCombinationForHDRKernel(SwFilterSubPipe *pipe)
3026 {
3027 VP_FUNC_CALL();
3028
3029 for (auto filterID : m_featurePool)
3030 {
3031 auto feature = pipe->GetSwFilter(FeatureType(filterID));
3032 if (feature && feature->GetFilterEngineCaps().bEnabled &&
3033 !feature->GetFilterEngineCaps().hdrKernelSupported)
3034 {
3035 auto feature = pipe->GetSwFilter(FeatureType(filterID));
3036 if (feature && feature->GetFilterEngineCaps().bEnabled)
3037 {
3038 feature->GetFilterEngineCaps().bEnabled = false;
3039 VP_PUBLIC_NORMALMESSAGE("Disable feature 0x%x for HDR.", filterID);
3040 PrintFeatureExecutionCaps("Disable feature for HDR", feature->GetFilterEngineCaps());
3041 }
3042 }
3043 }
3044 return MOS_STATUS_SUCCESS;
3045 }
3046
BuildExecuteFilter(SwFilterPipe & featurePipe,std::vector<int> & layerIndexes,VP_EXECUTE_CAPS & caps,HW_FILTER_PARAMS & params)3047 MOS_STATUS Policy::BuildExecuteFilter(SwFilterPipe& featurePipe, std::vector<int> &layerIndexes, VP_EXECUTE_CAPS& caps, HW_FILTER_PARAMS& params)
3048 {
3049 VP_FUNC_CALL();
3050
3051 params.Type = EngineTypeInvalid;
3052 // params.vpExecuteCaps will be assigned in Policy::BuildExecuteHwFilter.
3053 params.vpExecuteCaps.value = 0;
3054
3055 VP_PUBLIC_CHK_STATUS_RETURN(SetupExecuteFilter(featurePipe, layerIndexes, caps, params));
3056
3057 // Build Execute surface needed
3058 VP_PUBLIC_CHK_STATUS_RETURN(SetupFilterResource(featurePipe, layerIndexes, caps, params));
3059
3060 VP_PUBLIC_CHK_STATUS_RETURN(featurePipe.Update());
3061 VP_PUBLIC_CHK_STATUS_RETURN(params.executedFilters->Update());
3062
3063 if (featurePipe.IsEmpty())
3064 {
3065 caps.lastSubmission = true;
3066 }
3067
3068 VP_PUBLIC_CHK_STATUS_RETURN(BuildExecuteHwFilter(caps, params));
3069
3070 if (params.executedFilters)
3071 {
3072 params.executedFilters->AddRTLog();
3073 }
3074
3075 return MOS_STATUS_SUCCESS;
3076 }
3077
BuildExecuteHwFilter(VP_EXECUTE_CAPS & caps,HW_FILTER_PARAMS & params)3078 MOS_STATUS Policy::BuildExecuteHwFilter(VP_EXECUTE_CAPS& caps, HW_FILTER_PARAMS& params)
3079 {
3080 VP_FUNC_CALL();
3081
3082 if (caps.bVebox || caps.bSFC)
3083 {
3084 params.Type = caps.bSFC ? EngineTypeVeboxSfc : EngineTypeVebox;
3085 params.vpExecuteCaps = caps;
3086 auto it = m_VeboxSfcFeatureHandlers.begin();
3087 for (; it != m_VeboxSfcFeatureHandlers.end(); ++it)
3088 {
3089 if ((*(it->second)).IsFeatureEnabled(caps))
3090 {
3091 HwFilterParameter* pHwFilterParam = (*(it->second)).CreateHwFilterParam(caps, *params.executedFilters, m_vpInterface.GetHwInterface());
3092
3093 if (pHwFilterParam)
3094 {
3095 params.Params.push_back(pHwFilterParam);
3096 }
3097 else
3098 {
3099 VP_PUBLIC_ASSERTMESSAGE("Create HW Filter Failed, Return Error");
3100 MT_ERR2(MT_VP_HAL_POLICY, MT_ERROR_CODE, MOS_STATUS_NO_SPACE, MT_CODE_LINE, __LINE__);
3101 return MOS_STATUS_NO_SPACE;
3102 }
3103 }
3104 }
3105 }
3106 else if (caps.bRender)
3107 {
3108 params.Type = EngineTypeRender;
3109 params.vpExecuteCaps = caps;
3110
3111 auto it = m_RenderFeatureHandlers.begin();
3112 for (; it != m_RenderFeatureHandlers.end(); ++it)
3113 {
3114 if ((*(it->second)).IsFeatureEnabled(caps))
3115 {
3116 HwFilterParameter* pHwFilterParam = (*(it->second)).CreateHwFilterParam(caps, *params.executedFilters, m_vpInterface.GetHwInterface());
3117
3118 if (pHwFilterParam)
3119 {
3120 params.Params.push_back(pHwFilterParam);
3121 }
3122 else
3123 {
3124 VP_PUBLIC_ASSERTMESSAGE("Create HW Filter Failed, Return Error");
3125 MT_ERR2(MT_VP_HAL_POLICY, MT_ERROR_CODE, MOS_STATUS_NO_SPACE, MT_CODE_LINE, __LINE__);
3126 return MOS_STATUS_NO_SPACE;
3127 }
3128 }
3129 }
3130 }
3131 else if (caps.forceBypassWorkload)
3132 {
3133 VP_PUBLIC_NORMALMESSAGE("No engine is assigned. Skip this process for test usage.");
3134 VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_SUCCESS);
3135 }
3136 else
3137 {
3138 VP_PUBLIC_ASSERTMESSAGE("No engine is assigned.");
3139 VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_INVALID_PARAMETER);
3140 }
3141
3142 return MOS_STATUS_SUCCESS;
3143 }
3144
UpdateFeatureTypeWithEngine(std::vector<int> & layerIndexes,SwFilterPipe & featurePipe,VP_EXECUTE_CAPS & caps,bool isolatedFeatureSelected,bool outputPipeNeeded)3145 MOS_STATUS Policy::UpdateFeatureTypeWithEngine(std::vector<int> &layerIndexes, SwFilterPipe& featurePipe, VP_EXECUTE_CAPS& caps,
3146 bool isolatedFeatureSelected, bool outputPipeNeeded)
3147 {
3148 int inputSurfCount = featurePipe.GetSurfaceCount(true);
3149 int outputSurfCount = featurePipe.GetSurfaceCount(false);
3150 SwFilterSubPipe* featureSubPipe = nullptr;
3151
3152 for (uint32_t i = 0; i < layerIndexes.size(); ++i)
3153 {
3154 featureSubPipe = featurePipe.GetSwFilterSubPipe(true, layerIndexes[i]);
3155 VP_PUBLIC_CHK_STATUS_RETURN(UpdateFeatureTypeWithEngineSingleLayer(featureSubPipe, caps, isolatedFeatureSelected));
3156 }
3157
3158 if (outputPipeNeeded)
3159 {
3160 featureSubPipe = featurePipe.GetSwFilterSubPipe(false, 0);
3161 VP_PUBLIC_CHK_STATUS_RETURN(UpdateFeatureTypeWithEngineSingleLayer(featureSubPipe, caps, false));
3162 }
3163
3164 return MOS_STATUS_SUCCESS;
3165 }
3166
UpdateFeatureTypeWithEngineSingleLayer(SwFilterSubPipe * featureSubPipe,VP_EXECUTE_CAPS & caps,bool isolatedFeatureSelected)3167 MOS_STATUS Policy::UpdateFeatureTypeWithEngineSingleLayer(SwFilterSubPipe *featureSubPipe, VP_EXECUTE_CAPS& caps, bool isolatedFeatureSelected)
3168 {
3169 bool isolatedFeatureFound = false;
3170 // Set feature types with engine
3171 for (auto filterID : m_featurePool)
3172 {
3173 auto feature = featureSubPipe->GetSwFilter(FeatureType(filterID));
3174 if (feature)
3175 {
3176 VP_EngineEntry *engineCaps = &(feature->GetFilterEngineCaps());
3177
3178 if (isolatedFeatureSelected != engineCaps->isolated)
3179 {
3180 continue;
3181 }
3182
3183 // if SFC enabled, Vebox is must as SFC need connect with Vebox
3184 if (caps.bSFC &&
3185 (engineCaps->forceEnableForSfc ||
3186 engineCaps->bEnabled && (engineCaps->VeboxNeeded || engineCaps->SfcNeeded)))
3187 {
3188 if (engineCaps->forceEnableForSfc)
3189 {
3190 engineCaps->bEnabled = 1;
3191 engineCaps->SfcNeeded = 1;
3192 caps.enableSFCLinearOutputByTileConvert |= engineCaps->enableSFCLinearOutputByTileConvert;
3193 }
3194 // Choose SFC as execution engine
3195 VP_PUBLIC_CHK_STATUS_RETURN(UpdateExeCaps(feature, caps, engineCaps->SfcNeeded ? EngineTypeVeboxSfc : EngineTypeVebox));
3196 }
3197 // Vebox only cases
3198 else if (caps.bVebox &&
3199 (engineCaps->bEnabled && engineCaps->VeboxNeeded || caps.bIECP && filterID == FeatureTypeCsc))
3200 {
3201 // If HDR filter exist, handle CSC previous to HDR in AddFiltersBasedOnCaps
3202 if (filterID == FeatureTypeCsc && IsHDRfilterExist(featureSubPipe))
3203 {
3204 VP_PUBLIC_NORMALMESSAGE("HDR exist, handle CSC previous to HDR in AddFiltersBasedOnCaps");
3205 continue;
3206 }
3207
3208 if (!engineCaps->bEnabled && caps.bIECP && filterID == FeatureTypeCsc)
3209 {
3210 engineCaps->bEnabled = 1;
3211 engineCaps->VeboxNeeded = 1;
3212 }
3213
3214 VP_PUBLIC_CHK_STATUS_RETURN(UpdateExeCaps(feature, caps, EngineTypeVebox));
3215 }
3216 else if (caps.bRender && caps.bRenderHdr &&
3217 (engineCaps->forceEnableForHdrKernel ||
3218 engineCaps->bEnabled && engineCaps->hdrKernelSupported))
3219 {
3220 if (engineCaps->forceEnableForHdrKernel)
3221 {
3222 engineCaps->bEnabled = 1;
3223 engineCaps->RenderNeeded = 1;
3224 engineCaps->hdrKernelSupported = 1;
3225 }
3226 VP_PUBLIC_CHK_STATUS_RETURN(UpdateExeCaps(feature, caps, EngineTypeRender));
3227 }
3228 else if (caps.bRender &&
3229 (engineCaps->forceEnableForFc ||
3230 engineCaps->bEnabled && engineCaps->RenderNeeded))
3231 {
3232 if (engineCaps->forceEnableForFc)
3233 {
3234 engineCaps->bEnabled = 1;
3235 engineCaps->RenderNeeded = 1;
3236 }
3237 // use render path to implement feature.
3238 VP_PUBLIC_CHK_STATUS_RETURN(UpdateExeCaps(feature, caps, EngineTypeRender));
3239 }
3240
3241 if (engineCaps->isolated)
3242 {
3243 isolatedFeatureFound = true;
3244 break;
3245 }
3246 }
3247 }
3248
3249 if (isolatedFeatureSelected && !isolatedFeatureFound)
3250 {
3251 VP_PUBLIC_ASSERTMESSAGE("Isolated feature is not found!");
3252 VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_INVALID_PARAMETER);
3253 }
3254
3255 return MOS_STATUS_SUCCESS;
3256 }
3257
LayerSelectForProcess(std::vector<int> & layerIndexes,SwFilterPipe & featurePipe,bool isSingleSubPipe,uint32_t pipeIndex,VP_EXECUTE_CAPS & caps)3258 MOS_STATUS Policy::LayerSelectForProcess(std::vector<int> &layerIndexes, SwFilterPipe& featurePipe, bool isSingleSubPipe, uint32_t pipeIndex, VP_EXECUTE_CAPS& caps)
3259 {
3260 layerIndexes.clear();
3261 if (isSingleSubPipe && !caps.bComposite && !caps.bRenderHdr)
3262 {
3263 layerIndexes.push_back(pipeIndex);
3264 return MOS_STATUS_SUCCESS;
3265 }
3266
3267 if (caps.bRenderHdr)
3268 {
3269 auto it = m_RenderFeatureHandlers.find(FeatureTypeHdrOnRender);
3270 if (m_RenderFeatureHandlers.end() == it)
3271 {
3272 VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_INVALID_PARAMETER);
3273 }
3274 PolicyRenderHdrHandler *hdrHandler = dynamic_cast<PolicyRenderHdrHandler *>(it->second);
3275 VP_PUBLIC_CHK_NULL_RETURN(hdrHandler);
3276 VP_PUBLIC_CHK_STATUS_RETURN(hdrHandler->LayerSelectForProcess(layerIndexes, featurePipe, caps));
3277 return MOS_STATUS_SUCCESS;
3278 }
3279
3280 if (!caps.bComposite)
3281 {
3282 VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_INVALID_PARAMETER);
3283 }
3284
3285 auto it = m_RenderFeatureHandlers.find(FeatureTypeFcOnRender);
3286 if (m_RenderFeatureHandlers.end() == it)
3287 {
3288 VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_INVALID_PARAMETER);
3289 }
3290
3291 auto osInterface = m_vpInterface.GetHwInterface()->m_osInterface;
3292
3293 for (uint32_t i = 0; i < featurePipe.GetSurfaceCount(true); ++i)
3294 {
3295 VP_SURFACE *input = featurePipe.GetSurface(true, i);
3296 VP_PUBLIC_CHK_NULL_RETURN(input);
3297 VP_PUBLIC_CHK_NULL_RETURN(input->osSurface);
3298 uint64_t gpuVa = osInterface->pfnGetResourceGfxAddress(osInterface, &input->osSurface->OsResource);
3299
3300 VP_PUBLIC_NORMALMESSAGE("layer %d, gpuVa = 0x%llx", i, gpuVa);
3301 }
3302
3303 VP_SURFACE *output = featurePipe.GetSurface(false, 0);
3304 VP_PUBLIC_CHK_NULL_RETURN(output);
3305 VP_PUBLIC_CHK_NULL_RETURN(output->osSurface);
3306 uint64_t gpuVa = osInterface->pfnGetResourceGfxAddress(osInterface, &output->osSurface->OsResource);
3307 VP_PUBLIC_NORMALMESSAGE("target, gpuVa = 0x%llx", gpuVa);
3308
3309 PolicyFcWrapHandler *fcHandler = dynamic_cast<PolicyFcWrapHandler *>(it->second);
3310 VP_PUBLIC_CHK_NULL_RETURN(fcHandler);
3311 VP_PUBLIC_CHK_STATUS_RETURN(fcHandler->LayerSelectForProcess(layerIndexes, featurePipe, caps));
3312
3313 if (layerIndexes.size() < featurePipe.GetSurfaceCount(true))
3314 {
3315 // Multi pass needed.
3316 VP_PUBLIC_CHK_STATUS_RETURN(m_vpInterface.GetResourceManager()->PrepareFcIntermediateSurface(featurePipe));
3317 }
3318
3319 return MOS_STATUS_SUCCESS;
3320 }
3321
AddInputSurfaceForSingleLayer(SwFilterPipe & featurePipe,uint32_t pipeIndex,SwFilterPipe & executedFilters,uint32_t & executePipeIndex,VP_EXECUTE_CAPS & caps)3322 MOS_STATUS AddInputSurfaceForSingleLayer(SwFilterPipe &featurePipe, uint32_t pipeIndex, SwFilterPipe &executedFilters, uint32_t &executePipeIndex, VP_EXECUTE_CAPS& caps)
3323 {
3324 // Single layer add input surface
3325 if (caps.value)
3326 {
3327 // Move surfaces from subSwFilterPipe to executedFilters.
3328 VP_SURFACE *surfInput = featurePipe.GetSurface(true, pipeIndex);
3329 if (surfInput)
3330 {
3331 // surface should be added before swFilters, since empty feature pipe will be allocated accordingly when surface being added.
3332 executePipeIndex = executedFilters.GetSurfaceCount(true);
3333 VP_PUBLIC_CHK_STATUS_RETURN(executedFilters.AddSurface(surfInput, true, executePipeIndex));
3334 VP_SURFACE *pastRefSurface = featurePipe.RemovePastSurface(pipeIndex);
3335 VP_SURFACE *futureRefSurface = featurePipe.RemoveFutureSurface(pipeIndex);
3336 executedFilters.SetPastSurface(executePipeIndex, pastRefSurface);
3337 executedFilters.SetFutureSurface(executePipeIndex, futureRefSurface);
3338 executedFilters.SetLinkedLayerIndex(executePipeIndex, pipeIndex);
3339 }
3340 else
3341 {
3342 VP_PUBLIC_ASSERTMESSAGE("No input for current pipe");
3343 }
3344 }
3345 return MOS_STATUS_SUCCESS;
3346 }
3347
SetupExecuteFilter(SwFilterPipe & featurePipe,std::vector<int> & layerIndexes,VP_EXECUTE_CAPS & caps,HW_FILTER_PARAMS & params)3348 MOS_STATUS Policy::SetupExecuteFilter(SwFilterPipe& featurePipe, std::vector<int> &layerIndexes, VP_EXECUTE_CAPS& caps, HW_FILTER_PARAMS& params)
3349 {
3350 VP_FUNC_CALL();
3351
3352 VP_PUBLIC_CHK_NULL_RETURN(params.executedFilters);
3353
3354 for (uint32_t i = 0; i < layerIndexes.size(); ++i)
3355 {
3356 VP_PUBLIC_CHK_STATUS_RETURN(AddInputSurfaceForSingleLayer(featurePipe, layerIndexes[i], *params.executedFilters, i, caps));
3357 VP_PUBLIC_CHK_STATUS_RETURN(UpdateFeaturePipeSingleLayer(featurePipe, layerIndexes[i], *params.executedFilters, i, caps));
3358 VP_PUBLIC_CHK_STATUS_RETURN(AddFiltersBasedOnCaps(featurePipe, layerIndexes[i], caps, *params.executedFilters, i));
3359 }
3360
3361 /* Place Holder: order pipe need to be insert in next step*/
3362
3363 VP_PUBLIC_CHK_STATUS_RETURN(UpdateFeatureOutputPipe(layerIndexes, featurePipe, *params.executedFilters, caps));
3364
3365 return MOS_STATUS_SUCCESS;
3366 }
3367
UpdateFeaturePipe(SwFilterPipe & featurePipe,uint32_t pipeIndex,SwFilterPipe & executedFilters,uint32_t executePipeIndex,bool isInputPipe,VP_EXECUTE_CAPS & caps)3368 MOS_STATUS Policy::UpdateFeaturePipe(SwFilterPipe &featurePipe, uint32_t pipeIndex, SwFilterPipe &executedFilters, uint32_t executePipeIndex,
3369 bool isInputPipe, VP_EXECUTE_CAPS& caps)
3370 {
3371 SwFilterSubPipe* featureSubPipe = featurePipe.GetSwFilterSubPipe(isInputPipe, pipeIndex);
3372 uint32_t featureSelected = 0;
3373
3374 VP_PUBLIC_CHK_NULL_RETURN(featureSubPipe);
3375 // Move swfilter from feature sub pipe to params.executedFilters
3376 for (auto filterID : m_featurePool)
3377 {
3378 SwFilter *feature = (SwFilter*)featureSubPipe->GetSwFilter(FeatureType(filterID));
3379 if (feature)
3380 {
3381 VP_EngineEntry *engineCaps = &(feature->GetFilterEngineCaps());
3382
3383 if (engineCaps->usedForNextPass)
3384 {
3385 continue;
3386 }
3387
3388 if ((caps.bSFC || caps.bVebox) && engineCaps->bEnabled && IS_FEATURE_TYPE_ON_VEBOX_SFC(feature->GetFeatureType()) &&
3389 m_VeboxSfcFeatureHandlers.end() != m_VeboxSfcFeatureHandlers.find(feature->GetFeatureType()))
3390 {
3391 // Engine has been assigned to feature.
3392 auto it = m_VeboxSfcFeatureHandlers.find(feature->GetFeatureType());
3393 if (m_VeboxSfcFeatureHandlers.end() == it)
3394 {
3395 VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_NULL_POINTER);
3396 }
3397 PolicyFeatureHandler *handler = it->second;
3398 VP_PUBLIC_CHK_STATUS_RETURN(handler->UpdateFeaturePipe(caps, *feature, featurePipe, executedFilters, isInputPipe, executePipeIndex));
3399 if (!engineCaps->bEnabled)
3400 {
3401 VP_PUBLIC_NORMALMESSAGE("filter is disable during UpdateFeaturePipe");
3402 }
3403 ++featureSelected;
3404 }
3405 else if (caps.bRender && engineCaps->bEnabled && IS_FEATURE_TYPE_ON_RENDER(feature->GetFeatureType()) &&
3406 m_RenderFeatureHandlers.end() != m_RenderFeatureHandlers.find(feature->GetFeatureType()))
3407 {
3408 auto it = m_RenderFeatureHandlers.find(feature->GetFeatureType());
3409 if (m_RenderFeatureHandlers.end() == it)
3410 {
3411 VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_NULL_POINTER);
3412 }
3413 PolicyFeatureHandler *handler = it->second;
3414
3415 VP_PUBLIC_CHK_STATUS_RETURN(handler->UpdateFeaturePipe(caps, *feature, featurePipe, executedFilters, isInputPipe, executePipeIndex));
3416 if (!engineCaps->bEnabled)
3417 {
3418 VP_PUBLIC_NORMALMESSAGE("filter is disable during UpdateFeaturePipe");
3419 }
3420 ++featureSelected;
3421 }
3422 else
3423 {
3424 auto *handlers = (caps.bSFC || caps.bVebox) ? &m_VeboxSfcFeatureHandlers : &m_RenderFeatureHandlers;
3425 auto it = handlers->find(feature->GetFeatureType());
3426 if (handlers->end() != it)
3427 {
3428 PolicyFeatureHandler *handler = it->second;
3429 VP_PUBLIC_CHK_STATUS_RETURN(handler->UpdateUnusedFeature(caps, *feature, featurePipe, executedFilters, isInputPipe, executePipeIndex));
3430 }
3431 }
3432
3433 if (!engineCaps->bEnabled && !engineCaps->usedForNextPass)
3434 {
3435 // Feature may be disabled during UpdateFeaturePipe, such as colorfill and alpha, which will
3436 // be combined into scaling in sfc.
3437 SwFilterFeatureHandler *handler = m_vpInterface.GetSwFilterHandler(feature->GetFeatureType());
3438 if (!handler)
3439 {
3440 VP_PUBLIC_ASSERTMESSAGE("no Feature Handle, Return Pipe Init Error");
3441 return MOS_STATUS_INVALID_HANDLE;
3442 }
3443
3444 featurePipe.RemoveSwFilter(feature);
3445 handler->Destory(feature);
3446 VP_PUBLIC_NORMALMESSAGE("filter is disable during UpdateFeaturePipe");
3447 }
3448 }
3449 }
3450
3451 if (!isInputPipe && featureSelected && !featureSubPipe->IsEmpty() && featurePipe.IsAllInputPipeSurfaceFeatureEmpty())
3452 {
3453 VP_PUBLIC_ASSERTMESSAGE("Not all output features being selected!");
3454 }
3455
3456 return MOS_STATUS_SUCCESS;
3457 }
3458
UpdateFeaturePipeSingleLayer(SwFilterPipe & featurePipe,uint32_t pipeIndex,SwFilterPipe & executedFilters,uint32_t executePipeIndex,VP_EXECUTE_CAPS & caps)3459 MOS_STATUS Policy::UpdateFeaturePipeSingleLayer(SwFilterPipe &featurePipe, uint32_t pipeIndex, SwFilterPipe &executedFilters, uint32_t executePipeIndex, VP_EXECUTE_CAPS& caps)
3460 {
3461 VP_PUBLIC_CHK_STATUS_RETURN(UpdateFeaturePipe(featurePipe, pipeIndex, executedFilters, executePipeIndex, true, caps));
3462
3463 return MOS_STATUS_SUCCESS;
3464 }
3465
UpdateFeatureOutputPipe(std::vector<int> & layerIndexes,SwFilterPipe & featurePipe,SwFilterPipe & executedFilters,VP_EXECUTE_CAPS & caps)3466 MOS_STATUS Policy::UpdateFeatureOutputPipe(std::vector<int> &layerIndexes, SwFilterPipe &featurePipe, SwFilterPipe &executedFilters, VP_EXECUTE_CAPS& caps)
3467 {
3468 if (!caps.bOutputPipeFeatureInuse)
3469 {
3470 return MOS_STATUS_SUCCESS;
3471 }
3472
3473 if (!featurePipe.IsAllInputPipeSurfaceFeatureEmpty(layerIndexes))
3474 {
3475 VP_PUBLIC_ASSERTMESSAGE("bOutputPipeFeatureInuse being set but input pipe is not empty.");
3476 VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_INVALID_PARAMETER);
3477 }
3478
3479 VP_PUBLIC_CHK_STATUS_RETURN(UpdateFeaturePipe(featurePipe, 0, executedFilters, 0, false, caps));
3480
3481 return MOS_STATUS_SUCCESS;
3482 }
3483
SetupFilterResource(SwFilterPipe & featurePipe,std::vector<int> & layerIndexes,VP_EXECUTE_CAPS & caps,HW_FILTER_PARAMS & params)3484 MOS_STATUS Policy::SetupFilterResource(SwFilterPipe& featurePipe, std::vector<int> &layerIndexes, VP_EXECUTE_CAPS& caps, HW_FILTER_PARAMS& params)
3485 {
3486 VP_FUNC_CALL();
3487
3488 VP_SURFACE* surfInput = nullptr;
3489 VP_SURFACE* surfOutput = nullptr;
3490 uint32_t i = 0;
3491
3492 if (featurePipe.IsEmpty())
3493 {
3494 // If all subpipes are empty, which means no swfilter exists in featurePipe, just move output surface from featurePipe to executedFilters.
3495 // In such case, processing complete.
3496 // Update the input feature surfaces
3497 surfOutput = featurePipe.RemoveSurface(false, 0);
3498 VP_PUBLIC_CHK_NULL_RETURN(surfOutput);
3499 // surface should be added before swFilters, since empty feature pipe will be allocated accordingly when surface being added.
3500 VP_PUBLIC_CHK_STATUS_RETURN(params.executedFilters->AddSurface(surfOutput, false, 0));
3501 VP_PUBLIC_NORMALMESSAGE("Output surface in use, since no filters left in featurePipe.");
3502 }
3503 else if (RenderTargetTypeParameter == featurePipe.GetRenderTargetType() ||
3504 RenderTargetTypeParameter == params.executedFilters->GetRenderTargetType())
3505 {
3506 surfOutput = featurePipe.GetSurface(false, 0);
3507 VP_PUBLIC_CHK_NULL_RETURN(surfOutput);
3508 VP_SURFACE *surfOutput2 = m_vpInterface.GetAllocator().AllocateVpSurface(*surfOutput);
3509 VP_PUBLIC_CHK_NULL_RETURN(surfOutput2);
3510 VP_PUBLIC_CHK_STATUS_RETURN(params.executedFilters->AddSurface(surfOutput2, false, 0));
3511 VP_PUBLIC_NORMALMESSAGE("Output surface in use, since only parameter filters in featurePipe.");
3512 }
3513 else if (caps.bOutputPipeFeatureInuse)
3514 {
3515 // Use intermedia surfaces for multi layer case, or color fill during composition may not
3516 // act correctly.
3517 VP_PUBLIC_NORMALMESSAGE("Intermedia surface in use with 1 == bOutputPipeFeatureInuse.");
3518 }
3519 else if (IsSecureResourceNeeded(caps))
3520 {
3521 VP_PUBLIC_CHK_STATUS_RETURN(UpdateSecureExecuteResource(featurePipe, caps, params));
3522 }
3523 else
3524 {
3525 // If not assign output surface, intermedia surface will be assigned in AssignExecuteResource.
3526 }
3527
3528 VP_PUBLIC_CHK_STATUS_RETURN(AssignExecuteResource(caps, params));
3529
3530 SwFilterSubPipe *subPipe = nullptr;
3531
3532 if (1 == layerIndexes.size())
3533 {
3534 subPipe = featurePipe.GetSwFilterSubPipe(true, layerIndexes[0]);
3535 }
3536
3537 if (featurePipe.IsEmpty())
3538 {
3539 // Update the input feature surfaces
3540 for (i = 0; i < layerIndexes.size(); ++i)
3541 {
3542 surfInput = featurePipe.RemoveSurface(true, layerIndexes[i]);
3543 }
3544 }
3545 else if (subPipe && RenderTargetTypeParameter == subPipe->GetRenderTargetType() ||
3546 RenderTargetTypeParameter == params.executedFilters->GetRenderTargetType())
3547 {
3548 surfInput = featurePipe.GetSurface(true, layerIndexes[0]);
3549 VP_PUBLIC_CHK_NULL_RETURN(surfInput);
3550 VP_SURFACE* input = m_vpInterface.GetAllocator().AllocateVpSurface(*surfInput);
3551 VP_PUBLIC_CHK_NULL_RETURN(input);
3552 input->SurfType = SURF_IN_PRIMARY;
3553 featurePipe.ReplaceSurface(input, true, layerIndexes[0]);
3554 }
3555 else if (IsSecureResourceNeeded(caps))
3556 {
3557 VP_PUBLIC_NORMALMESSAGE("Secure Process Enabled, no need further process");
3558 }
3559 else
3560 {
3561 auto osInterface = m_vpInterface.GetHwInterface()->m_osInterface;
3562 auto outputSurfaceExePipe = params.executedFilters->GetSurface(false, 0);
3563 VP_PUBLIC_CHK_NULL_RETURN(outputSurfaceExePipe);
3564 auto outputSurface = featurePipe.GetSurface(false, 0);
3565 VP_PUBLIC_CHK_NULL_RETURN(outputSurface);
3566 bool outputSurfaceInuse =
3567 outputSurfaceExePipe->GetAllocationHandle(osInterface) == outputSurface->GetAllocationHandle(osInterface);
3568
3569 if (outputSurfaceInuse)
3570 {
3571 // Update the input feature surfaces
3572 for (i = 0; i < layerIndexes.size(); ++i)
3573 {
3574 surfInput = featurePipe.RemoveSurface(true, layerIndexes[i]);
3575 }
3576 }
3577 else
3578 {
3579 // multi-pass with intermedia surface case.
3580 auto intermediaSurface = outputSurfaceExePipe;
3581 VP_SURFACE *input = m_vpInterface.GetAllocator().AllocateVpSurface(*intermediaSurface);
3582 VP_PUBLIC_CHK_NULL_RETURN(input);
3583
3584 // For FC, also reuse first pipe for the composition layer in previous steps.
3585 auto originInput = featurePipe.GetSurface(true, layerIndexes[0]);
3586 if (originInput == nullptr)
3587 {
3588 m_vpInterface.GetAllocator().DestroyVpSurface(input);
3589 VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_NULL_POINTER);
3590 }
3591
3592 input->SurfType = originInput->SurfType;
3593 featurePipe.ReplaceSurface(input, true, layerIndexes[0]);
3594
3595 // Update other input surfaces
3596 for (i = 1; i < layerIndexes.size(); ++i)
3597 {
3598 surfInput = featurePipe.RemoveSurface(true, layerIndexes[i]);
3599 }
3600
3601 auto swFilterSubPipe = featurePipe.GetSwFilterSubPipe(true, layerIndexes[0]);
3602 VP_PUBLIC_CHK_NULL_RETURN(swFilterSubPipe);
3603
3604 VP_SURFACE *output = featurePipe.GetSurface(false, 0);
3605 VP_PUBLIC_CHK_NULL_RETURN(output);
3606
3607 // swFilters will be updated later in Policy::BuildExecuteFilter.
3608 VP_PUBLIC_CHK_STATUS_RETURN(AddCommonFilters(*swFilterSubPipe, input, output));
3609 }
3610 }
3611
3612 return MOS_STATUS_SUCCESS;
3613 }
3614
AddCommonFilters(SwFilterSubPipe & swFilterSubPipe,VP_SURFACE * input,VP_SURFACE * output)3615 MOS_STATUS Policy::AddCommonFilters(SwFilterSubPipe &swFilterSubPipe, VP_SURFACE *input, VP_SURFACE *output)
3616 {
3617 VP_FUNC_CALL();
3618 VP_PUBLIC_CHK_NULL_RETURN(input);
3619 VP_PUBLIC_CHK_NULL_RETURN(output);
3620
3621 MOS_STATUS status = MOS_STATUS_SUCCESS;
3622 FeatureType featureList[] = { FeatureTypeScaling };
3623 int32_t featureCount = sizeof(featureList) / sizeof(featureList[0]);
3624 VP_EXECUTE_CAPS caps = {};
3625
3626 for (int32_t i = 0; i < featureCount; ++i)
3627 {
3628 FeatureType featureType = featureList[i];
3629
3630 SwFilter *swFilter = swFilterSubPipe.GetSwFilter(featureType);
3631 if (nullptr != swFilter)
3632 {
3633 continue;
3634 }
3635
3636 VP_PUBLIC_NORMALMESSAGE("Feature %d is added.", FeatureTypeScaling);
3637
3638 caps.value = 0;
3639
3640 SwFilterFeatureHandler *handler = m_vpInterface.GetSwFilterHandler(featureType);
3641 VP_PUBLIC_CHK_NULL_RETURN(handler);
3642 swFilter = handler->CreateSwFilter();
3643 VP_PUBLIC_CHK_NULL_RETURN(swFilter);
3644
3645 status = swFilter->Configure(input, output, caps);
3646 if (MOS_FAILED(status))
3647 {
3648 handler->Destory(swFilter);
3649 VP_PUBLIC_CHK_STATUS_RETURN(status);
3650 }
3651 status = swFilterSubPipe.AddSwFilterUnordered(swFilter);
3652 if (MOS_FAILED(status))
3653 {
3654 handler->Destory(swFilter);
3655 VP_PUBLIC_CHK_STATUS_RETURN(status);
3656 }
3657 }
3658
3659 return MOS_STATUS_SUCCESS;
3660 }
3661
UpdateExeCaps(SwFilter * feature,VP_EXECUTE_CAPS & caps,EngineType Type)3662 MOS_STATUS Policy::UpdateExeCaps(SwFilter* feature, VP_EXECUTE_CAPS& caps, EngineType Type)
3663 {
3664 VP_FUNC_CALL();
3665 VP_PUBLIC_CHK_NULL_RETURN(feature);
3666
3667 FeatureType featureType = feature->GetFeatureType();
3668
3669 if (Type == EngineTypeVeboxSfc)
3670 {
3671 switch (featureType)
3672 {
3673 case FeatureTypeCsc:
3674 caps.bSfcCsc = 1;
3675 feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(Csc, Sfc)));
3676 break;
3677 case FeatureTypeScaling:
3678 caps.bSfcScaling = 1;
3679 if (feature->GetFilterEngineCaps().sfc2PassScalingNeededX || feature->GetFilterEngineCaps().sfc2PassScalingNeededY)
3680 {
3681 caps.b1stPassOfSfc2PassScaling = true;
3682 }
3683 feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(Scaling, Sfc)));
3684 break;
3685 case FeatureTypeRotMir:
3686 caps.bSfcRotMir = 1;
3687 feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(RotMir, Sfc)));
3688 break;
3689 case FeatureTypeColorFill:
3690 feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(ColorFill, Sfc)));
3691 break;
3692 case FeatureTypeAlpha:
3693 feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(Alpha, Sfc)));
3694 break;
3695 default:
3696 break;
3697 }
3698 }
3699
3700 if (Type == EngineTypeVebox)
3701 {
3702 switch (featureType)
3703 {
3704 case FeatureTypeDn:
3705 caps.bDN = 1;
3706 feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(Dn, Vebox)));
3707 break;
3708 case FeatureTypeSte:
3709 caps.bSTE = 1;
3710 feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(Ste, Vebox)));
3711 break;
3712 case FeatureTypeDi:
3713 caps.bDI = 1;
3714 feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(Di, Vebox)));
3715 break;
3716 case FeatureTypeTcc:
3717 caps.bTCC = 1;
3718 feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(Tcc, Vebox)));
3719 break;
3720 case FeatureTypeProcamp:
3721 if (caps.bForceProcampToRender)
3722 {
3723 caps.bProcamp = 0;
3724 break;
3725 }
3726 caps.bProcamp = 1;
3727 feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(Procamp, Vebox)));
3728 break;
3729 case FeatureTypeCsc:
3730 caps.bBeCSC = 1;
3731 feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(Csc, Vebox)));
3732 break;
3733 case FeatureTypeHdr:
3734 caps.bHDR3DLUT = 1;
3735 caps.b3DlutOutput |= 1;
3736 if (feature->GetFilterEngineCaps().isHdr33LutSizeEnabled)
3737 {
3738 caps.bHdr33lutsize = 1;
3739 }
3740 feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(Hdr, Vebox)));
3741 break;
3742 case FeatureTypeCgc:
3743 caps.bCGC = 1;
3744 feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(Cgc, Vebox)));
3745 VP_PUBLIC_CHK_STATUS_RETURN(UpdateCGCMode(feature, caps, Type));
3746 break;
3747 default:
3748 break;
3749 }
3750 }
3751
3752 if (Type == EngineTypeRender)
3753 {
3754 switch (featureType)
3755 {
3756 case FeatureTypeCsc:
3757 caps.bComposite = caps.bRenderHdr ? 0 : 1;
3758 feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(Csc, Render)));
3759 break;
3760 case FeatureTypeScaling:
3761 caps.bComposite = caps.bRenderHdr ? 0 : 1;
3762 feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(Scaling, Render)));
3763 break;
3764 case FeatureTypeRotMir:
3765 caps.bComposite = caps.bRenderHdr ? 0 : 1;
3766 feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(RotMir, Render)));
3767 break;
3768 case FeatureTypeProcamp:
3769 caps.bComposite = 1;
3770 feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(Procamp, Render)));
3771 break;
3772 case FeatureTypeDi:
3773 caps.bDI = 1;
3774 feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(Di, Render)));
3775 break;
3776 case FeatureTypeLumakey:
3777 caps.bComposite = 1;
3778 feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(Lumakey, Render)));
3779 break;
3780 case FeatureTypeBlending:
3781 caps.bComposite = 1;
3782 feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(Blending, Render)));
3783 break;
3784 case FeatureTypeColorFill:
3785 caps.bComposite = 1;
3786 feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(ColorFill, Render)));
3787 break;
3788 case FeatureTypeAlpha:
3789 caps.bComposite = 1;
3790 feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(Alpha, Render)));
3791 break;
3792 case FeatureTypeHdr:
3793 if (feature->GetFilterEngineCaps().isolated)
3794 {
3795 caps.b3DLutCalc = 1;
3796 if (feature->GetFilterEngineCaps().isHdr33LutSizeEnabled)
3797 {
3798 caps.bHdr33lutsize = 1;
3799 }
3800 feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(Hdr3DLutCal, Render)));
3801 }
3802 else
3803 {
3804 caps.bHdr = 1;
3805 feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(Hdr, Render)));
3806 }
3807 break;
3808 case FeatureTypeDn:
3809 if (feature->GetFilterEngineCaps().isolated)
3810 {
3811 caps.bHVSCalc = 1;
3812 feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(DnHVSCal, Render)));
3813 }
3814 else
3815 {
3816 VP_PUBLIC_ASSERTMESSAGE("DN HVS Kernel has not been enabled in APO path");
3817 }
3818 break;
3819 default:
3820 break;
3821 }
3822
3823 if (caps.bComposite && caps.bRenderHdr)
3824 {
3825 VP_PUBLIC_ASSERTMESSAGE("FC and Render HDR should not be selected at same time.");
3826 VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_INVALID_PARAMETER);
3827 }
3828 }
3829
3830 return MOS_STATUS_SUCCESS;
3831 }
3832
UpdateCGCMode(SwFilter * feature,VP_EXECUTE_CAPS & caps,EngineType Type)3833 MOS_STATUS Policy::UpdateCGCMode(SwFilter* feature, VP_EXECUTE_CAPS& caps, EngineType Type)
3834 {
3835 VP_FUNC_CALL();
3836
3837 VP_PUBLIC_CHK_NULL_RETURN(feature);
3838 SwFilterCgc *cgcFilter = dynamic_cast<SwFilterCgc*>(feature);
3839 VP_PUBLIC_CHK_NULL_RETURN(cgcFilter);
3840
3841 caps.bBt2020ToRGB = (caps.bCGC && cgcFilter->IsBt2020ToRGBEnabled()) ? 1 : 0;
3842
3843 return MOS_STATUS_SUCCESS;
3844 }
3845
AssignExecuteResource(VP_EXECUTE_CAPS & caps,HW_FILTER_PARAMS & params)3846 MOS_STATUS Policy::AssignExecuteResource(VP_EXECUTE_CAPS& caps, HW_FILTER_PARAMS& params)
3847 {
3848 VP_FUNC_CALL();
3849 VP_PUBLIC_CHK_NULL_RETURN(params.executedFilters);
3850 VP_PUBLIC_CHK_NULL_RETURN(m_vpInterface.GetResourceManager());
3851 VP_PUBLIC_CHK_STATUS_RETURN(m_vpInterface.GetResourceManager()->AssignExecuteResource(m_featurePool, caps, *params.executedFilters));
3852 return MOS_STATUS_SUCCESS;
3853 }
3854
BuildVeboxSecureFilters(SwFilterPipe & featurePipe,VP_EXECUTE_CAPS & caps,HW_FILTER_PARAMS & params)3855 MOS_STATUS Policy::BuildVeboxSecureFilters(SwFilterPipe& featurePipe, VP_EXECUTE_CAPS& caps, HW_FILTER_PARAMS& params)
3856 {
3857 VP_FUNC_CALL();
3858
3859 return MOS_STATUS_SUCCESS;
3860 }
3861
ReleaseHwFilterParam(HW_FILTER_PARAMS & params)3862 MOS_STATUS Policy::ReleaseHwFilterParam(HW_FILTER_PARAMS ¶ms)
3863 {
3864 VP_FUNC_CALL();
3865
3866 if (EngineTypeInvalid == params.Type || params.Params.empty())
3867 {
3868 params.Type = EngineTypeInvalid;
3869 while (!params.Params.empty())
3870 {
3871 HwFilterParameter *p = params.Params.back();
3872 params.Params.pop_back();
3873 MOS_Delete(p);
3874 }
3875
3876 m_vpInterface.GetSwFilterPipeFactory().Destory(params.executedFilters);
3877
3878 return MOS_STATUS_SUCCESS;
3879 }
3880
3881 std::map<FeatureType, PolicyFeatureHandler*> &featureHandler =
3882 (EngineTypeVebox == params.Type || EngineTypeVeboxSfc == params.Type) ? m_VeboxSfcFeatureHandlers : m_RenderFeatureHandlers;
3883
3884 params.Type = EngineTypeInvalid;
3885 while (!params.Params.empty())
3886 {
3887 HwFilterParameter *p = params.Params.back();
3888 params.Params.pop_back();
3889 if (p)
3890 {
3891 auto it = featureHandler.find(p->GetFeatureType());
3892 if (featureHandler.end() == it)
3893 {
3894 MOS_Delete(p);
3895 }
3896 else
3897 {
3898 it->second->ReleaseHwFeatureParameter(p);
3899 }
3900 }
3901 }
3902
3903 m_vpInterface.GetSwFilterPipeFactory().Destory(params.executedFilters);
3904
3905 return MOS_STATUS_SUCCESS;
3906 }
3907
AddFiltersBasedOnCaps(SwFilterPipe & featurePipe,uint32_t pipeIndex,VP_EXECUTE_CAPS & caps,SwFilterPipe & executedFilters,uint32_t executedPipeIndex)3908 MOS_STATUS Policy::AddFiltersBasedOnCaps(
3909 SwFilterPipe& featurePipe,
3910 uint32_t pipeIndex,
3911 VP_EXECUTE_CAPS& caps,
3912 SwFilterPipe& executedFilters,
3913 uint32_t executedPipeIndex)
3914 {
3915 VP_FUNC_CALL();
3916
3917 // Create and Add CSC filter for VEBOX IECP chromasiting config
3918 // HDR State holder: To keep same as Legacy path -- for VE 3DLut HDR, enable VE chroma up sampling when ONLY VE output.
3919 if (!caps.bBeCSC && ((caps.bSFC && (caps.bIECP || caps.bDI)) || (!caps.bSFC && (caps.bIECP || caps.b3DlutOutput || caps.bBt2020ToRGB))))
3920 {
3921 VP_PUBLIC_CHK_STATUS_RETURN(AddNewFilterOnVebox(featurePipe, pipeIndex, caps, executedFilters, executedPipeIndex, FeatureTypeCsc));
3922 }
3923 else
3924 {
3925 if (caps.bBeCSC && caps.bHDR3DLUT)
3926 {
3927 // bBeCSC won't be set in GetCSCExecutionCaps for HDR case
3928 VP_PUBLIC_ASSERTMESSAGE("bBeCSC shouldn't be set in GetCSCExecutionCaps for HDR case");
3929 VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_INVALID_PARAMETER);
3930 }
3931 }
3932 return MOS_STATUS_SUCCESS;
3933 }
3934
AddNewFilterOnVebox(SwFilterPipe & featurePipe,uint32_t pipeIndex,VP_EXECUTE_CAPS & caps,SwFilterPipe & executedFilters,uint32_t executedPipeIndex,FeatureType featureType)3935 MOS_STATUS Policy::AddNewFilterOnVebox(
3936 SwFilterPipe& featurePipe,
3937 uint32_t pipeIndex,
3938 VP_EXECUTE_CAPS& caps,
3939 SwFilterPipe& executedFilters,
3940 uint32_t executedPipeIndex,
3941 FeatureType featureType)
3942 {
3943 VP_FUNC_CALL();
3944
3945 MOS_STATUS status = MOS_STATUS_SUCCESS;
3946 PVP_SURFACE pSurfInput = featurePipe.GetSurface(true, pipeIndex);
3947 PVP_SURFACE pSurfOutput = featurePipe.GetSurface(false, 0);
3948 VP_PUBLIC_CHK_NULL_RETURN(pSurfInput);
3949 VP_PUBLIC_CHK_NULL_RETURN(pSurfOutput);
3950
3951 auto handler = m_vpInterface.GetSwFilterHandler(featureType);
3952
3953 if (!handler)
3954 {
3955 VP_PUBLIC_ASSERTMESSAGE("no Feature Handle, Return Pipe Init Error");
3956 return MOS_STATUS_INVALID_HANDLE;
3957 }
3958
3959 SwFilter* swfilter = handler->CreateSwFilter();
3960 VP_PUBLIC_CHK_NULL_RETURN(swfilter);
3961
3962 if (featureType == FeatureTypeCsc)
3963 {
3964 SwFilterCsc *csc = (SwFilterCsc *)swfilter;
3965 FeatureParamCsc cscParams = csc->GetSwFilterParams();
3966 status = GetCscParamsOnCaps(pSurfInput, pSurfOutput, caps, cscParams);
3967 if (MOS_FAILED(status))
3968 {
3969 handler->Destory(swfilter);
3970 VP_PUBLIC_CHK_STATUS_RETURN(status);
3971 }
3972 else
3973 {
3974 status = csc->Configure(cscParams);
3975 }
3976 }
3977 else if (featureType == FeatureTypeDn)
3978 {
3979 SwFilterDenoise *dn = (SwFilterDenoise *)swfilter;
3980 FeatureParamDenoise dnParams = dn->GetSwFilterParams();
3981 status = GetDnParamsOnCaps(pSurfInput, pSurfOutput, caps, dnParams);
3982 if (MOS_FAILED(status))
3983 {
3984 handler->Destory(swfilter);
3985 VP_PUBLIC_CHK_STATUS_RETURN(status);
3986 }
3987 else
3988 {
3989 status = dn->Configure(dnParams);
3990 }
3991 }
3992 else
3993 {
3994 status = swfilter->Configure(pSurfInput, pSurfOutput, caps);
3995 }
3996
3997 if (MOS_FAILED(status))
3998 {
3999 handler->Destory(swfilter);
4000 VP_PUBLIC_CHK_STATUS_RETURN(status);
4001 }
4002
4003 VP_PUBLIC_CHK_STATUS_RETURN(UpdateExeCaps(swfilter, caps, EngineTypeVebox));
4004
4005 status = executedFilters.AddSwFilterUnordered(swfilter, true, executedPipeIndex);
4006 VP_PUBLIC_CHK_STATUS_RETURN(status);
4007
4008 return status;
4009 }
4010
4011 MOS_STATUS GetVeboxOutputParams(VP_EXECUTE_CAPS &executeCaps, MOS_FORMAT inputFormat, MOS_TILE_TYPE inputTileType, MOS_FORMAT outputFormat, MOS_FORMAT &veboxOutputFormat, MOS_TILE_TYPE &veboxOutputTileType, VPHAL_CSPACE colorSpaceOutput);
4012
GetCscParamsOnCaps(PVP_SURFACE surfInput,PVP_SURFACE surfOutput,VP_EXECUTE_CAPS & caps,FeatureParamCsc & cscParams)4013 MOS_STATUS Policy::GetCscParamsOnCaps(PVP_SURFACE surfInput, PVP_SURFACE surfOutput, VP_EXECUTE_CAPS &caps, FeatureParamCsc &cscParams)
4014 {
4015 if (caps.bHDR3DLUT)
4016 {
4017 cscParams.input.colorSpace = surfInput->ColorSpace;
4018 cscParams.formatInput = surfInput->osSurface->Format;
4019 cscParams.formatforCUS = Format_None;
4020 cscParams.input.chromaSiting = surfInput->ChromaSiting;
4021
4022 // CSC before HDR converts BT2020 P010 to ARGB10
4023 cscParams.output.colorSpace = CSpace_BT2020_RGB;
4024 cscParams.formatOutput = Format_B10G10R10A2;
4025 cscParams.output.chromaSiting = surfOutput->ChromaSiting;
4026
4027 cscParams.pAlphaParams = nullptr;
4028 cscParams.pIEFParams = nullptr;
4029
4030 return MOS_STATUS_SUCCESS;
4031 }
4032 else if (caps.bSFC)
4033 {
4034 MOS_FORMAT veboxOutputFormat = surfInput->osSurface->Format;
4035 MOS_TILE_TYPE veboxOutputTileType = surfInput->osSurface->TileType;
4036
4037 GetVeboxOutputParams(caps, surfInput->osSurface->Format, surfInput->osSurface->TileType, surfOutput->osSurface->Format, veboxOutputFormat, veboxOutputTileType, surfOutput->ColorSpace);
4038 cscParams.input.colorSpace = surfInput->ColorSpace;
4039 cscParams.output.colorSpace = surfInput->ColorSpace;
4040
4041 cscParams.formatInput = surfInput->osSurface->Format;
4042 cscParams.formatforCUS = Format_None;
4043 cscParams.formatOutput = veboxOutputFormat;
4044 cscParams.input.chromaSiting = surfInput->ChromaSiting;
4045 cscParams.output.chromaSiting = surfOutput->ChromaSiting;
4046
4047 cscParams.pAlphaParams = nullptr;
4048 cscParams.pIEFParams = nullptr;
4049
4050 return MOS_STATUS_SUCCESS;
4051 }
4052 else if (caps.bBt2020ToRGB || caps.bIECP)
4053 {
4054 // For BeCsc filter added in policy based on caps, it's for chroma-sitting and
4055 // SetVeboxIecpStateBecsc to use.
4056 // For BT2020 to RGB case, the VeboxInterface_BT2020YUVToRGB will be used for BeCsc setting,
4057 // which will overwritten the one by SetVeboxIecpStateBecsc.
4058 // So in GetCscParamsOnCaps for BT2020ToRGB case,
4059 // we just need to use same format and colorspace for both input and output,
4060 // just use the input format to ensure chroma-sitting parameters being correct.
4061 cscParams.input.colorSpace = surfInput->ColorSpace;
4062 cscParams.formatInput = surfInput->osSurface->Format;
4063 cscParams.formatforCUS = Format_None;
4064 cscParams.input.chromaSiting = surfInput->ChromaSiting;
4065
4066 cscParams.output.colorSpace = surfInput->ColorSpace;
4067 cscParams.formatOutput = surfInput->osSurface->Format;
4068 cscParams.output.chromaSiting = surfOutput->ChromaSiting;
4069
4070 cscParams.pAlphaParams = nullptr;
4071 cscParams.pIEFParams = nullptr;
4072
4073 return MOS_STATUS_SUCCESS;
4074 }
4075
4076 return MOS_STATUS_UNIMPLEMENTED;
4077 }
4078
GetDnParamsOnCaps(PVP_SURFACE surfInput,PVP_SURFACE surfOutput,VP_EXECUTE_CAPS & caps,FeatureParamDenoise & dnParams)4079 MOS_STATUS Policy::GetDnParamsOnCaps(PVP_SURFACE surfInput, PVP_SURFACE surfOutput, VP_EXECUTE_CAPS &caps, FeatureParamDenoise &dnParams)
4080 {
4081 dnParams.formatInput = surfInput->osSurface->Format;
4082 dnParams.heightInput = surfInput->osSurface->dwHeight;
4083 dnParams.formatOutput = Format_NV12;
4084 dnParams.sampleTypeInput = SAMPLE_PROGRESSIVE;
4085
4086 dnParams.denoiseParams.bEnableLuma = true;
4087 dnParams.denoiseParams.bEnableChroma = true;
4088 dnParams.denoiseParams.bEnableHVSDenoise = false;
4089 dnParams.denoiseParams.bAutoDetect = false;
4090 dnParams.denoiseParams.fDenoiseFactor = 64.0f;
4091
4092 #if !EMUL
4093 GMM_RESOURCE_INFO *pSrcGmmResInfo = surfInput->osSurface->OsResource.pGmmResInfo;
4094 GMM_RESOURCE_INFO *pTargetGmmResInfo = surfOutput->osSurface->OsResource.pGmmResInfo;
4095 VP_PUBLIC_CHK_NULL_RETURN(pSrcGmmResInfo);
4096 VP_PUBLIC_CHK_NULL_RETURN(pTargetGmmResInfo);
4097
4098 bool inputProtected = pSrcGmmResInfo->GetSetCpSurfTag(0, 0);
4099 bool outputProtected = pTargetGmmResInfo->GetSetCpSurfTag(0, 0);
4100
4101 if (inputProtected || outputProtected ||
4102 (m_vpInterface.GetHwInterface()->m_osInterface->osCpInterface &&
4103 m_vpInterface.GetHwInterface()->m_osInterface->osCpInterface->IsHMEnabled()))
4104 {
4105 dnParams.secureDnNeeded = true;
4106 }
4107 #endif
4108
4109 return MOS_STATUS_SUCCESS;
4110 }
4111
PrintFeatureExecutionCaps(const char * name,VP_EngineEntry & engineCaps)4112 void Policy::PrintFeatureExecutionCaps(const char *name, VP_EngineEntry &engineCaps)
4113 {
4114 VP_PUBLIC_NORMALMESSAGE("%s, value 0x%x (bEnabled %d, VeboxNeeded %d, SfcNeeded %d, RenderNeeded %d, fcSupported %d, isolated %d, veboxNotSupported %d, sfcNotSupported %d)",
4115 name, engineCaps.value, engineCaps.bEnabled, engineCaps.VeboxNeeded, engineCaps.SfcNeeded,
4116 engineCaps.RenderNeeded, engineCaps.fcSupported, engineCaps.isolated, engineCaps.veboxNotSupported, engineCaps.sfcNotSupported);
4117 }
4118
4119 };
4120