1 /*
2 * Copyright (c) 2018-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_rot_mir_filter.cpp
24 //! \brief    Defines the common interface for rotation/mirror
25 //!           this file is for the base interface which is shared by rotation/mirror in driver.
26 //!
27 
28 #include "vp_rot_mir_filter.h"
29 #include "vp_vebox_cmd_packet_base.h"
30 #include "hw_filter.h"
31 #include "sw_filter_pipe.h"
32 
33 using namespace vp;
34 
VpRotMirFilter(PVP_MHWINTERFACE vpMhwInterface)35 VpRotMirFilter::VpRotMirFilter(PVP_MHWINTERFACE vpMhwInterface) :
36     VpFilter(vpMhwInterface)
37 {
38 
39 }
40 
Init()41 MOS_STATUS VpRotMirFilter::Init()
42 {
43     VP_FUNC_CALL();
44 
45     return MOS_STATUS_SUCCESS;
46 }
47 
Prepare()48 MOS_STATUS VpRotMirFilter::Prepare()
49 {
50     VP_FUNC_CALL();
51 
52     return MOS_STATUS_SUCCESS;
53 }
54 
Destroy()55 MOS_STATUS VpRotMirFilter::Destroy()
56 {
57     VP_FUNC_CALL();
58 
59     if (m_sfcRotMirParams)
60     {
61         MOS_FreeMemory(m_sfcRotMirParams);
62         m_sfcRotMirParams = nullptr;
63     }
64 
65     return MOS_STATUS_SUCCESS;
66 }
67 
SetExecuteEngineCaps(FeatureParamRotMir & rotMirParams,VP_EXECUTE_CAPS vpExecuteCaps)68 MOS_STATUS VpRotMirFilter::SetExecuteEngineCaps(
69     FeatureParamRotMir      &rotMirParams,
70     VP_EXECUTE_CAPS         vpExecuteCaps)
71 {
72     VP_FUNC_CALL();
73 
74     m_executeCaps   = vpExecuteCaps;
75     m_rotMirParams = rotMirParams;
76 
77     return MOS_STATUS_SUCCESS;
78 }
79 
CalculateEngineParams()80 MOS_STATUS VpRotMirFilter::CalculateEngineParams()
81 {
82     VP_FUNC_CALL();
83 
84     if (m_executeCaps.bSFC)
85     {
86         // create a filter Param buffer
87         if (!m_sfcRotMirParams)
88         {
89             m_sfcRotMirParams = (PSFC_ROT_MIR_PARAMS)MOS_AllocAndZeroMemory(sizeof(SFC_ROT_MIR_PARAMS));
90 
91             if (m_sfcRotMirParams == nullptr)
92             {
93                 VP_PUBLIC_ASSERTMESSAGE("sfc Rotation Pamas buffer allocate failed, return nullpointer");
94                 return MOS_STATUS_NO_SPACE;
95             }
96         }
97         else
98         {
99             MOS_ZeroMemory(m_sfcRotMirParams, sizeof(SFC_ROT_MIR_PARAMS));
100         }
101 
102         VP_PUBLIC_CHK_STATUS_RETURN(SetRotationAndMirrowParams(m_rotMirParams.rotation));
103     }
104     else
105     {
106 
107     }
108 
109     return MOS_STATUS_SUCCESS;
110 }
111 
SetRotationAndMirrowParams(VPHAL_ROTATION Rotation)112 MOS_STATUS VpRotMirFilter::SetRotationAndMirrowParams(
113     VPHAL_ROTATION Rotation)
114 {
115     VP_FUNC_CALL();
116 
117     VP_PUBLIC_CHK_NULL_RETURN(m_sfcRotMirParams);
118 
119     if (Rotation <= VPHAL_ROTATION_270)
120     {
121         // Rotation only
122         m_sfcRotMirParams->rotationMode  = GetRotationParam(Rotation);
123         m_sfcRotMirParams->bMirrorEnable = false;
124     }
125     else if (Rotation <= VPHAL_MIRROR_VERTICAL)
126     {
127         // Mirror only
128         m_sfcRotMirParams->mirrorType    = GetRotationParam(Rotation) - 4;
129         m_sfcRotMirParams->rotationMode  = VPHAL_ROTATION_IDENTITY;
130         m_sfcRotMirParams->bMirrorEnable = true;
131     }
132     else
133     {
134         // Rotation + Mirror
135         m_sfcRotMirParams->mirrorType    = MHW_MIRROR_HORIZONTAL;
136         m_sfcRotMirParams->rotationMode  = GetRotationParam(Rotation);
137         m_sfcRotMirParams->bMirrorEnable = true;
138     }
139 
140     return MOS_STATUS_SUCCESS;
141 }
142 
GetRotationParam(VPHAL_ROTATION Rotation)143 VPHAL_ROTATION VpRotMirFilter::GetRotationParam(VPHAL_ROTATION Rotation)
144 {
145     VP_FUNC_CALL();
146 
147     switch (Rotation)
148     {
149     case VPHAL_ROTATION_90:
150         return VPHAL_ROTATION_90;                         // 90 Degree Rotation
151 
152     case VPHAL_ROTATION_180:
153         return VPHAL_ROTATION_180;                        // 180 Degree Rotation
154 
155     case VPHAL_ROTATION_270:
156         return VPHAL_ROTATION_270;                        // 270 Degree Rotation
157 
158     case VPHAL_MIRROR_HORIZONTAL:
159         return VPHAL_MIRROR_HORIZONTAL;                   // Horizontal Mirror
160 
161     case VPHAL_MIRROR_VERTICAL:
162         return VPHAL_MIRROR_VERTICAL;                     // Vertical Mirror
163 
164     case VPHAL_ROTATE_90_MIRROR_VERTICAL:
165         return VPHAL_ROTATION_270;                        // 270 Degree rotation and Horizontal Mirror
166 
167     case VPHAL_ROTATE_90_MIRROR_HORIZONTAL:
168         return VPHAL_ROTATION_90;                         // 90 Degree rotation and Horizontal Mirror
169 
170     default:
171         return VPHAL_ROTATION_IDENTITY;
172     }
173 }
174 
175 /****************************************************************************************************/
176 /*                          HwFilter Rotation and Mirror Parameter                                  */
177 /****************************************************************************************************/
Create(HW_FILTER_ROT_MIR_PARAM & param,FeatureType featureType)178 HwFilterParameter *HwFilterRotMirParameter::Create(HW_FILTER_ROT_MIR_PARAM &param, FeatureType featureType)
179 {
180     VP_FUNC_CALL();
181 
182     HwFilterRotMirParameter *p = MOS_New(HwFilterRotMirParameter, featureType);
183     if (p)
184     {
185         if (MOS_FAILED(p->Initialize(param)))
186         {
187             MOS_Delete(p);
188             return nullptr;
189         }
190     }
191     return p;
192 }
193 
HwFilterRotMirParameter(FeatureType featureType)194 HwFilterRotMirParameter::HwFilterRotMirParameter(FeatureType featureType) : HwFilterParameter(featureType)
195 {
196 }
197 
~HwFilterRotMirParameter()198 HwFilterRotMirParameter::~HwFilterRotMirParameter()
199 {
200 }
201 
ConfigParams(HwFilter & hwFilter)202 MOS_STATUS HwFilterRotMirParameter::ConfigParams(HwFilter &hwFilter)
203 {
204     VP_FUNC_CALL();
205 
206     return hwFilter.ConfigParam(m_Params);
207 }
208 
Initialize(HW_FILTER_ROT_MIR_PARAM & param)209 MOS_STATUS HwFilterRotMirParameter::Initialize(HW_FILTER_ROT_MIR_PARAM &param)
210 {
211     VP_FUNC_CALL();
212 
213     m_Params = param;
214     return MOS_STATUS_SUCCESS;
215 }
216 
217 /****************************************************************************************************/
218 /*                          Packet Sfc Rotation and Mirror Parameter                                */
219 /****************************************************************************************************/
Create(HW_FILTER_ROT_MIR_PARAM & param)220 VpPacketParameter *VpSfcRotMirParameter::Create(HW_FILTER_ROT_MIR_PARAM &param)
221 {
222     VP_FUNC_CALL();
223 
224     if (nullptr == param.pPacketParamFactory)
225     {
226         return nullptr;
227     }
228     VpSfcRotMirParameter *p = dynamic_cast<VpSfcRotMirParameter *>(param.pPacketParamFactory->GetPacketParameter(param.pHwInterface));
229     if (p)
230     {
231         if (MOS_FAILED(p->Initialize(param)))
232         {
233             VpPacketParameter *pParam = p;
234             param.pPacketParamFactory->ReturnPacketParameter(pParam);
235             return nullptr;
236         }
237     }
238     return p;
239 }
240 
VpSfcRotMirParameter(PVP_MHWINTERFACE pHwInterface,PacketParamFactoryBase * packetParamFactory)241 VpSfcRotMirParameter::VpSfcRotMirParameter(PVP_MHWINTERFACE pHwInterface, PacketParamFactoryBase *packetParamFactory) :
242     VpPacketParameter(packetParamFactory), m_RotMirFilter(pHwInterface)
243 {
244 }
~VpSfcRotMirParameter()245 VpSfcRotMirParameter::~VpSfcRotMirParameter() {}
246 
SetPacketParam(VpCmdPacket * pPacket)247 bool VpSfcRotMirParameter::SetPacketParam(VpCmdPacket *pPacket)
248 {
249     VP_FUNC_CALL();
250 
251     SFC_ROT_MIR_PARAMS *pParams = m_RotMirFilter.GetSfcParams();
252     if (nullptr == pParams)
253     {
254         VP_PUBLIC_ASSERTMESSAGE("Failed to get sfc rotation/mirror params");
255         return false;
256     }
257 
258     VpVeboxCmdPacketBase *packet = dynamic_cast<VpVeboxCmdPacketBase *>(pPacket);
259     if (packet)
260     {
261         return MOS_SUCCEEDED(packet->SetSfcRotMirParams(pParams));
262     }
263 
264     VP_PUBLIC_ASSERTMESSAGE("Invalid packet for sfc rotation/mirror");
265     return false;
266 }
267 
Initialize(HW_FILTER_ROT_MIR_PARAM & params)268 MOS_STATUS VpSfcRotMirParameter::Initialize(HW_FILTER_ROT_MIR_PARAM & params)
269 {
270     VP_FUNC_CALL();
271 
272     VP_PUBLIC_CHK_STATUS_RETURN(m_RotMirFilter.Init());
273     VP_PUBLIC_CHK_STATUS_RETURN(m_RotMirFilter.SetExecuteEngineCaps(params.rotMirParams, params.vpExecuteCaps));
274     VP_PUBLIC_CHK_STATUS_RETURN(m_RotMirFilter.CalculateEngineParams());
275     return MOS_STATUS_SUCCESS;
276 }
277 
278 /****************************************************************************************************/
279 /*                        Policy Sfc Rotation and Mirror Handler                                    */
280 /****************************************************************************************************/
PolicySfcRotMirHandler(VP_HW_CAPS & hwCaps)281 PolicySfcRotMirHandler::PolicySfcRotMirHandler(VP_HW_CAPS &hwCaps) : PolicyFeatureHandler(hwCaps)
282 {
283     m_Type = FeatureTypeRotMirOnSfc;
284 }
~PolicySfcRotMirHandler()285 PolicySfcRotMirHandler::~PolicySfcRotMirHandler()
286 {
287 }
288 
IsFeatureEnabled(VP_EXECUTE_CAPS vpExecuteCaps)289 bool PolicySfcRotMirHandler::IsFeatureEnabled(VP_EXECUTE_CAPS vpExecuteCaps)
290 {
291     VP_FUNC_CALL();
292 
293     return vpExecuteCaps.bSfcRotMir;
294 }
295 
CreateHwFilterParam(VP_EXECUTE_CAPS vpExecuteCaps,SwFilterPipe & swFilterPipe,PVP_MHWINTERFACE pHwInterface)296 HwFilterParameter *PolicySfcRotMirHandler::CreateHwFilterParam(VP_EXECUTE_CAPS vpExecuteCaps, SwFilterPipe &swFilterPipe, PVP_MHWINTERFACE pHwInterface)
297 {
298     VP_FUNC_CALL();
299 
300     if (IsFeatureEnabled(vpExecuteCaps))
301     {
302         if (SwFilterPipeType1To1 != swFilterPipe.GetSwFilterPipeType())
303         {
304             VP_PUBLIC_ASSERTMESSAGE("Invalid parameter! Sfc only support 1To1 swFilterPipe!");
305             return nullptr;
306         }
307 
308         SwFilterRotMir *swFilter = dynamic_cast<SwFilterRotMir *>(swFilterPipe.GetSwFilter(true, 0, FeatureTypeRotMirOnSfc));
309 
310         if (nullptr == swFilter)
311         {
312             VP_PUBLIC_ASSERTMESSAGE("Invalid parameter! Feature enabled in vpExecuteCaps but no swFilter exists!");
313             return nullptr;
314         }
315 
316         FeatureParamRotMir &param = swFilter->GetSwFilterParams();
317 
318         HW_FILTER_ROT_MIR_PARAM paramRotMir = {};
319         paramRotMir.type = m_Type;
320         paramRotMir.pHwInterface = pHwInterface;
321         paramRotMir.vpExecuteCaps = vpExecuteCaps;
322         paramRotMir.pPacketParamFactory = &m_PacketParamFactory;
323         paramRotMir.rotMirParams = param;
324         paramRotMir.pfnCreatePacketParam = PolicySfcRotMirHandler::CreatePacketParam;
325 
326         HwFilterParameter *pHwFilterParam = GetHwFeatureParameterFromPool();
327 
328         if (pHwFilterParam)
329         {
330             if (MOS_FAILED(((HwFilterRotMirParameter*)pHwFilterParam)->Initialize(paramRotMir)))
331             {
332                 ReleaseHwFeatureParameter(pHwFilterParam);
333             }
334         }
335         else
336         {
337             pHwFilterParam = HwFilterRotMirParameter::Create(paramRotMir, m_Type);
338         }
339 
340         return pHwFilterParam;
341    }
342     else
343     {
344         return nullptr;
345     }
346 }
347 
UpdateFeaturePipe(VP_EXECUTE_CAPS caps,SwFilter & feature,SwFilterPipe & featurePipe,SwFilterPipe & executePipe,bool isInputPipe,int index)348 MOS_STATUS PolicySfcRotMirHandler::UpdateFeaturePipe(VP_EXECUTE_CAPS caps, SwFilter &feature, SwFilterPipe &featurePipe, SwFilterPipe &executePipe, bool isInputPipe, int index)
349 {
350     VP_FUNC_CALL();
351 
352     SwFilterRotMir *featureRotMir = dynamic_cast<SwFilterRotMir *>(&feature);
353     VP_PUBLIC_CHK_NULL_RETURN(featureRotMir);
354 
355     if (caps.b1stPassOfSfc2PassScaling)
356     {
357         SwFilterRotMir *filter2ndPass = featureRotMir;
358         SwFilterRotMir *filter1ndPass = (SwFilterRotMir *)feature.Clone();
359         VP_PUBLIC_CHK_NULL_RETURN(filter1ndPass);
360         FeatureParamRotMir &params1stPass = filter1ndPass->GetSwFilterParams();
361 
362         // No rotation in 1st pass.
363         params1stPass.rotation = VPHAL_ROTATION_IDENTITY;
364 
365         // Clear engine caps for filter in 2nd pass.
366         filter2ndPass->SetFeatureType(FeatureTypeRotMir);
367         filter2ndPass->GetFilterEngineCaps().usedForNextPass = 1;
368 
369         executePipe.AddSwFilterUnordered(filter1ndPass, isInputPipe, index);
370     }
371     else
372     {
373         return PolicyFeatureHandler::UpdateFeaturePipe(caps, feature, featurePipe, executePipe, isInputPipe, index);
374     }
375 
376     return MOS_STATUS_SUCCESS;
377 }
378