1 /*
2 * Copyright (c) 2020-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 //! \file vp_dn_filter.cpp
24 //! \brief Defines the common interface for denoise
25 //! this file is for the base interface which is shared by all denoise in driver.
26 //!
27 #include "vp_csc_filter.h"
28 #include "vp_vebox_cmd_packet.h"
29 #include "vp_render_cmd_packet.h"
30 #include "hw_filter.h"
31 #include "sw_filter_pipe.h"
32
33 namespace vp {
VpDnFilter(PVP_MHWINTERFACE vpMhwInterface)34 VpDnFilter::VpDnFilter(PVP_MHWINTERFACE vpMhwInterface) :
35 VpFilter(vpMhwInterface)
36 {
37
38 }
39
Init()40 MOS_STATUS VpDnFilter::Init()
41 {
42 VP_FUNC_CALL();
43
44 return MOS_STATUS_SUCCESS;
45 }
46
Prepare()47 MOS_STATUS VpDnFilter::Prepare()
48 {
49 VP_FUNC_CALL();
50
51 return MOS_STATUS_SUCCESS;
52 }
53
Destroy()54 MOS_STATUS VpDnFilter::Destroy()
55 {
56 VP_FUNC_CALL();
57
58 if (m_veboxDnParams)
59 {
60 MOS_FreeMemory(m_veboxDnParams);
61 m_veboxDnParams = nullptr;
62 }
63
64 return MOS_STATUS_SUCCESS;
65 }
66
SetExecuteEngineCaps(FeatureParamDenoise & dnParams,VP_EXECUTE_CAPS vpExecuteCaps)67 MOS_STATUS VpDnFilter::SetExecuteEngineCaps(
68 FeatureParamDenoise &dnParams,
69 VP_EXECUTE_CAPS vpExecuteCaps)
70 {
71 VP_FUNC_CALL();
72
73 m_dnParams = dnParams;
74 m_executeCaps = vpExecuteCaps;
75
76 return MOS_STATUS_SUCCESS;
77 }
78
CalculateRenderDnHVSParams()79 MOS_STATUS VpDnFilter::CalculateRenderDnHVSParams()
80 {
81 VP_FUNC_CALL();
82 VP_SURFACE *pStatisticsOutput;
83
84 return MOS_STATUS_SUCCESS;
85 }
86
CalculateEngineParams()87 MOS_STATUS VpDnFilter::CalculateEngineParams()
88 {
89 VP_FUNC_CALL();
90 if (m_executeCaps.bVebox)
91 {
92 // create a filter Param buffer
93 if (!m_veboxDnParams)
94 {
95 m_veboxDnParams = (PVEBOX_DN_PARAMS)MOS_AllocAndZeroMemory(sizeof(VEBOX_DN_PARAMS));
96
97 if (m_veboxDnParams == nullptr)
98 {
99 VP_PUBLIC_ASSERTMESSAGE("sfc Rotation Pamas buffer allocate failed, return nullpointer");
100 return MOS_STATUS_NO_SPACE;
101 }
102 }
103 else
104 {
105 MOS_ZeroMemory(m_veboxDnParams, sizeof(VEBOX_DN_PARAMS));
106 }
107
108 m_veboxDnParams->bDnEnabled = m_executeCaps.bDN;
109 m_veboxDnParams->bChromaDenoise = m_dnParams.denoiseParams.bEnableChroma;
110 m_veboxDnParams->bAutoDetect = m_dnParams.denoiseParams.bAutoDetect;
111 m_veboxDnParams->fDenoiseFactor = m_dnParams.denoiseParams.fDenoiseFactor;
112 m_veboxDnParams->NoiseLevel = m_dnParams.denoiseParams.NoiseLevel;
113 m_veboxDnParams->bEnableHVSDenoise = m_dnParams.denoiseParams.bEnableHVSDenoise;
114 m_veboxDnParams->HVSDenoise = m_dnParams.denoiseParams.HVSDenoise;
115 m_veboxDnParams->bProgressive = SAMPLE_PROGRESSIVE == m_dnParams.sampleTypeInput;
116 }
117 else if (m_executeCaps.bRender && DN_STAGE_HVS_KERNEL == m_dnParams.stage)
118 {
119 // create a filter Param buffer
120 MOS_ZeroMemory(&m_renderDnHVSParams, sizeof(RENDER_DN_HVS_CAL_PARAMS));
121 m_renderDnHVSParams.kernelId = (VpKernelID)kernelHVSCalc;
122
123 m_renderDnHVSParams.threadWidth = 1;
124 m_renderDnHVSParams.threadHeight = 1;
125
126 KRN_ARG krnArg = {};
127 krnArg.uIndex = 0;
128 krnArg.eArgKind = ARG_KIND_SURFACE;
129 krnArg.uSize = 4;
130 krnArg.pData = &m_surfTypeHVSTable;
131 m_renderDnHVSParams.kernelArgs.push_back(krnArg);
132
133 // Other Render's params will add in SetKernelArgs()
134 }
135 else
136 {
137 VP_PUBLIC_ASSERTMESSAGE("Wrong engine caps! Vebox should be used for Dn");
138 }
139 return MOS_STATUS_SUCCESS;
140 }
141
142
143 /****************************************************************************************************/
144 /* HwFilter Dn Parameter */
145 /****************************************************************************************************/
Create(HW_FILTER_DN_PARAM & param,FeatureType featureType)146 HwFilterParameter *HwFilterDnParameter::Create(HW_FILTER_DN_PARAM ¶m, FeatureType featureType)
147 {
148 VP_FUNC_CALL();
149
150 HwFilterDnParameter *p = MOS_New(HwFilterDnParameter, featureType);
151 if (p)
152 {
153 if (MOS_FAILED(p->Initialize(param)))
154 {
155 MOS_Delete(p);
156 return nullptr;
157 }
158 }
159 return p;
160 }
161
HwFilterDnParameter(FeatureType featureType)162 HwFilterDnParameter::HwFilterDnParameter(FeatureType featureType) : HwFilterParameter(featureType)
163 {
164 }
165
~HwFilterDnParameter()166 HwFilterDnParameter::~HwFilterDnParameter()
167 {
168 }
169
ConfigParams(HwFilter & hwFilter)170 MOS_STATUS HwFilterDnParameter::ConfigParams(HwFilter &hwFilter)
171 {
172 VP_FUNC_CALL();
173
174 return hwFilter.ConfigParam(m_Params);
175 }
176
Initialize(HW_FILTER_DN_PARAM & param)177 MOS_STATUS HwFilterDnParameter::Initialize(HW_FILTER_DN_PARAM ¶m)
178 {
179 VP_FUNC_CALL();
180
181 m_Params = param;
182 return MOS_STATUS_SUCCESS;
183 }
184
185 /****************************************************************************************************/
186 /* Packet Vebox Dn Parameter */
187 /****************************************************************************************************/
Create(HW_FILTER_DN_PARAM & param)188 VpPacketParameter *VpVeboxDnParameter::Create(HW_FILTER_DN_PARAM ¶m)
189 {
190 VP_FUNC_CALL();
191
192 if (nullptr == param.pPacketParamFactory)
193 {
194 return nullptr;
195 }
196 VpVeboxDnParameter *p = dynamic_cast<VpVeboxDnParameter *>(param.pPacketParamFactory->GetPacketParameter(param.pHwInterface));
197 if (p)
198 {
199 if (MOS_FAILED(p->Initialize(param)))
200 {
201 VpPacketParameter *pParam = p;
202 param.pPacketParamFactory->ReturnPacketParameter(pParam);
203 return nullptr;
204 }
205 }
206 return p;
207 }
208
VpVeboxDnParameter(PVP_MHWINTERFACE pHwInterface,PacketParamFactoryBase * packetParamFactory)209 VpVeboxDnParameter::VpVeboxDnParameter(PVP_MHWINTERFACE pHwInterface, PacketParamFactoryBase *packetParamFactory) :
210 VpPacketParameter(packetParamFactory), m_dnFilter(pHwInterface)
211 {
212 }
~VpVeboxDnParameter()213 VpVeboxDnParameter::~VpVeboxDnParameter() {}
214
SetPacketParam(VpCmdPacket * pPacket)215 bool VpVeboxDnParameter::SetPacketParam(VpCmdPacket *pPacket)
216 {
217 VP_FUNC_CALL();
218
219 //VpVeboxCmdPacket *pVeboxPacket = dynamic_cast<VpVeboxCmdPacket *>(pPacket);
220 //if (nullptr == pVeboxPacket)
221 //{
222 // return false;
223 //}
224
225 //VEBOX_DN_PARAMS *pParams = m_dnFilter.GetVeboxParams();
226 //if (nullptr == pParams)
227 //{
228 // return false;
229 //}
230 //return MOS_SUCCEEDED(pVeboxPacket->SetDnParams(pParams));
231
232 VEBOX_DN_PARAMS *pParams = m_dnFilter.GetVeboxParams();
233 if (nullptr == pParams)
234 {
235 VP_PUBLIC_ASSERTMESSAGE("Failed to get Vebox DN params");
236 return false;
237 }
238
239 VpVeboxCmdPacketBase *packet = dynamic_cast<VpVeboxCmdPacketBase *>(pPacket);
240 if (packet)
241 {
242 return MOS_SUCCEEDED(packet->SetDnParams(pParams));
243 }
244
245 VP_PUBLIC_ASSERTMESSAGE("Invalid packet for Vebox DN");
246 return false;
247 }
248
Initialize(HW_FILTER_DN_PARAM & params)249 MOS_STATUS VpVeboxDnParameter::Initialize(HW_FILTER_DN_PARAM ¶ms)
250 {
251 VP_FUNC_CALL();
252
253 VP_PUBLIC_CHK_STATUS_RETURN(m_dnFilter.Init());
254 VP_PUBLIC_CHK_STATUS_RETURN(m_dnFilter.SetExecuteEngineCaps(params.dnParams, params.vpExecuteCaps));
255 VP_PUBLIC_CHK_STATUS_RETURN(m_dnFilter.CalculateEngineParams());
256 return MOS_STATUS_SUCCESS;
257 }
258
259 /****************************************************************************************************/
260 /* Policy Vebox Dn Handler */
261 /****************************************************************************************************/
PolicyVeboxDnHandler(VP_HW_CAPS & hwCaps)262 PolicyVeboxDnHandler::PolicyVeboxDnHandler(VP_HW_CAPS &hwCaps) : PolicyFeatureHandler(hwCaps)
263 {
264 m_Type = FeatureTypeDnOnVebox;
265 }
~PolicyVeboxDnHandler()266 PolicyVeboxDnHandler::~PolicyVeboxDnHandler()
267 {
268 }
269
IsFeatureEnabled(VP_EXECUTE_CAPS vpExecuteCaps)270 bool PolicyVeboxDnHandler::IsFeatureEnabled(VP_EXECUTE_CAPS vpExecuteCaps)
271 {
272 VP_FUNC_CALL();
273
274 return vpExecuteCaps.bDN;
275 }
276
CreateHwFilterParam(VP_EXECUTE_CAPS vpExecuteCaps,SwFilterPipe & swFilterPipe,PVP_MHWINTERFACE pHwInterface)277 HwFilterParameter* PolicyVeboxDnHandler::CreateHwFilterParam(VP_EXECUTE_CAPS vpExecuteCaps, SwFilterPipe& swFilterPipe, PVP_MHWINTERFACE pHwInterface)
278 {
279 VP_FUNC_CALL();
280
281 if (IsFeatureEnabled(vpExecuteCaps))
282 {
283 if (SwFilterPipeType1To1 != swFilterPipe.GetSwFilterPipeType())
284 {
285 VP_PUBLIC_ASSERTMESSAGE("Invalid parameter! Sfc only support 1To1 swFilterPipe!");
286 return nullptr;
287 }
288
289 SwFilterDenoise *swFilter = dynamic_cast<SwFilterDenoise *>(swFilterPipe.GetSwFilter(true, 0, FeatureTypeDnOnVebox));
290
291 if (nullptr == swFilter)
292 {
293 VP_PUBLIC_ASSERTMESSAGE("Invalid parameter! Feature enabled in vpExecuteCaps but no swFilter exists!");
294 return nullptr;
295 }
296
297 FeatureParamDenoise ¶m = swFilter->GetSwFilterParams();
298
299 HW_FILTER_DN_PARAM paramDn = {};
300 paramDn.type = m_Type;
301 paramDn.pHwInterface = pHwInterface;
302 paramDn.vpExecuteCaps = vpExecuteCaps;
303 paramDn.pPacketParamFactory = &m_PacketParamFactory;
304 paramDn.dnParams = param;
305 paramDn.pfnCreatePacketParam = PolicyVeboxDnHandler::CreatePacketParam;
306
307 HwFilterParameter *pHwFilterParam = GetHwFeatureParameterFromPool();
308
309 if (pHwFilterParam)
310 {
311 if (MOS_FAILED(((HwFilterDnParameter*)pHwFilterParam)->Initialize(paramDn)))
312 {
313 ReleaseHwFeatureParameter(pHwFilterParam);
314 }
315 }
316 else
317 {
318 pHwFilterParam = HwFilterDnParameter::Create(paramDn, m_Type);
319 }
320
321 return pHwFilterParam;
322 }
323 else
324 {
325 return nullptr;
326 }
327 }
328
329
330 /****************************************************************************************************/
331 /* Packet Render Dn HVS Caculation Parameter */
332 /****************************************************************************************************/
Create(HW_FILTER_DN_PARAM & param)333 VpPacketParameter *VpRenderDnHVSCalParameter::Create(HW_FILTER_DN_PARAM ¶m)
334 {
335 VP_FUNC_CALL();
336
337 if (nullptr == param.pPacketParamFactory)
338 {
339 return nullptr;
340 }
341 VpRenderDnHVSCalParameter *p = dynamic_cast<VpRenderDnHVSCalParameter *>(param.pPacketParamFactory->GetPacketParameter(param.pHwInterface));
342 if (p)
343 {
344 if (MOS_FAILED(p->Initialize(param)))
345 {
346 VpPacketParameter *pParam = p;
347 param.pPacketParamFactory->ReturnPacketParameter(pParam);
348 return nullptr;
349 }
350 }
351 return p;
352 }
353
VpRenderDnHVSCalParameter(PVP_MHWINTERFACE pHwInterface,PacketParamFactoryBase * packetParamFactory)354 VpRenderDnHVSCalParameter::VpRenderDnHVSCalParameter(PVP_MHWINTERFACE pHwInterface, PacketParamFactoryBase *packetParamFactory) : VpPacketParameter(packetParamFactory), m_DnFilter(pHwInterface)
355 {
356 }
357
~VpRenderDnHVSCalParameter()358 VpRenderDnHVSCalParameter::~VpRenderDnHVSCalParameter()
359 {
360 }
361
SetPacketParam(VpCmdPacket * packet)362 bool VpRenderDnHVSCalParameter::SetPacketParam(VpCmdPacket *packet)
363 {
364 VP_FUNC_CALL();
365
366 VpRenderCmdPacket *pRenderPacket = dynamic_cast<VpRenderCmdPacket *>(packet);
367 if (nullptr == pRenderPacket)
368 {
369 return false;
370 }
371 RENDER_DN_HVS_CAL_PARAMS * params = m_DnFilter.GetRenderDnHVSParams();
372 if (nullptr == params)
373 {
374 return false;
375 }
376 return MOS_SUCCEEDED(pRenderPacket->SetDnHVSParams(params));
377 }
378
Initialize(HW_FILTER_DN_PARAM & params)379 MOS_STATUS VpRenderDnHVSCalParameter::Initialize(HW_FILTER_DN_PARAM ¶ms)
380 {
381 VP_FUNC_CALL();
382
383 VP_PUBLIC_CHK_STATUS_RETURN(m_DnFilter.Init());
384 VP_PUBLIC_CHK_STATUS_RETURN(m_DnFilter.SetExecuteEngineCaps(params.dnParams, params.vpExecuteCaps));
385 VP_PUBLIC_CHK_STATUS_RETURN(m_DnFilter.CalculateEngineParams());
386 return MOS_STATUS_SUCCESS;
387 }
388
389 /****************************************************************************************************/
390 /* Policy Render DN HVS Caculation Handler */
391 /****************************************************************************************************/
PolicyRenderDnHVSCalHandler(VP_HW_CAPS & hwCaps)392 PolicyRenderDnHVSCalHandler::PolicyRenderDnHVSCalHandler(VP_HW_CAPS &hwCaps) : PolicyFeatureHandler(hwCaps)
393 {
394 m_Type = FeatureTypeDnHVSCalOnRender;
395 }
~PolicyRenderDnHVSCalHandler()396 PolicyRenderDnHVSCalHandler::~PolicyRenderDnHVSCalHandler()
397 {
398 }
399
IsFeatureEnabled(VP_EXECUTE_CAPS vpExecuteCaps)400 bool PolicyRenderDnHVSCalHandler::IsFeatureEnabled(VP_EXECUTE_CAPS vpExecuteCaps)
401 {
402 VP_FUNC_CALL();
403
404 //Need to check if other path activated
405 return vpExecuteCaps.bHVSCalc;
406 }
407
CreateHwFilterParam(VP_EXECUTE_CAPS vpExecuteCaps,SwFilterPipe & swFilterPipe,PVP_MHWINTERFACE pHwInterface)408 HwFilterParameter *PolicyRenderDnHVSCalHandler::CreateHwFilterParam(VP_EXECUTE_CAPS vpExecuteCaps, SwFilterPipe &swFilterPipe, PVP_MHWINTERFACE pHwInterface)
409 {
410 VP_FUNC_CALL();
411
412 if (IsFeatureEnabled(vpExecuteCaps))
413 {
414 if (SwFilterPipeType1To1 != swFilterPipe.GetSwFilterPipeType())
415 {
416 VP_PUBLIC_ASSERTMESSAGE("Invalid parameter! Sfc only support 1To1 swFilterPipe!");
417 return nullptr;
418 }
419
420 SwFilterDenoise *swFilter = dynamic_cast<SwFilterDenoise *>(swFilterPipe.GetSwFilter(true, 0, FeatureTypeDnHVSCalOnRender));
421
422 if (nullptr == swFilter)
423 {
424 VP_PUBLIC_ASSERTMESSAGE("Invalid parameter! Feature enabled in vpExecuteCaps but no swFilter exists!");
425 return nullptr;
426 }
427
428 FeatureParamDenoise ¶m = swFilter->GetSwFilterParams();
429
430 HW_FILTER_DN_PARAM paramDn = {};
431
432 paramDn.type = m_Type;
433 paramDn.pHwInterface = pHwInterface;
434 paramDn.vpExecuteCaps = vpExecuteCaps;
435 paramDn.pPacketParamFactory = &m_PacketParamFactory;
436 paramDn.dnParams = param;
437 paramDn.pfnCreatePacketParam = PolicyRenderDnHVSCalHandler::CreatePacketParam;
438
439 HwFilterParameter *pHwFilterParam = GetHwFeatureParameterFromPool();
440
441 if (pHwFilterParam)
442 {
443 if (MOS_FAILED(((HwFilterDnParameter *)pHwFilterParam)->Initialize(paramDn)))
444 {
445 ReleaseHwFeatureParameter(pHwFilterParam);
446 }
447 }
448 else
449 {
450 pHwFilterParam = HwFilterDnParameter::Create(paramDn, m_Type);
451 }
452
453 return pHwFilterParam;
454 }
455 else
456 {
457 return nullptr;
458 }
459 }
460
UpdateFeaturePipe(VP_EXECUTE_CAPS caps,SwFilter & feature,SwFilterPipe & featurePipe,SwFilterPipe & executePipe,bool isInputPipe,int index)461 MOS_STATUS PolicyRenderDnHVSCalHandler::UpdateFeaturePipe(VP_EXECUTE_CAPS caps, SwFilter &feature, SwFilterPipe &featurePipe, SwFilterPipe &executePipe, bool isInputPipe, int index)
462 {
463 VP_FUNC_CALL();
464
465 SwFilterDenoise *featureDn = dynamic_cast<SwFilterDenoise *>(&feature);
466 uint32_t widthAlignUint = 0;
467 uint32_t heightAlignUnit = 0;
468 VP_PUBLIC_CHK_NULL_RETURN(featureDn);
469
470 // only stage in HVS_KERNEL need update engine caps
471 if (caps.bHVSCalc && featureDn->GetSwFilterParams().stage == DN_STAGE_HVS_KERNEL)
472 {
473 SwFilterDenoise *filter2ndPass = featureDn;
474 SwFilterDenoise *filter1ndPass = (SwFilterDenoise *)feature.Clone();
475
476 VP_PUBLIC_CHK_NULL_RETURN(filter1ndPass);
477 VP_PUBLIC_CHK_NULL_RETURN(filter2ndPass);
478
479 filter1ndPass->GetFilterEngineCaps() = filter2ndPass->GetFilterEngineCaps();
480 filter1ndPass->SetFeatureType(filter2ndPass->GetFeatureType());
481
482 FeatureParamDenoise ¶ms2ndPass = filter2ndPass->GetSwFilterParams();
483 FeatureParamDenoise ¶ms1stPass = filter1ndPass->GetSwFilterParams();
484
485 params2ndPass.stage = DN_STAGE_VEBOX_HVS_UPDATE;
486
487 // Clear engine caps for filter in 2nd pass.
488 filter2ndPass->SetFeatureType(FeatureTypeDn);
489 filter2ndPass->SetRenderTargetType(RenderTargetTypeSurface);
490 filter2ndPass->GetFilterEngineCaps().RenderNeeded = 0;
491 filter2ndPass->GetFilterEngineCaps().isolated = 0;
492
493 widthAlignUint = featureDn->GetSwFilterParams().widthAlignUnitInput;
494 heightAlignUnit = featureDn->GetSwFilterParams().heightAlignUnitInput;
495
496 widthAlignUint = MOS_ALIGN_CEIL(widthAlignUint, 2);
497
498 if (featureDn->GetSwFilterParams().formatInput == Format_NV12 ||
499 featureDn->GetSwFilterParams().formatInput == Format_P010 ||
500 featureDn->GetSwFilterParams().formatInput == Format_P016)
501 {
502 heightAlignUnit = MOS_ALIGN_CEIL(heightAlignUnit, 4);
503 }
504 else
505 {
506 heightAlignUnit = MOS_ALIGN_CEIL(heightAlignUnit, 2);
507 }
508
509 if (MOS_IS_ALIGNED(featureDn->GetSwFilterParams().heightInput, heightAlignUnit))
510 {
511 filter2ndPass->GetFilterEngineCaps().bEnabled = 1;
512 filter2ndPass->GetFilterEngineCaps().VeboxNeeded = 1;
513 }
514 else
515 {
516 VP_PUBLIC_NORMALMESSAGE("Denoise Feature is disabled since heightInput (%d) not being %d aligned.", featureDn->GetSwFilterParams().heightInput, heightAlignUnit);
517 }
518
519 featureDn->GetSwFilterParams().widthAlignUnitInput = widthAlignUint;
520 featureDn->GetSwFilterParams().heightAlignUnitInput = heightAlignUnit;
521 executePipe.AddSwFilterUnordered(filter1ndPass, isInputPipe, index);
522 }
523 else
524 {
525 return PolicyFeatureHandler::UpdateFeaturePipe(caps, feature, featurePipe, executePipe, isInputPipe, index);
526 }
527
528 return MOS_STATUS_SUCCESS;
529 }
530 }
531