xref: /aosp_15_r20/external/intel-media-driver/media_softlet/agnostic/common/vp/hal/packet/vp_packet_pipe.cpp (revision ba62d9d3abf0e404f2022b4cd7a85e107f48596f)
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 }