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