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 #include "vp_cmd_packet.h"
23 #include "vp_utils.h"
24 #include "vp_packet_pipe.h"
25 #include "media_task.h"
26 #include "media_context.h"
27 #include "vp_feature_manager.h"
28 #include "vp_platform_interface.h"
29
30 using namespace vp;
31
PacketFactory(VpPlatformInterface * vpPlatformInterface)32 PacketFactory::PacketFactory(VpPlatformInterface *vpPlatformInterface) : m_vpPlatformInterface(vpPlatformInterface)
33 {
34 }
35
~PacketFactory()36 PacketFactory::~PacketFactory()
37 {
38 ClearPacketPool(m_VeboxPacketPool);
39 ClearPacketPool(m_RenderPacketPool);
40 }
41
ClearPacketPool(std::vector<VpCmdPacket * > & pool)42 void PacketFactory::ClearPacketPool(std::vector<VpCmdPacket *> &pool)
43 {
44 VP_FUNC_CALL();
45
46 while (!pool.empty())
47 {
48 VpCmdPacket *p = pool.back();
49 pool.pop_back();
50 MOS_Delete(p);
51 }
52 }
53
Initialize(MediaTask * pTask,PVP_MHWINTERFACE pHwInterface,PVpAllocator pAllocator,VPMediaMemComp * pMmc,VP_PACKET_SHARED_CONTEXT * packetSharedContext,VpKernelSet * vpKernels,void * debugInterface)54 MOS_STATUS PacketFactory::Initialize(MediaTask *pTask, PVP_MHWINTERFACE pHwInterface, PVpAllocator pAllocator, VPMediaMemComp *pMmc, VP_PACKET_SHARED_CONTEXT *packetSharedContext, VpKernelSet* vpKernels,
55 void *debugInterface)
56 {
57 VP_FUNC_CALL();
58
59 m_pTask = pTask;
60 m_pHwInterface = pHwInterface;
61 m_pAllocator = pAllocator;
62 m_pMmc = pMmc;
63 m_packetSharedContext = packetSharedContext;
64 m_kernelSet = vpKernels;
65
66 #if (_DEBUG || _RELEASE_INTERNAL)
67 m_debugInterface = static_cast<VpDebugInterface*>(debugInterface);
68 #endif
69
70 return MOS_STATUS_SUCCESS;
71 }
72
CreatePacket(EngineType type)73 VpCmdPacket *PacketFactory::CreatePacket(EngineType type)
74 {
75 VP_FUNC_CALL();
76
77 switch(type)
78 {
79 case EngineTypeVebox:
80 case EngineTypeVeboxSfc:
81 if (!m_VeboxPacketPool.empty())
82 {
83 VpCmdPacket *p = m_VeboxPacketPool.back();
84 m_VeboxPacketPool.pop_back();
85 return p;
86 }
87 return CreateVeboxPacket();
88 case EngineTypeRender:
89 if (!m_RenderPacketPool.empty())
90 {
91 VpCmdPacket *p = m_RenderPacketPool.back();
92 m_RenderPacketPool.pop_back();
93 return p;
94 }
95 return CreateRenderPacket();
96 default:
97 return nullptr;
98 }
99 }
100
ReturnPacket(VpCmdPacket * & pPacket)101 void PacketFactory::ReturnPacket(VpCmdPacket *&pPacket)
102 {
103 VP_FUNC_CALL();
104
105 if (nullptr == pPacket)
106 {
107 return;
108 }
109 PacketType type = pPacket->GetPacketId();
110 switch (type)
111 {
112 case VP_PIPELINE_PACKET_VEBOX:
113 m_VeboxPacketPool.push_back(pPacket);
114 break;
115 case VP_PIPELINE_PACKET_RENDER:
116 case VP_PIPELINE_PACKET_COMPUTE:
117 m_RenderPacketPool.push_back(pPacket);
118 break;
119 default:
120 break;
121 }
122 pPacket = nullptr;
123 }
124
CreateVeboxPacket()125 VpCmdPacket *PacketFactory::CreateVeboxPacket()
126 {
127 VP_FUNC_CALL();
128
129 VpCmdPacket *p = m_vpPlatformInterface ? m_vpPlatformInterface->CreateVeboxPacket(m_pTask, m_pHwInterface, m_pAllocator, m_pMmc) : nullptr;
130 if (p)
131 {
132 p->SetPacketSharedContext(m_packetSharedContext);
133 }
134 return p;
135 }
136
CreateRenderPacket()137 VpCmdPacket *PacketFactory::CreateRenderPacket()
138 {
139 VP_FUNC_CALL();
140
141 VpCmdPacket *p = m_vpPlatformInterface ? m_vpPlatformInterface->CreateRenderPacket(m_pTask, m_pHwInterface, m_pAllocator, m_pMmc, m_kernelSet) : nullptr;
142 if (p)
143 {
144 MOS_STATUS status = MOS_STATUS_SUCCESS;
145
146 status = p->Init();
147
148 if (MOS_STATUS_SUCCESS != status)
149 {
150 VP_PUBLIC_ASSERTMESSAGE("Render CMD Packet Init Fail");
151 }
152
153 p->SetPacketSharedContext(m_packetSharedContext);
154 }
155 return p;
156 }
157
PacketPipe(PacketFactory & packetFactory)158 PacketPipe::PacketPipe(PacketFactory &packetFactory) : m_PacketFactory(packetFactory)
159 {
160 }
161
~PacketPipe()162 PacketPipe::~PacketPipe()
163 {
164 Clean();
165 }
166
Clean()167 MOS_STATUS PacketPipe::Clean()
168 {
169 VP_FUNC_CALL();
170
171 m_outputPipeMode = VPHAL_OUTPUT_PIPE_MODE_INVALID;
172 m_veboxFeatureInuse = false;
173 for (std::vector<VpCmdPacket *>::iterator it = m_Pipe.begin(); it != m_Pipe.end(); ++it)
174 {
175 m_PacketFactory.ReturnPacket(*it);
176 }
177 m_Pipe.clear();
178 return MOS_STATUS_SUCCESS;
179 }
180
AddPacket(HwFilter & hwFilter)181 MOS_STATUS PacketPipe::AddPacket(HwFilter &hwFilter)
182 {
183 VP_FUNC_CALL();
184
185 VpCmdPacket *pPacket = m_PacketFactory.CreatePacket(hwFilter.GetEngineType());
186 VP_PUBLIC_CHK_NULL_RETURN(pPacket);
187 MOS_STATUS status = hwFilter.SetPacketParams(*pPacket);
188 if (MOS_FAILED(status))
189 {
190 MOS_OS_ASSERTMESSAGE("SetPacketParams failed!");
191 m_PacketFactory.ReturnPacket(pPacket);
192 return status;
193 }
194 m_Pipe.push_back(pPacket);
195 if (hwFilter.GetRenderTargetType() == RenderTargetTypeSurface)
196 {
197 VP_PUBLIC_CHK_STATUS_RETURN(SetOutputPipeMode(hwFilter.GetEngineType()));
198 }
199
200 m_veboxFeatureInuse |= hwFilter.IsVeboxFeatureInuse();
201
202 return MOS_STATUS_SUCCESS;
203 }
204
SetOutputPipeMode(EngineType engineType)205 MOS_STATUS PacketPipe::SetOutputPipeMode(EngineType engineType)
206 {
207 VP_FUNC_CALL();
208
209 switch (engineType)
210 {
211 case EngineTypeVebox:
212 m_outputPipeMode = VPHAL_OUTPUT_PIPE_MODE_VEBOX;
213 break;
214 case EngineTypeVeboxSfc:
215 m_outputPipeMode = VPHAL_OUTPUT_PIPE_MODE_SFC;
216 break;
217 case EngineTypeRender:
218 m_outputPipeMode = VPHAL_OUTPUT_PIPE_MODE_COMP;
219 break;
220 default:
221 m_outputPipeMode = VPHAL_OUTPUT_PIPE_MODE_INVALID;
222 VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_INVALID_PARAMETER);
223 }
224
225 return MOS_STATUS_SUCCESS;
226 }
227
SwitchContext(PacketType type,MediaScalability * & scalability,MediaContext * mediaContext,bool bEnableVirtualEngine,uint8_t numVebox)228 MOS_STATUS PacketPipe::SwitchContext(PacketType type, MediaScalability *&scalability, MediaContext *mediaContext, bool bEnableVirtualEngine, uint8_t numVebox)
229 {
230 VP_FUNC_CALL();
231
232 ScalabilityPars scalPars = {};
233 switch (type)
234 {
235 case VP_PIPELINE_PACKET_VEBOX:
236 {
237 VP_PUBLIC_NORMALMESSAGE("Switch to Vebox Context");
238
239 scalPars.enableVE = bEnableVirtualEngine;
240 scalPars.numVebox = numVebox;
241
242 VP_PUBLIC_CHK_STATUS_RETURN(mediaContext->SwitchContext(VeboxVppFunc, &scalPars, &scalability));
243 VP_PUBLIC_CHK_NULL_RETURN(scalability);
244 break;
245 }
246 case VP_PIPELINE_PACKET_RENDER:
247 {
248 VP_PUBLIC_NORMALMESSAGE("Switch to Render Context");
249 VP_PUBLIC_CHK_STATUS_RETURN(mediaContext->SwitchContext(RenderGenericFunc, &scalPars, &scalability));
250 VP_PUBLIC_CHK_NULL_RETURN(scalability);
251 break;
252 }
253 case VP_PIPELINE_PACKET_COMPUTE:
254 {
255 VP_PUBLIC_NORMALMESSAGE("Switch to Compute Context");
256 VP_PUBLIC_CHK_STATUS_RETURN(mediaContext->SwitchContext(ComputeVppFunc, &scalPars, &scalability));
257 VP_PUBLIC_CHK_NULL_RETURN(scalability);
258 break;
259 }
260 default:
261 VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_INVALID_PARAMETER);
262 }
263 return MOS_STATUS_SUCCESS;
264 }
265
Execute(MediaStatusReport * statusReport,MediaScalability * & scalability,MediaContext * mediaContext,bool bEnableVirtualEngine,uint8_t numVebox)266 MOS_STATUS PacketPipe::Execute(MediaStatusReport *statusReport, MediaScalability *&scalability, MediaContext *mediaContext, bool bEnableVirtualEngine, uint8_t numVebox)
267 {
268 VP_FUNC_CALL();
269
270 VP_PUBLIC_NORMALMESSAGE("PacketPipe %p in execute.", this);
271
272 // PrePare Packet in case any packet resources shared
273 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
274 for (std::vector<VpCmdPacket*>::reverse_iterator it = m_Pipe.rbegin(); it != m_Pipe.rend(); ++it)
275 {
276 VpCmdPacket* packet = *it;
277 VP_PUBLIC_CHK_STATUS_RETURN(packet->PrepareState());
278 }
279
280 for (std::vector<VpCmdPacket *>::iterator it = m_Pipe.begin(); it != m_Pipe.end(); ++it)
281 {
282 VpCmdPacket *pPacket = *it;
283 PacketProperty prop = {};
284 prop.packetId = pPacket->GetPacketId();
285 prop.packet = pPacket;
286 prop.immediateSubmit = true;
287 prop.stateProperty.statusReport = statusReport;
288
289 bool isSkip = false;
290 // Checking if extra processing is needed.
291 isSkip = pPacket->ExtraProcessing();
292 if (isSkip)
293 {
294 VP_PUBLIC_NORMALMESSAGE("Skip this packet.");
295 continue;
296 }
297
298 MediaTask *pTask = pPacket->GetActiveTask();
299 VP_PUBLIC_CHK_NULL_RETURN(pTask);
300
301 VP_PUBLIC_CHK_STATUS_RETURN(SwitchContext(pPacket->GetPacketId(), scalability, mediaContext, bEnableVirtualEngine, numVebox));
302 VP_PUBLIC_CHK_NULL_RETURN(scalability);
303 pPacket->SetMediaScalability(scalability);
304
305 VP_PUBLIC_CHK_STATUS_RETURN(pTask->AddPacket(&prop));
306 if (prop.immediateSubmit)
307 {
308 VP_PUBLIC_NORMALMESSAGE("Execute Packet %p.", pPacket);
309 VP_PUBLIC_CHK_STATUS_RETURN(pTask->Submit(true, scalability, nullptr));
310 }
311
312 #if USE_MEDIA_DEBUG_TOOL
313 for (auto& handle : pPacket->GetSurfSetting().surfGroup)
314 {
315 if(handle.first && handle.second)
316 {
317 VP_SURFACE_DUMP(m_PacketFactory.m_debugInterface,
318 handle.second,
319 0,
320 handle.first,
321 VPHAL_DUMP_TYPE_POST_COMP,
322 VPHAL_SURF_DUMP_DDI_VP_BLT);
323 }
324 }
325 #endif
326 }
327
328 return eStatus;
329 }
330
CreatePacket(EngineType type)331 VpCmdPacket *PacketPipe::CreatePacket(EngineType type)
332 {
333 return m_PacketFactory.CreatePacket(type);
334 }
335
336
PacketPipeFactory(PacketFactory & pPacketFactory)337 PacketPipeFactory::PacketPipeFactory(PacketFactory &pPacketFactory) : m_pPacketFactory(pPacketFactory)
338 {
339 }
340
~PacketPipeFactory()341 PacketPipeFactory::~PacketPipeFactory()
342 {
343 while (!m_Pool.empty())
344 {
345 PacketPipe *p = m_Pool.back();
346 m_Pool.pop_back();
347 MOS_Delete(p);
348 }
349 }
350
CreatePacketPipe()351 PacketPipe *PacketPipeFactory::CreatePacketPipe()
352 {
353 VP_FUNC_CALL();
354
355 if (!m_Pool.empty())
356 {
357 PacketPipe *p = m_Pool.back();
358 m_Pool.pop_back();
359 p->Clean();
360 return p;
361 }
362 return MOS_New(PacketPipe, m_pPacketFactory);
363 }
364
ReturnPacketPipe(PacketPipe * & pPipe)365 void PacketPipeFactory::ReturnPacketPipe(PacketPipe *&pPipe)
366 {
367 VP_FUNC_CALL();
368
369 if (nullptr == pPipe)
370 {
371 return;
372 }
373 pPipe->Clean();
374 if (std::find(m_Pool.begin(), m_Pool.end(), pPipe) == m_Pool.end())
375 {
376 m_Pool.push_back(pPipe);
377 }
378 else
379 {
380 VP_PUBLIC_ASSERTMESSAGE("packetPipe %p is existing in m_Pool!, m_Pool size is %d.", pPipe, (uint32_t)m_Pool.size());
381 }
382 pPipe = nullptr;
383 }