1 /*
2 * Copyright (c) 2019-2021, 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_user_feature_control.h"
35 
36 using namespace vp;
37 
38 /****************************************************************************************************/
39 /*                                      Policy                                                      */
40 /****************************************************************************************************/
41 
Policy(VpInterface & vpInterface)42 Policy::Policy(VpInterface &vpInterface) : m_vpInterface(vpInterface)
43 {
44 }
45 
~Policy()46 Policy::~Policy()
47 {
48     UnregisterFeatures();
49 }
50 
Initialize()51 MOS_STATUS Policy::Initialize()
52 {
53     VP_FUNC_CALL();
54 
55     VpPlatformInterface *vpPlatformInterface = (VpPlatformInterface *)m_vpInterface.GetHwInterface()->m_vpPlatformInterface;
56     VP_PUBLIC_CHK_NULL_RETURN(vpPlatformInterface);
57     VP_PUBLIC_CHK_STATUS_RETURN(vpPlatformInterface->InitVpHwCaps(m_hwCaps));
58     VP_PUBLIC_CHK_STATUS_RETURN(RegisterFeatures());
59     m_initialized = true;
60     return MOS_STATUS_SUCCESS;
61 }
62 
IsVeboxSfcFormatSupported(MOS_FORMAT formatInput,MOS_FORMAT formatOutput)63 bool Policy::IsVeboxSfcFormatSupported(MOS_FORMAT  formatInput, MOS_FORMAT formatOutput)
64 {
65     VP_FUNC_CALL();
66 
67     if (!m_initialized)
68     {
69         return false;
70     }
71     if (m_hwCaps.m_sfcHwEntry[formatInput].inputSupported   &&
72         m_hwCaps.m_sfcHwEntry[formatOutput].outputSupported)
73     {
74         return true;
75     }
76     else
77     {
78         return false;
79     }
80 }
81 
IsAlphaEnabled(FeatureParamScaling * scalingParams)82 bool Policy::IsAlphaEnabled(FeatureParamScaling* scalingParams)
83 {
84     VP_FUNC_CALL();
85 
86     if (scalingParams == nullptr)
87     {
88         return false;
89     }
90 
91     return scalingParams->pCompAlpha != nullptr;
92 }
93 
IsColorfillEnabled(FeatureParamScaling * scalingParams)94 bool Policy::IsColorfillEnabled(FeatureParamScaling* scalingParams)
95 {
96     VP_FUNC_CALL();
97 
98     if (scalingParams == nullptr)
99     {
100         return false;
101     }
102 
103     bool isColorFill = false;
104     isColorFill      = (scalingParams->pColorFillParams &&
105                      (!scalingParams->pColorFillParams->bDisableColorfillinSFC) &&
106                      (scalingParams->pColorFillParams->bOnePixelBiasinSFC ?
107                      (!RECT1_CONTAINS_RECT2_ONEPIXELBIAS(scalingParams->input.rcDst, scalingParams->output.rcDst)):
108                      (!RECT1_CONTAINS_RECT2(scalingParams->input.rcDst, scalingParams->output.rcDst))))
109                      ? true
110                      : false;
111 
112     return isColorFill;
113 }
114 
RegisterFeatures()115 MOS_STATUS Policy::RegisterFeatures()
116 {
117     VP_FUNC_CALL();
118 
119     UnregisterFeatures();
120 
121     // Vebox/Sfc features.
122     PolicyFeatureHandler *p = MOS_New(PolicySfcCscHandler, m_hwCaps);
123     VP_PUBLIC_CHK_NULL_RETURN(p);
124     m_VeboxSfcFeatureHandlers.insert(std::make_pair(FeatureTypeCscOnSfc, p));
125 
126     p = MOS_New(PolicySfcRotMirHandler, m_hwCaps);
127     VP_PUBLIC_CHK_NULL_RETURN(p);
128     m_VeboxSfcFeatureHandlers.insert(std::make_pair(FeatureTypeRotMirOnSfc, p));
129 
130     p = MOS_New(PolicySfcScalingHandler, m_hwCaps);
131     VP_PUBLIC_CHK_NULL_RETURN(p);
132     m_VeboxSfcFeatureHandlers.insert(std::make_pair(FeatureTypeScalingOnSfc, p));
133 
134     p = MOS_New(PolicyVeboxDnHandler, m_hwCaps);
135     VP_PUBLIC_CHK_NULL_RETURN(p);
136     m_VeboxSfcFeatureHandlers.insert(std::make_pair(FeatureTypeDnOnVebox, p));
137 
138     p = MOS_New(PolicyVeboxCscHandler, m_hwCaps);
139     VP_PUBLIC_CHK_NULL_RETURN(p);
140     m_VeboxSfcFeatureHandlers.insert(std::make_pair(FeatureTypeCscOnVebox, p));
141 
142     p = MOS_New(PolicyVeboxSteHandler, m_hwCaps);
143     VP_PUBLIC_CHK_NULL_RETURN(p);
144     m_VeboxSfcFeatureHandlers.insert(std::make_pair(FeatureTypeSteOnVebox, p));
145 
146     p = MOS_New(PolicyVeboxTccHandler, m_hwCaps);
147     VP_PUBLIC_CHK_NULL_RETURN(p);
148     m_VeboxSfcFeatureHandlers.insert(std::make_pair(FeatureTypeTccOnVebox, p));
149 
150     p = MOS_New(PolicyVeboxProcampHandler, m_hwCaps);
151     VP_PUBLIC_CHK_NULL_RETURN(p);
152     m_VeboxSfcFeatureHandlers.insert(std::make_pair(FeatureTypeProcampOnVebox, p));
153 
154     p = MOS_New(PolicyVeboxHdrHandler, m_hwCaps);
155     VP_PUBLIC_CHK_NULL_RETURN(p);
156     m_VeboxSfcFeatureHandlers.insert(std::make_pair(FeatureTypeHdrOnVebox, p));
157 
158     p = MOS_New(PolicyDiHandler, m_hwCaps);
159     VP_PUBLIC_CHK_NULL_RETURN(p);
160     m_VeboxSfcFeatureHandlers.insert(std::make_pair(FeatureTypeDiOnVebox, p));
161 
162     p = MOS_New(PolicySfcColorFillHandler, m_hwCaps);
163     VP_PUBLIC_CHK_NULL_RETURN(p);
164     m_VeboxSfcFeatureHandlers.insert(std::make_pair(FeatureTypeColorFillOnSfc, p));
165 
166     p = MOS_New(PolicySfcAlphaHandler, m_hwCaps);
167     VP_PUBLIC_CHK_NULL_RETURN(p);
168     m_VeboxSfcFeatureHandlers.insert(std::make_pair(FeatureTypeAlphaOnSfc, p));
169 
170     p = MOS_New(PolicyDiHandler, m_hwCaps);
171     VP_PUBLIC_CHK_NULL_RETURN(p);
172     m_RenderFeatureHandlers.insert(std::make_pair(FeatureTypeDiFmdOnRender, p));
173 
174     p = MOS_New(PolicyFcHandler, m_hwCaps);
175     VP_PUBLIC_CHK_NULL_RETURN(p);
176     m_RenderFeatureHandlers.insert(std::make_pair(FeatureTypeFcOnRender, p));
177 
178     p = MOS_New(PolicyFcFeatureHandler, m_hwCaps);
179     VP_PUBLIC_CHK_NULL_RETURN(p);
180     m_RenderFeatureHandlers.insert(std::make_pair(FeatureTypeLumakeyOnRender, p));
181 
182     p = MOS_New(PolicyFcFeatureHandler, m_hwCaps);
183     VP_PUBLIC_CHK_NULL_RETURN(p);
184     m_RenderFeatureHandlers.insert(std::make_pair(FeatureTypeBlendingOnRender, p));
185 
186     p = MOS_New(PolicyFcFeatureHandler, m_hwCaps);
187     VP_PUBLIC_CHK_NULL_RETURN(p);
188     m_RenderFeatureHandlers.insert(std::make_pair(FeatureTypeColorFillOnRender, p));
189 
190     p = MOS_New(PolicyFcFeatureHandler, m_hwCaps);
191     VP_PUBLIC_CHK_NULL_RETURN(p);
192     m_RenderFeatureHandlers.insert(std::make_pair(FeatureTypeAlphaOnRender, p));
193 
194     p = MOS_New(PolicyFcFeatureHandler, m_hwCaps);
195     VP_PUBLIC_CHK_NULL_RETURN(p);
196     m_RenderFeatureHandlers.insert(std::make_pair(FeatureTypeCscOnRender, p));
197 
198     p = MOS_New(PolicyFcFeatureHandler, m_hwCaps);
199     VP_PUBLIC_CHK_NULL_RETURN(p);
200     m_RenderFeatureHandlers.insert(std::make_pair(FeatureTypeScalingOnRender, p));
201 
202     p = MOS_New(PolicyFcFeatureHandler, m_hwCaps);
203     VP_PUBLIC_CHK_NULL_RETURN(p);
204     m_RenderFeatureHandlers.insert(std::make_pair(FeatureTypeRotMirOnRender, p));
205 
206     p = MOS_New(PolicyFcFeatureHandler, m_hwCaps);
207     VP_PUBLIC_CHK_NULL_RETURN(p);
208     m_RenderFeatureHandlers.insert(std::make_pair(FeatureTypeDiOnRender, p));
209 
210     // Next step to add a table to trace all SW features based on platforms
211     m_featurePool.push_back(FeatureTypeCsc);
212     m_featurePool.push_back(FeatureTypeScaling);
213     m_featurePool.push_back(FeatureTypeRotMir);
214     m_featurePool.push_back(FeatureTypeDn);
215     m_featurePool.push_back(FeatureTypeSte);
216     m_featurePool.push_back(FeatureTypeTcc);
217     m_featurePool.push_back(FeatureTypeProcamp);
218     m_featurePool.push_back(FeatureTypeHdr);
219     m_featurePool.push_back(FeatureTypeDi);
220     m_featurePool.push_back(FeatureTypeFc);
221     m_featurePool.push_back(FeatureTypeLumakey);
222     m_featurePool.push_back(FeatureTypeBlending);
223     m_featurePool.push_back(FeatureTypeColorFill);
224     m_featurePool.push_back(FeatureTypeAlpha);
225 
226     return MOS_STATUS_SUCCESS;
227 }
228 
UnregisterFeatures()229 void Policy::UnregisterFeatures()
230 {
231     while (!m_VeboxSfcFeatureHandlers.empty())
232     {
233         std::map<FeatureType, PolicyFeatureHandler*>::iterator it = m_VeboxSfcFeatureHandlers.begin();
234         MOS_Delete(it->second);
235         m_VeboxSfcFeatureHandlers.erase(it);
236     }
237 
238     while (!m_RenderFeatureHandlers.empty())
239     {
240         std::map<FeatureType, PolicyFeatureHandler*>::iterator it = m_RenderFeatureHandlers.begin();
241         MOS_Delete(it->second);
242         m_RenderFeatureHandlers.erase(it);
243     }
244 
245     m_featurePool.clear();
246 }
247 
248 /*                                    Enable SwFilterPipe                                           */
249 
CreateHwFilter(SwFilterPipe & subSwFilterPipe,HwFilter * & pFilter)250 MOS_STATUS Policy::CreateHwFilter(SwFilterPipe &subSwFilterPipe, HwFilter *&pFilter)
251 {
252     VP_FUNC_CALL();
253 
254     if (subSwFilterPipe.IsEmpty())
255     {
256         pFilter = nullptr;
257         return MOS_STATUS_SUCCESS;
258     }
259 
260     HW_FILTER_PARAMS param = {};
261 
262     MOS_STATUS status = GetHwFilterParam(subSwFilterPipe, param);
263 
264     if (MOS_FAILED(status))
265     {
266         VP_PUBLIC_ASSERTMESSAGE("Create HW Filter Failed, Return Error");
267         MT_ERR2(MT_VP_HAL_POLICY, MT_ERROR_CODE, status, MT_CODE_LINE, __LINE__);
268         return status;
269     }
270 
271     pFilter = m_vpInterface.GetHwFilterFactory().Create(param);
272 
273     ReleaseHwFilterParam(param);
274 
275     if (!pFilter)
276     {
277         VP_PUBLIC_ASSERTMESSAGE("Create HW Filter Failed, Return Error");
278         MT_ERR2(MT_VP_HAL_POLICY, MT_ERROR_CODE, MOS_STATUS_UNIMPLEMENTED, MT_CODE_LINE, __LINE__);
279         return MOS_STATUS_UNIMPLEMENTED;
280     }
281 
282     return MOS_STATUS_SUCCESS;
283 }
284 
GetHwFilterParam(SwFilterPipe & subSwFilterPipe,HW_FILTER_PARAMS & params)285 MOS_STATUS Policy::GetHwFilterParam(SwFilterPipe& subSwFilterPipe, HW_FILTER_PARAMS& params)
286 {
287     VP_FUNC_CALL();
288 
289     MOS_STATUS status = MOS_STATUS_SUCCESS;
290 
291     params.Type = EngineTypeInvalid;
292 
293     // Create and clear executedFilters.
294     if (params.executedFilters)
295     {
296         params.executedFilters->Clean();
297     }
298     else
299     {
300         status = m_vpInterface.GetSwFilterPipeFactory().Create(params.executedFilters);
301 
302         if (status != MOS_STATUS_SUCCESS)
303         {
304             m_vpInterface.GetSwFilterPipeFactory().Destory(params.executedFilters);
305             VP_PUBLIC_ASSERTMESSAGE("Create Executed Filter Failed, Return Error");
306             MT_ERR2(MT_VP_HAL_POLICY, MT_ERROR_CODE, status, MT_CODE_LINE, __LINE__);
307             return status;
308         }
309     }
310 
311     params.executedFilters->SetExePipeFlag(true);
312 
313     status = GetExecuteCaps(subSwFilterPipe, params);
314 
315     if (status != MOS_STATUS_SUCCESS)
316     {
317         m_vpInterface.GetSwFilterPipeFactory().Destory(params.executedFilters);
318         VP_PUBLIC_ASSERTMESSAGE("Create Executed 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     return MOS_STATUS_SUCCESS;
324 }
325 
GetExecuteCaps(SwFilterPipe & subSwFilterPipe,HW_FILTER_PARAMS & params)326 MOS_STATUS Policy::GetExecuteCaps(SwFilterPipe& subSwFilterPipe, HW_FILTER_PARAMS& params)
327 {
328     VP_FUNC_CALL();
329 
330     VP_EXECUTE_CAPS  caps = {};
331     SwFilterSubPipe* pipe = nullptr;
332     uint32_t index = 0;
333 
334     VP_PUBLIC_NORMALMESSAGE("Only Support primary layer for advanced processing");
335 
336     uint32_t inputSurfCount     = subSwFilterPipe.GetSurfaceCount(true);
337     uint32_t outputSurfCount    = subSwFilterPipe.GetSurfaceCount(false);
338 
339     for (index = 0; index < inputSurfCount; ++index)
340     {
341         VP_PUBLIC_CHK_STATUS_RETURN(BuildExecutionEngines(subSwFilterPipe, true, index));
342     }
343 
344     for (index = 0; index < outputSurfCount; ++index)
345     {
346         VP_PUBLIC_CHK_STATUS_RETURN(BuildExecutionEngines(subSwFilterPipe, false, index));
347     }
348 
349     VP_PUBLIC_CHK_STATUS_RETURN(BuildFilters(subSwFilterPipe, params));
350 
351     return MOS_STATUS_SUCCESS;
352 }
353 
GetExecutionCapsForSingleFeature(FeatureType featureType,SwFilterSubPipe & swFilterPipe)354 MOS_STATUS Policy::GetExecutionCapsForSingleFeature(FeatureType featureType, SwFilterSubPipe& swFilterPipe)
355 {
356     VP_FUNC_CALL();
357 
358     SwFilter* feature = swFilterPipe.GetSwFilter(featureType);
359     SwFilter* diFilter = nullptr;
360 
361     if (!feature)
362     {
363         VP_PUBLIC_NORMALMESSAGE("Feature %d is not enabled in current pipe", featureType);
364         return MOS_STATUS_SUCCESS;
365     }
366     else
367     {
368         VP_PUBLIC_NORMALMESSAGE("Feature %d is enabled in current pipe", featureType);
369     }
370 
371     // Always clean engine caps before Query. For next step, need to add new caps variable in swFilter
372     // for forcing engine case.
373     // feature->GetFilterEngineCaps().value = 0;
374 
375     switch (featureType)
376     {
377     case FeatureTypeCsc:
378         diFilter = swFilterPipe.GetSwFilter(FeatureTypeDi);
379         if (diFilter)
380         {
381             VP_PUBLIC_CHK_STATUS_RETURN(GetDeinterlaceExecutionCaps(diFilter));
382 
383             VP_EngineEntry *diEngine = &diFilter->GetFilterEngineCaps();
384             if (diEngine->bEnabled && diEngine->VeboxNeeded)
385             {
386                 VP_PUBLIC_CHK_STATUS_RETURN(GetCSCExecutionCapsDi(feature));
387             }
388             else
389             {
390                 VP_PUBLIC_CHK_STATUS_RETURN(GetCSCExecutionCaps(feature));
391             }
392         }
393         else
394         {
395             VP_PUBLIC_CHK_STATUS_RETURN(GetCSCExecutionCaps(feature));
396         }
397         break;
398     case FeatureTypeScaling:
399         VP_PUBLIC_CHK_STATUS_RETURN(GetScalingExecutionCaps(feature));
400         break;
401     case FeatureTypeRotMir:
402         VP_PUBLIC_CHK_STATUS_RETURN(GetRotationExecutionCaps(feature));
403         break;
404     case FeatureTypeDn:
405         VP_PUBLIC_CHK_STATUS_RETURN(GetDenoiseExecutionCaps(feature));
406         break;
407     case FeatureTypeSte:
408         VP_PUBLIC_CHK_STATUS_RETURN(GetSteExecutionCaps(feature));
409         break;
410     case FeatureTypeTcc:
411         VP_PUBLIC_CHK_STATUS_RETURN(GetTccExecutionCaps(feature));
412         break;
413     case FeatureTypeProcamp:
414         VP_PUBLIC_CHK_STATUS_RETURN(GetProcampExecutionCaps(feature));
415         break;
416     case FeatureTypeHdr:
417         VP_PUBLIC_CHK_STATUS_RETURN(GetHdrExecutionCaps(feature));
418         break;
419     case FeatureTypeDi:
420         VP_PUBLIC_CHK_STATUS_RETURN(GetDeinterlaceExecutionCaps(feature));
421         break;
422     case FeatureTypeLumakey:
423         VP_PUBLIC_CHK_STATUS_RETURN(GetLumakeyExecutionCaps(feature));
424         break;
425     case FeatureTypeBlending:
426         VP_PUBLIC_CHK_STATUS_RETURN(GetBlendingExecutionCaps(feature));
427         break;
428     case FeatureTypeColorFill:
429         VP_PUBLIC_CHK_STATUS_RETURN(GetColorFillExecutionCaps(feature));
430         break;
431     case FeatureTypeAlpha:
432         VP_PUBLIC_CHK_STATUS_RETURN(GetAlphaExecutionCaps(feature));
433         break;
434     default:
435         VP_PUBLIC_CHK_STATUS_RETURN(GetExecutionCaps(feature));
436         VP_PUBLIC_ASSERTMESSAGE("Feature is not supported by driver, bypass it");
437         break;
438     }
439 
440     VP_EngineEntry& engineCaps = feature->GetFilterEngineCaps();
441 
442     if (engineCaps.value == 0)
443     {
444         // Return success after all feature enabled and fully switched to APO path.
445         VP_PUBLIC_NORMALMESSAGE("No engine being assigned for feature %d. Will bypass it.", featureType);
446     }
447 
448     MT_LOG7(MT_VP_HAL_POLICY_GET_EXTCAPS4FTR, MT_NORMAL, MT_VP_HAL_FEATUERTYPE, featureType,
449         MT_VP_HAL_ENGINECAPS, engineCaps.value, MT_VP_HAL_ENGINECAPS_EN, engineCaps.bEnabled, MT_VP_HAL_ENGINECAPS_VE_NEEDED,
450         engineCaps.VeboxNeeded, MT_VP_HAL_ENGINECAPS_SFC_NEEDED, engineCaps.SfcNeeded, MT_VP_HAL_ENGINECAPS_RENDER_NEEDED, engineCaps.RenderNeeded,
451         MT_VP_HAL_ENGINECAPS_FC_SUPPORT, engineCaps.fcSupported);
452 
453     return MOS_STATUS_SUCCESS;
454 }
455 
BuildExecutionEngines(SwFilterPipe & swFilterPipe,bool isInputPipe,uint32_t index)456 MOS_STATUS Policy::BuildExecutionEngines(SwFilterPipe &swFilterPipe, bool isInputPipe, uint32_t index)
457 {
458     VP_FUNC_CALL();
459 
460     SwFilterSubPipe *pipe    = nullptr;
461     SwFilter *       feature = nullptr;
462     pipe                     = swFilterPipe.GetSwFilterSubPipe(isInputPipe, index);
463 
464     VP_PUBLIC_NORMALMESSAGE("isInputPipe %d, index %d", (isInputPipe ? 1 : 0), index);
465 
466     if (pipe)
467     {
468         for (auto filterID : m_featurePool)
469         {
470             VP_PUBLIC_CHK_STATUS_RETURN(GetExecutionCapsForSingleFeature(filterID, *pipe));
471         }
472         VP_PUBLIC_CHK_STATUS_RETURN(FilterFeatureCombination(swFilterPipe, isInputPipe, index));
473     }
474     return MOS_STATUS_SUCCESS;
475 }
476 
GetCSCExecutionCapsHdr(SwFilter * HDR,SwFilter * CSC)477 MOS_STATUS Policy::GetCSCExecutionCapsHdr(SwFilter *HDR, SwFilter *CSC)
478 {
479     VP_FUNC_CALL();
480 
481     SwFilterHdr     *hdr       = nullptr;
482     SwFilterCsc     *csc       = nullptr;
483     FeatureParamHdr *hdrParams = nullptr;
484     FeatureParamCsc *cscParams = nullptr;
485     VP_EngineEntry  *cscEngine = nullptr;
486 
487     VP_PUBLIC_CHK_NULL_RETURN(HDR);
488     VP_PUBLIC_CHK_NULL_RETURN(CSC);
489     hdr = (SwFilterHdr *)HDR;
490     csc = (SwFilterCsc *)CSC;
491 
492     hdrParams = &hdr->GetSwFilterParams();
493     cscParams = &csc->GetSwFilterParams();
494     cscEngine = &csc->GetFilterEngineCaps();
495     //HDR CSC processing
496     if (!hdrParams || hdrParams->hdrMode == VPHAL_HDR_MODE_NONE)
497     {
498         VP_PUBLIC_ASSERTMESSAGE("HDR Mode is NONE");
499         VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_INVALID_PARAMETER);
500     }
501 
502     MOS_FORMAT   hdrFormat  = Format_Any;
503     VPHAL_CSPACE hdrCSpace  = CSpace_Any;
504     hdrCSpace               = IS_COLOR_SPACE_BT2020(cscParams->output.colorSpace) ? CSpace_BT2020_RGB : CSpace_sRGB;
505     hdrFormat               = IS_COLOR_SPACE_BT2020(cscParams->output.colorSpace) ? Format_R10G10B10A2 : Format_A8R8G8B8;
506     if (m_hwCaps.m_sfcHwEntry[hdrFormat].inputSupported &&
507         m_hwCaps.m_sfcHwEntry[cscParams->formatOutput].outputSupported &&
508         m_hwCaps.m_sfcHwEntry[hdrFormat].cscSupported)
509     {
510 
511         if (hdrFormat == cscParams->formatOutput && hdrCSpace == cscParams->output.colorSpace)
512         {
513             VP_PUBLIC_NORMALMESSAGE("Skip CSC for HDR case.");
514             cscEngine->forceEnableForSfc = 1;
515         }
516         else
517         {
518             cscEngine->bEnabled     = 1;
519             cscEngine->SfcNeeded    = 1;
520         }
521     }
522     else
523     {
524         VP_PUBLIC_ASSERTMESSAGE("Post CSC for HDR not supported by SFC");
525         return MOS_STATUS_INVALID_PARAMETER;
526     }
527 
528     return MOS_STATUS_SUCCESS;
529 }
530 
GetCSCExecutionCapsDi(SwFilter * feature)531 MOS_STATUS Policy::GetCSCExecutionCapsDi(SwFilter* feature)
532 {
533     VP_FUNC_CALL();
534 
535     VP_PUBLIC_CHK_NULL_RETURN(feature);
536 
537     SwFilterCsc* csc = dynamic_cast<SwFilterCsc*>(feature);
538     VP_PUBLIC_CHK_NULL_RETURN(csc);
539 
540     VP_PUBLIC_CHK_STATUS_RETURN(GetCSCExecutionCaps(feature));
541 
542     VP_EngineEntry *cscEngine = &csc->GetFilterEngineCaps();
543     VP_PUBLIC_CHK_NULL_RETURN(cscEngine);
544     if ((cscEngine->bEnabled && (cscEngine->SfcNeeded || cscEngine->VeboxNeeded)) ||
545         !cscEngine->bEnabled && cscEngine->forceEnableForSfc)
546     {
547         cscEngine->bEnabled     = 1;
548         cscEngine->SfcNeeded    = 1;
549         cscEngine->VeboxNeeded  = 0;
550         cscEngine->RenderNeeded = 0;
551     }
552     return MOS_STATUS_SUCCESS;
553 }
554 
GetCSCExecutionCaps(SwFilter * feature)555 MOS_STATUS Policy::GetCSCExecutionCaps(SwFilter* feature)
556 {
557     VP_FUNC_CALL();
558     VP_PUBLIC_CHK_NULL_RETURN(feature);
559     VP_PUBLIC_CHK_NULL_RETURN(m_vpInterface.GetHwInterface());
560     VP_PUBLIC_CHK_NULL_RETURN(m_vpInterface.GetHwInterface()->m_userFeatureControl);
561 
562     auto userFeatureControl = m_vpInterface.GetHwInterface()->m_userFeatureControl;
563     bool disableVeboxOutput = userFeatureControl->IsVeboxOutputDisabled();
564     bool disableSfc = userFeatureControl->IsSfcDisabled();
565 
566     SwFilterCsc* csc = (SwFilterCsc*)feature;
567 
568     FeatureParamCsc *cscParams = &csc->GetSwFilterParams();
569 
570     MOS_FORMAT midFormat = Format_Any;
571 
572     VP_EngineEntry *cscEngine = &csc->GetFilterEngineCaps();
573 
574     if (cscEngine->value != 0)
575     {
576         VP_PUBLIC_NORMALMESSAGE("CSC Feature Already been processed, Skip further process");
577         // Clean usedForNextPass flag.
578         if (cscEngine->usedForNextPass)
579         {
580             cscEngine->usedForNextPass = false;
581         }
582         PrintFeatureExecutionCaps(__FUNCTION__, *cscEngine);
583         return MOS_STATUS_SUCCESS;
584     }
585 
586     if (cscParams->formatInput          == cscParams->formatOutput          &&
587         cscParams->input.colorSpace     == cscParams->output.colorSpace     &&
588         cscParams->input.chromaSiting   == cscParams->output.chromaSiting   &&
589         nullptr                         == cscParams->pIEFParams)
590     {
591         bool veboxSupported = m_hwCaps.m_veboxHwEntry[cscParams->formatInput].inputSupported;
592         bool sfcSupported = veboxSupported && m_hwCaps.m_sfcHwEntry[cscParams->formatInput].inputSupported;
593 
594         if (!veboxSupported)
595         {
596             VP_PUBLIC_NORMALMESSAGE("Format %d not supported by vebox. Force to render.", cscParams->formatInput);
597             cscEngine->bEnabled     = 1;
598             cscEngine->SfcNeeded    = 0;
599             cscEngine->VeboxNeeded  = 0;
600             cscEngine->RenderNeeded = 1;
601             cscEngine->fcSupported  = 1;
602             cscEngine->sfcNotSupported = 1;
603         }
604         else if (disableVeboxOutput)
605         {
606             VP_PUBLIC_NORMALMESSAGE("Non-csc cases. Still keep csc filter to avoid output from vebox.");
607             cscEngine->bEnabled             = 1;
608             cscEngine->SfcNeeded            = (disableSfc || !sfcSupported) ? 0 : 1;
609             cscEngine->VeboxNeeded          = 0;
610             cscEngine->RenderNeeded         = 1;
611             cscEngine->fcSupported          = 1;
612         }
613         else
614         {
615             // for non-csc cases, all engine supported
616             cscEngine->bEnabled             = 0;
617             cscEngine->SfcNeeded            = 0;
618             cscEngine->VeboxNeeded          = 0;
619             cscEngine->RenderNeeded         = 0;
620             if (sfcSupported)
621             {
622                 cscEngine->forceEnableForSfc = 1;
623             }
624             else
625             {
626                 cscEngine->sfcNotSupported = 1;
627             }
628         }
629 
630         PrintFeatureExecutionCaps(__FUNCTION__, *cscEngine);
631         return MOS_STATUS_SUCCESS;
632     }
633 
634     if (IS_COLOR_SPACE_BT2020_YUV(cscParams->input.colorSpace))
635     {
636         if ((cscParams->output.colorSpace == CSpace_BT601)              ||
637             (cscParams->output.colorSpace == CSpace_BT709)              ||
638             (cscParams->output.colorSpace == CSpace_BT601_FullRange)    ||
639             (cscParams->output.colorSpace == CSpace_BT709_FullRange)    ||
640             (cscParams->output.colorSpace == CSpace_stRGB)              ||
641             (cscParams->output.colorSpace == CSpace_sRGB))
642         {
643             midFormat = Format_A8R8G8B8; // Vebox Gamut compression is needed, Vebox output is ARGB as SFC input
644         }
645         else
646         {
647             midFormat = Format_Any;
648         }
649     }
650 
651     if (midFormat != Format_Any)
652     {
653         if (m_hwCaps.m_sfcHwEntry[midFormat].cscSupported &&
654             m_hwCaps.m_sfcHwEntry[cscParams->formatOutput].outputSupported &&
655             m_hwCaps.m_sfcHwEntry[midFormat].inputSupported)
656         {
657             // Vebox GC + SFC CSC to handle legacy 2 pass CSC case.
658             cscEngine->bEnabled    = 1;
659             cscEngine->SfcNeeded   = 1;
660             cscEngine->VeboxNeeded = 0;
661             if (disableSfc)
662             {
663                 VP_PUBLIC_ASSERTMESSAGE("Not support 2 pass csc case for render.");
664             }
665             PrintFeatureExecutionCaps(__FUNCTION__, *cscEngine);
666             return MOS_STATUS_SUCCESS;
667         }
668         else
669         {
670             PrintFeatureExecutionCaps(__FUNCTION__, *cscEngine);
671             VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_INVALID_PARAMETER);
672         }
673     }
674 
675     cscEngine->bEnabled     = 1;
676     cscEngine->RenderNeeded = 1;
677     cscEngine->fcSupported  = 1;
678 
679     // SFC CSC enabling check
680     if (!disableSfc                                                    &&
681         m_hwCaps.m_sfcHwEntry[cscParams->formatInput].inputSupported   &&
682         m_hwCaps.m_sfcHwEntry[cscParams->formatOutput].outputSupported &&
683         m_hwCaps.m_sfcHwEntry[cscParams->formatInput].cscSupported)
684     {
685         cscEngine->SfcNeeded = 1;
686     }
687 
688     if (disableVeboxOutput)
689     {
690         // If vebox output disabled, then such mega feature like CSC will not take effect in Vebox.
691         // then CSC will must be assign to SFC/Render path for execution.
692         VP_PUBLIC_NORMALMESSAGE("Force to use sfc or render for csc.");
693     }
694     else
695     {
696         if (!cscParams->pIEFParams                                                   &&
697            (!cscParams->pAlphaParams                                                 ||
698              cscParams->pAlphaParams->AlphaMode != VPHAL_ALPHA_FILL_MODE_BACKGROUND) &&
699             m_hwCaps.m_veboxHwEntry[cscParams->formatInput].inputSupported                    &&
700             m_hwCaps.m_veboxHwEntry[cscParams->formatOutput].outputSupported                  &&
701             m_hwCaps.m_veboxHwEntry[cscParams->formatInput].iecp                              &&
702             m_hwCaps.m_veboxHwEntry[cscParams->formatInput].backEndCscSupported)
703         {
704             cscEngine->VeboxNeeded = 1;
705         }
706     }
707 
708     PrintFeatureExecutionCaps(__FUNCTION__, *cscEngine);
709     return MOS_STATUS_SUCCESS;
710 }
711 
GetScalingExecutionCaps(SwFilter * feature)712 MOS_STATUS Policy::GetScalingExecutionCaps(SwFilter* feature)
713 {
714     VP_FUNC_CALL();
715 
716     uint32_t dwSurfaceWidth = 0, dwSurfaceHeight = 0;
717     uint32_t dwOutputSurfaceWidth = 0, dwOutputSurfaceHeight = 0;
718     uint32_t veboxMinWidth = 0, veboxMaxWidth = 0;
719     uint32_t veboxMinHeight = 0, veboxMaxHeight = 0;
720     uint32_t dwSfcMinWidth = 0, dwSfcMaxWidth = 0;
721     uint32_t dwSfcMinHeight = 0, dwSfcMaxHeight = 0;
722     uint32_t dwDstMinHeight = 0;
723     float    fScaleMin = 0, fScaleMax = 0;
724     float    fScaleMin2Pass = 0, fScaleMax2Pass = 0;
725     float    fScaleX = 0, fScaleY = 0;
726 
727     VP_PUBLIC_CHK_NULL_RETURN(feature);
728     VP_PUBLIC_CHK_NULL_RETURN(m_vpInterface.GetHwInterface());
729     VP_PUBLIC_CHK_NULL_RETURN(m_vpInterface.GetHwInterface()->m_userFeatureControl);
730 
731     auto userFeatureControl = m_vpInterface.GetHwInterface()->m_userFeatureControl;
732     bool disableSfc = userFeatureControl->IsSfcDisabled();
733     SwFilterScaling* scaling = (SwFilterScaling*)feature;
734     FeatureParamScaling *scalingParams = &scaling->GetSwFilterParams();
735     VP_EngineEntry *scalingEngine = &scaling->GetFilterEngineCaps();
736 
737     if (scalingEngine->value != 0)
738     {
739         VP_PUBLIC_NORMALMESSAGE("Scaling Feature Already been processed, Skip further process");
740         // Clean usedForNextPass flag.
741         if (scalingEngine->usedForNextPass)
742         {
743             scalingEngine->usedForNextPass = false;
744         }
745         PrintFeatureExecutionCaps(__FUNCTION__, *scalingEngine);
746         return MOS_STATUS_SUCCESS;
747     }
748 
749     // For AVS sampler not enabled case, HQ/Fast scaling should go to SFC.
750     // And Ief should only be done by SFC.
751     if (!m_hwCaps.m_rules.isAvsSamplerSupported &&
752         scalingParams->scalingPreference != VPHAL_SCALING_PREFER_SFC)
753     {
754         VP_PUBLIC_NORMALMESSAGE("Force scalingPreference from %d to SFC");
755         scalingParams->scalingPreference = VPHAL_SCALING_PREFER_SFC;
756     }
757 
758     if (!m_hwCaps.m_veboxHwEntry[scalingParams->formatInput].inputSupported)
759     {
760         VP_PUBLIC_NORMALMESSAGE("Input format %d is not support vebox, force to use fc.", scalingParams->formatInput);
761         scalingEngine->bEnabled             = 1;
762         scalingEngine->SfcNeeded            = 0;
763         scalingEngine->VeboxNeeded          = 0;
764         scalingEngine->RenderNeeded         = 1;
765         scalingEngine->fcSupported          = 1;
766         scalingEngine->forceEnableForSfc    = 0;
767         scalingEngine->forceEnableForRender = 0;
768         PrintFeatureExecutionCaps(__FUNCTION__, *scalingEngine);
769         return MOS_STATUS_SUCCESS;
770     }
771 
772     veboxMinWidth  = m_hwCaps.m_veboxHwEntry[scalingParams->formatInput].minResolution;
773     veboxMaxWidth  = m_hwCaps.m_veboxHwEntry[scalingParams->formatInput].maxResolution;
774     veboxMinHeight = m_hwCaps.m_veboxHwEntry[scalingParams->formatInput].minResolution;
775     veboxMaxHeight = m_hwCaps.m_veboxHwEntry[scalingParams->formatInput].maxResolution;
776     dwSfcMinWidth  = m_hwCaps.m_sfcHwEntry[scalingParams->formatInput].minResolution;
777     dwSfcMaxWidth  = m_hwCaps.m_sfcHwEntry[scalingParams->formatInput].maxResolution;
778     dwSfcMinHeight = m_hwCaps.m_sfcHwEntry[scalingParams->formatInput].minResolution;
779     dwSfcMaxHeight = m_hwCaps.m_sfcHwEntry[scalingParams->formatInput].maxResolution;
780     fScaleMin      = m_hwCaps.m_sfcHwEntry[scalingParams->formatInput].minScalingRatio;
781     fScaleMax      = m_hwCaps.m_sfcHwEntry[scalingParams->formatInput].maxScalingRatio;
782     if (m_hwCaps.m_rules.sfcMultiPassSupport.scaling.enable)
783     {
784         fScaleMin2Pass = fScaleMin * m_hwCaps.m_rules.sfcMultiPassSupport.scaling.downScaling.minRatioEnlarged;
785         fScaleMax2Pass = fScaleMax * m_hwCaps.m_rules.sfcMultiPassSupport.scaling.upScaling.maxRatioEnlarged;
786     }
787 
788     if (scalingParams->interlacedScalingType == ISCALING_FIELD_TO_INTERLEAVED)
789     {
790         dwDstMinHeight = dwSfcMinHeight * 2;
791     }
792     else
793     {
794         dwDstMinHeight = dwSfcMinHeight;
795     }
796 
797     dwSurfaceWidth  = scalingParams->input.dwWidth;
798     dwSurfaceHeight = scalingParams->input.dwHeight;
799     dwOutputSurfaceWidth  = scalingParams->output.dwWidth;
800     dwOutputSurfaceHeight = scalingParams->output.dwHeight;
801 
802     // Region of the input frame which needs to be processed by SFC
803     uint32_t dwSourceRegionHeight = MOS_ALIGN_FLOOR(
804         MOS_MIN((uint32_t)(scalingParams->input.rcSrc.bottom - scalingParams->input.rcSrc.top), dwSurfaceHeight),
805         m_hwCaps.m_sfcHwEntry[scalingParams->formatInput].verticalAlignUnit);
806     uint32_t dwSourceRegionWidth = MOS_ALIGN_FLOOR(
807         MOS_MIN((uint32_t)(scalingParams->input.rcSrc.right - scalingParams->input.rcSrc.left), dwSurfaceWidth),
808         m_hwCaps.m_sfcHwEntry[scalingParams->formatInput].horizontalAlignUnit);
809 
810     // Size of the Output Region over the Render Target
811     uint32_t dwOutputRegionHeight = MOS_ALIGN_CEIL(
812         (uint32_t)(scalingParams->input.rcDst.bottom - scalingParams->input.rcDst.top),
813         m_hwCaps.m_sfcHwEntry[scalingParams->formatOutput].verticalAlignUnit);
814     uint32_t dwOutputRegionWidth = MOS_ALIGN_CEIL(
815         (uint32_t)(scalingParams->input.rcDst.right - scalingParams->input.rcDst.left),
816         m_hwCaps.m_sfcHwEntry[scalingParams->formatOutput].horizontalAlignUnit);
817 
818     // Calculate the scaling ratio
819     // Both source region and scaled region are pre-rotated
820     // Need to take Interlace scaling into consideration next step
821     fScaleX = (float)dwOutputRegionWidth / (float)dwSourceRegionWidth;
822     fScaleY = (float)dwOutputRegionHeight / (float)dwSourceRegionHeight;
823 
824     if (fScaleX == 1.0f && fScaleY == 1.0f &&
825         // Only support vebox crop from left-top, which is to align with legacy path.
826         0 == scalingParams->input.rcSrc.left && 0 == scalingParams->input.rcSrc.top &&
827         SAME_SIZE_RECT(scalingParams->input.rcDst, scalingParams->output.rcDst) &&
828         // If Alpha enabled, which should go SFC pipe.
829         !IsAlphaEnabled(scalingParams) &&
830         // If Colorfill enabled, which should go SFC pipe.
831         !IsColorfillEnabled(scalingParams) &&
832         scalingParams->interlacedScalingType != ISCALING_INTERLEAVED_TO_FIELD &&
833         scalingParams->interlacedScalingType != ISCALING_FIELD_TO_INTERLEAVED)
834     {
835         if (OUT_OF_BOUNDS(dwSurfaceWidth, veboxMinWidth, veboxMaxWidth) ||
836             OUT_OF_BOUNDS(dwSurfaceHeight, veboxMinHeight, veboxMaxHeight))
837         {
838             // for non-Scaling cases, all engine supported
839             scalingEngine->bEnabled             = 1;
840             scalingEngine->SfcNeeded            = 0;
841             scalingEngine->VeboxNeeded          = 0;
842             scalingEngine->RenderNeeded         = 1;
843             scalingEngine->fcSupported          = 1;
844             scalingEngine->forceEnableForSfc    = 0;
845             scalingEngine->forceEnableForRender = 0;
846             VP_PUBLIC_NORMALMESSAGE("The surface resolution is not supported by vebox.");
847         }
848         else if (OUT_OF_BOUNDS(dwSurfaceWidth, dwSfcMinWidth, dwSfcMaxWidth)    ||
849                 OUT_OF_BOUNDS(dwSurfaceHeight, dwSfcMinHeight, dwSfcMaxHeight))
850         {
851             // for non-Scaling cases, all engine supported
852             scalingEngine->bEnabled             = 0;
853             scalingEngine->SfcNeeded            = 0;
854             scalingEngine->VeboxNeeded          = 0;
855             scalingEngine->RenderNeeded         = 0;
856             scalingEngine->forceEnableForSfc    = 0;
857             scalingEngine->forceEnableForRender = 1;
858             scalingEngine->fcSupported          = 1;
859             scalingEngine->sfcNotSupported      = 1;
860             VP_PUBLIC_NORMALMESSAGE("The surface resolution is not supported by sfc.");
861         }
862         else if (scalingParams->input.rcDst.left > 0    ||
863                  scalingParams->input.rcDst.top  > 0)
864         {
865             // for dst left and top non zero cases, should go SFC or Render Pipe
866             scalingEngine->bEnabled             = 1;
867             scalingEngine->SfcNeeded            = 1;
868             scalingEngine->VeboxNeeded          = 0;
869             scalingEngine->RenderNeeded         = 1;
870             scalingEngine->fcSupported          = 1;
871             VP_PUBLIC_NORMALMESSAGE("The dst left and top non zero is not supported by vebox ");
872         }
873         else
874         {
875             // for non-Scaling cases, all engine supported
876             scalingEngine->bEnabled             = 0;
877             scalingEngine->SfcNeeded            = 0;
878             scalingEngine->VeboxNeeded          = 0;
879             scalingEngine->RenderNeeded         = 0;
880             scalingEngine->forceEnableForSfc    = 1;
881             scalingEngine->forceEnableForRender = 1;
882             scalingEngine->fcSupported          = 1;
883         }
884 
885         PrintFeatureExecutionCaps(__FUNCTION__, *scalingEngine);
886         return MOS_STATUS_SUCCESS;
887     }
888 
889     if (disableSfc)
890     {
891         scalingEngine->bEnabled     = 1;
892         scalingEngine->RenderNeeded = 1;
893         scalingEngine->fcSupported  = 1;
894         scalingEngine->SfcNeeded    = 0;
895         VP_PUBLIC_NORMALMESSAGE("Force scaling to FC. disableSfc %d", disableSfc);
896         PrintFeatureExecutionCaps(__FUNCTION__, *scalingEngine);
897         return MOS_STATUS_SUCCESS;
898     }
899 
900     // SFC Scaling enabling check
901     if (m_hwCaps.m_sfcHwEntry[scalingParams->formatInput].inputSupported   &&
902         m_hwCaps.m_sfcHwEntry[scalingParams->formatOutput].outputSupported &&
903         m_hwCaps.m_sfcHwEntry[scalingParams->formatInput].scalingSupported)
904     {
905         if (!(OUT_OF_BOUNDS(dwSurfaceWidth, dwSfcMinWidth, dwSfcMaxWidth)         ||
906               OUT_OF_BOUNDS(dwSurfaceHeight, dwSfcMinHeight, dwSfcMaxHeight)      ||
907               OUT_OF_BOUNDS(dwSourceRegionWidth, dwSfcMinWidth, dwSfcMaxWidth)    ||
908               OUT_OF_BOUNDS(dwSourceRegionHeight, dwSfcMinHeight, dwSfcMaxHeight) ||
909               OUT_OF_BOUNDS(dwOutputRegionWidth, dwSfcMinWidth, dwSfcMaxWidth)    ||
910               OUT_OF_BOUNDS(dwOutputRegionHeight, dwSfcMinHeight, dwSfcMaxHeight) ||
911               OUT_OF_BOUNDS(dwOutputSurfaceWidth, dwSfcMinWidth, dwSfcMaxWidth)   ||
912               OUT_OF_BOUNDS(dwOutputSurfaceHeight, dwDstMinHeight, dwSfcMaxHeight)))
913         {
914             if ((m_hwCaps.m_rules.sfcMultiPassSupport.scaling.enable            &&
915                 (OUT_OF_BOUNDS(fScaleX, fScaleMin2Pass, fScaleMax2Pass)         ||
916                  OUT_OF_BOUNDS(fScaleY, fScaleMin2Pass, fScaleMax2Pass)))       ||
917                 (!m_hwCaps.m_rules.sfcMultiPassSupport.scaling.enable           &&
918                 (OUT_OF_BOUNDS(fScaleX, fScaleMin, fScaleMax)                   ||
919                  OUT_OF_BOUNDS(fScaleY, fScaleMin, fScaleMax)))                 ||
920                 (scalingParams->scalingPreference == VPHAL_SCALING_PREFER_COMP))
921             {
922                 // Render Pipe, need to add more conditions next step for multiple SFC mode
923                 // if Render didn't have AVS but Scaling quality mode needed
924                 scalingEngine->bEnabled     = 1;
925                 scalingEngine->RenderNeeded = 1;
926                 scalingEngine->fcSupported  = 1;
927                 scalingEngine->SfcNeeded    = 0;
928                 VP_PUBLIC_NORMALMESSAGE("Fc selected. fScaleX %f, fScaleY %f, scalingPreference %d",
929                     fScaleX, fScaleY, scalingParams->scalingPreference);
930             }
931             // SFC feasible
932             else
933             {
934                 bool sfc2PassScalingNeededX = OUT_OF_BOUNDS(fScaleX, fScaleMin, fScaleMax);
935                 bool sfc2PassScalingNeededY = OUT_OF_BOUNDS(fScaleY, fScaleMin, fScaleMax);
936 
937                 scalingEngine->bEnabled = 1;
938                 if (!m_hwCaps.m_rules.isAvsSamplerSupported && scalingParams->isPrimary)
939                 {
940                     // For primary layer, force to use sfc for better quailty.
941                     scalingEngine->SfcNeeded = 1;
942                     scalingEngine->sfc2PassScalingNeededX = sfc2PassScalingNeededX ? 1 : 0;
943                     scalingEngine->sfc2PassScalingNeededY = sfc2PassScalingNeededY ? 1 : 0;
944                     scalingEngine->multiPassNeeded = sfc2PassScalingNeededX || sfc2PassScalingNeededY;
945 
946                     if (1 == fScaleX && 1 == fScaleY)
947                     {
948                         VP_PUBLIC_NORMALMESSAGE("Fc can be selected for scale ratio being 1 case on primary, e.g. crop only case.");
949                         scalingEngine->RenderNeeded = 1;
950                         scalingEngine->fcSupported  = 1;
951                     }
952                 }
953                 else
954                 {
955                     scalingEngine->RenderNeeded = 1;
956                     scalingEngine->fcSupported  = 1;
957                     // For non-primary layer, only consider sfc for non-2-pass case.
958                     if (!sfc2PassScalingNeededX && !sfc2PassScalingNeededY)
959                     {
960                         scalingEngine->SfcNeeded = 1;
961                     }
962                 }
963             }
964         }
965         else
966         {
967             scalingEngine->bEnabled     = 1;
968             scalingEngine->RenderNeeded = 1;
969             scalingEngine->fcSupported  = 1;
970             scalingEngine->SfcNeeded    = 0;
971             VP_PUBLIC_NORMALMESSAGE("Scaling parameters are not supported by SFC. Switch to Render.");
972         }
973     }
974     else
975     {
976         scalingEngine->bEnabled     = 1;
977         scalingEngine->RenderNeeded = 1;
978         scalingEngine->fcSupported  = 1;
979         scalingEngine->SfcNeeded    = 0;
980         VP_PUBLIC_NORMALMESSAGE("Format is not supported by SFC. Switch to Render.");
981     }
982 
983     PrintFeatureExecutionCaps(__FUNCTION__, *scalingEngine);
984     return MOS_STATUS_SUCCESS;
985 }
986 
IsSfcRotationSupported(FeatureParamRotMir * rotationParams)987 bool Policy::IsSfcRotationSupported(FeatureParamRotMir *rotationParams)
988 {
989     VP_FUNC_CALL();
990 
991     bool isSfcRotationSupported = false;
992     if (m_hwCaps.m_sfcHwEntry[rotationParams->formatInput].inputSupported &&
993         m_hwCaps.m_sfcHwEntry[rotationParams->formatOutput].outputSupported)
994     {
995         if (VPHAL_ROTATION_IDENTITY == rotationParams->rotation)
996         {
997             isSfcRotationSupported = true;
998         }
999         else if (VPHAL_MIRROR_HORIZONTAL == rotationParams->rotation)
1000         {
1001             if (m_hwCaps.m_sfcHwEntry[rotationParams->formatInput].mirrorSupported)
1002             {
1003                 isSfcRotationSupported = true;
1004             }
1005         }
1006         else if (rotationParams->rotation <= VPHAL_ROTATION_270)
1007         {
1008             // Rotation w/o mirror case
1009             if (m_hwCaps.m_sfcHwEntry[rotationParams->formatInput].rotationSupported &&
1010                 rotationParams->surfInfo.tileOutput == MOS_TILE_Y)
1011             {
1012                 isSfcRotationSupported = true;
1013             }
1014         }
1015         else
1016         {
1017             // Rotation w/ mirror case
1018             if (m_hwCaps.m_sfcHwEntry[rotationParams->formatInput].mirrorSupported &&
1019                 m_hwCaps.m_sfcHwEntry[rotationParams->formatInput].rotationSupported &&
1020                 rotationParams->surfInfo.tileOutput == MOS_TILE_Y)
1021             {
1022                 isSfcRotationSupported = true;
1023             }
1024         }
1025     }
1026 
1027     VP_PUBLIC_NORMALMESSAGE("Is rotation supported by sfc: %d", isSfcRotationSupported ? 1 : 0);
1028     return isSfcRotationSupported;
1029 }
1030 
GetRotationExecutionCaps(SwFilter * feature)1031 MOS_STATUS Policy::GetRotationExecutionCaps(SwFilter* feature)
1032 {
1033     VP_FUNC_CALL();
1034 
1035     VP_PUBLIC_CHK_NULL_RETURN(feature);
1036     VP_PUBLIC_CHK_NULL_RETURN(m_vpInterface.GetHwInterface());
1037     VP_PUBLIC_CHK_NULL_RETURN(m_vpInterface.GetHwInterface()->m_userFeatureControl);
1038 
1039     auto userFeatureControl = m_vpInterface.GetHwInterface()->m_userFeatureControl;
1040     bool disableSfc = userFeatureControl->IsSfcDisabled();
1041     SwFilterRotMir* rotation = (SwFilterRotMir*)feature;
1042     FeatureParamRotMir *rotationParams = &rotation->GetSwFilterParams();
1043     VP_EngineEntry *rotationEngine = &rotation->GetFilterEngineCaps();
1044 
1045     if (rotationEngine->value != 0)
1046     {
1047         VP_PUBLIC_NORMALMESSAGE("Scaling Feature Already been processed, Skip further process");
1048         // Clean usedForNextPass flag.
1049         if (rotationEngine->usedForNextPass)
1050         {
1051             rotationEngine->usedForNextPass = false;
1052         }
1053         PrintFeatureExecutionCaps(__FUNCTION__, *rotationEngine);
1054         return MOS_STATUS_SUCCESS;
1055     }
1056 
1057     if (rotationParams->rotation == VPHAL_ROTATION_IDENTITY)
1058     {
1059         // for non-rotation cases, all engine supported
1060         rotationEngine->bEnabled                = 0;
1061         rotationEngine->VeboxNeeded             = 0;
1062         rotationEngine->SfcNeeded               = 0;
1063         rotationEngine->RenderNeeded            = 0;
1064         rotationEngine->forceEnableForSfc       = 1;
1065         PrintFeatureExecutionCaps(__FUNCTION__, *rotationEngine);
1066         return MOS_STATUS_SUCCESS;
1067     }
1068 
1069     rotationEngine->bEnabled        = 1;
1070     rotationEngine->RenderNeeded    = 1;
1071     rotationEngine->fcSupported     = 1;
1072 
1073     if (disableSfc)
1074     {
1075         VP_PUBLIC_NORMALMESSAGE("Force rotation to FC. disableSfc %d", disableSfc);
1076         PrintFeatureExecutionCaps(__FUNCTION__, *rotationEngine);
1077         return MOS_STATUS_SUCCESS;
1078     }
1079 
1080     rotationEngine->SfcNeeded       = IsSfcRotationSupported(rotationParams);
1081 
1082     PrintFeatureExecutionCaps(__FUNCTION__, *rotationEngine);
1083     return MOS_STATUS_SUCCESS;
1084 }
1085 
GetDenoiseExecutionCaps(SwFilter * feature)1086 MOS_STATUS Policy::GetDenoiseExecutionCaps(SwFilter* feature)
1087 {
1088     VP_FUNC_CALL();
1089     VP_PUBLIC_CHK_NULL_RETURN(feature);
1090 
1091     SwFilterDenoise* denoise = dynamic_cast<SwFilterDenoise*>(feature);
1092     VP_PUBLIC_CHK_NULL_RETURN(denoise);
1093 
1094     FeatureParamDenoise& denoiseParams = denoise->GetSwFilterParams();
1095     VP_EngineEntry& denoiseEngine = denoise->GetFilterEngineCaps();
1096     MOS_FORMAT inputformat = denoiseParams.formatInput;
1097 
1098     // MOS_FORMAT is [-14,103], cannot use -14~-1 as index for m_veboxHwEntry
1099     if (inputformat < 0)
1100     {
1101         inputformat = Format_Any;
1102     }
1103 
1104     uint32_t        widthAlignUint  = m_hwCaps.m_veboxHwEntry[inputformat].horizontalAlignUnit;
1105     uint32_t        heightAlignUnit = m_hwCaps.m_veboxHwEntry[inputformat].verticalAlignUnit;
1106 
1107     if (denoiseEngine.value != 0)
1108     {
1109         VP_PUBLIC_NORMALMESSAGE("Scaling Feature Already been processed, Skip further process");
1110         PrintFeatureExecutionCaps(__FUNCTION__, denoiseEngine);
1111         return MOS_STATUS_SUCCESS;
1112     }
1113 
1114     if (m_hwCaps.m_veboxHwEntry[inputformat].denoiseSupported)
1115     {
1116         widthAlignUint = MOS_ALIGN_CEIL(m_hwCaps.m_veboxHwEntry[inputformat].horizontalAlignUnit, 2);
1117 
1118         if (inputformat == Format_NV12 ||
1119             inputformat == Format_P010 ||
1120             inputformat == Format_P016)
1121         {
1122             heightAlignUnit = MOS_ALIGN_CEIL(m_hwCaps.m_veboxHwEntry[inputformat].verticalAlignUnit, 4);
1123         }
1124         else
1125         {
1126             heightAlignUnit = MOS_ALIGN_CEIL(m_hwCaps.m_veboxHwEntry[inputformat].verticalAlignUnit, 2);
1127         }
1128 
1129         if (MOS_IS_ALIGNED(denoiseParams.heightInput, heightAlignUnit))
1130         {
1131             denoiseEngine.bEnabled    = 1;
1132             denoiseEngine.VeboxNeeded = 1;
1133         }
1134         else
1135         {
1136             VP_PUBLIC_NORMALMESSAGE("Denoise Feature is disabled since heightInput (%d) not being %d aligned.", denoiseParams.heightInput, heightAlignUnit);
1137         }
1138     }
1139 
1140     denoiseParams.widthAlignUnitInput = widthAlignUint;
1141     denoiseParams.heightAlignUnitInput = heightAlignUnit;
1142 
1143     PrintFeatureExecutionCaps(__FUNCTION__, denoiseEngine);
1144     return MOS_STATUS_SUCCESS;
1145 }
1146 
GetDeinterlaceExecutionCaps(SwFilter * feature)1147 MOS_STATUS Policy::GetDeinterlaceExecutionCaps(SwFilter* feature)
1148 {
1149     VP_FUNC_CALL();
1150     VP_PUBLIC_CHK_NULL_RETURN(feature);
1151 
1152     SwFilterDeinterlace* swFilterDi = dynamic_cast<SwFilterDeinterlace*>(feature);
1153     VP_PUBLIC_CHK_NULL_RETURN(swFilterDi);
1154     VP_PUBLIC_CHK_NULL_RETURN(m_vpInterface.GetHwInterface());
1155     VP_PUBLIC_CHK_NULL_RETURN(m_vpInterface.GetHwInterface()->m_userFeatureControl);
1156 
1157     auto userFeatureControl = m_vpInterface.GetHwInterface()->m_userFeatureControl;
1158     FeatureParamDeinterlace &diParams = swFilterDi->GetSwFilterParams();
1159     VP_EngineEntry &diEngine = swFilterDi->GetFilterEngineCaps();
1160     MOS_FORMAT      inputformat = diParams.formatInput;
1161 
1162     // MOS_FORMAT is [-14,103], cannot use -14~-1 as index for m_veboxHwEntry
1163     if (inputformat < 0)
1164     {
1165         inputformat = Format_Any;
1166     }
1167 
1168     if (diEngine.value != 0)
1169     {
1170         VP_PUBLIC_NORMALMESSAGE("DI Feature Already been processed, Skip further process.");
1171         PrintFeatureExecutionCaps(__FUNCTION__, diEngine);
1172         return MOS_STATUS_SUCCESS;
1173     }
1174 
1175     if (!m_hwCaps.m_veboxHwEntry[inputformat].deinterlaceSupported              ||
1176         diParams.diParams && diParams.diParams->DIMode == DI_MODE_BOB           &&
1177         !MOS_IS_ALIGNED(MOS_MIN((uint32_t)diParams.heightInput, (uint32_t)diParams.rcSrc.bottom), 4) &&
1178         (diParams.formatInput == Format_P010                                    ||
1179          diParams.formatInput == Format_P016                                    ||
1180          diParams.formatInput == Format_NV12))
1181     {
1182         diEngine.bEnabled     = 1;
1183         diEngine.RenderNeeded = 1;
1184         diEngine.fcSupported  = 1;
1185         PrintFeatureExecutionCaps(__FUNCTION__, diEngine);
1186         return MOS_STATUS_SUCCESS;
1187     }
1188 
1189     if (m_vpInterface.GetResourceManager()->IsRefValid() &&
1190         diParams.diParams && diParams.diParams->bEnableFMD)
1191     {
1192         diParams.bFmdExtraVariance = true;
1193     }
1194 
1195     if (m_vpInterface.GetResourceManager()->IsRefValid()    &&
1196         m_vpInterface.GetResourceManager()->IsSameSamples())
1197     {
1198         diEngine.bypassVeboxFeatures    = 1;
1199         diEngine.diProcess2ndField      = 1;
1200     }
1201     else if (diParams.bFmdExtraVariance && diParams.bFmdKernelEnable)
1202     {
1203         diEngine.bEnabled     = 1;
1204         diEngine.RenderNeeded = 1;
1205         diEngine.isolated     = 1;
1206     }
1207     else
1208     {
1209         diEngine.bEnabled     = 1;
1210         diEngine.RenderNeeded = 1;
1211         diEngine.fcSupported  = 1;
1212         diEngine.VeboxNeeded  = 1;
1213     }
1214 
1215     PrintFeatureExecutionCaps(__FUNCTION__, diEngine);
1216     return MOS_STATUS_SUCCESS;
1217 }
1218 
GetSteExecutionCaps(SwFilter * feature)1219 MOS_STATUS Policy::GetSteExecutionCaps(SwFilter* feature)
1220 {
1221     VP_FUNC_CALL();
1222     VP_PUBLIC_CHK_NULL_RETURN(feature);
1223 
1224     SwFilterSte* steFilter = dynamic_cast<SwFilterSte*>(feature);
1225     VP_PUBLIC_CHK_NULL_RETURN(steFilter);
1226 
1227     FeatureParamSte& steParams = steFilter->GetSwFilterParams();
1228     VP_EngineEntry& steEngine = steFilter->GetFilterEngineCaps();
1229     MOS_FORMAT inputformat = steParams.formatInput;
1230 
1231     // MOS_FORMAT is [-14,103], cannot use -14~-1 as index for m_veboxHwEntry
1232     if (inputformat < 0)
1233     {
1234         inputformat = Format_Any;
1235     }
1236 
1237     if (steEngine.value != 0)
1238     {
1239         VP_PUBLIC_NORMALMESSAGE("ACE Feature Already been processed, Skip further process");
1240         PrintFeatureExecutionCaps(__FUNCTION__, steEngine);
1241         return MOS_STATUS_SUCCESS;
1242     }
1243 
1244     if (m_hwCaps.m_veboxHwEntry[inputformat].steSupported   &&
1245         m_hwCaps.m_veboxHwEntry[inputformat].inputSupported &&
1246         m_hwCaps.m_veboxHwEntry[inputformat].iecp)
1247     {
1248         steEngine.bEnabled = 1;
1249         steEngine.VeboxNeeded = 1;
1250         steEngine.VeboxIECPNeeded = 1;
1251     }
1252 
1253     PrintFeatureExecutionCaps(__FUNCTION__, steEngine);
1254     return MOS_STATUS_SUCCESS;
1255 }
1256 
GetTccExecutionCaps(SwFilter * feature)1257 MOS_STATUS Policy::GetTccExecutionCaps(SwFilter* feature)
1258 {
1259     VP_FUNC_CALL();
1260     VP_PUBLIC_CHK_NULL_RETURN(feature);
1261 
1262     SwFilterTcc* tccFilter = dynamic_cast<SwFilterTcc*>(feature);
1263     VP_PUBLIC_CHK_NULL_RETURN(tccFilter);
1264 
1265     FeatureParamTcc& tccParams = tccFilter->GetSwFilterParams();
1266     VP_EngineEntry& tccEngine = tccFilter->GetFilterEngineCaps();
1267     MOS_FORMAT inputformat = tccParams.formatInput;
1268 
1269     // MOS_FORMAT is [-14,103], cannot use -14~-1 as index for m_veboxHwEntry
1270     if (inputformat < 0)
1271     {
1272         inputformat = Format_Any;
1273     }
1274 
1275     if (tccEngine.value != 0)
1276     {
1277         VP_PUBLIC_NORMALMESSAGE("TCC Feature Already been processed, Skip further process");
1278         PrintFeatureExecutionCaps(__FUNCTION__, tccEngine);
1279         return MOS_STATUS_SUCCESS;
1280     }
1281 
1282     if (m_hwCaps.m_veboxHwEntry[inputformat].inputSupported &&
1283         m_hwCaps.m_veboxHwEntry[inputformat].iecp           &&
1284         m_hwCaps.m_veboxHwEntry[inputformat].tccSupported)
1285     {
1286         tccEngine.bEnabled = 1;
1287         tccEngine.VeboxNeeded = 1;
1288         tccEngine.VeboxIECPNeeded = 1;
1289     }
1290 
1291     PrintFeatureExecutionCaps(__FUNCTION__, tccEngine);
1292     return MOS_STATUS_SUCCESS;
1293 }
1294 
GetProcampExecutionCaps(SwFilter * feature)1295 MOS_STATUS Policy::GetProcampExecutionCaps(SwFilter* feature)
1296 {
1297     VP_FUNC_CALL();
1298     VP_PUBLIC_CHK_NULL_RETURN(feature);
1299 
1300     SwFilterProcamp* procampFilter = dynamic_cast<SwFilterProcamp*>(feature);
1301     VP_PUBLIC_CHK_NULL_RETURN(procampFilter);
1302     VP_PUBLIC_CHK_NULL_RETURN(m_vpInterface.GetHwInterface());
1303     VP_PUBLIC_CHK_NULL_RETURN(m_vpInterface.GetHwInterface()->m_userFeatureControl);
1304 
1305     auto userFeatureControl = m_vpInterface.GetHwInterface()->m_userFeatureControl;
1306     FeatureParamProcamp& procampParams = procampFilter->GetSwFilterParams();
1307     VP_EngineEntry& procampEngine = procampFilter->GetFilterEngineCaps();
1308     MOS_FORMAT inputformat = procampParams.formatInput;
1309 
1310     // MOS_FORMAT is [-14,103], cannot use -14~-1 as index for m_veboxHwEntry
1311     if (inputformat < 0)
1312     {
1313         inputformat = Format_Any;
1314     }
1315 
1316     if (procampEngine.value != 0)
1317     {
1318         VP_PUBLIC_NORMALMESSAGE("Procamp Feature Already been processed, Skip further process");
1319         PrintFeatureExecutionCaps(__FUNCTION__, procampEngine);
1320         return MOS_STATUS_SUCCESS;
1321     }
1322 
1323     procampEngine.bEnabled = 1;
1324     procampEngine.RenderNeeded = 1;
1325     procampEngine.fcSupported = 1;
1326 
1327     if (m_hwCaps.m_veboxHwEntry[inputformat].inputSupported &&
1328         m_hwCaps.m_veboxHwEntry[inputformat].iecp)
1329     {
1330         procampEngine.VeboxNeeded = 1;
1331         procampEngine.VeboxIECPNeeded = 1;
1332     }
1333 
1334     PrintFeatureExecutionCaps(__FUNCTION__, procampEngine);
1335     return MOS_STATUS_SUCCESS;
1336 }
1337 
GetHdrExecutionCaps(SwFilter * feature)1338 MOS_STATUS Policy::GetHdrExecutionCaps(SwFilter *feature)
1339 {
1340     VP_FUNC_CALL();
1341     VP_PUBLIC_CHK_NULL_RETURN(feature);
1342 
1343     SwFilterHdr *hdrFilter = dynamic_cast<SwFilterHdr *>(feature);
1344 
1345     FeatureParamHdr *hdrParams = &hdrFilter->GetSwFilterParams();
1346 
1347     VP_EngineEntry *pHDREngine  = &hdrFilter->GetFilterEngineCaps();
1348     MOS_FORMAT      inputformat = hdrParams->formatInput;
1349 
1350     // MOS_FORMAT is [-14,103], cannot use -14~-1 as index for m_veboxHwEntry
1351     if (inputformat < 0)
1352     {
1353         inputformat = Format_Any;
1354     }
1355 
1356     if (pHDREngine->value != 0)
1357     {
1358         VP_PUBLIC_NORMALMESSAGE("HDR Feature Already been processed, Skip further process");
1359         PrintFeatureExecutionCaps(__FUNCTION__, *pHDREngine);
1360         return MOS_STATUS_SUCCESS;
1361     }
1362 
1363     if (m_hwCaps.m_veboxHwEntry[hdrParams->formatInput].inputSupported &&
1364         m_hwCaps.m_veboxHwEntry[hdrParams->formatInput].hdrSupported)
1365     {
1366         pHDREngine->bEnabled        = 1;
1367         pHDREngine->VeboxNeeded     = 1;
1368         if (hdrParams->formatOutput == Format_A8B8G8R8 || hdrParams->formatOutput == Format_A8R8G8B8)
1369         {
1370             pHDREngine->VeboxARGBOut = 1;
1371         }
1372         else if (hdrParams->formatOutput == Format_B10G10R10A2 || hdrParams->formatOutput == Format_R10G10B10A2)
1373         {
1374             pHDREngine->VeboxARGB10bitOutput = 1;
1375         }
1376     }
1377 
1378     PrintFeatureExecutionCaps(__FUNCTION__, *pHDREngine);
1379     return MOS_STATUS_SUCCESS;
1380 }
1381 
GetColorFillExecutionCaps(SwFilter * feature)1382 MOS_STATUS Policy::GetColorFillExecutionCaps(SwFilter* feature)
1383 {
1384     VP_FUNC_CALL();
1385     VP_PUBLIC_CHK_NULL_RETURN(feature);
1386 
1387     SwFilterColorFill* filter = dynamic_cast<SwFilterColorFill*>(feature);
1388     VP_PUBLIC_CHK_NULL_RETURN(filter);
1389     VP_PUBLIC_CHK_NULL_RETURN(m_vpInterface.GetHwInterface());
1390     VP_PUBLIC_CHK_NULL_RETURN(m_vpInterface.GetHwInterface()->m_userFeatureControl);
1391 
1392     auto userFeatureControl = m_vpInterface.GetHwInterface()->m_userFeatureControl;
1393     bool disableSfc = userFeatureControl->IsSfcDisabled();
1394     FeatureParamColorFill& params = filter->GetSwFilterParams();
1395     VP_EngineEntry& engine = filter->GetFilterEngineCaps();
1396     MOS_FORMAT inputformat = params.formatInput;
1397 
1398     // MOS_FORMAT is [-14,103], cannot use -14~-1 as index for m_veboxHwEntry
1399     if (inputformat < 0)
1400     {
1401         inputformat = Format_Any;
1402     }
1403 
1404     if (engine.value != 0)
1405     {
1406         VP_PUBLIC_NORMALMESSAGE("ColorFill Feature Already been processed, Skip further process");
1407         PrintFeatureExecutionCaps(__FUNCTION__, engine);
1408         return MOS_STATUS_SUCCESS;
1409     }
1410 
1411     engine.bEnabled = 1;
1412     engine.RenderNeeded = 1;
1413     engine.fcSupported = 1;
1414     // For disableSfc case, sfc will be filtered in SwFilterColorFill::GetCombinedFilterEngineCapss
1415     // with scaling setting.
1416     engine.SfcNeeded = 1;    // For SFC, the parameter in scaling is used.
1417 
1418     PrintFeatureExecutionCaps(__FUNCTION__, engine);
1419     return MOS_STATUS_SUCCESS;
1420 }
1421 
GetAlphaExecutionCaps(SwFilter * feature)1422 MOS_STATUS Policy::GetAlphaExecutionCaps(SwFilter* feature)
1423 {
1424     VP_FUNC_CALL();
1425     VP_PUBLIC_CHK_NULL_RETURN(feature);
1426 
1427     SwFilterAlpha* filter = dynamic_cast<SwFilterAlpha*>(feature);
1428     VP_PUBLIC_CHK_NULL_RETURN(filter);
1429     VP_PUBLIC_CHK_NULL_RETURN(m_vpInterface.GetHwInterface());
1430     VP_PUBLIC_CHK_NULL_RETURN(m_vpInterface.GetHwInterface()->m_userFeatureControl);
1431 
1432     auto userFeatureControl = m_vpInterface.GetHwInterface()->m_userFeatureControl;
1433     bool disableSfc = userFeatureControl->IsSfcDisabled();
1434     FeatureParamAlpha& params = filter->GetSwFilterParams();
1435     VP_EngineEntry& engine = filter->GetFilterEngineCaps();
1436     MOS_FORMAT inputformat = params.formatInput;
1437 
1438     // MOS_FORMAT is [-14,103], cannot use -14~-1 as index for m_veboxHwEntry
1439     if (inputformat < 0)
1440     {
1441         inputformat = Format_Any;
1442     }
1443 
1444     if (engine.value != 0)
1445     {
1446         VP_PUBLIC_NORMALMESSAGE("Alpha Feature Already been processed, Skip further process");
1447         PrintFeatureExecutionCaps(__FUNCTION__, engine);
1448         return MOS_STATUS_SUCCESS;
1449     }
1450     engine.bEnabled = 1;
1451     engine.RenderNeeded = 1;
1452     engine.fcSupported = 1;
1453 
1454     engine.SfcNeeded = disableSfc ? 0 : 1;    // For SFC, the parameter in scaling is used.
1455     engine.VeboxNeeded = params.compAlpha->AlphaMode != VPHAL_ALPHA_FILL_MODE_BACKGROUND;
1456 
1457     PrintFeatureExecutionCaps(__FUNCTION__, engine);
1458     return MOS_STATUS_SUCCESS;
1459 }
1460 
GetLumakeyExecutionCaps(SwFilter * feature)1461 MOS_STATUS Policy::GetLumakeyExecutionCaps(SwFilter* feature)
1462 {
1463     VP_FUNC_CALL();
1464     VP_PUBLIC_CHK_NULL_RETURN(feature);
1465 
1466     SwFilterLumakey* filter = dynamic_cast<SwFilterLumakey*>(feature);
1467     VP_PUBLIC_CHK_NULL_RETURN(filter);
1468 
1469     FeatureParamLumakey& params = filter->GetSwFilterParams();
1470     VP_EngineEntry& engine = filter->GetFilterEngineCaps();
1471     MOS_FORMAT inputformat = params.formatInput;
1472 
1473     // MOS_FORMAT is [-14,103], cannot use -14~-1 as index for m_veboxHwEntry
1474     if (inputformat < 0)
1475     {
1476         inputformat = Format_Any;
1477     }
1478 
1479     if (engine.value != 0)
1480     {
1481         VP_PUBLIC_NORMALMESSAGE("Lumakey Feature Already been processed, Skip further process");
1482         PrintFeatureExecutionCaps(__FUNCTION__, engine);
1483         return MOS_STATUS_SUCCESS;
1484     }
1485 
1486     engine.bEnabled = 1;
1487     engine.RenderNeeded = 1;
1488     engine.fcSupported = 1;
1489 
1490     PrintFeatureExecutionCaps(__FUNCTION__, engine);
1491     return MOS_STATUS_SUCCESS;
1492 }
1493 
GetBlendingExecutionCaps(SwFilter * feature)1494 MOS_STATUS Policy::GetBlendingExecutionCaps(SwFilter* feature)
1495 {
1496     VP_FUNC_CALL();
1497     VP_PUBLIC_CHK_NULL_RETURN(feature);
1498 
1499     SwFilterBlending* filter = dynamic_cast<SwFilterBlending*>(feature);
1500     VP_PUBLIC_CHK_NULL_RETURN(filter);
1501 
1502     FeatureParamBlending& params = filter->GetSwFilterParams();
1503     VP_EngineEntry& engine = filter->GetFilterEngineCaps();
1504     MOS_FORMAT inputformat = params.formatInput;
1505 
1506     // MOS_FORMAT is [-14,103], cannot use -14~-1 as index for m_veboxHwEntry
1507     if (inputformat < 0)
1508     {
1509         inputformat = Format_Any;
1510     }
1511 
1512     if (engine.value != 0)
1513     {
1514         VP_PUBLIC_NORMALMESSAGE("Blending Feature Already been processed, Skip further process");
1515         PrintFeatureExecutionCaps(__FUNCTION__, engine);
1516         return MOS_STATUS_SUCCESS;
1517     }
1518 
1519     engine.bEnabled = 1;
1520     engine.RenderNeeded = 1;
1521     engine.fcSupported = 1;
1522 
1523     PrintFeatureExecutionCaps(__FUNCTION__, engine);
1524     return MOS_STATUS_SUCCESS;
1525 }
1526 
GetExecutionCaps(SwFilter * feature)1527 MOS_STATUS Policy::GetExecutionCaps(SwFilter* feature)
1528 {
1529     VP_FUNC_CALL();
1530 
1531     VP_PUBLIC_CHK_NULL_RETURN(feature);
1532 
1533     VP_EngineEntry &defaultEngine = feature->GetFilterEngineCaps();
1534     defaultEngine.value = 0;
1535 
1536     PrintFeatureExecutionCaps(__FUNCTION__, defaultEngine);
1537     return MOS_STATUS_SUCCESS;
1538 }
1539 
InitExecuteCaps(VP_EXECUTE_CAPS & caps,VP_EngineEntry & engineCapsInputPipe,VP_EngineEntry & engineCapsOutputPipe)1540 MOS_STATUS Policy::InitExecuteCaps(VP_EXECUTE_CAPS &caps, VP_EngineEntry &engineCapsInputPipe, VP_EngineEntry &engineCapsOutputPipe)
1541 {
1542     caps.value = 0;
1543 
1544     if (0 == engineCapsInputPipe.value)
1545     {
1546         caps.bOutputPipeFeatureInuse = engineCapsOutputPipe.bEnabled;
1547         // For color fill w/o input surface case, engineCapsOutputPipe.fcOnlyFeatureExists should be set.
1548         if (0 == engineCapsOutputPipe.value || engineCapsOutputPipe.nonFcFeatureExists || !engineCapsOutputPipe.fcOnlyFeatureExists)
1549         {
1550             caps.bVebox = true;
1551             caps.bIECP = engineCapsOutputPipe.VeboxIECPNeeded;
1552             caps.bSFC = engineCapsOutputPipe.nonVeboxFeatureExists;
1553         }
1554         else
1555         {
1556             caps.bRender = 1;
1557             caps.bComposite = 1;
1558         }
1559     }
1560     else if (engineCapsInputPipe.isolated)
1561     {
1562         if (engineCapsInputPipe.VeboxNeeded != 0 || engineCapsInputPipe.SfcNeeded != 0)
1563         {
1564             caps.bVebox = true;
1565             caps.bIECP = engineCapsInputPipe.VeboxIECPNeeded;
1566             caps.bSFC = engineCapsInputPipe.SfcNeeded != 0;
1567         }
1568         else if (engineCapsInputPipe.RenderNeeded)
1569         {
1570             caps.bRender = 1;
1571             caps.bOutputPipeFeatureInuse = true;
1572         }
1573         else
1574         {
1575             // No valid engine selected.
1576             VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_INVALID_PARAMETER);
1577         }
1578     }
1579     else if (engineCapsInputPipe.nonFcFeatureExists)
1580     {
1581         VP_EngineEntry engineCaps = engineCapsInputPipe;
1582         bool multiPassNeeded = false;
1583         if (!engineCaps.fcOnlyFeatureExists && !engineCapsOutputPipe.fcOnlyFeatureExists &&
1584             !engineCaps.multiPassNeeded)
1585         {
1586             caps.bOutputPipeFeatureInuse = true;
1587             engineCaps.value |= engineCapsOutputPipe.value;
1588         }
1589         caps.bVebox = true;
1590         caps.bIECP = engineCaps.VeboxIECPNeeded;
1591         caps.bSFC = engineCaps.nonVeboxFeatureExists;
1592         caps.bDiProcess2ndField = engineCaps.diProcess2ndField;
1593 
1594         if (engineCaps.fcOnlyFeatureExists)
1595         {
1596             // For vebox/sfc+render case, use 2nd workload (render) to do csc for better performance
1597             // in most VP common cases, e.g. NV12->RGB, to save the memory bandwidth.
1598             caps.bForceCscToRender = true;
1599         }
1600     }
1601     else
1602     {
1603         if (!engineCapsInputPipe.fcSupported)
1604         {
1605             // Should be only fc feature here.
1606             VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_INVALID_PARAMETER);
1607         }
1608         VP_EngineEntry engineCaps = engineCapsInputPipe;
1609         engineCaps.value |= engineCapsOutputPipe.value;
1610         caps.bOutputPipeFeatureInuse = true;
1611         // Fc cases.
1612         if (!engineCaps.fcOnlyFeatureExists)
1613         {
1614             // If all feature can support both vebox/sfc and fc.
1615             caps.bVebox = true;
1616             caps.bIECP = engineCapsInputPipe.VeboxIECPNeeded;
1617             caps.bSFC = engineCapsInputPipe.nonVeboxFeatureExists;
1618         }
1619         else
1620         {
1621             caps.bRender = 1;
1622             caps.bComposite = 1;
1623         }
1624 
1625         caps.bDiProcess2ndField = engineCaps.diProcess2ndField;
1626     }
1627 
1628     VP_PUBLIC_NORMALMESSAGE("Execute Caps, value 0x%x (bVebox %d, bSFC %d, bRender %d, bComposite %d, bOutputPipeFeatureInuse %d, bIECP %d, bForceCscToRender %d, bDiProcess2ndField %d)",
1629         caps.value, caps.bVebox, caps.bSFC, caps.bRender, caps.bComposite, caps.bOutputPipeFeatureInuse, caps.bIECP,
1630         caps.bForceCscToRender, caps.bDiProcess2ndField);
1631     PrintFeatureExecutionCaps("engineCapsInputPipe", engineCapsInputPipe);
1632     PrintFeatureExecutionCaps("engineCapsOutputPipe", engineCapsOutputPipe);
1633 
1634     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,
1635         (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);
1636     MT_LOG7(MT_VP_HAL_POLICY_GET_INPIPECAPS, MT_NORMAL, MT_VP_HAL_ENGINECAPS, engineCapsInputPipe.value, MT_VP_HAL_ENGINECAPS_EN, engineCapsInputPipe.bEnabled, MT_VP_HAL_ENGINECAPS_VE_NEEDED,
1637         engineCapsInputPipe.VeboxNeeded, MT_VP_HAL_ENGINECAPS_SFC_NEEDED, engineCapsInputPipe.SfcNeeded, MT_VP_HAL_ENGINECAPS_RENDER_NEEDED, engineCapsInputPipe.RenderNeeded,
1638         MT_VP_HAL_ENGINECAPS_FC_SUPPORT, engineCapsInputPipe.fcSupported, MT_VP_HAL_ENGINECAPS_ISOLATED, engineCapsInputPipe.isolated);
1639     MT_LOG7(MT_VP_HAL_POLICY_GET_OUTPIPECAPS, MT_NORMAL, MT_VP_HAL_ENGINECAPS, engineCapsOutputPipe.value, MT_VP_HAL_ENGINECAPS_EN, engineCapsOutputPipe.bEnabled, MT_VP_HAL_ENGINECAPS_VE_NEEDED,
1640         engineCapsOutputPipe.VeboxNeeded, MT_VP_HAL_ENGINECAPS_SFC_NEEDED, engineCapsOutputPipe.SfcNeeded, MT_VP_HAL_ENGINECAPS_RENDER_NEEDED, engineCapsOutputPipe.RenderNeeded,
1641         MT_VP_HAL_ENGINECAPS_FC_SUPPORT, engineCapsOutputPipe.fcSupported, MT_VP_HAL_ENGINECAPS_ISOLATED, engineCapsOutputPipe.isolated);
1642 
1643     return MOS_STATUS_SUCCESS;
1644 }
1645 
GetOutputPipeEngineCaps(SwFilterPipe & featurePipe,VP_EngineEntry & engineCapsOutputPipe,SwFilterSubPipe * inputPipeSelected)1646 MOS_STATUS Policy::GetOutputPipeEngineCaps(SwFilterPipe& featurePipe, VP_EngineEntry &engineCapsOutputPipe, SwFilterSubPipe *inputPipeSelected)
1647 {
1648     SwFilterSubPipe *featureSubPipe = featurePipe.GetSwFilterSubPipe(false, 0);
1649     VP_PUBLIC_CHK_NULL_RETURN(featureSubPipe);
1650 
1651     engineCapsOutputPipe.value = 0;
1652 
1653     for (auto featureType : m_featurePool)
1654     {
1655         SwFilter *swFilter = featureSubPipe->GetSwFilter(featureType);
1656 
1657         if (nullptr == swFilter)
1658         {
1659             continue;
1660         }
1661 
1662         VP_EngineEntry engineCaps = swFilter->GetCombinedFilterEngineCaps(inputPipeSelected);
1663 
1664         if (!engineCaps.bEnabled)
1665         {
1666             continue;
1667         }
1668 
1669         if (engineCaps.isolated || !engineCaps.RenderNeeded || !engineCaps.fcSupported)
1670         {
1671             // No support for non-fc supported feature in current stage.
1672             // Will add it if needed.
1673             VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_INVALID_PARAMETER);
1674         }
1675 
1676         if (!engineCaps.SfcNeeded && !engineCaps.VeboxNeeded && !engineCaps.bypassIfVeboxSfcInUse)
1677         {
1678             engineCapsOutputPipe.fcOnlyFeatureExists = true;
1679         }
1680         engineCapsOutputPipe.value |= engineCaps.value;
1681         engineCapsOutputPipe.nonVeboxFeatureExists |= (!engineCaps.VeboxNeeded && !engineCaps.bypassIfVeboxSfcInUse);
1682     }
1683 
1684     PrintFeatureExecutionCaps(__FUNCTION__, engineCapsOutputPipe);
1685     MT_LOG7(MT_VP_HAL_POLICY_GET_OUTPIPECAPS, MT_NORMAL, MT_VP_HAL_ENGINECAPS, engineCapsOutputPipe.value, MT_VP_HAL_ENGINECAPS_EN, engineCapsOutputPipe.bEnabled, MT_VP_HAL_ENGINECAPS_VE_NEEDED,
1686         engineCapsOutputPipe.VeboxNeeded, MT_VP_HAL_ENGINECAPS_SFC_NEEDED, engineCapsOutputPipe.SfcNeeded, MT_VP_HAL_ENGINECAPS_RENDER_NEEDED, engineCapsOutputPipe.RenderNeeded,
1687         MT_VP_HAL_ENGINECAPS_FC_SUPPORT, engineCapsOutputPipe.fcSupported, MT_VP_HAL_ENGINECAPS_ISOLATED, engineCapsOutputPipe.isolated);
1688 
1689     return MOS_STATUS_SUCCESS;
1690 }
1691 
IsExcludedFeatureForHdr(FeatureType feature)1692 bool Policy::IsExcludedFeatureForHdr(FeatureType feature)
1693 {
1694     return (FeatureTypeTcc  == feature  ||
1695         FeatureTypeSte      == feature  ||
1696         FeatureTypeProcamp  == feature);
1697 }
1698 
GetInputPipeEngineCaps(SwFilterPipe & featurePipe,VP_EngineEntry & engineCapsInputPipe,SwFilterSubPipe * & singlePipeSelected,bool & isSingleSubPipe,uint32_t & selectedPipeIndex)1699 MOS_STATUS Policy::GetInputPipeEngineCaps(SwFilterPipe& featurePipe, VP_EngineEntry &engineCapsInputPipe,
1700                                         SwFilterSubPipe *&singlePipeSelected, bool &isSingleSubPipe, uint32_t &selectedPipeIndex)
1701 {
1702     // Priority for selecting features to be processed in current workload.
1703     // 1. Features with isolated flag. One isolated feature can only be processed without any other features involved.
1704     // 2. Features without fc supported flag.
1705     // 3. For single layer, select vebox, if all vebox == 1
1706     //                      select sfc, if all sfc/vebox == 1 and sfc == 1/vebox == 0 exists
1707     //    For multi layer, select FC
1708     // Add support for ordered pipe later.
1709     isSingleSubPipe = featurePipe.GetSurfaceCount(true) <= 1;
1710     singlePipeSelected = isSingleSubPipe ? featurePipe.GetSwFilterSubPipe(true, 0) : nullptr;
1711     selectedPipeIndex = 0;
1712 
1713     VP_EngineEntry engineCapsIsolated = {};     // Input pipe engine caps for isolated feature exists case.
1714     VP_EngineEntry engineCapsForVeboxSfc = {};  // Input pipe engine caps for non-fc feature exists case.
1715     VP_EngineEntry engineCapsForFc = {};        // Input pipe engine caps for fc supported by all features cases.
1716 
1717     for (uint32_t pipeIndex = 0; pipeIndex < featurePipe.GetSurfaceCount(true); ++pipeIndex)
1718     {
1719         SwFilterSubPipe *featureSubPipe = featurePipe.GetSwFilterSubPipe(true, pipeIndex);
1720         VP_PUBLIC_CHK_NULL_RETURN(featureSubPipe);
1721 
1722         bool isSfcNeeded = false;
1723         engineCapsForVeboxSfc.value = 0;
1724 
1725         for (auto featureType : m_featurePool)
1726         {
1727             SwFilter *swFilter = featureSubPipe->GetSwFilter(featureType);
1728             if (nullptr == swFilter)
1729             {
1730                 continue;
1731             }
1732 
1733             VP_EngineEntry &engineCaps = swFilter->GetFilterEngineCaps();
1734 
1735             if (!engineCaps.bEnabled)
1736             {
1737                 // Some features need to be bypassed with requirement on workload, e.g. 2nd field for DI.
1738                 if (engineCaps.bypassVeboxFeatures || engineCaps.diProcess2ndField)
1739                 {
1740                     isSingleSubPipe = true;
1741                     selectedPipeIndex = pipeIndex;
1742                     singlePipeSelected = featureSubPipe;
1743                     engineCapsForVeboxSfc.value |= engineCaps.value;
1744                     engineCapsForFc.value |= engineCaps.value;
1745                 }
1746                 if (engineCaps.sfcNotSupported)
1747                 {
1748                     // sfc cannot be selected. Resolution limit is checked with scaling filter, even scaling
1749                     // feature itself not being enabled.
1750                     engineCapsForVeboxSfc.sfcNotSupported = engineCaps.sfcNotSupported;
1751                     engineCapsForFc.sfcNotSupported = engineCaps.sfcNotSupported;
1752                     VP_PUBLIC_NORMALMESSAGE("sfcNotSupported flag is set.");
1753                 }
1754                 continue;
1755             }
1756 
1757             if (engineCaps.isolated)
1758             {
1759                 // 1. Process feature with isolated flag firstly.
1760                 isSingleSubPipe = true;
1761                 selectedPipeIndex = pipeIndex;
1762                 singlePipeSelected = featureSubPipe;
1763                 engineCapsIsolated = engineCaps;
1764                 break;
1765             }
1766             else if (!engineCaps.fcSupported)
1767             {
1768                 // 2. Process non-fc features by vebox/sfc.
1769                 if (engineCaps.RenderNeeded)
1770                 {
1771                     // Non-FC render feature should be isolated.
1772                     VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_INVALID_PARAMETER);
1773                 }
1774                 if (!engineCaps.SfcNeeded && !engineCaps.VeboxNeeded)
1775                 {
1776                     // Invalid feature with no engine enabled.
1777                     VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_INVALID_PARAMETER);
1778                 }
1779 
1780                 isSingleSubPipe = true;
1781                 selectedPipeIndex = pipeIndex;
1782                 singlePipeSelected = featureSubPipe;
1783                 engineCapsForVeboxSfc.value |= engineCaps.value;
1784                 engineCapsForVeboxSfc.nonFcFeatureExists = true;
1785                 engineCapsForVeboxSfc.nonVeboxFeatureExists |= !engineCaps.VeboxNeeded;
1786             }
1787             else
1788             {
1789                 // 3. Process features support FC.
1790                 if (engineCaps.SfcNeeded || engineCaps.VeboxNeeded)
1791                 {
1792                     engineCapsForVeboxSfc.value |= engineCaps.value;
1793                     engineCapsForVeboxSfc.nonVeboxFeatureExists |= !engineCaps.VeboxNeeded;
1794                 }
1795                 else
1796                 {
1797                     // Set fcOnlyFeatureExists flag for engineCapsForVeboxSfc to indicate that
1798                     // not all features in input pipe can be processed by vebox/sfc and
1799                     // features in output pipe cannot be combined to vebox/sfc workload.
1800                     engineCapsForVeboxSfc.fcOnlyFeatureExists = true;
1801                     engineCapsForFc.fcOnlyFeatureExists = true;
1802                 }
1803                 engineCapsForFc.value |= engineCaps.value;
1804                 engineCapsForFc.nonVeboxFeatureExists |= !engineCaps.VeboxNeeded;
1805             }
1806         }
1807 
1808         if (isSingleSubPipe)
1809         {
1810             break;
1811         }
1812     }
1813 
1814     // For multi-layer case or color fill case, force to set fcOnlyFeatureExists flag.
1815     engineCapsForFc.fcOnlyFeatureExists = engineCapsForFc.fcOnlyFeatureExists ||
1816                                         featurePipe.GetSurfaceCount(true) > 1 ||
1817                                         featurePipe.GetSurfaceCount(true) == 0 ||
1818                                         engineCapsForFc.nonVeboxFeatureExists && engineCapsForFc.sfcNotSupported;
1819 
1820     if (engineCapsForVeboxSfc.nonVeboxFeatureExists && engineCapsForVeboxSfc.sfcNotSupported)
1821     {
1822         VP_PUBLIC_NORMALMESSAGE("Clear nonVeboxFeatureExists flag to avoid sfc being selected, since sfcNotSupported == 1.");
1823         engineCapsForVeboxSfc.nonVeboxFeatureExists = 0;
1824     }
1825 
1826     // If want to disable vebox/sfc output to output surface with color fill directly for multilayer case,
1827     // fcOnlyFeatureExists need be set for vebox sfc for multi layer case here.
1828     engineCapsForVeboxSfc.fcOnlyFeatureExists = engineCapsForFc.fcOnlyFeatureExists;
1829 
1830     if (engineCapsIsolated.isolated)
1831     {
1832         VP_PUBLIC_NORMALMESSAGE("engineCapsIsolated selected.");
1833         engineCapsInputPipe = engineCapsIsolated;
1834     }
1835     else if (engineCapsForVeboxSfc.nonFcFeatureExists)
1836     {
1837         VP_PUBLIC_NORMALMESSAGE("engineCapsForVeboxSfc selected.");
1838         engineCapsInputPipe = engineCapsForVeboxSfc;
1839     }
1840     else
1841     {
1842         VP_PUBLIC_NORMALMESSAGE("engineCapsForFc selected.");
1843         if (0 == engineCapsForFc.bEnabled)
1844         {
1845             engineCapsForFc.fcSupported = true;
1846             // Decision on choosing between vebox/sfc and render will be made in InitExecuteCaps.
1847             VP_PUBLIC_NORMALMESSAGE("Surface copy with no feature enabled. Force set fcSupported flag.");
1848         }
1849         engineCapsInputPipe = engineCapsForFc;
1850     }
1851 
1852     PrintFeatureExecutionCaps(__FUNCTION__, engineCapsInputPipe);
1853     MT_LOG7(MT_VP_HAL_POLICY_GET_INPIPECAPS, MT_NORMAL, MT_VP_HAL_ENGINECAPS, engineCapsInputPipe.value, MT_VP_HAL_ENGINECAPS_EN, engineCapsInputPipe.bEnabled,
1854         MT_VP_HAL_ENGINECAPS_VE_NEEDED, engineCapsInputPipe.VeboxNeeded, MT_VP_HAL_ENGINECAPS_SFC_NEEDED, engineCapsInputPipe.SfcNeeded, MT_VP_HAL_ENGINECAPS_RENDER_NEEDED,
1855         engineCapsInputPipe.RenderNeeded, MT_VP_HAL_ENGINECAPS_FC_SUPPORT, engineCapsInputPipe.fcSupported, MT_VP_HAL_ENGINECAPS_ISOLATED, engineCapsInputPipe.isolated);
1856 
1857     return MOS_STATUS_SUCCESS;
1858 }
1859 
BypassVeboxFeatures(SwFilterSubPipe * featureSubPipe,VP_EngineEntry & engineCaps)1860 MOS_STATUS Policy::BypassVeboxFeatures(SwFilterSubPipe *featureSubPipe, VP_EngineEntry &engineCaps)
1861 {
1862     VP_PUBLIC_CHK_NULL_RETURN(featureSubPipe);
1863 
1864     for (auto filterID : m_featurePool)
1865     {
1866         SwFilter *feature = featureSubPipe->GetSwFilter(FeatureType(filterID));
1867 
1868         if (nullptr == feature)
1869         {
1870             continue;
1871         }
1872 
1873         if (feature->GetFilterEngineCaps().VeboxNeeded)
1874         {
1875             // Disable vebox features and avoid it run into render path.
1876             feature->GetFilterEngineCaps().VeboxNeeded = 0;
1877             feature->GetFilterEngineCaps().RenderNeeded = 0;
1878             feature->GetFilterEngineCaps().bEnabled = feature->GetFilterEngineCaps().SfcNeeded;
1879         }
1880     }
1881 
1882     engineCaps.nonVeboxFeatureExists = true;
1883 
1884     return MOS_STATUS_SUCCESS;
1885 }
1886 
BuildExecuteCaps(SwFilterPipe & featurePipe,VP_EXECUTE_CAPS & caps,VP_EngineEntry & engineCapsInputPipe,VP_EngineEntry & engineCapsOutputPipe,bool & isSingleSubPipe,uint32_t & selectedPipeIndex)1887 MOS_STATUS Policy::BuildExecuteCaps(SwFilterPipe& featurePipe, VP_EXECUTE_CAPS &caps, VP_EngineEntry &engineCapsInputPipe, VP_EngineEntry &engineCapsOutputPipe,
1888                                     bool &isSingleSubPipe, uint32_t &selectedPipeIndex)
1889 {
1890     SwFilterSubPipe *singlePipeSelected = nullptr;
1891 
1892     caps.value = 0;
1893     engineCapsOutputPipe.value = 0;
1894     engineCapsInputPipe.value = 0;
1895     isSingleSubPipe = false;
1896     selectedPipeIndex = 0;
1897 
1898     VP_PUBLIC_CHK_STATUS_RETURN(GetInputPipeEngineCaps(featurePipe, engineCapsInputPipe,
1899                                                     singlePipeSelected, isSingleSubPipe, selectedPipeIndex));
1900     VP_PUBLIC_CHK_STATUS_RETURN(GetOutputPipeEngineCaps(featurePipe, engineCapsOutputPipe, singlePipeSelected));
1901 
1902     if (engineCapsInputPipe.bypassVeboxFeatures)
1903     {
1904         if (engineCapsInputPipe.isolated)
1905         {
1906             // isolated feature case should not come here.
1907             VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_INVALID_PARAMETER);
1908         }
1909         VP_PUBLIC_CHK_STATUS_RETURN(BypassVeboxFeatures(singlePipeSelected, engineCapsInputPipe));
1910     }
1911 
1912     VP_PUBLIC_CHK_STATUS_RETURN(InitExecuteCaps(caps, engineCapsInputPipe, engineCapsOutputPipe));
1913 
1914     return MOS_STATUS_SUCCESS;
1915 }
1916 
BuildFilters(SwFilterPipe & featurePipe,HW_FILTER_PARAMS & params)1917 MOS_STATUS Policy::BuildFilters(SwFilterPipe& featurePipe, HW_FILTER_PARAMS& params)
1918 {
1919     VP_FUNC_CALL();
1920 
1921     VP_EngineEntry engineCaps = {};
1922     VP_EXECUTE_CAPS caps = {};
1923     VP_EngineEntry engineCapsInputPipe = {};
1924     VP_EngineEntry engineCapsOutputPipe = {};
1925     bool isSingleSubPipe = false;
1926     uint32_t selectedPipeIndex = 0;
1927 
1928     VP_PUBLIC_CHK_STATUS_RETURN(BuildExecuteCaps(featurePipe, caps, engineCapsInputPipe, engineCapsOutputPipe, isSingleSubPipe, selectedPipeIndex));
1929 
1930     std::vector<int> layerIndexes;
1931     VP_PUBLIC_CHK_STATUS_RETURN(LayerSelectForProcess(layerIndexes, featurePipe, isSingleSubPipe, selectedPipeIndex, caps));
1932 
1933     if (IsVeboxSecurePathEnabled(featurePipe, caps))
1934     {
1935         // Process Vebox Secure workload
1936         VP_PUBLIC_CHK_STATUS_RETURN(BuildVeboxSecureFilters(featurePipe, caps, params));
1937 
1938         VP_PUBLIC_CHK_STATUS_RETURN(SetupFilterResource(featurePipe, layerIndexes, caps, params));
1939 
1940         VP_PUBLIC_CHK_STATUS_RETURN(BuildExecuteHwFilter(caps, params));
1941         return MOS_STATUS_SUCCESS;
1942     }
1943 
1944     // Set feature types with engine for selected features
1945     VP_PUBLIC_CHK_STATUS_RETURN(UpdateFeatureTypeWithEngine(layerIndexes, featurePipe, caps, engineCapsInputPipe.isolated, caps.bOutputPipeFeatureInuse/*engineCapsOutputPipe.bEnabled*/));
1946 
1947     VP_PUBLIC_CHK_STATUS_RETURN(BuildExecuteFilter(featurePipe, layerIndexes, caps, params));
1948     VP_PUBLIC_CHK_STATUS_RETURN(featurePipe.ResetSecureFlag());
1949 
1950     /* Place Holder for Resource Manager to manage intermedia surface or HW needed surface in policy*/
1951 
1952     return MOS_STATUS_SUCCESS;
1953 }
1954 
FilterFeatureCombination(SwFilterPipe & swFilterPipe,bool isInputPipe,uint32_t index)1955 MOS_STATUS Policy::FilterFeatureCombination(SwFilterPipe &swFilterPipe, bool isInputPipe, uint32_t index)
1956 {
1957     VP_FUNC_CALL();
1958 
1959     SwFilterSubPipe *pipe = nullptr;
1960     pipe                  = swFilterPipe.GetSwFilterSubPipe(isInputPipe, index);
1961     VP_PUBLIC_CHK_NULL_RETURN(pipe);
1962 
1963     auto hdr = pipe->GetSwFilter(FeatureTypeHdr);
1964     if (nullptr != hdr)
1965     {
1966         for (auto filterID : m_featurePool)
1967         {
1968             if (IsExcludedFeatureForHdr(filterID))
1969             {
1970                 auto feature = pipe->GetSwFilter(FeatureType(filterID));
1971                 if (feature && feature->GetFilterEngineCaps().bEnabled)
1972                 {
1973                     feature->GetFilterEngineCaps().bEnabled = false;
1974                 }
1975             }
1976             if (filterID == FeatureTypeCsc)
1977             {
1978                 SwFilterCsc *feature = (SwFilterCsc *)pipe->GetSwFilter(FeatureType(filterID));
1979                 if (feature)
1980                 {
1981                     auto &params      = feature->GetSwFilterParams();
1982                     params.pIEFParams = nullptr;
1983                 }
1984             }
1985         }
1986     }
1987     return MOS_STATUS_SUCCESS;
1988 }
1989 
BuildExecuteFilter(SwFilterPipe & featurePipe,std::vector<int> & layerIndexes,VP_EXECUTE_CAPS & caps,HW_FILTER_PARAMS & params)1990 MOS_STATUS Policy::BuildExecuteFilter(SwFilterPipe& featurePipe, std::vector<int> &layerIndexes, VP_EXECUTE_CAPS& caps, HW_FILTER_PARAMS& params)
1991 {
1992     VP_FUNC_CALL();
1993 
1994     params.Type = EngineTypeInvalid;
1995     // params.vpExecuteCaps will be assigned in Policy::BuildExecuteHwFilter.
1996     params.vpExecuteCaps.value = 0;
1997 
1998     VP_PUBLIC_CHK_STATUS_RETURN(SetupExecuteFilter(featurePipe, layerIndexes, caps, params));
1999 
2000     // Build Execute surface needed
2001     VP_PUBLIC_CHK_STATUS_RETURN(SetupFilterResource(featurePipe, layerIndexes, caps, params));
2002 
2003     VP_PUBLIC_CHK_STATUS_RETURN(featurePipe.Update());
2004     VP_PUBLIC_CHK_STATUS_RETURN(params.executedFilters->Update());
2005 
2006     if (featurePipe.IsEmpty())
2007     {
2008         caps.lastSubmission = true;
2009     }
2010 
2011     VP_PUBLIC_CHK_STATUS_RETURN(BuildExecuteHwFilter(caps, params));
2012 
2013     return MOS_STATUS_SUCCESS;
2014 }
2015 
BuildExecuteHwFilter(VP_EXECUTE_CAPS & caps,HW_FILTER_PARAMS & params)2016 MOS_STATUS Policy::BuildExecuteHwFilter(VP_EXECUTE_CAPS& caps, HW_FILTER_PARAMS& params)
2017 {
2018     VP_FUNC_CALL();
2019 
2020     if (caps.bVebox || caps.bSFC)
2021     {
2022         params.Type = caps.bSFC ? EngineTypeVeboxSfc : EngineTypeVebox;
2023         params.vpExecuteCaps = caps;
2024         auto it = m_VeboxSfcFeatureHandlers.begin();
2025         for (; it != m_VeboxSfcFeatureHandlers.end(); ++it)
2026         {
2027             if ((*(it->second)).IsFeatureEnabled(caps))
2028             {
2029                 HwFilterParameter* pHwFilterParam = (*(it->second)).CreateHwFilterParam(caps, *params.executedFilters, m_vpInterface.GetHwInterface());
2030 
2031                 if (pHwFilterParam)
2032                 {
2033                     params.Params.push_back(pHwFilterParam);
2034                 }
2035                 else
2036                 {
2037                     VP_PUBLIC_ASSERTMESSAGE("Create HW Filter Failed, Return Error");
2038                     MT_ERR2(MT_VP_HAL_POLICY, MT_ERROR_CODE, MOS_STATUS_NO_SPACE, MT_CODE_LINE, __LINE__);
2039                     return MOS_STATUS_NO_SPACE;
2040                 }
2041             }
2042         }
2043     }
2044     else if (caps.bRender)
2045     {
2046         params.Type = EngineTypeRender;
2047         params.vpExecuteCaps = caps;
2048 
2049         auto it = m_RenderFeatureHandlers.begin();
2050         for (; it != m_RenderFeatureHandlers.end(); ++it)
2051         {
2052             if ((*(it->second)).IsFeatureEnabled(caps))
2053             {
2054                 HwFilterParameter* pHwFilterParam = (*(it->second)).CreateHwFilterParam(caps, *params.executedFilters, m_vpInterface.GetHwInterface());
2055 
2056                 if (pHwFilterParam)
2057                 {
2058                     params.Params.push_back(pHwFilterParam);
2059                 }
2060                 else
2061                 {
2062                     VP_PUBLIC_ASSERTMESSAGE("Create HW Filter Failed, Return Error");
2063                     MT_ERR2(MT_VP_HAL_POLICY, MT_ERROR_CODE, MOS_STATUS_NO_SPACE, MT_CODE_LINE, __LINE__);
2064                     return MOS_STATUS_NO_SPACE;
2065                 }
2066             }
2067         }
2068     }
2069     else
2070     {
2071         VP_PUBLIC_ASSERTMESSAGE("No engine is assigned.");
2072         VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_INVALID_PARAMETER);
2073     }
2074 
2075     return MOS_STATUS_SUCCESS;
2076 }
2077 
UpdateFeatureTypeWithEngine(std::vector<int> & layerIndexes,SwFilterPipe & featurePipe,VP_EXECUTE_CAPS & caps,bool isolatedFeatureSelected,bool outputPipeNeeded)2078 MOS_STATUS Policy::UpdateFeatureTypeWithEngine(std::vector<int> &layerIndexes, SwFilterPipe& featurePipe, VP_EXECUTE_CAPS& caps,
2079                                             bool isolatedFeatureSelected, bool outputPipeNeeded)
2080 {
2081     int inputSurfCount = featurePipe.GetSurfaceCount(true);
2082     int outputSurfCount = featurePipe.GetSurfaceCount(false);
2083     SwFilterSubPipe* featureSubPipe = nullptr;
2084 
2085     for (uint32_t i = 0; i < layerIndexes.size(); ++i)
2086     {
2087         featureSubPipe = featurePipe.GetSwFilterSubPipe(true, layerIndexes[i]);
2088         VP_PUBLIC_CHK_STATUS_RETURN(UpdateFeatureTypeWithEngineSingleLayer(featureSubPipe, caps, isolatedFeatureSelected));
2089     }
2090 
2091     if (outputPipeNeeded)
2092     {
2093         featureSubPipe = featurePipe.GetSwFilterSubPipe(false, 0);
2094         VP_PUBLIC_CHK_STATUS_RETURN(UpdateFeatureTypeWithEngineSingleLayer(featureSubPipe, caps, false));
2095     }
2096 
2097     return MOS_STATUS_SUCCESS;
2098 }
2099 
UpdateFeatureTypeWithEngineSingleLayer(SwFilterSubPipe * featureSubPipe,VP_EXECUTE_CAPS & caps,bool isolatedFeatureSelected)2100 MOS_STATUS Policy::UpdateFeatureTypeWithEngineSingleLayer(SwFilterSubPipe *featureSubPipe, VP_EXECUTE_CAPS& caps, bool isolatedFeatureSelected)
2101 {
2102     bool isolatedFeatureFound = false;
2103     // Set feature types with engine
2104     for (auto filterID : m_featurePool)
2105     {
2106         auto feature = featureSubPipe->GetSwFilter(FeatureType(filterID));
2107         if (feature)
2108         {
2109             VP_EngineEntry *engineCaps = &(feature->GetFilterEngineCaps());
2110 
2111             if (isolatedFeatureSelected != engineCaps->isolated)
2112             {
2113                 continue;
2114             }
2115 
2116             // if SFC enabled, Vebox is must as SFC need connect with Vebox
2117             if (caps.bSFC                           &&
2118                 (engineCaps->forceEnableForSfc      ||
2119                 engineCaps->bEnabled && (engineCaps->VeboxNeeded || engineCaps->SfcNeeded)))
2120             {
2121                 if (engineCaps->forceEnableForSfc)
2122                 {
2123                     engineCaps->bEnabled = 1;
2124                     engineCaps->SfcNeeded = 1;
2125                 }
2126                 // Choose SFC as execution engine
2127                 VP_PUBLIC_CHK_STATUS_RETURN(UpdateExeCaps(feature, caps, engineCaps->SfcNeeded ? EngineTypeVeboxSfc : EngineTypeVebox));
2128             }
2129             // Vebox only cases
2130             else if (caps.bVebox &&
2131                 (engineCaps->bEnabled && engineCaps->VeboxNeeded || caps.bIECP && filterID == FeatureTypeCsc))
2132             {
2133                 // If HDR filter exist, handle CSC previous to HDR in AddFiltersBasedOnCaps
2134                 if (filterID == FeatureTypeCsc && IsHDRfilterExist(featureSubPipe))
2135                 {
2136                     VP_PUBLIC_NORMALMESSAGE("HDR exist, handle CSC previous to HDR in AddFiltersBasedOnCaps");
2137                     continue;
2138                 }
2139 
2140                 if (!engineCaps->bEnabled && caps.bIECP && filterID == FeatureTypeCsc)
2141                 {
2142                     engineCaps->bEnabled = 1;
2143                     engineCaps->VeboxNeeded = 1;
2144                 }
2145 
2146                 VP_PUBLIC_CHK_STATUS_RETURN(UpdateExeCaps(feature, caps, EngineTypeVebox));
2147             }
2148             else if (caps.bRender                   &&
2149                 (engineCaps->forceEnableForRender ||
2150                 engineCaps->bEnabled && engineCaps->RenderNeeded))
2151             {
2152                 if (engineCaps->forceEnableForRender)
2153                 {
2154                     engineCaps->bEnabled = 1;
2155                     engineCaps->RenderNeeded = 1;
2156                 }
2157                 // use render path to implement feature.
2158                 VP_PUBLIC_CHK_STATUS_RETURN(UpdateExeCaps(feature, caps, EngineTypeRender));
2159             }
2160 
2161             if (engineCaps->isolated)
2162             {
2163                 isolatedFeatureFound = true;
2164                 break;
2165             }
2166         }
2167     }
2168 
2169     if (isolatedFeatureSelected && !isolatedFeatureFound)
2170     {
2171         VP_PUBLIC_ASSERTMESSAGE("Isolated feature is not found!");
2172         VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_INVALID_PARAMETER);
2173     }
2174 
2175     return MOS_STATUS_SUCCESS;
2176 }
2177 
LayerSelectForProcess(std::vector<int> & layerIndexes,SwFilterPipe & featurePipe,bool isSingleSubPipe,uint32_t pipeIndex,VP_EXECUTE_CAPS & caps)2178 MOS_STATUS Policy::LayerSelectForProcess(std::vector<int> &layerIndexes, SwFilterPipe& featurePipe, bool isSingleSubPipe, uint32_t pipeIndex, VP_EXECUTE_CAPS& caps)
2179 {
2180     layerIndexes.clear();
2181     if (isSingleSubPipe && !caps.bComposite)
2182     {
2183         layerIndexes.push_back(pipeIndex);
2184         return MOS_STATUS_SUCCESS;
2185     }
2186 
2187     if (!caps.bComposite)
2188     {
2189         VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_INVALID_PARAMETER);
2190     }
2191 
2192     auto it = m_RenderFeatureHandlers.find(FeatureTypeFcOnRender);
2193     if (m_RenderFeatureHandlers.end() == it)
2194     {
2195         VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_INVALID_PARAMETER);
2196     }
2197 
2198     auto osInterface = m_vpInterface.GetHwInterface()->m_osInterface;
2199 
2200     for (uint32_t i = 0; i < featurePipe.GetSurfaceCount(true); ++i)
2201     {
2202         VP_SURFACE *input = featurePipe.GetSurface(true, i);
2203         VP_PUBLIC_CHK_NULL_RETURN(input);
2204         VP_PUBLIC_CHK_NULL_RETURN(input->osSurface);
2205         uint64_t gpuVa = osInterface->pfnGetResourceGfxAddress(osInterface, &input->osSurface->OsResource);
2206 
2207         VP_PUBLIC_NORMALMESSAGE("layer %d, gpuVa = 0x%llx", i, gpuVa);
2208     }
2209 
2210     VP_SURFACE *output = featurePipe.GetSurface(false, 0);
2211     VP_PUBLIC_CHK_NULL_RETURN(output);
2212     VP_PUBLIC_CHK_NULL_RETURN(output->osSurface);
2213     uint64_t gpuVa = osInterface->pfnGetResourceGfxAddress(osInterface, &output->osSurface->OsResource);
2214     VP_PUBLIC_NORMALMESSAGE("target, gpuVa = 0x%llx", gpuVa);
2215 
2216     PolicyFcHandler *fcHandler = dynamic_cast<PolicyFcHandler *>(it->second);
2217     VP_PUBLIC_CHK_STATUS_RETURN(fcHandler->LayerSelectForProcess(layerIndexes, featurePipe, isSingleSubPipe, pipeIndex, caps));
2218 
2219     if (layerIndexes.size() < featurePipe.GetSurfaceCount(true))
2220     {
2221         // Multi pass needed.
2222         VP_PUBLIC_CHK_STATUS_RETURN(m_vpInterface.GetResourceManager()->PrepareFcIntermediateSurface(featurePipe));
2223     }
2224 
2225     return MOS_STATUS_SUCCESS;
2226 }
2227 
AddInputSurfaceForSingleLayer(SwFilterPipe & featurePipe,uint32_t pipeIndex,SwFilterPipe & executedFilters,uint32_t & executePipeIndex,VP_EXECUTE_CAPS & caps)2228 MOS_STATUS AddInputSurfaceForSingleLayer(SwFilterPipe &featurePipe, uint32_t pipeIndex, SwFilterPipe &executedFilters, uint32_t &executePipeIndex, VP_EXECUTE_CAPS& caps)
2229 {
2230     // Single layer add input surface
2231     if (caps.value)
2232     {
2233         // Move surfaces from subSwFilterPipe to executedFilters.
2234         VP_SURFACE *surfInput = featurePipe.GetSurface(true, pipeIndex);
2235         if (surfInput)
2236         {
2237             // surface should be added before swFilters, since empty feature pipe will be allocated accordingly when surface being added.
2238             executePipeIndex = executedFilters.GetSurfaceCount(true);
2239             VP_PUBLIC_CHK_STATUS_RETURN(executedFilters.AddSurface(surfInput, true, executePipeIndex));
2240             VP_SURFACE *pastRefSurface = featurePipe.RemovePastSurface(pipeIndex);
2241             VP_SURFACE *futureRefSurface = featurePipe.RemoveFutureSurface(pipeIndex);
2242             executedFilters.SetPastSurface(executePipeIndex, pastRefSurface);
2243             executedFilters.SetFutureSurface(executePipeIndex, futureRefSurface);
2244             executedFilters.SetLinkedLayerIndex(executePipeIndex, pipeIndex);
2245         }
2246         else
2247         {
2248             VP_PUBLIC_ASSERTMESSAGE("No input for current pipe");
2249         }
2250     }
2251     return MOS_STATUS_SUCCESS;
2252 }
2253 
SetupExecuteFilter(SwFilterPipe & featurePipe,std::vector<int> & layerIndexes,VP_EXECUTE_CAPS & caps,HW_FILTER_PARAMS & params)2254 MOS_STATUS Policy::SetupExecuteFilter(SwFilterPipe& featurePipe, std::vector<int> &layerIndexes, VP_EXECUTE_CAPS& caps, HW_FILTER_PARAMS& params)
2255 {
2256     VP_FUNC_CALL();
2257 
2258     VP_PUBLIC_CHK_NULL_RETURN(params.executedFilters);
2259 
2260     for (uint32_t i = 0; i < layerIndexes.size(); ++i)
2261     {
2262         VP_PUBLIC_CHK_STATUS_RETURN(AddInputSurfaceForSingleLayer(featurePipe, layerIndexes[i], *params.executedFilters, i, caps));
2263         VP_PUBLIC_CHK_STATUS_RETURN(UpdateFeaturePipeSingleLayer(featurePipe, layerIndexes[i], *params.executedFilters, i, caps));
2264         VP_PUBLIC_CHK_STATUS_RETURN(AddFiltersBasedOnCaps(featurePipe, layerIndexes[i], caps, *params.executedFilters, i));
2265     }
2266 
2267     /* Place Holder: order pipe need to be insert in next step*/
2268 
2269     VP_PUBLIC_CHK_STATUS_RETURN(UpdateFeatureOutputPipe(layerIndexes, featurePipe, *params.executedFilters, caps));
2270 
2271     return MOS_STATUS_SUCCESS;
2272 }
2273 
UpdateFeaturePipe(SwFilterPipe & featurePipe,uint32_t pipeIndex,SwFilterPipe & executedFilters,uint32_t executePipeIndex,bool isInputPipe,VP_EXECUTE_CAPS & caps)2274 MOS_STATUS Policy::UpdateFeaturePipe(SwFilterPipe &featurePipe, uint32_t pipeIndex, SwFilterPipe &executedFilters, uint32_t executePipeIndex,
2275                                     bool isInputPipe, VP_EXECUTE_CAPS& caps)
2276 {
2277     SwFilterSubPipe* featureSubPipe = featurePipe.GetSwFilterSubPipe(isInputPipe, pipeIndex);
2278     uint32_t featureSelected = 0;
2279 
2280     VP_PUBLIC_CHK_NULL_RETURN(featureSubPipe);
2281     // Move swfilter from feature sub pipe to params.executedFilters
2282     for (auto filterID : m_featurePool)
2283     {
2284         SwFilter *feature = (SwFilter*)featureSubPipe->GetSwFilter(FeatureType(filterID));
2285         if (feature)
2286         {
2287             VP_EngineEntry *engineCaps = &(feature->GetFilterEngineCaps());
2288 
2289             if (engineCaps->usedForNextPass)
2290             {
2291                 continue;
2292             }
2293 
2294             if ((caps.bSFC || caps.bVebox) && engineCaps->bEnabled && IS_FEATURE_TYPE_ON_VEBOX_SFC(feature->GetFeatureType()) &&
2295                 m_VeboxSfcFeatureHandlers.end() != m_VeboxSfcFeatureHandlers.find(feature->GetFeatureType()))
2296             {
2297                 // Engine has been assigned to feature.
2298                 auto it = m_VeboxSfcFeatureHandlers.find(feature->GetFeatureType());
2299                 if (m_VeboxSfcFeatureHandlers.end() == it)
2300                 {
2301                     VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_NULL_POINTER);
2302                 }
2303                 PolicyFeatureHandler *handler = it->second;
2304                 VP_PUBLIC_CHK_STATUS_RETURN(handler->UpdateFeaturePipe(caps, *feature, featurePipe, executedFilters, isInputPipe, executePipeIndex));
2305                 if (!engineCaps->bEnabled)
2306                 {
2307                     VP_PUBLIC_NORMALMESSAGE("filter is disable during UpdateFeaturePipe");
2308                 }
2309                 ++featureSelected;
2310             }
2311             else if (caps.bRender && engineCaps->bEnabled && IS_FEATURE_TYPE_ON_RENDER(feature->GetFeatureType()) &&
2312                     m_RenderFeatureHandlers.end() != m_RenderFeatureHandlers.find(feature->GetFeatureType()))
2313             {
2314                 auto it = m_RenderFeatureHandlers.find(feature->GetFeatureType());
2315                 if (m_RenderFeatureHandlers.end() == it)
2316                 {
2317                     VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_NULL_POINTER);
2318                 }
2319                 PolicyFeatureHandler *handler = it->second;
2320 
2321                 VP_PUBLIC_CHK_STATUS_RETURN(handler->UpdateFeaturePipe(caps, *feature, featurePipe, executedFilters, isInputPipe, executePipeIndex));
2322                 if (!engineCaps->bEnabled)
2323                 {
2324                     VP_PUBLIC_NORMALMESSAGE("filter is disable during UpdateFeaturePipe");
2325                 }
2326                 ++featureSelected;
2327             }
2328             else
2329             {
2330                 auto *handlers = (caps.bSFC || caps.bVebox) ? &m_VeboxSfcFeatureHandlers : &m_RenderFeatureHandlers;
2331                 auto it = handlers->find(feature->GetFeatureType());
2332                 if (handlers->end() != it)
2333                 {
2334                     PolicyFeatureHandler *handler = it->second;
2335                     VP_PUBLIC_CHK_STATUS_RETURN(handler->UpdateUnusedFeature(caps, *feature, featurePipe, executedFilters, isInputPipe, executePipeIndex));
2336                 }
2337             }
2338 
2339             if (!engineCaps->bEnabled)
2340             {
2341                 // Feature may be disabled during UpdateFeaturePipe, such as colorfill and alpha, which will
2342                 // be combined into scaling in sfc.
2343                 SwFilterFeatureHandler *handler = m_vpInterface.GetSwFilterHandler(feature->GetFeatureType());
2344                 if (!handler)
2345                 {
2346                     VP_PUBLIC_ASSERTMESSAGE("no Feature Handle, Return Pipe Init Error");
2347                     return MOS_STATUS_INVALID_HANDLE;
2348                 }
2349 
2350                 featurePipe.RemoveSwFilter(feature);
2351                 handler->Destory(feature);
2352                 VP_PUBLIC_NORMALMESSAGE("filter is disable during UpdateFeaturePipe");
2353             }
2354         }
2355     }
2356 
2357     if (!isInputPipe && featureSelected && !featureSubPipe->IsEmpty() && featurePipe.IsAllInputPipeSurfaceFeatureEmpty())
2358     {
2359         VP_PUBLIC_ASSERTMESSAGE("Not all output features being selected!");
2360     }
2361 
2362     return MOS_STATUS_SUCCESS;
2363 }
2364 
UpdateFeaturePipeSingleLayer(SwFilterPipe & featurePipe,uint32_t pipeIndex,SwFilterPipe & executedFilters,uint32_t executePipeIndex,VP_EXECUTE_CAPS & caps)2365 MOS_STATUS Policy::UpdateFeaturePipeSingleLayer(SwFilterPipe &featurePipe, uint32_t pipeIndex, SwFilterPipe &executedFilters, uint32_t executePipeIndex, VP_EXECUTE_CAPS& caps)
2366 {
2367     VP_PUBLIC_CHK_STATUS_RETURN(UpdateFeaturePipe(featurePipe, pipeIndex, executedFilters, executePipeIndex, true, caps));
2368 
2369     return MOS_STATUS_SUCCESS;
2370 }
2371 
UpdateFeatureOutputPipe(std::vector<int> & layerIndexes,SwFilterPipe & featurePipe,SwFilterPipe & executedFilters,VP_EXECUTE_CAPS & caps)2372 MOS_STATUS Policy::UpdateFeatureOutputPipe(std::vector<int> &layerIndexes, SwFilterPipe &featurePipe, SwFilterPipe &executedFilters, VP_EXECUTE_CAPS& caps)
2373 {
2374     if (!caps.bOutputPipeFeatureInuse)
2375     {
2376         return MOS_STATUS_SUCCESS;
2377     }
2378 
2379     if (!featurePipe.IsAllInputPipeSurfaceFeatureEmpty(layerIndexes))
2380     {
2381         VPHAL_PUBLIC_ASSERTMESSAGE("bOutputPipeFeatureInuse being set but input pipe is not empty.");
2382         VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_INVALID_PARAMETER);
2383     }
2384 
2385     VP_PUBLIC_CHK_STATUS_RETURN(UpdateFeaturePipe(featurePipe, 0, executedFilters, 0, false, caps));
2386 
2387     return MOS_STATUS_SUCCESS;
2388 }
2389 
SetupFilterResource(SwFilterPipe & featurePipe,std::vector<int> & layerIndexes,VP_EXECUTE_CAPS & caps,HW_FILTER_PARAMS & params)2390 MOS_STATUS Policy::SetupFilterResource(SwFilterPipe& featurePipe, std::vector<int> &layerIndexes, VP_EXECUTE_CAPS& caps, HW_FILTER_PARAMS& params)
2391 {
2392     VP_FUNC_CALL();
2393 
2394     VP_SURFACE* surfInput  = nullptr;
2395     VP_SURFACE* surfOutput = nullptr;
2396     uint32_t i = 0;
2397 
2398     if (featurePipe.IsEmpty())
2399     {
2400         // If all subpipes are empty, which means no swfilter exists in featurePipe, just move output surface from featurePipe to executedFilters.
2401         // In such case, processing complete.
2402         // Update the input feature surfaces
2403         surfOutput = featurePipe.RemoveSurface(false, 0);
2404         VP_PUBLIC_CHK_NULL_RETURN(surfOutput);
2405         // surface should be added before swFilters, since empty feature pipe will be allocated accordingly when surface being added.
2406         VP_PUBLIC_CHK_STATUS_RETURN(params.executedFilters->AddSurface(surfOutput, false, 0));
2407         VP_PUBLIC_NORMALMESSAGE("Output surface in use, since no filters left in featurePipe.");
2408     }
2409     else if (RenderTargetTypeParameter == featurePipe.GetRenderTargetType())
2410     {
2411         surfOutput = featurePipe.GetSurface(false, 0);
2412         VP_PUBLIC_CHK_NULL_RETURN(surfOutput);
2413         VP_SURFACE *surfOutput2 = m_vpInterface.GetAllocator().AllocateVpSurface(*surfOutput);
2414         VP_PUBLIC_CHK_NULL_RETURN(surfOutput2);
2415         VP_PUBLIC_CHK_STATUS_RETURN(params.executedFilters->AddSurface(surfOutput2, false, 0));
2416         VP_PUBLIC_NORMALMESSAGE("Output surface in use, since only parameter filters in featurePipe.");
2417     }
2418     else if (caps.bOutputPipeFeatureInuse)
2419     {
2420         // Use intermedia surfaces for multi layer case, or color fill during composition may not
2421         // act correctly.
2422         VP_PUBLIC_NORMALMESSAGE("Intermedia surface in use with 1 == bOutputPipeFeatureInuse.");
2423     }
2424     else if (IsSecureResourceNeeded(caps))
2425     {
2426         VP_PUBLIC_CHK_STATUS_RETURN(UpdateSecureExecuteResource(featurePipe, caps, params));
2427     }
2428     else
2429     {
2430         // If not assign output surface, intermedia surface will be assigned in AssignExecuteResource.
2431     }
2432 
2433     VP_PUBLIC_CHK_STATUS_RETURN(AssignExecuteResource(caps, params));
2434 
2435     SwFilterSubPipe *subPipe = nullptr;
2436 
2437     if (1 == layerIndexes.size())
2438     {
2439         subPipe = featurePipe.GetSwFilterSubPipe(true, layerIndexes[0]);
2440     }
2441 
2442     if (featurePipe.IsEmpty())
2443     {
2444         // Update the input feature surfaces
2445         for (i = 0; i < layerIndexes.size(); ++i)
2446         {
2447             surfInput = featurePipe.RemoveSurface(true, layerIndexes[i]);
2448         }
2449     }
2450     else if (subPipe && RenderTargetTypeParameter == subPipe->GetRenderTargetType())
2451     {
2452         surfInput = featurePipe.GetSurface(true, layerIndexes[0]);
2453         VP_PUBLIC_CHK_NULL_RETURN(surfInput);
2454         VP_SURFACE* input = m_vpInterface.GetAllocator().AllocateVpSurface(*surfInput);
2455         VP_PUBLIC_CHK_NULL_RETURN(input);
2456         input->SurfType = SURF_IN_PRIMARY;
2457         featurePipe.ReplaceSurface(input, true, layerIndexes[0]);
2458     }
2459     else if (IsSecureResourceNeeded(caps))
2460     {
2461         VP_PUBLIC_NORMALMESSAGE("Secure Process Enabled, no need further process");
2462     }
2463     else
2464     {
2465         auto osInterface = m_vpInterface.GetHwInterface()->m_osInterface;
2466         auto outputSurfaceExePipe = params.executedFilters->GetSurface(false, 0);
2467         VP_PUBLIC_CHK_NULL_RETURN(outputSurfaceExePipe);
2468         auto outputSurface = featurePipe.GetSurface(false, 0);
2469         VP_PUBLIC_CHK_NULL_RETURN(outputSurface);
2470         bool outputSurfaceInuse =
2471             outputSurfaceExePipe->GetAllocationHandle(osInterface) == outputSurface->GetAllocationHandle(osInterface);
2472 
2473         if (outputSurfaceInuse)
2474         {
2475             // Update the input feature surfaces
2476             for (i = 0; i < layerIndexes.size(); ++i)
2477             {
2478                 surfInput = featurePipe.RemoveSurface(true, layerIndexes[i]);
2479             }
2480         }
2481         else
2482         {
2483             // multi-pass with intermedia surface case.
2484             auto intermediaSurface = outputSurfaceExePipe;
2485             VP_SURFACE *input =  m_vpInterface.GetAllocator().AllocateVpSurface(*intermediaSurface);
2486             VP_PUBLIC_CHK_NULL_RETURN(input);
2487 
2488             // For FC, also reuse first pipe for the composition layer in previous steps.
2489             auto originInput = featurePipe.GetSurface(true, layerIndexes[0]);
2490             VP_PUBLIC_CHK_NULL_RETURN(originInput);
2491 
2492             input->SurfType = originInput->SurfType;
2493             featurePipe.ReplaceSurface(input, true, layerIndexes[0]);
2494 
2495             // Update other input surfaces
2496             for (i = 1; i < layerIndexes.size(); ++i)
2497             {
2498                 surfInput = featurePipe.RemoveSurface(true, layerIndexes[i]);
2499             }
2500 
2501             auto swFilterSubPipe = featurePipe.GetSwFilterSubPipe(true, layerIndexes[0]);
2502             VP_PUBLIC_CHK_NULL_RETURN(swFilterSubPipe);
2503 
2504             VP_SURFACE *output = featurePipe.GetSurface(false, 0);
2505             VP_PUBLIC_CHK_NULL_RETURN(output);
2506 
2507             // swFilters will be updated later in Policy::BuildExecuteFilter.
2508             VP_PUBLIC_CHK_STATUS_RETURN(AddCommonFilters(*swFilterSubPipe, input, output));
2509         }
2510     }
2511 
2512     return MOS_STATUS_SUCCESS;
2513 }
2514 
AddCommonFilters(SwFilterSubPipe & swFilterSubPipe,VP_SURFACE * input,VP_SURFACE * output)2515 MOS_STATUS Policy::AddCommonFilters(SwFilterSubPipe &swFilterSubPipe, VP_SURFACE *input, VP_SURFACE *output)
2516 {
2517     VP_FUNC_CALL();
2518     VP_PUBLIC_CHK_NULL_RETURN(input);
2519     VP_PUBLIC_CHK_NULL_RETURN(output);
2520 
2521     FeatureType featureList[] = { FeatureTypeScaling };
2522     int32_t featureCount = sizeof(featureList) / sizeof(featureList[0]);
2523     VP_EXECUTE_CAPS caps = {};
2524 
2525     for (int32_t i = 0; i < featureCount; ++i)
2526     {
2527         FeatureType featureType = featureList[i];
2528 
2529         SwFilter *swFilter = swFilterSubPipe.GetSwFilter(featureType);
2530         if (nullptr != swFilter)
2531         {
2532             continue;
2533         }
2534 
2535         VP_PUBLIC_NORMALMESSAGE("Feature %d is added.", FeatureTypeScaling);
2536 
2537         caps.value = 0;
2538 
2539         SwFilterFeatureHandler *handler = m_vpInterface.GetSwFilterHandler(featureType);
2540         VP_PUBLIC_CHK_NULL_RETURN(handler);
2541         swFilter = handler->CreateSwFilter();
2542         VP_PUBLIC_CHK_NULL_RETURN(swFilter);
2543 
2544         VP_PUBLIC_CHK_STATUS_RETURN(swFilter->Configure(input, output, caps));
2545 
2546         VP_PUBLIC_CHK_STATUS_RETURN(swFilterSubPipe.AddSwFilterUnordered(swFilter));
2547     }
2548 
2549     return MOS_STATUS_SUCCESS;
2550 }
2551 
UpdateExeCaps(SwFilter * feature,VP_EXECUTE_CAPS & caps,EngineType Type)2552 MOS_STATUS Policy::UpdateExeCaps(SwFilter* feature, VP_EXECUTE_CAPS& caps, EngineType Type)
2553 {
2554     VP_FUNC_CALL();
2555     VP_PUBLIC_CHK_NULL_RETURN(feature);
2556 
2557     FeatureType featureType = feature->GetFeatureType();
2558 
2559     if (Type == EngineTypeVeboxSfc)
2560     {
2561         switch (featureType)
2562         {
2563         case FeatureTypeCsc:
2564             caps.bSfcCsc = 1;
2565             feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(Csc, Sfc)));
2566             break;
2567         case FeatureTypeScaling:
2568             caps.bSfcScaling = 1;
2569             if (feature->GetFilterEngineCaps().sfc2PassScalingNeededX || feature->GetFilterEngineCaps().sfc2PassScalingNeededY)
2570             {
2571                 caps.b1stPassOfSfc2PassScaling = true;
2572             }
2573             feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(Scaling, Sfc)));
2574             break;
2575         case FeatureTypeRotMir:
2576             caps.bSfcRotMir = 1;
2577             feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(RotMir, Sfc)));
2578             break;
2579         case FeatureTypeColorFill:
2580             feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(ColorFill, Sfc)));
2581             break;
2582         case FeatureTypeAlpha:
2583             feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(Alpha, Sfc)));
2584             break;
2585         default:
2586             break;
2587         }
2588     }
2589 
2590     if (Type == EngineTypeVebox)
2591     {
2592         switch (featureType)
2593         {
2594         case FeatureTypeDn:
2595             caps.bDN = 1;
2596             feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(Dn, Vebox)));
2597             break;
2598         case FeatureTypeSte:
2599             caps.bSTE = 1;
2600             feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(Ste, Vebox)));
2601             break;
2602         case FeatureTypeDi:
2603             caps.bDI = 1;
2604             feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(Di, Vebox)));
2605             break;
2606         case FeatureTypeAce:
2607             caps.bACE = 1;
2608             feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(Ace, Vebox)));
2609             break;
2610         case FeatureTypeTcc:
2611             caps.bTCC = 1;
2612             feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(Tcc, Vebox)));
2613             break;
2614         case FeatureTypeProcamp:
2615             caps.bProcamp = 1;
2616             feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(Procamp, Vebox)));
2617             break;
2618         case FeatureTypeCsc:
2619             caps.bBeCSC = 1;
2620             feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(Csc, Vebox)));
2621             break;
2622         case FeatureTypeHdr:
2623             caps.bHDR3DLUT = 1;
2624             caps.b3DlutOutput |= 1;
2625             feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(Hdr, Vebox)));
2626             break;
2627         case FeatureTypeLace:
2628             caps.bLACE = 1;
2629             feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(Lace, Vebox)));
2630             break;
2631         default:
2632             break;
2633         }
2634     }
2635 
2636     if (Type == EngineTypeRender)
2637     {
2638         switch (featureType)
2639         {
2640         case FeatureTypeCsc:
2641             caps.bComposite = 1;
2642             feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(Csc, Render)));
2643             break;
2644         case FeatureTypeScaling:
2645             caps.bComposite = 1;
2646             feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(Scaling, Render)));
2647             break;
2648         case FeatureTypeRotMir:
2649             caps.bComposite = 1;
2650             feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(RotMir, Render)));
2651             break;
2652         case FeatureTypeSR:
2653             caps.bSR = 1;
2654             feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(SR, Render)));
2655         case FeatureTypeLace:
2656             caps.bLACE = 1;
2657             feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(Lace, Render)));
2658             break;
2659         case FeatureTypeDi:
2660             caps.bDI          = 1;
2661             if (feature->GetFilterEngineCaps().isolated)
2662             {
2663                 caps.bDIFmdKernel = 1;
2664                 feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(DiFmd, Render)));
2665             }
2666             else
2667             {
2668                 feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(Di, Render)));
2669             }
2670             break;
2671         case FeatureTypeLumakey:
2672             caps.bComposite = 1;
2673             feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(Lumakey, Render)));
2674             break;
2675         case FeatureTypeBlending:
2676             caps.bComposite = 1;
2677             feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(Blending, Render)));
2678             break;
2679         case FeatureTypeColorFill:
2680             caps.bComposite = 1;
2681             feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(ColorFill, Render)));
2682             break;
2683         case FeatureTypeAlpha:
2684             caps.bComposite = 1;
2685             feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(Alpha, Render)));
2686             break;
2687         default:
2688             break;
2689         }
2690     }
2691 
2692     return MOS_STATUS_SUCCESS;
2693 }
2694 
AssignExecuteResource(VP_EXECUTE_CAPS & caps,HW_FILTER_PARAMS & params)2695 MOS_STATUS Policy::AssignExecuteResource(VP_EXECUTE_CAPS& caps, HW_FILTER_PARAMS& params)
2696 {
2697     VP_FUNC_CALL();
2698     VP_PUBLIC_CHK_NULL_RETURN(params.executedFilters);
2699     VP_PUBLIC_CHK_NULL_RETURN(m_vpInterface.GetResourceManager());
2700     VP_PUBLIC_CHK_STATUS_RETURN(m_vpInterface.GetResourceManager()->AssignExecuteResource(m_featurePool, caps, *params.executedFilters));
2701     return MOS_STATUS_SUCCESS;
2702 }
2703 
BuildVeboxSecureFilters(SwFilterPipe & featurePipe,VP_EXECUTE_CAPS & caps,HW_FILTER_PARAMS & params)2704 MOS_STATUS Policy::BuildVeboxSecureFilters(SwFilterPipe& featurePipe, VP_EXECUTE_CAPS& caps, HW_FILTER_PARAMS& params)
2705 {
2706     VP_FUNC_CALL();
2707 
2708     return MOS_STATUS_SUCCESS;
2709 }
2710 
ReleaseHwFilterParam(HW_FILTER_PARAMS & params)2711 MOS_STATUS Policy::ReleaseHwFilterParam(HW_FILTER_PARAMS &params)
2712 {
2713     VP_FUNC_CALL();
2714 
2715     if (EngineTypeInvalid == params.Type || params.Params.empty())
2716     {
2717         params.Type = EngineTypeInvalid;
2718         while (!params.Params.empty())
2719         {
2720             HwFilterParameter *p = params.Params.back();
2721             params.Params.pop_back();
2722             MOS_Delete(p);
2723         }
2724 
2725         m_vpInterface.GetSwFilterPipeFactory().Destory(params.executedFilters);
2726 
2727         return MOS_STATUS_SUCCESS;
2728     }
2729 
2730     std::map<FeatureType, PolicyFeatureHandler*> &featureHandler =
2731             (EngineTypeVebox == params.Type || EngineTypeVeboxSfc == params.Type) ? m_VeboxSfcFeatureHandlers : m_RenderFeatureHandlers;
2732 
2733     params.Type = EngineTypeInvalid;
2734     while (!params.Params.empty())
2735     {
2736         HwFilterParameter *p = params.Params.back();
2737         params.Params.pop_back();
2738         if (p)
2739         {
2740             auto it = featureHandler.find(p->GetFeatureType());
2741             if (featureHandler.end() == it)
2742             {
2743                 MOS_Delete(p);
2744             }
2745             else
2746             {
2747                 it->second->ReleaseHwFeatureParameter(p);
2748             }
2749         }
2750     }
2751 
2752     m_vpInterface.GetSwFilterPipeFactory().Destory(params.executedFilters);
2753 
2754     return MOS_STATUS_SUCCESS;
2755 }
2756 
AddFiltersBasedOnCaps(SwFilterPipe & featurePipe,uint32_t pipeIndex,VP_EXECUTE_CAPS & caps,SwFilterPipe & executedFilters,uint32_t executedPipeIndex)2757 MOS_STATUS Policy::AddFiltersBasedOnCaps(
2758     SwFilterPipe& featurePipe,
2759     uint32_t pipeIndex,
2760     VP_EXECUTE_CAPS& caps,
2761     SwFilterPipe& executedFilters,
2762     uint32_t executedPipeIndex)
2763 {
2764     VP_FUNC_CALL();
2765 
2766     // Create and Add CSC filter for VEBOX IECP chromasiting config
2767     // HDR State holder: To keep same as Legacy path -- for VE 3DLut HDR, enable VE chroma up sampling when ONLY VE output.
2768     if (!caps.bBeCSC && ((caps.bSFC && (caps.bIECP || caps.bDI)) || (!caps.bSFC && caps.b3DlutOutput)))
2769     {
2770         VP_PUBLIC_CHK_STATUS_RETURN(AddNewFilterOnVebox(featurePipe, pipeIndex, caps, executedFilters, executedPipeIndex, FeatureTypeCsc));
2771     }
2772     else
2773     {
2774         if (caps.bBeCSC && caps.bHDR3DLUT)
2775         {
2776             // bBeCSC won't be set in GetCSCExecutionCaps for HDR case
2777             VP_PUBLIC_ASSERTMESSAGE("bBeCSC shouldn't be set in GetCSCExecutionCaps for HDR case");
2778             VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_INVALID_PARAMETER);
2779         }
2780     }
2781     return MOS_STATUS_SUCCESS;
2782 }
2783 
AddNewFilterOnVebox(SwFilterPipe & featurePipe,uint32_t pipeIndex,VP_EXECUTE_CAPS & caps,SwFilterPipe & executedFilters,uint32_t executedPipeIndex,FeatureType featureType)2784 MOS_STATUS Policy::AddNewFilterOnVebox(
2785     SwFilterPipe& featurePipe,
2786     uint32_t pipeIndex,
2787     VP_EXECUTE_CAPS& caps,
2788     SwFilterPipe& executedFilters,
2789     uint32_t executedPipeIndex,
2790     FeatureType featureType)
2791 {
2792     VP_FUNC_CALL();
2793 
2794     MOS_STATUS  status      = MOS_STATUS_SUCCESS;
2795     PVP_SURFACE pSurfInput = featurePipe.GetSurface(true, pipeIndex);
2796     PVP_SURFACE pSurfOutput = featurePipe.GetSurface(false, 0);
2797     VP_PUBLIC_CHK_NULL_RETURN(pSurfInput);
2798     VP_PUBLIC_CHK_NULL_RETURN(pSurfOutput);
2799 
2800     auto handler = m_vpInterface.GetSwFilterHandler(featureType);
2801 
2802     if (!handler)
2803     {
2804         VP_PUBLIC_ASSERTMESSAGE("no Feature Handle, Return Pipe Init Error");
2805         return MOS_STATUS_INVALID_HANDLE;
2806     }
2807 
2808     SwFilter* swfilter = handler->CreateSwFilter();
2809     VP_PUBLIC_CHK_NULL_RETURN(swfilter);
2810 
2811     if (featureType == FeatureTypeCsc)
2812     {
2813         SwFilterCsc *csc = (SwFilterCsc *)swfilter;
2814         FeatureParamCsc cscParams = csc->GetSwFilterParams();
2815         VP_PUBLIC_CHK_STATUS_RETURN(GetCscParamsOnCaps(pSurfInput, pSurfOutput, caps, cscParams));
2816 
2817         status = csc->Configure(cscParams);
2818     }
2819     else
2820     {
2821         status = swfilter->Configure(pSurfInput, pSurfOutput, caps);
2822     }
2823 
2824     if (MOS_FAILED(status))
2825     {
2826         handler->Destory(swfilter);
2827         VP_PUBLIC_CHK_STATUS_RETURN(status);
2828     }
2829 
2830     VP_PUBLIC_CHK_STATUS_RETURN(UpdateExeCaps(swfilter, caps, EngineTypeVebox));
2831 
2832     status = executedFilters.AddSwFilterUnordered(swfilter, true, executedPipeIndex);
2833     VP_PUBLIC_CHK_STATUS_RETURN(status);
2834 
2835     return status;
2836 }
2837 
2838 namespace vp
2839 {
2840 MOS_STATUS GetVeboxOutputParams(VP_EXECUTE_CAPS &executeCaps, MOS_FORMAT inputFormat, MOS_TILE_TYPE inputTileType, MOS_FORMAT outputFormat, MOS_FORMAT &veboxOutputFormat, MOS_TILE_TYPE &veboxOutputTileType);
2841 }
2842 
GetCscParamsOnCaps(PVP_SURFACE surfInput,PVP_SURFACE surfOutput,VP_EXECUTE_CAPS & caps,FeatureParamCsc & cscParams)2843 MOS_STATUS Policy::GetCscParamsOnCaps(PVP_SURFACE surfInput, PVP_SURFACE surfOutput, VP_EXECUTE_CAPS &caps, FeatureParamCsc &cscParams)
2844 {
2845     if (caps.bHDR3DLUT)
2846     {
2847         cscParams.input.colorSpace  = surfInput->ColorSpace;
2848         cscParams.formatInput       = surfInput->osSurface->Format;
2849         cscParams.input.chromaSiting = surfInput->ChromaSiting;
2850 
2851         // CSC before HDR converts BT2020 P010 to ARGB10
2852         cscParams.output.colorSpace  = CSpace_BT2020_RGB;
2853         cscParams.formatOutput       = Format_B10G10R10A2;
2854         cscParams.output.chromaSiting = surfOutput->ChromaSiting;
2855 
2856         cscParams.pAlphaParams = nullptr;
2857         cscParams.pIEFParams   = nullptr;
2858 
2859         return MOS_STATUS_SUCCESS;
2860     }
2861     else if (caps.bSFC)
2862     {
2863         MOS_FORMAT    veboxOutputFormat   = surfInput->osSurface->Format;
2864         MOS_TILE_TYPE veboxOutputTileType = surfInput->osSurface->TileType;
2865 
2866         GetVeboxOutputParams(caps, surfInput->osSurface->Format, surfInput->osSurface->TileType, surfOutput->osSurface->Format, veboxOutputFormat, veboxOutputTileType);
2867         cscParams.input.colorSpace = surfInput->ColorSpace;
2868         cscParams.output.colorSpace = surfInput->ColorSpace;
2869 
2870         cscParams.formatInput        = surfInput->osSurface->Format;
2871         cscParams.formatOutput       = veboxOutputFormat;
2872         cscParams.input.chromaSiting = surfInput->ChromaSiting;
2873         cscParams.output.chromaSiting = surfOutput->ChromaSiting;
2874 
2875         cscParams.pAlphaParams = nullptr;
2876         cscParams.pIEFParams   = nullptr;
2877 
2878         return MOS_STATUS_SUCCESS;
2879     }
2880 
2881     return MOS_STATUS_UNIMPLEMENTED;
2882 }
2883 
PrintFeatureExecutionCaps(const char * name,VP_EngineEntry & engineCaps)2884 void Policy::PrintFeatureExecutionCaps(const char *name, VP_EngineEntry &engineCaps)
2885 {
2886     VP_PUBLIC_NORMALMESSAGE("%s, value 0x%x (bEnabled %d, VeboxNeeded %d, SfcNeeded %d, RenderNeeded %d, fcSupported %d, isolated %d)",
2887         name, engineCaps.value, engineCaps.bEnabled, engineCaps.VeboxNeeded, engineCaps.SfcNeeded,
2888         engineCaps.RenderNeeded, engineCaps.fcSupported, engineCaps.isolated);
2889 }
2890