xref: /aosp_15_r20/external/intel-media-driver/media_softlet/agnostic/common/vp/hal/features/vp_hdr_filter.cpp (revision ba62d9d3abf0e404f2022b4cd7a85e107f48596f)
1 /*
2 * Copyright (c) 2020-2022, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 //!
23 //! \file     vp_hdr_filter.cpp
24 //! \brief    Defines the common interface for Adaptive Contrast Enhancement
25 //!           this file is for the base interface which is shared by all Hdr in driver.
26 //!
27 #include "vp_hdr_filter.h"
28 #include "hw_filter.h"
29 #include "sw_filter_pipe.h"
30 #include "vp_render_cmd_packet.h"
31 #include "igvp3dlut_args.h"
32 
33 namespace vp
34 {
VpHdrFilter(PVP_MHWINTERFACE vpMhwInterface)35 VpHdrFilter::VpHdrFilter(PVP_MHWINTERFACE vpMhwInterface) :
36     VpFilter(vpMhwInterface), m_3DLutSurfaceWidth(LUT65_SEG_SIZE * 2), m_3DLutSurfaceHeight(LUT65_SEG_SIZE * LUT65_MUL_SIZE)
37 {
38 }
39 
Init()40 MOS_STATUS VpHdrFilter::Init()
41 {
42     VP_FUNC_CALL();
43 
44     return MOS_STATUS_SUCCESS;
45 }
46 
Prepare()47 MOS_STATUS VpHdrFilter::Prepare()
48 {
49     VP_FUNC_CALL();
50 
51     return MOS_STATUS_SUCCESS;
52 }
53 
Destroy()54 MOS_STATUS VpHdrFilter::Destroy()
55 {
56     VP_FUNC_CALL();
57     for (auto &handle : m_renderHdr3DLutL0Params)
58     {
59         KRN_ARG &krnArg = handle.second;
60         MOS_FreeMemAndSetNull(krnArg.pData);
61     }
62     return MOS_STATUS_SUCCESS;
63 }
64 
Init()65 void _RENDER_HDR_3DLUT_CAL_PARAMS::Init()
66 {
67     maxDisplayLum      = 0;
68     maxContentLevelLum = 0;
69     hdrMode            = VPHAL_HDR_MODE_NONE;
70     kernelId           = kernelCombinedFc;
71     threadWidth        = 0;
72     threadHeight       = 0;
73     kernelArgs.clear();
74 }
75 
SetExecuteEngineCaps(SwFilterPipe * executedPipe,VP_EXECUTE_CAPS vpExecuteCaps)76 MOS_STATUS VpHdrFilter::SetExecuteEngineCaps(
77         SwFilterPipe    *executedPipe,
78         VP_EXECUTE_CAPS vpExecuteCaps)
79 {
80     VP_FUNC_CALL();
81 
82     m_executedPipe  = executedPipe;
83     m_executeCaps   = vpExecuteCaps;
84 
85     return MOS_STATUS_SUCCESS;
86 }
87 
CalculateEngineParams(FeatureParamHdr & hdrParams,VP_EXECUTE_CAPS vpExecuteCaps)88 MOS_STATUS VpHdrFilter::CalculateEngineParams(
89     FeatureParamHdr &hdrParams,
90     VP_EXECUTE_CAPS  vpExecuteCaps)
91 {
92     VP_FUNC_CALL();
93     if (vpExecuteCaps.bVebox)
94     {
95         // create a filter Param buffer
96         MOS_ZeroMemory(&m_veboxHdrParams, sizeof(VEBOX_HDR_PARAMS));
97         m_veboxHdrParams.uiMaxDisplayLum      = hdrParams.uiMaxDisplayLum;
98         m_veboxHdrParams.uiMaxContentLevelLum = hdrParams.uiMaxContentLevelLum;
99         m_veboxHdrParams.hdrMode              = hdrParams.hdrMode;
100         m_veboxHdrParams.srcColorSpace        = hdrParams.srcColorSpace;
101         m_veboxHdrParams.dstColorSpace        = hdrParams.dstColorSpace;
102         m_veboxHdrParams.dstFormat            = hdrParams.formatOutput;
103         m_veboxHdrParams.stage                = hdrParams.stage;
104         m_veboxHdrParams.lutSize              = hdrParams.lutSize;
105         m_veboxHdrParams.isFp16Enable         = (hdrParams.formatInput == Format_A16B16G16R16F) ? true : false;
106         m_veboxHdrParams.external3DLutParams  = hdrParams.external3DLutParams;
107     }
108     else if (vpExecuteCaps.bRender && HDR_STAGE_3DLUT_KERNEL == hdrParams.stage)
109     {
110         // create a filter Param buffer
111         m_renderHdr3DLutParams.Init();
112         m_renderHdr3DLutParams.maxDisplayLum       = hdrParams.uiMaxDisplayLum;
113         m_renderHdr3DLutParams.maxContentLevelLum  = hdrParams.uiMaxContentLevelLum;
114         m_renderHdr3DLutParams.hdrMode             = hdrParams.hdrMode;
115 
116         m_renderHdr3DLutParams.threadWidth  = hdrParams.lutSize;
117         m_renderHdr3DLutParams.threadHeight = hdrParams.lutSize;
118 
119         if (hdrParams.isL0KernelEnabled == false)
120         {
121             KRN_ARG krnArg  = {};
122             krnArg.uIndex   = 0;
123             krnArg.eArgKind = ARG_KIND_SURFACE;
124             krnArg.uSize    = 4;
125             krnArg.pData    = &m_surfType3DLut;
126             m_renderHdr3DLutParams.kernelArgs.push_back(krnArg);
127 
128             krnArg.uIndex   = 1;
129             krnArg.eArgKind = ARG_KIND_SURFACE;
130             krnArg.uSize    = 4;
131             krnArg.pData    = &m_surfType3DLutCoef;
132             m_renderHdr3DLutParams.kernelArgs.push_back(krnArg);
133 
134             krnArg.uIndex   = 2;
135             krnArg.eArgKind = ARG_KIND_GENERAL;
136             krnArg.uSize    = 2;
137             krnArg.pData    = &m_3DLutSurfaceWidth;
138             m_renderHdr3DLutParams.kernelArgs.push_back(krnArg);
139 
140             krnArg.uIndex                   = 3;
141             krnArg.eArgKind                 = ARG_KIND_GENERAL;
142             krnArg.uSize                    = 2;
143             krnArg.pData                    = &m_3DLutSurfaceHeight;
144             m_renderHdr3DLutParams.kernelId = (VpKernelID)kernelHdr3DLutCalc;
145             m_renderHdr3DLutParams.kernelArgs.push_back(krnArg);
146         }
147         else
148         {
149             VP_PUBLIC_CHK_NULL_RETURN(m_pvpMhwInterface);
150             VP_PUBLIC_CHK_NULL_RETURN(m_pvpMhwInterface->m_vpPlatformInterface);
151 
152             auto handle = m_pvpMhwInterface->m_vpPlatformInterface->GetKernelPool().find("fillLutTable_3dlut");
153             VP_PUBLIC_CHK_NOT_FOUND_RETURN(handle, &m_pvpMhwInterface->m_vpPlatformInterface->GetKernelPool());
154             KERNEL_ARGS kernelArgs             = handle->second.GetKernelArgs();
155             uint32_t    localWidth             = 128;
156             uint32_t    localHeight            = 1;
157             uint32_t    localDepth             = 1;
158             m_renderHdr3DLutParams.localWidth  = localWidth;
159             m_renderHdr3DLutParams.localHeight = localHeight;
160             m_renderHdr3DLutParams.kernelId    = (VpKernelID)kernelHdr3DLutCalcL0;
161 
162             //step 1: setting curbe arguments
163             for (auto const &kernelArg : kernelArgs)
164             {
165                 uint32_t uIndex    = kernelArg.uIndex;
166                 auto     argHandle = m_renderHdr3DLutL0Params.find(uIndex);
167                 if (argHandle == m_renderHdr3DLutL0Params.end())
168                 {
169                     KRN_ARG krnArg = {};
170                     argHandle      = m_renderHdr3DLutL0Params.insert(std::make_pair(uIndex, krnArg)).first;
171                     VP_PUBLIC_CHK_NOT_FOUND_RETURN(argHandle, &m_renderHdr3DLutL0Params);
172                 }
173                 KRN_ARG &krnArg = argHandle->second;
174                 krnArg.uIndex   = uIndex;
175                 bool bInit      = true;
176                 if (krnArg.pData == nullptr)
177                 {
178                     if (kernelArg.uSize > 0)
179                     {
180                         krnArg.uSize = kernelArg.uSize;
181                         krnArg.pData = MOS_AllocAndZeroMemory(kernelArg.uSize);
182                     }
183                 }
184                 else
185                 {
186                     VP_PUBLIC_CHK_VALUE_RETURN(krnArg.uSize, kernelArg.uSize);
187                     MOS_ZeroMemory(krnArg.pData, krnArg.uSize);
188                 }
189                 uint16_t mulSize = hdrParams.lutSize == 65 ? 128 : 64;
190                 krnArg.eArgKind  = kernelArg.eArgKind;
191                 switch (krnArg.uIndex)
192                 {
193                 case LUT_FILLLUTTABLE_IOLUTINDEX:
194                     VP_PUBLIC_CHK_NULL_RETURN(krnArg.pData);
195                     *(uint32_t *)krnArg.pData = SurfaceType3DLut;
196                     break;
197                 case LUT_FILLLUTTABLE_ICOEFINDEX:
198                     VP_PUBLIC_CHK_NULL_RETURN(krnArg.pData);
199                     *(uint32_t *)krnArg.pData = SurfaceType3DLutCoef;
200                     break;
201                 case LUT_FILLLUTTABLE_LUTSIZE:
202                     VP_PUBLIC_CHK_NULL_RETURN(krnArg.pData);
203                     MOS_SecureMemcpy(krnArg.pData, kernelArg.uSize, &hdrParams.lutSize, sizeof(uint16_t));
204                     break;
205                 case LUT_FILLLUTTABLE_MULSIZE:
206                     VP_PUBLIC_CHK_NULL_RETURN(krnArg.pData);
207                     MOS_SecureMemcpy(krnArg.pData, kernelArg.uSize, &mulSize, sizeof(uint16_t));
208                     break;
209                 case LUT_FILLLUTTABLE_LOCAL_SIZE:
210                     VP_PUBLIC_CHK_NULL_RETURN(krnArg.pData);
211                     static_cast<uint32_t *>(krnArg.pData)[0] = localWidth;
212                     static_cast<uint32_t *>(krnArg.pData)[1] = localHeight;
213                     static_cast<uint32_t *>(krnArg.pData)[2] = localDepth;
214                     break;
215                 default:
216                     bInit = false;
217                     break;
218                 }
219                 if (bInit)
220                 {
221                     m_renderHdr3DLutParams.kernelArgs.push_back(krnArg);
222                 }
223             }
224         }
225     }
226     else
227     {
228         VP_PUBLIC_ASSERTMESSAGE("Not implement on render path for Hdr yet");
229         return MOS_STATUS_INVALID_PARAMETER;
230     }
231 
232     return MOS_STATUS_SUCCESS;
233 }
234 
235 /****************************************************************************************************/
236 /*                                   HwFilter Hdr Parameter                                         */
237 /****************************************************************************************************/
Create(HW_FILTER_HDR_PARAM & param,FeatureType featureType)238 HwFilterParameter *HwFilterHdrParameter::Create(HW_FILTER_HDR_PARAM &param, FeatureType featureType)
239 {
240     VP_FUNC_CALL();
241 
242     HwFilterHdrParameter *p = MOS_New(HwFilterHdrParameter, featureType);
243     if (p)
244     {
245         if (MOS_FAILED(p->Initialize(param)))
246         {
247             MOS_Delete(p);
248             return nullptr;
249         }
250     }
251     return p;
252 }
253 
HwFilterHdrParameter(FeatureType featureType)254 HwFilterHdrParameter::HwFilterHdrParameter(FeatureType featureType) : HwFilterParameter(featureType)
255 {
256 }
257 
~HwFilterHdrParameter()258 HwFilterHdrParameter::~HwFilterHdrParameter()
259 {
260 }
261 
ConfigParams(HwFilter & hwFilter)262 MOS_STATUS HwFilterHdrParameter::ConfigParams(HwFilter &hwFilter)
263 {
264     VP_FUNC_CALL();
265 
266     return hwFilter.ConfigParam(m_Params);
267 }
268 
Initialize(HW_FILTER_HDR_PARAM & param)269 MOS_STATUS HwFilterHdrParameter::Initialize(HW_FILTER_HDR_PARAM &param)
270 {
271     VP_FUNC_CALL();
272 
273     m_Params = param;
274     return MOS_STATUS_SUCCESS;
275 }
276 
277 /****************************************************************************************************/
278 /*                                   Packet Vebox Hdr Parameter                                       */
279 /****************************************************************************************************/
Create(HW_FILTER_HDR_PARAM & param)280 VpPacketParameter *VpVeboxHdrParameter::Create(HW_FILTER_HDR_PARAM &param)
281 {
282     VP_FUNC_CALL();
283 
284     if (nullptr == param.pPacketParamFactory)
285     {
286         return nullptr;
287     }
288     VpVeboxHdrParameter *p = dynamic_cast<VpVeboxHdrParameter *>(param.pPacketParamFactory->GetPacketParameter(param.pHwInterface));
289     if (p)
290     {
291         if (MOS_FAILED(p->Initialize(param)))
292         {
293             VpPacketParameter *pParam = p;
294             param.pPacketParamFactory->ReturnPacketParameter(pParam);
295             return nullptr;
296         }
297     }
298     return p;
299 }
300 
VpVeboxHdrParameter(PVP_MHWINTERFACE pHwInterface,PacketParamFactoryBase * packetParamFactory)301 VpVeboxHdrParameter::VpVeboxHdrParameter(PVP_MHWINTERFACE pHwInterface, PacketParamFactoryBase *packetParamFactory) : VpPacketParameter(packetParamFactory), m_HdrFilter(pHwInterface)
302 {
303 }
~VpVeboxHdrParameter()304 VpVeboxHdrParameter::~VpVeboxHdrParameter() {}
305 
SetPacketParam(VpCmdPacket * pPacket)306 bool VpVeboxHdrParameter::SetPacketParam(VpCmdPacket *pPacket)
307 {
308     VP_FUNC_CALL();
309 
310     VEBOX_HDR_PARAMS *pParams = m_HdrFilter.GetVeboxParams();
311     if (nullptr == pParams)
312     {
313         VP_PUBLIC_ASSERTMESSAGE("Failed to get vebox hdr params");
314         return false;
315     }
316 
317     VpVeboxCmdPacketBase *packet = dynamic_cast<VpVeboxCmdPacketBase *>(pPacket);
318     if (packet)
319     {
320         return MOS_SUCCEEDED(packet->SetHdrParams(pParams));
321     }
322 
323     VP_PUBLIC_ASSERTMESSAGE("Invalid packet for Vebox hdr");
324     return false;
325 
326 }
327 
Initialize(HW_FILTER_HDR_PARAM & params)328 MOS_STATUS VpVeboxHdrParameter::Initialize(HW_FILTER_HDR_PARAM &params)
329 {
330     VP_FUNC_CALL();
331 
332     VP_PUBLIC_CHK_STATUS_RETURN(m_HdrFilter.Init());
333     VP_PUBLIC_CHK_STATUS_RETURN(m_HdrFilter.CalculateEngineParams(params.hdrParams, params.vpExecuteCaps));
334     return MOS_STATUS_SUCCESS;
335 }
336 
337 /****************************************************************************************************/
338 /*                                   Policy Vebox Hdr Handler                                         */
339 /****************************************************************************************************/
PolicyVeboxHdrHandler(VP_HW_CAPS & hwCaps)340 PolicyVeboxHdrHandler::PolicyVeboxHdrHandler(VP_HW_CAPS &hwCaps) : PolicyFeatureHandler(hwCaps)
341 {
342     m_Type = FeatureTypeHdrOnVebox;
343 }
~PolicyVeboxHdrHandler()344 PolicyVeboxHdrHandler::~PolicyVeboxHdrHandler()
345 {
346 }
347 
IsFeatureEnabled(VP_EXECUTE_CAPS vpExecuteCaps)348 bool PolicyVeboxHdrHandler::IsFeatureEnabled(VP_EXECUTE_CAPS vpExecuteCaps)
349 {
350     VP_FUNC_CALL();
351 
352     //Need to check if other path activated
353     return vpExecuteCaps.bHDR3DLUT;
354 }
355 
CreateHwFilterParam(VP_EXECUTE_CAPS vpExecuteCaps,SwFilterPipe & swFilterPipe,PVP_MHWINTERFACE pHwInterface)356 HwFilterParameter *PolicyVeboxHdrHandler::CreateHwFilterParam(VP_EXECUTE_CAPS vpExecuteCaps, SwFilterPipe &swFilterPipe, PVP_MHWINTERFACE pHwInterface)
357 {
358     VP_FUNC_CALL();
359 
360     if (IsFeatureEnabled(vpExecuteCaps))
361     {
362         if (SwFilterPipeType1To1 != swFilterPipe.GetSwFilterPipeType())
363         {
364             VP_PUBLIC_ASSERTMESSAGE("Invalid parameter! Sfc only support 1To1 swFilterPipe!");
365             return nullptr;
366         }
367 
368         SwFilterHdr *swFilter = dynamic_cast<SwFilterHdr *>(swFilterPipe.GetSwFilter(true, 0, FeatureTypeHdrOnVebox));
369 
370         if (nullptr == swFilter)
371         {
372             VP_PUBLIC_ASSERTMESSAGE("Invalid parameter! Feature enabled in vpExecuteCaps but no swFilter exists!");
373             return nullptr;
374         }
375 
376         FeatureParamHdr &param = swFilter->GetSwFilterParams();
377 
378         HW_FILTER_HDR_PARAM paramHdr = {};
379         paramHdr.type                = m_Type;
380         paramHdr.pHwInterface        = pHwInterface;
381         paramHdr.vpExecuteCaps       = vpExecuteCaps;
382         paramHdr.pPacketParamFactory = &m_PacketParamFactory;
383         paramHdr.hdrParams           = param;
384         paramHdr.pfnCreatePacketParam = PolicyVeboxHdrHandler::CreatePacketParam;
385 
386         HwFilterParameter *pHwFilterParam = GetHwFeatureParameterFromPool();
387 
388         if (pHwFilterParam)
389         {
390             if (MOS_FAILED(((HwFilterHdrParameter *)pHwFilterParam)->Initialize(paramHdr)))
391             {
392                 ReleaseHwFeatureParameter(pHwFilterParam);
393             }
394         }
395         else
396         {
397             pHwFilterParam = HwFilterHdrParameter::Create(paramHdr, m_Type);
398         }
399 
400         return pHwFilterParam;
401     }
402     else
403     {
404         return nullptr;
405     }
406 }
407 
408 
409 /****************************************************************************************************/
410 /*                      Packet Render Hdr 3DLut Caculation Parameter                                */
411 /****************************************************************************************************/
Create(HW_FILTER_HDR_PARAM & param)412 VpPacketParameter *VpRenderHdr3DLutCalParameter::Create(HW_FILTER_HDR_PARAM &param)
413 {
414     VP_FUNC_CALL();
415 
416     if (nullptr == param.pPacketParamFactory)
417     {
418         return nullptr;
419     }
420     VpRenderHdr3DLutCalParameter *p = dynamic_cast<VpRenderHdr3DLutCalParameter *>(param.pPacketParamFactory->GetPacketParameter(param.pHwInterface));
421     if (p)
422     {
423         if (MOS_FAILED(p->Initialize(param)))
424         {
425             VpPacketParameter *pParam = p;
426             param.pPacketParamFactory->ReturnPacketParameter(pParam);
427             return nullptr;
428         }
429     }
430     return p;
431 }
432 
VpRenderHdr3DLutCalParameter(PVP_MHWINTERFACE pHwInterface,PacketParamFactoryBase * packetParamFactory)433 VpRenderHdr3DLutCalParameter::VpRenderHdr3DLutCalParameter(PVP_MHWINTERFACE pHwInterface, PacketParamFactoryBase *packetParamFactory) : VpPacketParameter(packetParamFactory), m_HdrFilter(pHwInterface)
434 {
435 }
~VpRenderHdr3DLutCalParameter()436 VpRenderHdr3DLutCalParameter::~VpRenderHdr3DLutCalParameter() {}
437 
SetPacketParam(VpCmdPacket * packet)438 bool VpRenderHdr3DLutCalParameter::SetPacketParam(VpCmdPacket *packet)
439 {
440     VP_FUNC_CALL();
441 
442     VpRenderCmdPacket *pRenderPacket = dynamic_cast<VpRenderCmdPacket *>(packet);
443     if (nullptr == pRenderPacket)
444     {
445         return false;
446     }
447 
448     RENDER_HDR_3DLUT_CAL_PARAMS *params = m_HdrFilter.GetRenderHdr3DLutParams();
449     if (nullptr == params)
450     {
451         return false;
452     }
453     return MOS_SUCCEEDED(pRenderPacket->SetHdr3DLutParams(params));
454 }
455 
Initialize(HW_FILTER_HDR_PARAM & params)456 MOS_STATUS VpRenderHdr3DLutCalParameter::Initialize(HW_FILTER_HDR_PARAM &params)
457 {
458     VP_FUNC_CALL();
459 
460     VP_PUBLIC_CHK_STATUS_RETURN(m_HdrFilter.Init());
461     VP_PUBLIC_CHK_STATUS_RETURN(m_HdrFilter.CalculateEngineParams(params.hdrParams, params.vpExecuteCaps));
462     return MOS_STATUS_SUCCESS;
463 }
464 
465 /****************************************************************************************************/
466 /*                            Policy Render Hdr 3DLut Caculation Handler                            */
467 /****************************************************************************************************/
PolicyRenderHdr3DLutCalHandler(VP_HW_CAPS & hwCaps)468 PolicyRenderHdr3DLutCalHandler::PolicyRenderHdr3DLutCalHandler(VP_HW_CAPS &hwCaps) : PolicyFeatureHandler(hwCaps)
469 {
470     m_Type = FeatureTypeHdr3DLutCalOnRender;
471 }
~PolicyRenderHdr3DLutCalHandler()472 PolicyRenderHdr3DLutCalHandler::~PolicyRenderHdr3DLutCalHandler()
473 {
474 }
475 
IsFeatureEnabled(VP_EXECUTE_CAPS vpExecuteCaps)476 bool PolicyRenderHdr3DLutCalHandler::IsFeatureEnabled(VP_EXECUTE_CAPS vpExecuteCaps)
477 {
478     VP_FUNC_CALL();
479 
480     //Need to check if other path activated
481     return vpExecuteCaps.b3DLutCalc;
482 }
483 
CreateHwFilterParam(VP_EXECUTE_CAPS vpExecuteCaps,SwFilterPipe & swFilterPipe,PVP_MHWINTERFACE pHwInterface)484 HwFilterParameter *PolicyRenderHdr3DLutCalHandler::CreateHwFilterParam(VP_EXECUTE_CAPS vpExecuteCaps, SwFilterPipe &swFilterPipe, PVP_MHWINTERFACE pHwInterface)
485 {
486     VP_FUNC_CALL();
487 
488     if (IsFeatureEnabled(vpExecuteCaps))
489     {
490         if (SwFilterPipeType1To1 != swFilterPipe.GetSwFilterPipeType())
491         {
492             VP_PUBLIC_ASSERTMESSAGE("Invalid parameter! Sfc only support 1To1 swFilterPipe!");
493             return nullptr;
494         }
495 
496         SwFilterHdr *swFilter = dynamic_cast<SwFilterHdr *>(swFilterPipe.GetSwFilter(true, 0, FeatureTypeHdr3DLutCalOnRender));
497 
498         if (nullptr == swFilter)
499         {
500             VP_PUBLIC_ASSERTMESSAGE("Invalid parameter! Feature enabled in vpExecuteCaps but no swFilter exists!");
501             return nullptr;
502         }
503 
504         FeatureParamHdr &param = swFilter->GetSwFilterParams();
505 
506         HW_FILTER_HDR_PARAM paramHdr  = {};
507         paramHdr.type                 = m_Type;
508         paramHdr.pHwInterface         = pHwInterface;
509         paramHdr.vpExecuteCaps        = vpExecuteCaps;
510         paramHdr.pPacketParamFactory  = &m_PacketParamFactory;
511         paramHdr.hdrParams            = param;
512         paramHdr.pfnCreatePacketParam = PolicyRenderHdr3DLutCalHandler::CreatePacketParam;
513 
514         HwFilterParameter *pHwFilterParam = GetHwFeatureParameterFromPool();
515 
516         if (pHwFilterParam)
517         {
518             if (MOS_FAILED(((HwFilterHdrParameter *)pHwFilterParam)->Initialize(paramHdr)))
519             {
520                 ReleaseHwFeatureParameter(pHwFilterParam);
521             }
522         }
523         else
524         {
525             pHwFilterParam = HwFilterHdrParameter::Create(paramHdr, m_Type);
526         }
527 
528         return pHwFilterParam;
529     }
530     else
531     {
532         return nullptr;
533     }
534 }
535 
UpdateFeaturePipe(VP_EXECUTE_CAPS caps,SwFilter & feature,SwFilterPipe & featurePipe,SwFilterPipe & executePipe,bool isInputPipe,int index)536 MOS_STATUS PolicyRenderHdr3DLutCalHandler::UpdateFeaturePipe(VP_EXECUTE_CAPS caps, SwFilter &feature, SwFilterPipe &featurePipe, SwFilterPipe &executePipe, bool isInputPipe, int index)
537 {
538     VP_FUNC_CALL();
539 
540     SwFilterHdr *featureHdr = dynamic_cast<SwFilterHdr *>(&feature);
541     VP_PUBLIC_CHK_NULL_RETURN(featureHdr);
542 
543     // only stage in 3DLUT_KERNEL need update engine caps
544     if (caps.b3DLutCalc && featureHdr->GetSwFilterParams().stage == HDR_STAGE_3DLUT_KERNEL)
545     {
546         SwFilterHdr *filter2ndPass = featureHdr;
547         SwFilterHdr *filter1ndPass = (SwFilterHdr *)feature.Clone();
548 
549         VP_PUBLIC_CHK_NULL_RETURN(filter1ndPass);
550         VP_PUBLIC_CHK_NULL_RETURN(filter2ndPass);
551 
552         filter1ndPass->GetFilterEngineCaps() = filter2ndPass->GetFilterEngineCaps();
553         filter1ndPass->SetFeatureType(filter2ndPass->GetFeatureType());
554 
555         FeatureParamHdr &params2ndPass = filter2ndPass->GetSwFilterParams();
556         FeatureParamHdr &params1stPass = filter1ndPass->GetSwFilterParams();
557 
558         params2ndPass.stage = HDR_STAGE_VEBOX_3DLUT_UPDATE;
559 
560         // Clear engine caps for filter in 2nd pass.
561         filter2ndPass->SetFeatureType(FeatureTypeHdr);
562         filter2ndPass->SetRenderTargetType(RenderTargetTypeSurface);
563         filter2ndPass->GetFilterEngineCaps().bEnabled     = 1;
564         filter2ndPass->GetFilterEngineCaps().RenderNeeded = 0;
565         filter2ndPass->GetFilterEngineCaps().VeboxNeeded  = 1;
566         filter2ndPass->GetFilterEngineCaps().isolated     = 0;
567         if (featureHdr->GetSwFilterParams().is3DLutKernelOnly)
568         {
569             filter2ndPass->GetFilterEngineCaps().forceBypassWorkload = 1;
570         }
571         if (featureHdr->GetSwFilterParams().formatOutput == Format_A8B8G8R8 || featureHdr->GetSwFilterParams().formatOutput == Format_A8R8G8B8)
572         {
573             filter2ndPass->GetFilterEngineCaps().VeboxARGBOut = 1;
574         }
575         else if (featureHdr->GetSwFilterParams().formatOutput == Format_B10G10R10A2 || featureHdr->GetSwFilterParams().formatOutput == Format_R10G10B10A2)
576         {
577             filter2ndPass->GetFilterEngineCaps().VeboxARGB10bitOutput = 1;
578         }
579 
580         executePipe.AddSwFilterUnordered(filter1ndPass, isInputPipe, index);
581     }
582     else
583     {
584         return PolicyFeatureHandler::UpdateFeaturePipe(caps, feature, featurePipe, executePipe, isInputPipe, index);
585     }
586 
587     return MOS_STATUS_SUCCESS;
588 }
589 }  // namespace vp
590