xref: /aosp_15_r20/external/intel-media-driver/media_softlet/agnostic/common/os/mos_gpucontextmgr_next.cpp (revision ba62d9d3abf0e404f2022b4cd7a85e107f48596f)
1 /*
2 * Copyright (c) 2019, 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    mos_gpucontextmgr_next.cpp
24 //! \brief   Container class for the basic gpu context manager
25 //!
26 
27 #include "mos_gpucontextmgr_next.h"
28 #include "mos_gpucontext_specific_next.h"
29 #include "mos_graphicsresource_specific_next.h"
30 #include "mos_context_next.h"
31 #include "mos_oca_rtlog_mgr.h"
32 
GpuContextMgrNext(OsContextNext * osContext)33 GpuContextMgrNext::GpuContextMgrNext(OsContextNext *osContext)
34 {
35     MOS_OS_FUNCTION_ENTER;
36     m_initialized = false;
37 
38     if (osContext)
39     {
40         m_osContext = osContext;
41     }
42     else
43     {
44         MOS_OS_ASSERTMESSAGE("Input osContext cannot be nullptr");
45         return;
46     }
47 }
48 
~GpuContextMgrNext()49 GpuContextMgrNext::~GpuContextMgrNext()
50 {
51     MOS_OS_FUNCTION_ENTER;
52 
53     if (m_gpuContextArrayMutex)
54     {
55         MosUtilities::MosDestroyMutex(m_gpuContextArrayMutex);
56         m_gpuContextArrayMutex = nullptr;
57     }
58 }
59 
Initialize()60 MOS_STATUS GpuContextMgrNext::Initialize()
61 {
62     MOS_STATUS status = MOS_STATUS_SUCCESS;
63     m_gpuContextArrayMutex = MosUtilities::MosCreateMutex();
64     MOS_OS_CHK_NULL_RETURN(m_gpuContextArrayMutex);
65 
66     MosUtilities::MosLockMutex(m_gpuContextArrayMutex);
67     m_gpuContextMap.clear();
68     MosUtilities::MosUnlockMutex(m_gpuContextArrayMutex);
69 
70     m_initialized = true;
71     return status;
72 }
73 
74 
GetObject(OsContextNext * osContext)75 GpuContextMgrNext *GpuContextMgrNext::GetObject(
76     OsContextNext     *osContext)
77 {
78     MOS_OS_FUNCTION_ENTER;
79     if (osContext == nullptr)
80     {
81         MOS_OS_ASSERTMESSAGE("Invalid input parameters!");
82         return nullptr;
83     }
84 
85     MOS_STATUS status = MOS_STATUS_SUCCESS;
86     GpuContextMgrNext* pGpuContext = MOS_New(GpuContextMgrNext, osContext);
87     if (!pGpuContext)
88     {
89         return nullptr;
90     }
91     status = pGpuContext->Initialize();
92     if (MOS_FAILED(status))
93     {
94         MOS_Delete(pGpuContext);
95         return nullptr;
96     }
97     return pGpuContext;
98 }
99 
CleanUp()100 void GpuContextMgrNext::CleanUp()
101 {
102     MOS_OS_FUNCTION_ENTER;
103 
104     if (m_initialized)
105     {
106         DestroyAllGpuContexts();
107 
108         MosUtilities::MosLockMutex(m_gpuContextArrayMutex);
109         m_gpuContextMap.clear();
110         MosUtilities::MosUnlockMutex(m_gpuContextArrayMutex);
111 
112         m_initialized = false;
113     }
114 
115     return;
116 }
117 
ContextReuseNeeded()118 bool GpuContextMgrNext::ContextReuseNeeded()
119 {
120     MOS_OS_FUNCTION_ENTER;
121 
122     // to be added after scalable design is nailed down
123     return false;
124 }
125 
SelectContextToReuse()126 GpuContextNext *GpuContextMgrNext::SelectContextToReuse()
127 {
128     MOS_OS_FUNCTION_ENTER;
129 
130     // to be added after scalable design is nailed down
131     return nullptr;
132 }
133 
CreateGpuContext(const MOS_GPU_NODE gpuNode,CmdBufMgrNext * cmdBufMgr)134 GpuContextNext *GpuContextMgrNext::CreateGpuContext(
135     const MOS_GPU_NODE gpuNode,
136     CmdBufMgrNext *    cmdBufMgr)
137 {
138     MOS_OS_FUNCTION_ENTER;
139 
140     if (cmdBufMgr == nullptr && !m_osContext->IsAynchronous())
141     {
142         MOS_OS_ASSERTMESSAGE("nullptr of cmdbufmgr in normal mode. nullptr can only be applied in Async mode");
143         return nullptr;
144     }
145 
146     GpuContextNext *reusedContext = nullptr;
147     if (ContextReuseNeeded())
148     {
149         reusedContext = SelectContextToReuse();
150     }
151 
152     GpuContextNext *gpuContext = GpuContextSpecificNext::Create(gpuNode, cmdBufMgr, reusedContext);
153     if (gpuContext == nullptr)
154     {
155         MOS_OS_ASSERTMESSAGE("nullptr returned by GpuContext::Create.");
156         return nullptr;
157     }
158 
159     MosUtilities::MosLockMutex(m_gpuContextArrayMutex);
160 
161     GPU_CONTEXT_HANDLE gpuContextHandle = 0;
162     bool found = false;
163 
164     if (m_noCycledGpuCxtMgmt)
165     {
166         // new created context at the end of m_gpuContextArray.
167         gpuContextHandle = m_gpuContextHanleForNonCycledCase;
168         m_gpuContextHanleForNonCycledCase++;
169     }
170     else
171     {
172         // Directly replace nullptr with new created context in m_gpuContextArray.
173         GpuContextNext *curGpuContext = nullptr;
174         for (auto &igpu : m_gpuContextMap)
175         {
176             if (igpu.second == nullptr)
177             {
178                 gpuContextHandle = igpu.first;
179                 igpu.second = gpuContext;
180                 found = true;
181                 break;
182             }
183         }
184         if(!found)
185         {
186             gpuContextHandle = m_gpuContextMap.size();
187         }
188     }
189     gpuContext->SetGpuContextHandle(gpuContextHandle);
190 
191 
192     m_gpuContextMap[gpuContextHandle] = gpuContext;
193     m_gpuContextCount++;
194 
195     MT_LOG5(MT_MOS_GPUCXT_CREATE, MT_NORMAL, MT_MOS_GPUCXT_MGR_PTR, (int64_t)this, MT_MOS_GPUCXT_PTR, (int64_t)gpuContext,
196         MT_MOS_GPUCXT_COUNT, m_gpuContextCount, MT_MOS_GPU_NODE, gpuNode, MT_MOS_GPUCXT_HANDLE, gpuContextHandle);
197 
198     MosUtilities::MosUnlockMutex(m_gpuContextArrayMutex);
199 
200     return gpuContext;
201 }
202 
GetGpuContext(GPU_CONTEXT_HANDLE gpuContextHandle)203 GpuContextNext *GpuContextMgrNext::GetGpuContext(GPU_CONTEXT_HANDLE gpuContextHandle)
204 {
205     MOS_OS_FUNCTION_ENTER;
206 
207     if (gpuContextHandle == MOS_GPU_CONTEXT_INVALID_HANDLE)
208     {
209         MOS_OS_ASSERTMESSAGE("Input gpucontext handle cannot be MOS_GPU_CONTEXT_INVALID_HANDLE!");
210         return nullptr;
211     }
212 
213     GpuContextNext *gpuContext = nullptr;
214     MosUtilities::MosLockMutex(m_gpuContextArrayMutex);
215     auto it = std::find_if(m_gpuContextMap.begin(), m_gpuContextMap.end(),  [&](auto &curGpuCtx)
216         { return curGpuCtx.first == gpuContextHandle; });
217     if (m_gpuContextMap.end() != it)
218     {
219         gpuContext = m_gpuContextMap.at(gpuContextHandle);
220     }
221     else
222     {
223         MOS_OS_NORMALMESSAGE("Gpu context may have been deleted already!");
224         MT_LOG2(MT_MOS_GPUCXT_GET, MT_NORMAL, MT_MOS_GPUCXT_MGR_PTR, (int64_t)this, MT_MOS_GPUCXT_HANDLE, gpuContextHandle);
225         gpuContext = nullptr;
226     }
227     MosUtilities::MosUnlockMutex(m_gpuContextArrayMutex);
228     return gpuContext;
229 }
230 
DestroyGpuContext(GpuContextNext * gpuContext)231 void GpuContextMgrNext::DestroyGpuContext(GpuContextNext *gpuContext)
232 {
233     MOS_OS_FUNCTION_ENTER;
234     MOS_OS_CHK_NULL_NO_STATUS_RETURN(gpuContext);
235 
236     GpuContextNext *curGpuContext = nullptr;
237     bool        found         = false;
238 
239     MosUtilities::MosLockMutex(m_gpuContextArrayMutex);
240     auto it = std::find_if(m_gpuContextMap.begin(), m_gpuContextMap.end(), [&](auto &curGpuCtx)
241         { return curGpuCtx.second == gpuContext; });
242     if (m_gpuContextMap.end() != it)
243     {
244         found = true;
245         if (m_noCycledGpuCxtMgmt)
246         {
247             m_gpuContextMap.erase(it);
248         }
249         else
250         {
251             it->second = nullptr;
252         }
253         m_gpuContextCount--;
254     }
255 
256     if (m_gpuContextCount == 0 && !m_noCycledGpuCxtMgmt)
257     {
258         m_gpuContextMap.clear();  // clear whole array
259     }
260 
261     MT_LOG3(MT_MOS_GPUCXT_DESTROY, MT_NORMAL, MT_MOS_GPUCXT_MGR_PTR, (int64_t)this, MT_MOS_GPUCXT_PTR, (int64_t)gpuContext, MT_MOS_GPUCXT_COUNT, m_gpuContextCount);
262 
263     MosStreamState streamState = {};
264     streamState.osDeviceContext = m_osContext;
265     MosUtilities::MosUnlockMutex(m_gpuContextArrayMutex);
266 
267     if (found)
268     {
269         MOS_Delete(gpuContext);  // delete gpu context.
270     }
271     else
272     {
273         MOS_OS_ASSERTMESSAGE("cannot find specified gpuContext in the gpucontext pool, something must be wrong");
274         MT_ERR3(MT_MOS_GPUCXT_DESTROY, MT_MOS_GPUCXT_MGR_PTR, (int64_t)this, MT_MOS_GPUCXT_PTR, (int64_t)gpuContext, MT_CODE_LINE, __LINE__);
275     }
276 }
277 
DestroyAllGpuContexts()278 void GpuContextMgrNext::DestroyAllGpuContexts()
279 {
280     MOS_OS_FUNCTION_ENTER;
281 
282     GpuContextNext *curGpuContext = nullptr;
283 
284     MosUtilities::MosLockMutex(m_gpuContextArrayMutex);
285 
286     // delete each instance in m_gpuContextArray
287     for (auto &curGpuContext : m_gpuContextMap)
288     {
289         MT_LOG2(MT_MOS_GPUCXT_DESTROY, MT_NORMAL, MT_MOS_GPUCXT_MGR_PTR, (int64_t)this, MT_MOS_GPUCXT_PTR, (int64_t)curGpuContext.second);
290         MOS_Delete(curGpuContext.second);
291     }
292 
293     m_gpuContextMap.clear();  // clear whole array
294 
295     MosUtilities::MosUnlockMutex(m_gpuContextArrayMutex);
296 }
297