xref: /aosp_15_r20/external/intel-media-driver/media_softlet/agnostic/common/vp/hal/feature_manager/policy.cpp (revision ba62d9d3abf0e404f2022b4cd7a85e107f48596f)
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 &params      = 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 &params)
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