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 ¶m, 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 ¶m)
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 ¶m)
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 ¶m = 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 ¶ms1stPass = 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