xref: /aosp_15_r20/external/intel-media-driver/media_driver/agnostic/common/os/mos_gpucontextmgr.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 //!
23 //! \file    mos_gpucontextmgr.cpp
24 //! \brief   Container class for the basic gpu context manager
25 //!
26 
27 #include "mos_gpucontextmgr.h"
28 #include "mos_gpucontext_specific.h"
29 #include "mos_graphicsresource_specific.h"
30 
GpuContextMgr(GT_SYSTEM_INFO * gtSystemInfo,OsContext * osContext)31 GpuContextMgr::GpuContextMgr(GT_SYSTEM_INFO *gtSystemInfo, OsContext *osContext)
32 {
33     MOS_OS_FUNCTION_ENTER;
34     m_initialized = false;
35 
36     m_gpuContextArrayMutex = MosUtilities::MosCreateMutex();
37     MOS_OS_CHK_NULL_NO_STATUS_RETURN(m_gpuContextArrayMutex);
38 
39     MosUtilities::MosLockMutex(m_gpuContextArrayMutex);
40     m_gpuContextArray.clear();
41     MosUtilities::MosUnlockMutex(m_gpuContextArrayMutex);
42 
43     if (gtSystemInfo)
44     {
45         MOS_SecureMemcpy(&m_gtSystemInfo, sizeof(GT_SYSTEM_INFO), gtSystemInfo, sizeof(GT_SYSTEM_INFO));
46     }
47     else
48     {
49         MOS_OS_ASSERTMESSAGE("Input GTSystemInfo cannot be nullptr");
50         return;
51     }
52 
53     if (osContext)
54     {
55         m_osContext = osContext;
56     }
57     else
58     {
59         MOS_OS_ASSERTMESSAGE("Input osContext cannot be nullptr");
60         return;
61     }
62 
63     m_initialized = true;
64 }
65 
~GpuContextMgr()66 GpuContextMgr::~GpuContextMgr()
67 {
68     MOS_OS_FUNCTION_ENTER;
69 
70     if (m_gpuContextArrayMutex)
71     {
72         MosUtilities::MosDestroyMutex(m_gpuContextArrayMutex);
73         m_gpuContextArrayMutex = nullptr;
74     }
75 }
76 
GetObject(GT_SYSTEM_INFO * gtSystemInfo,OsContext * osContext)77 GpuContextMgr *GpuContextMgr::GetObject(
78     GT_SYSTEM_INFO *gtSystemInfo,
79     OsContext *     osContext)
80 {
81     MOS_OS_FUNCTION_ENTER;
82     if (gtSystemInfo == nullptr || osContext == nullptr)
83     {
84         MOS_OS_ASSERTMESSAGE("Invalid input parameters!");
85         return nullptr;
86     }
87     return MOS_New(GpuContextMgr, gtSystemInfo, osContext);
88 }
89 
CleanUp()90 void GpuContextMgr::CleanUp()
91 {
92     MOS_OS_FUNCTION_ENTER;
93 
94     if (m_initialized)
95     {
96         DestroyAllGpuContexts();
97 
98         MosUtilities::MosLockMutex(m_gpuContextArrayMutex);
99         m_gpuContextArray.clear();
100         MosUtilities::MosUnlockMutex(m_gpuContextArrayMutex);
101 
102         m_initialized = false;
103     }
104 
105     return;
106 }
107 
ContextReuseNeeded()108 bool GpuContextMgr::ContextReuseNeeded()
109 {
110     MOS_OS_FUNCTION_ENTER;
111 
112     // to be added after scalable design is nailed down
113     return false;
114 }
115 
SelectContextToReuse()116 GpuContext *GpuContextMgr::SelectContextToReuse()
117 {
118     MOS_OS_FUNCTION_ENTER;
119 
120     // to be added after scalable design is nailed down
121     return nullptr;
122 }
123 
CreateGpuContext(const MOS_GPU_NODE gpuNode,CmdBufMgr * cmdBufMgr,MOS_GPU_CONTEXT mosGpuCtx)124 GpuContext *GpuContextMgr::CreateGpuContext(
125     const MOS_GPU_NODE gpuNode,
126     CmdBufMgr *        cmdBufMgr,
127     MOS_GPU_CONTEXT    mosGpuCtx)
128 {
129     MOS_OS_FUNCTION_ENTER;
130 
131     if (cmdBufMgr == nullptr)
132     {
133         MOS_OS_ASSERTMESSAGE("nullptr of cmdbufmgr.");
134         return nullptr;
135     }
136 
137     GpuContext *reusedContext = nullptr;
138     if (ContextReuseNeeded())
139     {
140         reusedContext = SelectContextToReuse();
141     }
142 
143     GpuContext *gpuContext = GpuContext::Create(gpuNode, mosGpuCtx, cmdBufMgr, reusedContext);
144     if (gpuContext == nullptr)
145     {
146         MOS_OS_ASSERTMESSAGE("nullptr returned by GpuContext::Create.");
147         return nullptr;
148     }
149 
150     MosUtilities::MosLockMutex(m_gpuContextArrayMutex);
151 
152     GPU_CONTEXT_HANDLE gpuContextHandle = 0;
153 
154     if (m_noCycledGpuCxtMgmt)
155     {
156         // new created context at the end of m_gpuContextArray.
157         gpuContextHandle = m_gpuContextArray.size() ? m_gpuContextArray.size() : 0;
158     }
159     else
160     {
161         // Directly replace nullptr with new created context in m_gpuContextArray.
162         GpuContext *curGpuContext = nullptr;
163         int         index         = 0;
164         for (auto &curGpuContext : m_gpuContextArray)
165         {
166             if (curGpuContext == nullptr)
167             {
168                 break;
169             }
170             index++;
171         }
172         gpuContextHandle = m_gpuContextArray.size() ? index : 0;
173     }
174     gpuContext->SetGpuContextHandle(gpuContextHandle);
175 
176     if (gpuContextHandle == m_gpuContextArray.size())
177     {
178         m_gpuContextArray.push_back(gpuContext);
179     }
180     else
181     {
182         m_gpuContextArray[gpuContextHandle] = gpuContext;
183     }
184     m_gpuContextCount++;
185 
186     MosUtilities::MosUnlockMutex(m_gpuContextArrayMutex);
187 
188     return gpuContext;
189 }
190 
GetGpuContext(GPU_CONTEXT_HANDLE gpuContextHandle)191 GpuContext *GpuContextMgr::GetGpuContext(GPU_CONTEXT_HANDLE gpuContextHandle)
192 {
193     MOS_OS_FUNCTION_ENTER;
194 
195     if (gpuContextHandle == MOS_GPU_CONTEXT_INVALID_HANDLE)
196     {
197         MOS_OS_ASSERTMESSAGE("Input gpucontext handle cannot be MOS_GPU_CONTEXT_INVALID_HANDLE!");
198         return nullptr;
199     }
200 
201     GpuContext *gpuContext = nullptr;
202     MosUtilities::MosLockMutex(m_gpuContextArrayMutex);
203 
204     if (!m_gpuContextArray.empty() && gpuContextHandle < m_gpuContextArray.size())
205     {
206         gpuContext = m_gpuContextArray.at(gpuContextHandle);
207     }
208     else
209     {
210         MOS_OS_ASSERTMESSAGE("GPU context array is empty or got invalid index, something must be wrong!");
211         gpuContext = nullptr;
212     }
213     MosUtilities::MosUnlockMutex(m_gpuContextArrayMutex);
214     return gpuContext;
215 }
216 
DestroyGpuContext(GpuContext * gpuContext)217 void GpuContextMgr::DestroyGpuContext(GpuContext *gpuContext)
218 {
219     MOS_OS_FUNCTION_ENTER;
220     MOS_OS_CHK_NULL_NO_STATUS_RETURN(gpuContext);
221 
222     GpuContext *curGpuContext = nullptr;
223     bool        found         = false;
224 
225     MosUtilities::MosLockMutex(m_gpuContextArrayMutex);
226     for (auto &curGpuContext : m_gpuContextArray)
227     {
228         if (curGpuContext == gpuContext)
229         {
230             found = true;
231             // to keep original order, here should not erase gpucontext, replace with nullptr in array.
232             MOS_Delete(curGpuContext);  // delete gpu context.
233             m_gpuContextCount--;
234             break;
235         }
236     }
237 
238     if (m_gpuContextCount == 0 && !m_noCycledGpuCxtMgmt)
239     {
240         m_gpuContextArray.clear();  // clear whole array
241     }
242 
243     MosUtilities::MosUnlockMutex(m_gpuContextArrayMutex);
244 
245     if (!found)
246     {
247         MOS_OS_ASSERTMESSAGE("cannot find specified gpuContext in the gpucontext pool, something must be wrong");
248     }
249 }
250 
DestroyAllGpuContexts()251 void GpuContextMgr::DestroyAllGpuContexts()
252 {
253     MOS_OS_FUNCTION_ENTER;
254 
255     GpuContext *curGpuContext = nullptr;
256 
257     MosUtilities::MosLockMutex(m_gpuContextArrayMutex);
258 
259     // delete each instance in m_gpuContextArray
260     for (auto &curGpuContext : m_gpuContextArray)
261     {
262         MOS_Delete(curGpuContext);
263     }
264 
265     m_gpuContextArray.clear();  // clear whole array
266 
267     MosUtilities::MosUnlockMutex(m_gpuContextArrayMutex);
268 }
269