xref: /aosp_15_r20/external/intel-media-driver/media_driver/linux/common/os/mos_gpucontext_specific.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_gpucontext_specific.cpp
24 //! \brief   Container class for the Linux specific gpu context
25 //!
26 
27 #include <unistd.h>
28 #include "mos_context_specific.h"
29 #include "mos_gpucontext_specific.h"
30 #include "mos_graphicsresource_specific.h"
31 #include "mos_commandbuffer_specific.h"
32 #include "mos_util_devult_specific.h"
33 #include "mos_cmdbufmgr.h"
34 #include "mos_os_virtualengine.h"
35 #include "mos_os_cp_interface_specific.h"
36 
37 #define MI_BATCHBUFFER_END 0x05000000
38 static pthread_mutex_t command_dump_mutex = PTHREAD_MUTEX_INITIALIZER;
39 
GpuContextSpecific(const MOS_GPU_NODE gpuNode,MOS_GPU_CONTEXT mosGpuCtx,CmdBufMgr * cmdBufMgr,GpuContext * reusedContext)40 GpuContextSpecific::GpuContextSpecific(
41     const MOS_GPU_NODE gpuNode,
42     MOS_GPU_CONTEXT    mosGpuCtx,
43     CmdBufMgr         *cmdBufMgr,
44     GpuContext        *reusedContext)
45 {
46     MOS_OS_FUNCTION_ENTER;
47 
48     m_nodeOrdinal          = gpuNode;
49     m_cmdBufMgr            = cmdBufMgr;
50     m_gpuContext           = mosGpuCtx;
51     m_statusBufferResource = nullptr;
52     m_maxPatchLocationsize = PATCHLOCATIONLIST_SIZE;
53 
54     if (reusedContext)
55     {
56         MOS_OS_NORMALMESSAGE("gpucontex reusing not enabled on Linux.");
57     }
58 
59 #if (_DEBUG || _RELEASE_INTERNAL)
60     // get user engine instance setting from environment variable
61     char *engineInstances = getenv("INTEL_ENGINE_INSTANCE");
62     if (engineInstances != nullptr)
63     {
64         errno             = 0;
65         long int instance = strtol(engineInstances, nullptr, 16);
66         /* Check for various possible errors. */
67         if ((errno == ERANGE && instance == LONG_MAX) || (instance < 0))
68         {
69             MOS_OS_NORMALMESSAGE("Invalid INTEL_ENGINE_INSTANCE setting.(%s)\n", engineInstances);
70             m_engineInstanceSelect = 0x0;
71         }
72         else
73         {
74             m_engineInstanceSelect = (uint32_t)instance;
75         }
76     }
77 #endif
78 }
79 
~GpuContextSpecific()80 GpuContextSpecific::~GpuContextSpecific()
81 {
82     MOS_OS_FUNCTION_ENTER;
83 
84     Clear();
85 }
86 
Init(OsContext * osContext,PMOS_INTERFACE osInterface,MOS_GPU_NODE GpuNode,PMOS_GPUCTX_CREATOPTIONS createOption)87 MOS_STATUS GpuContextSpecific::Init(OsContext *osContext,
88                     PMOS_INTERFACE osInterface,
89                     MOS_GPU_NODE GpuNode,
90                     PMOS_GPUCTX_CREATOPTIONS createOption)
91 {
92     MOS_OS_FUNCTION_ENTER;
93 
94     MOS_OS_CHK_NULL_RETURN(osContext);
95 
96     if (m_cmdBufPoolMutex == nullptr)
97     {
98         m_cmdBufPoolMutex = MosUtilities::MosCreateMutex();
99     }
100 
101     MOS_OS_CHK_NULL_RETURN(m_cmdBufPoolMutex);
102 
103     MosUtilities::MosLockMutex(m_cmdBufPoolMutex);
104 
105     m_cmdBufPool.clear();
106 
107     MosUtilities::MosUnlockMutex(m_cmdBufPoolMutex);
108 
109     m_commandBufferSize = COMMAND_BUFFER_SIZE;
110 
111     m_nextFetchIndex = 0;
112 
113     m_cmdBufFlushed = true;
114 
115     m_osContext = osContext;
116 
117     MOS_OS_CHK_STATUS_RETURN(AllocateGPUStatusBuf());
118 
119     m_commandBuffer = (PMOS_COMMAND_BUFFER)MOS_AllocAndZeroMemory(sizeof(MOS_COMMAND_BUFFER));
120 
121     MOS_OS_CHK_NULL_RETURN(m_commandBuffer);
122 
123     m_IndirectHeapSize = 0;
124 
125     // each thread has its own GPU context, so do not need any lock as guarder here
126     m_allocationList = (ALLOCATION_LIST *)MOS_AllocAndZeroMemory(sizeof(ALLOCATION_LIST) * ALLOCATIONLIST_SIZE);
127     MOS_OS_CHK_NULL_RETURN(m_allocationList);
128     m_maxNumAllocations = ALLOCATIONLIST_SIZE;
129 
130     m_patchLocationList = (PATCHLOCATIONLIST *)MOS_AllocAndZeroMemory(sizeof(PATCHLOCATIONLIST) * PATCHLOCATIONLIST_SIZE);
131     MOS_OS_CHK_NULL_RETURN(m_patchLocationList);
132     m_maxPatchLocationsize = PATCHLOCATIONLIST_SIZE;
133 
134     m_attachedResources = (PMOS_RESOURCE)MOS_AllocAndZeroMemory(sizeof(MOS_RESOURCE) * ALLOCATIONLIST_SIZE);
135     MOS_OS_CHK_NULL_RETURN(m_attachedResources);
136 
137     m_writeModeList = (bool *)MOS_AllocAndZeroMemory(sizeof(bool) * ALLOCATIONLIST_SIZE);
138     MOS_OS_CHK_NULL_RETURN(m_writeModeList);
139 
140     m_GPUStatusTag = 1;
141 
142     m_createOptionEnhanced = (MOS_GPUCTX_CREATOPTIONS_ENHANCED*)MOS_AllocAndZeroMemory(sizeof(MOS_GPUCTX_CREATOPTIONS_ENHANCED));
143     MOS_OS_CHK_NULL_RETURN(m_createOptionEnhanced);
144     m_createOptionEnhanced->SSEUValue = createOption->SSEUValue;
145 
146     if (typeid(*createOption) == typeid(MOS_GPUCTX_CREATOPTIONS_ENHANCED))
147     {
148         PMOS_GPUCTX_CREATOPTIONS_ENHANCED createOptionEnhanced = static_cast<PMOS_GPUCTX_CREATOPTIONS_ENHANCED>(createOption);
149         m_createOptionEnhanced->UsingSFC = createOptionEnhanced->UsingSFC;
150     }
151 
152     for (int i=0; i<MAX_ENGINE_INSTANCE_NUM+1; i++)
153     {
154         m_i915Context[i] = nullptr;
155     }
156 
157     if (osInterface->ctxBasedScheduling)
158     {
159         unsigned int nengine              = 0;
160         struct i915_engine_class_instance *engine_map = nullptr;
161 
162         MOS_TraceEventExt(EVENT_GPU_CONTEXT_CREATE, EVENT_TYPE_START,
163                           &GpuNode, sizeof(GpuNode), nullptr, 0);
164 
165         m_i915Context[0] = mos_context_create_shared(osInterface->pOsContext->bufmgr,
166                                              osInterface->pOsContext->intel_context,
167                                              I915_CONTEXT_CREATE_FLAGS_SINGLE_TIMELINE,
168                                              false,
169                                              (void *)engine_map,
170                                              1,
171                                              nengine,
172                                              0);
173         if (m_i915Context[0] == nullptr)
174         {
175             MOS_OS_ASSERTMESSAGE("Failed to create context.\n");
176             return MOS_STATUS_UNKNOWN;
177         }
178         m_i915Context[0]->pOsContext = osInterface->pOsContext;
179 
180         m_i915ExecFlag = I915_EXEC_DEFAULT;
181 
182         if (mos_query_engines_count(osInterface->pOsContext->bufmgr, &nengine) || (nengine == 0))
183         {
184             MOS_OS_ASSERTMESSAGE("Failed to query engines count.\n");
185             return MOS_STATUS_UNKNOWN;
186         }
187         engine_map = (struct i915_engine_class_instance *)MOS_AllocAndZeroMemory(nengine * sizeof(struct i915_engine_class_instance));
188         MOS_OS_CHK_NULL_RETURN(engine_map);
189 
190         if (GpuNode == MOS_GPU_NODE_3D)
191         {
192             __u16 engine_class = I915_ENGINE_CLASS_RENDER;
193             __u64 caps = 0;
194 
195             if (mos_query_engines(osInterface->pOsContext->bufmgr, engine_class, caps, &nengine, (void *)engine_map))
196             {
197                 MOS_OS_ASSERTMESSAGE("Failed to query engines.\n");
198                 MOS_SafeFreeMemory(engine_map);
199                 return MOS_STATUS_UNKNOWN;
200             }
201 
202             if (mos_set_context_param_load_balance(m_i915Context[0], engine_map, nengine))
203             {
204                 MOS_OS_ASSERTMESSAGE("Failed to set balancer extension.\n");
205                 MOS_SafeFreeMemory(engine_map);
206                 return MOS_STATUS_UNKNOWN;
207             }
208 
209             if (createOption->SSEUValue != 0)
210             {
211                 struct drm_i915_gem_context_param_sseu sseu;
212                 MOS_ZeroMemory(&sseu, sizeof(sseu));
213                 sseu.flags = I915_CONTEXT_SSEU_FLAG_ENGINE_INDEX;
214                 sseu.engine.engine_instance = m_i915ExecFlag;
215 
216                 if (mos_get_context_param_sseu(m_i915Context[0], &sseu))
217                 {
218                     MOS_OS_ASSERTMESSAGE("Failed to get sseu configuration.");
219                     MOS_SafeFreeMemory(engine_map);
220                     return MOS_STATUS_UNKNOWN;
221                 }
222 
223                 if (mos_hweight8(m_i915Context[0], sseu.subslice_mask) > createOption->packed.SubSliceCount)
224                 {
225                     sseu.subslice_mask = mos_switch_off_n_bits(m_i915Context[0], sseu.subslice_mask,
226                             mos_hweight8(m_i915Context[0], sseu.subslice_mask)-createOption->packed.SubSliceCount);
227                 }
228 
229                 if (mos_set_context_param_sseu(m_i915Context[0], sseu))
230                 {
231                     MOS_OS_ASSERTMESSAGE("Failed to set sseu configuration.");
232                     MOS_SafeFreeMemory(engine_map);
233                     return MOS_STATUS_UNKNOWN;
234                 }
235             }
236         }
237         else if (GpuNode == MOS_GPU_NODE_COMPUTE)
238         {
239             __u16 engine_class = 4; //To change later when linux define the name
240             __u64 caps = 0;
241 
242             if (mos_query_engines(osInterface->pOsContext->bufmgr, engine_class, caps, &nengine, (void *)engine_map))
243             {
244                 MOS_OS_ASSERTMESSAGE("Failed to query engines.\n");
245                 MOS_SafeFreeMemory(engine_map);
246                 return MOS_STATUS_UNKNOWN;
247             }
248 
249 #if (_DEBUG || _RELEASE_INTERNAL)
250             SelectEngineInstanceByUser(engine_map, &nengine, m_engineInstanceSelect, GpuNode);
251 #endif
252             if (mos_set_context_param_load_balance(m_i915Context[0], engine_map, nengine))
253             {
254                 MOS_OS_ASSERTMESSAGE("Failed to set balancer extension.\n");
255                 MOS_SafeFreeMemory(engine_map);
256                 return MOS_STATUS_UNKNOWN;
257             }
258         }
259         else if (GpuNode == MOS_GPU_NODE_VIDEO || GpuNode == MOS_GPU_NODE_VIDEO2
260                  || GpuNode == MOS_GPU_NODE_VE)
261         {
262             __u16 engine_class = (GpuNode == MOS_GPU_NODE_VE)? I915_ENGINE_CLASS_VIDEO_ENHANCE : I915_ENGINE_CLASS_VIDEO;
263             __u64 caps = 0;
264 
265             SetEngineQueryFlags(createOption, caps);
266 
267             if (mos_query_engines(osInterface->pOsContext->bufmgr, engine_class, caps, &nengine, (void *)engine_map))
268             {
269                 MOS_OS_ASSERTMESSAGE("Failed to query engines.\n");
270                 MOS_SafeFreeMemory(engine_map);
271                 return MOS_STATUS_UNKNOWN;
272             }
273 
274 #if (_DEBUG || _RELEASE_INTERNAL)
275             SelectEngineInstanceByUser(engine_map, &nengine, m_engineInstanceSelect, GpuNode);
276 #endif
277             if (mos_set_context_param_load_balance(m_i915Context[0], engine_map, nengine))
278             {
279                 MOS_OS_ASSERTMESSAGE("Failed to set balancer extension.\n");
280                 MOS_SafeFreeMemory(engine_map);
281                 return MOS_STATUS_UNKNOWN;
282             }
283 
284             if (nengine >= 2)
285             {
286                 int i;
287                 //master queue
288                 m_i915Context[1] = mos_context_create_shared(osInterface->pOsContext->bufmgr,
289                                                                     osInterface->pOsContext->intel_context,
290                                                                     I915_CONTEXT_CREATE_FLAGS_SINGLE_TIMELINE,
291                                                                     false,
292                                                                     (void *)engine_map,
293                                                                     1,
294                                                                     1,
295                                                                     0);
296                 if (m_i915Context[1] == nullptr)
297                 {
298                     MOS_OS_ASSERTMESSAGE("Failed to create master context.\n");
299                     MOS_SafeFreeMemory(engine_map);
300                     return MOS_STATUS_UNKNOWN;
301                 }
302                 m_i915Context[1]->pOsContext = osInterface->pOsContext;
303 
304                 if (mos_set_context_param_load_balance(m_i915Context[1], engine_map, 1))
305                 {
306                     MOS_OS_ASSERTMESSAGE("Failed to set master context bond extension.\n");
307                     MOS_SafeFreeMemory(engine_map);
308                     return MOS_STATUS_UNKNOWN;
309                 }
310 
311                 //slave queue
312                 for (i=1; i<nengine; i++)
313                 {
314                     m_i915Context[i+1] = mos_context_create_shared(osInterface->pOsContext->bufmgr,
315                                                                         osInterface->pOsContext->intel_context,
316                                                                         I915_CONTEXT_CREATE_FLAGS_SINGLE_TIMELINE,
317                                                                         false,
318                                                                         (void *)engine_map,
319                                                                         1,
320                                                                         1,
321                                                                         0);
322                     if (m_i915Context[i+1] == nullptr)
323                     {
324                         MOS_OS_ASSERTMESSAGE("Failed to create slave context.\n");
325                         MOS_SafeFreeMemory(engine_map);
326                         return MOS_STATUS_UNKNOWN;
327                     }
328                     m_i915Context[i+1]->pOsContext = osInterface->pOsContext;
329 
330                     if (mos_set_context_param_bond(m_i915Context[i+1], engine_map[0], &engine_map[i], 1) != S_SUCCESS)
331                     {
332                         int err = errno;
333                         if (err == ENODEV)
334                         {
335                             mos_context_destroy(m_i915Context[1]);
336                             mos_context_destroy(m_i915Context[i+1]);
337                             m_i915Context[i+1] = nullptr;
338                             break;
339                         }
340                         else
341                         {
342                             MOS_OS_ASSERTMESSAGE("Failed to set slave context bond extension. errno=%d\n",err);
343                             MOS_SafeFreeMemory(engine_map);
344                             return MOS_STATUS_UNKNOWN;
345                         }
346                     }
347                 }
348                 if (i == nengine)
349                 {
350                     osInterface->bParallelSubmission = false;
351                 }
352                 else
353                 {
354                     osInterface->bParallelSubmission = true;
355                     //create context with different width
356                     for(i = 1; i < nengine; i++)
357                     {
358                         unsigned int ctxWidth = i + 1;
359                         m_i915Context[i] = mos_context_create_shared(osInterface->pOsContext->bufmgr,
360                                                                      osInterface->pOsContext->intel_context,
361                                                                      0, // I915_CONTEXT_CREATE_FLAGS_SINGLE_TIMELINE not allowed for parallel submission
362                                                                      false,
363                                                                      (void *)engine_map,
364                                                                      ctxWidth,
365                                                                      1,
366                                                                      0);
367                         if (mos_set_context_param_parallel(m_i915Context[i], engine_map, ctxWidth) != S_SUCCESS)
368                         {
369                             MOS_OS_ASSERTMESSAGE("Failed to set parallel extension since discontinuous logical engine.\n");
370                             mos_context_destroy(m_i915Context[i]);
371                             m_i915Context[i] = nullptr;
372                             break;
373                         }
374                     }
375                 }
376             }
377         }
378         else if (GpuNode == MOS_GPU_NODE_BLT)
379         {
380             __u16 engine_class = I915_ENGINE_CLASS_COPY;
381             __u64 caps = 0;
382 
383             if (mos_query_engines(osInterface->pOsContext->bufmgr, engine_class, caps, &nengine, (void *)engine_map))
384             {
385                 MOS_OS_ASSERTMESSAGE("Failed to query engines.\n");
386                 MOS_SafeFreeMemory(engine_map);
387                 return MOS_STATUS_UNKNOWN;
388             }
389 
390             if (mos_set_context_param_load_balance(m_i915Context[0], engine_map, nengine))
391             {
392                 MOS_OS_ASSERTMESSAGE("Failed to set balancer extension.\n");
393                 MOS_SafeFreeMemory(engine_map);
394                 return MOS_STATUS_UNKNOWN;
395             }
396         }
397         else
398         {
399             MOS_OS_ASSERTMESSAGE("Unknown engine class.\n");
400             MOS_SafeFreeMemory(engine_map);
401             return MOS_STATUS_UNKNOWN;
402         }
403         MOS_SafeFreeMemory(engine_map);
404         MOS_TraceEventExt(EVENT_GPU_CONTEXT_CREATE, EVENT_TYPE_END,
405                           m_i915Context, sizeof(void *),
406                           &nengine, sizeof(nengine));
407     }
408     return MOS_STATUS_SUCCESS;
409 }
410 
Clear()411 void GpuContextSpecific::Clear()
412 {
413     MOS_OS_FUNCTION_ENTER;
414 
415     MOS_TraceEventExt(EVENT_GPU_CONTEXT_DESTROY, EVENT_TYPE_START,
416                       m_i915Context, sizeof(void *), nullptr, 0);
417     // hanlde the status buf bundled w/ the specified gpucontext
418     if (m_statusBufferResource)
419     {
420         if (m_statusBufferResource->Unlock(m_osContext) != MOS_STATUS_SUCCESS)
421         {
422             MOS_OS_ASSERTMESSAGE("failed to unlock the status buf bundled w/ the specified gpucontext");
423         }
424         m_statusBufferResource->Free(m_osContext, 0);
425         MOS_Delete(m_statusBufferResource);
426     }
427     MOS_FreeMemAndSetNull(m_statusBufferMosResource);
428 
429     MosUtilities::MosLockMutex(m_cmdBufPoolMutex);
430 
431     if (m_cmdBufMgr)
432     {
433         for (auto& curCommandBuffer : m_cmdBufPool)
434         {
435             auto curCommandBufferSpecific = static_cast<CommandBufferSpecific *>(curCommandBuffer);
436             if (curCommandBufferSpecific == nullptr)
437                 continue;
438             curCommandBufferSpecific->waitReady(); // wait ready and return to comamnd buffer manager.
439             m_cmdBufMgr->ReleaseCmdBuf(curCommandBuffer);
440         }
441     }
442 
443     m_cmdBufPool.clear();
444 
445     MosUtilities::MosUnlockMutex(m_cmdBufPoolMutex);
446     MosUtilities::MosDestroyMutex(m_cmdBufPoolMutex);
447     m_cmdBufPoolMutex = nullptr;
448     MOS_SafeFreeMemory(m_commandBuffer);
449     MOS_SafeFreeMemory(m_allocationList);
450     MOS_SafeFreeMemory(m_patchLocationList);
451     MOS_SafeFreeMemory(m_attachedResources);
452     MOS_SafeFreeMemory(m_writeModeList);
453     MOS_SafeFreeMemory(m_createOptionEnhanced);
454 
455     for (int i=0; i<MAX_ENGINE_INSTANCE_NUM; i++)
456     {
457         if (m_i915Context[i])
458         {
459             mos_context_destroy(m_i915Context[i]);
460             m_i915Context[i] = nullptr;
461         }
462     }
463     MOS_TraceEventExt(EVENT_GPU_CONTEXT_DESTROY, EVENT_TYPE_END,
464                       nullptr, 0, nullptr, 0);
465 }
466 
RegisterResource(PMOS_RESOURCE osResource,bool writeFlag)467 MOS_STATUS GpuContextSpecific::RegisterResource(
468     PMOS_RESOURCE osResource,
469     bool          writeFlag)
470 {
471     MOS_OS_FUNCTION_ENTER;
472 
473     MOS_OS_CHK_NULL_RETURN(osResource);
474 
475     MOS_OS_CHK_NULL_RETURN(m_attachedResources);
476 
477     PMOS_RESOURCE registeredResources = m_attachedResources;
478     uint32_t      allocationIndex     = 0;
479 
480     for ( allocationIndex = 0; allocationIndex < m_resCount; allocationIndex++, registeredResources++)
481     {
482         if (osResource->bo == registeredResources->bo)
483         {
484             break;
485         }
486     }
487 
488     // Allocation list to be updated
489     if (allocationIndex < m_maxNumAllocations)
490     {
491         // New buffer
492         if (allocationIndex == m_resCount)
493         {
494             m_resCount++;
495         }
496 
497         // Set allocation
498         if (m_gpuContext >= MOS_GPU_CONTEXT_MAX)
499         {
500             MOS_OS_ASSERTMESSAGE("Gpu context exceeds max.");
501             return MOS_STATUS_UNKNOWN;
502         }
503 
504         osResource->iAllocationIndex[m_gpuContext] = (allocationIndex);
505         m_attachedResources[allocationIndex]           = *osResource;
506         m_writeModeList[allocationIndex] |= writeFlag;
507         m_allocationList[allocationIndex].hAllocation = &m_attachedResources[allocationIndex];
508         m_allocationList[allocationIndex].WriteOperation |= writeFlag;
509         m_numAllocations = m_resCount;
510     }
511     else
512     {
513         MOS_OS_ASSERTMESSAGE("Reached max # registrations.");
514         return MOS_STATUS_UNKNOWN;
515     }
516 
517     return MOS_STATUS_SUCCESS;
518 }
519 
SetPatchEntry(PMOS_INTERFACE osInterface,PMOS_PATCH_ENTRY_PARAMS params)520 MOS_STATUS GpuContextSpecific::SetPatchEntry(
521     PMOS_INTERFACE          osInterface,
522     PMOS_PATCH_ENTRY_PARAMS params)
523 {
524     MOS_OS_FUNCTION_ENTER;
525 
526     MOS_OS_CHK_NULL_RETURN(m_patchLocationList);
527     MOS_OS_CHK_NULL_RETURN(osInterface);
528     MOS_OS_CHK_NULL_RETURN(params);
529 
530     m_patchLocationList[m_currentNumPatchLocations].AllocationIndex  = params->uiAllocationIndex;
531     m_patchLocationList[m_currentNumPatchLocations].AllocationOffset = params->uiResourceOffset;
532     m_patchLocationList[m_currentNumPatchLocations].PatchOffset      = params->uiPatchOffset;
533     m_patchLocationList[m_currentNumPatchLocations].uiWriteOperation = params->bWrite ? true: false;
534     m_patchLocationList[m_currentNumPatchLocations].cmdBo            =
535                 params->cmdBuffer != nullptr ? params->cmdBuffer->OsResource.bo : nullptr;
536 
537     if (osInterface->osCpInterface &&
538         osInterface->osCpInterface->IsHMEnabled())
539     {
540         if (MOS_STATUS_SUCCESS != osInterface->osCpInterface->RegisterPatchForHM(
541             (uint32_t *)(params->cmdBufBase + params->uiPatchOffset),
542             params->bWrite,
543             params->HwCommandType,
544             params->forceDwordOffset,
545             params->presResource,
546             &m_patchLocationList[m_currentNumPatchLocations]))
547         {
548             MOS_OS_ASSERTMESSAGE("Failed to RegisterPatchForHM.");
549         }
550     }
551 
552     m_currentNumPatchLocations++;
553 
554     return MOS_STATUS_SUCCESS;
555 }
556 
GetCommandBuffer(PMOS_COMMAND_BUFFER comamndBuffer,uint32_t flags)557 MOS_STATUS GpuContextSpecific::GetCommandBuffer(
558     PMOS_COMMAND_BUFFER comamndBuffer,
559     uint32_t            flags)
560 {
561     MOS_OS_FUNCTION_ENTER;
562 
563     MOS_OS_CHK_NULL_RETURN(comamndBuffer);
564     MOS_OS_CHK_NULL_RETURN(m_cmdBufMgr);
565     MOS_OS_CHK_NULL_RETURN(m_commandBuffer);
566 
567     MOS_STATUS      eStatus = MOS_STATUS_SUCCESS;
568     CommandBuffer* cmdBuf = nullptr;
569 
570     uint32_t secondaryIdx = flags;
571     bool isPrimaryCmdBuffer = (secondaryIdx == 0);
572     bool hasSecondaryCmdBuffer = (!isPrimaryCmdBuffer &&
573                                (m_secondaryCmdBufs.count(secondaryIdx) != 0));
574 
575     bool needToAlloc = ((isPrimaryCmdBuffer && m_cmdBufFlushed) ||
576                         (!isPrimaryCmdBuffer && !hasSecondaryCmdBuffer));
577 
578     if (needToAlloc)
579     {
580         MosUtilities::MosLockMutex(m_cmdBufPoolMutex);
581         if (m_cmdBufPool.size() < MAX_CMD_BUF_NUM)
582         {
583             cmdBuf = m_cmdBufMgr->PickupOneCmdBuf(m_commandBufferSize);
584             if (cmdBuf == nullptr)
585             {
586                 MOS_OS_ASSERTMESSAGE("Invalid (nullptr) Pointer.");
587                 MosUtilities::MosUnlockMutex(m_cmdBufPoolMutex);
588                 return MOS_STATUS_NULL_POINTER;
589             }
590             if ((eStatus = cmdBuf->BindToGpuContext(this)) != MOS_STATUS_SUCCESS)
591             {
592                 MOS_OS_ASSERTMESSAGE("Invalid status of BindToGpuContext.");
593                 MosUtilities::MosUnlockMutex(m_cmdBufPoolMutex);
594                 return eStatus;
595             }
596             m_cmdBufPool.push_back(cmdBuf);
597         }
598         else if (m_cmdBufPool.size() == MAX_CMD_BUF_NUM && m_nextFetchIndex < m_cmdBufPool.size())
599         {
600             auto cmdBufOld = m_cmdBufPool[m_nextFetchIndex];
601             auto cmdBufSpecificOld = static_cast<CommandBufferSpecific *>(cmdBufOld);
602             if (cmdBufSpecificOld == nullptr)
603             {
604                 MOS_OS_ASSERTMESSAGE("Invalid (nullptr) Pointer.");
605                 MosUtilities::MosUnlockMutex(m_cmdBufPoolMutex);
606                 return MOS_STATUS_NULL_POINTER;
607             }
608             cmdBufSpecificOld->waitReady();
609             cmdBufSpecificOld->UnBindToGpuContext();
610             m_cmdBufMgr->ReleaseCmdBuf(cmdBufOld);  // here just return old command buffer to available pool
611 
612             //pick up new comamnd buffer
613             cmdBuf = m_cmdBufMgr->PickupOneCmdBuf(m_commandBufferSize);
614             if (cmdBuf == nullptr)
615             {
616                 MOS_OS_ASSERTMESSAGE("Invalid (nullptr) Pointer.");
617                 MosUtilities::MosUnlockMutex(m_cmdBufPoolMutex);
618                 return MOS_STATUS_NULL_POINTER;
619             }
620             if ((eStatus = cmdBuf->BindToGpuContext(this)) != MOS_STATUS_SUCCESS)
621             {
622                 MOS_OS_ASSERTMESSAGE("Invalid status of BindToGpuContext.");
623                 MosUtilities::MosUnlockMutex(m_cmdBufPoolMutex);
624                 return eStatus;
625             }
626             m_cmdBufPool[m_nextFetchIndex] = cmdBuf;
627         }
628         else
629         {
630             MOS_OS_ASSERTMESSAGE("Command buffer bool size exceed max.");
631             MosUtilities::MosUnlockMutex(m_cmdBufPoolMutex);
632             return MOS_STATUS_UNKNOWN;
633         }
634         MosUtilities::MosUnlockMutex(m_cmdBufPoolMutex);
635 
636         // util now, we got new command buffer from CmdBufMgr, next step to fill in the input command buffer
637         MOS_OS_CHK_STATUS_RETURN(cmdBuf->GetResource()->ConvertToMosResource(&comamndBuffer->OsResource));
638         comamndBuffer->pCmdBase   = (uint32_t *)cmdBuf->GetLockAddr();
639         comamndBuffer->pCmdPtr    = (uint32_t *)cmdBuf->GetLockAddr();
640         comamndBuffer->iOffset    = 0;
641         comamndBuffer->iRemaining = cmdBuf->GetCmdBufSize();
642         comamndBuffer->iCmdIndex  = m_nextFetchIndex;
643         comamndBuffer->iVdboxNodeIndex = MOS_VDBOX_NODE_INVALID;
644         comamndBuffer->iVeboxNodeIndex = MOS_VEBOX_NODE_INVALID;
645         comamndBuffer->is1stLvlBB = true;
646         comamndBuffer->Attributes.pAttriVe = nullptr;
647 
648         // zero comamnd buffer
649         MOS_ZeroMemory(comamndBuffer->pCmdBase, comamndBuffer->iRemaining);
650         comamndBuffer->iSubmissionType = SUBMISSION_TYPE_SINGLE_PIPE;
651         MOS_ZeroMemory(&comamndBuffer->Attributes,sizeof(comamndBuffer->Attributes));
652 
653         if (isPrimaryCmdBuffer)
654         {
655             // update command buffer relared filed in GPU context
656             m_cmdBufFlushed = false;
657 
658             // keep a copy in GPU context
659             MOS_SecureMemcpy(m_commandBuffer, sizeof(MOS_COMMAND_BUFFER), comamndBuffer, sizeof(MOS_COMMAND_BUFFER));
660         }
661         else
662         {
663             PMOS_COMMAND_BUFFER tempCmdBuf = (PMOS_COMMAND_BUFFER)MOS_AllocAndZeroMemory(sizeof(MOS_COMMAND_BUFFER));
664             MOS_OS_CHK_NULL_RETURN(tempCmdBuf);
665             m_secondaryCmdBufs[secondaryIdx] = tempCmdBuf;
666             MOS_SecureMemcpy(tempCmdBuf, sizeof(MOS_COMMAND_BUFFER), comamndBuffer, sizeof(MOS_COMMAND_BUFFER));
667         }
668 
669         // Command buffers are treated as cyclical buffers, the CB after the just submitted one
670         // has the minimal fence value that we should wait
671         m_nextFetchIndex++;
672         if (m_nextFetchIndex >= MAX_CMD_BUF_NUM)
673         {
674             m_nextFetchIndex = 0;
675         }
676     }
677     else
678     {
679         // current command buffer still active, directly copy to comamndBuffer
680         if (isPrimaryCmdBuffer)
681         {
682             MOS_SecureMemcpy(comamndBuffer, sizeof(MOS_COMMAND_BUFFER), m_commandBuffer, sizeof(MOS_COMMAND_BUFFER));
683         }
684         else
685         {
686             MOS_SecureMemcpy(comamndBuffer, sizeof(MOS_COMMAND_BUFFER), m_secondaryCmdBufs[secondaryIdx], sizeof(MOS_COMMAND_BUFFER));
687         }
688     }
689 
690     if (isPrimaryCmdBuffer)
691     {
692         MOS_OS_CHK_STATUS_RETURN(RegisterResource(&m_commandBuffer->OsResource, false));
693     }
694     else
695     {
696         MOS_OS_CHK_STATUS_RETURN(RegisterResource(&m_secondaryCmdBufs[secondaryIdx]->OsResource, false));
697     }
698 
699     return MOS_STATUS_SUCCESS;
700 }
701 
ReturnCommandBuffer(PMOS_COMMAND_BUFFER cmdBuffer,uint32_t flags)702 void GpuContextSpecific::ReturnCommandBuffer(
703     PMOS_COMMAND_BUFFER cmdBuffer,
704     uint32_t            flags)
705 {
706     MOS_OS_FUNCTION_ENTER;
707 
708     MOS_OS_ASSERT(cmdBuffer);
709     MOS_OS_ASSERT(m_commandBuffer);
710 
711     bool isPrimaryCmdBuf = (flags == 0);
712 
713     if (isPrimaryCmdBuf)
714     {
715         m_commandBuffer->iOffset    = cmdBuffer->iOffset;
716         m_commandBuffer->iRemaining = cmdBuffer->iRemaining;
717         m_commandBuffer->pCmdPtr    = cmdBuffer->pCmdPtr;
718         m_commandBuffer->iVdboxNodeIndex = cmdBuffer->iVdboxNodeIndex;
719         m_commandBuffer->iVeboxNodeIndex = cmdBuffer->iVeboxNodeIndex;
720     }
721     else
722     {
723         uint32_t secondaryIdx = flags;
724         MOS_OS_ASSERT(m_secondaryCmdBufs.count(secondaryIdx));
725 
726         MOS_SecureMemcpy(m_secondaryCmdBufs[secondaryIdx], sizeof(MOS_COMMAND_BUFFER), cmdBuffer, sizeof(MOS_COMMAND_BUFFER));
727     }
728 }
729 
ResetCommandBuffer()730 MOS_STATUS GpuContextSpecific::ResetCommandBuffer()
731 {
732     m_cmdBufFlushed = true;
733     auto it = m_secondaryCmdBufs.begin();
734     while(it != m_secondaryCmdBufs.end())
735     {
736         MOS_FreeMemory(it->second);
737         it++;
738     }
739     m_secondaryCmdBufs.clear();
740     return MOS_STATUS_SUCCESS;
741 }
742 
SetIndirectStateSize(const uint32_t size)743 MOS_STATUS GpuContextSpecific::SetIndirectStateSize(const uint32_t size)
744 {
745     if(size < m_commandBufferSize)
746     {
747         m_IndirectHeapSize = size;
748         return MOS_STATUS_SUCCESS;
749     }
750     else
751     {
752         MOS_OS_ASSERTMESSAGE("Indirect State Size if out of boundry!");
753         return MOS_STATUS_UNKNOWN;
754     }
755 }
756 
GetIndirectState(uint32_t * offset,uint32_t * size)757 MOS_STATUS GpuContextSpecific::GetIndirectState(
758     uint32_t *offset,
759     uint32_t *size)
760 {
761     MOS_OS_FUNCTION_ENTER;
762 
763     if (offset)
764     {
765         *offset = m_commandBufferSize - m_IndirectHeapSize;
766     }
767 
768     if (size)
769     {
770         *size = m_IndirectHeapSize;
771     }
772 
773     return MOS_STATUS_SUCCESS;
774 }
775 
GetIndirectStatePointer(uint8_t ** indirectState)776 MOS_STATUS GpuContextSpecific::GetIndirectStatePointer(
777     uint8_t **indirectState)
778 {
779     MOS_OS_FUNCTION_ENTER;
780 
781     MOS_OS_CHK_NULL_RETURN(indirectState);
782 
783     *indirectState = (uint8_t *)m_commandBuffer->pCmdBase + m_commandBufferSize - m_IndirectHeapSize;
784 
785     return MOS_STATUS_SUCCESS;
786 }
787 
ResizeCommandBufferAndPatchList(uint32_t requestedCommandBufferSize,uint32_t requestedPatchListSize,uint32_t flags)788 MOS_STATUS GpuContextSpecific::ResizeCommandBufferAndPatchList(
789     uint32_t requestedCommandBufferSize,
790     uint32_t requestedPatchListSize,
791     uint32_t flags)
792 {
793     MOS_OS_FUNCTION_ENTER;
794 
795     // m_commandBufferSize is used for allocate command buffer and submit command buffer, in this moment, command buffer has not allocated yet.
796     // Linux KMD requires command buffer size align to 8 bytes, or it will not execute the commands.
797     m_commandBufferSize = MOS_ALIGN_CEIL(requestedCommandBufferSize, 8);
798 
799     if (requestedPatchListSize > m_maxPatchLocationsize)
800     {
801         PPATCHLOCATIONLIST newPatchList = (PPATCHLOCATIONLIST)realloc(m_patchLocationList, sizeof(PATCHLOCATIONLIST) * requestedPatchListSize);
802         MOS_OS_CHK_NULL_RETURN(newPatchList);
803 
804         m_patchLocationList = newPatchList;
805 
806         // now zero the extended portion
807         MOS_ZeroMemory((m_patchLocationList + m_maxPatchLocationsize), sizeof(PATCHLOCATIONLIST) * (requestedPatchListSize - m_maxPatchLocationsize));
808         m_maxPatchLocationsize = requestedPatchListSize;
809     }
810 
811     return MOS_STATUS_SUCCESS;
812 }
813 
ResizeCommandBuffer(uint32_t requestedSize)814 MOS_STATUS GpuContextSpecific::ResizeCommandBuffer(uint32_t requestedSize)
815 {
816     MOS_OS_FUNCTION_ENTER;
817 
818     m_commandBufferSize = requestedSize;
819 
820     return MOS_STATUS_SUCCESS;
821 }
822 
GetVcsExecFlag(PMOS_INTERFACE osInterface,PMOS_COMMAND_BUFFER cmdBuffer,MOS_GPU_NODE gpuNode)823 uint32_t GetVcsExecFlag(PMOS_INTERFACE osInterface,
824                             PMOS_COMMAND_BUFFER cmdBuffer,
825                             MOS_GPU_NODE gpuNode)
826 {
827     if (osInterface == 0 ||
828         cmdBuffer == 0)
829     {
830         MOS_OS_ASSERTMESSAGE("Input invalid(null) parameter.");
831         return I915_EXEC_DEFAULT;
832     }
833 
834     uint32_t vcsExecFlag = I915_EXEC_BSD | I915_EXEC_BSD_RING1;
835 
836     if (MOS_VDBOX_NODE_INVALID == cmdBuffer->iVdboxNodeIndex)
837     {
838        // That's those case when BB did not have any VDBOX# specific commands.
839        // Thus, we need to select VDBOX# here. Alternatively we can rely on KMD
840        // to make balancing for us, i.e. rely on Virtual Engine support.
841        cmdBuffer->iVdboxNodeIndex = osInterface->pfnGetVdboxNodeId(osInterface, cmdBuffer);
842        if (MOS_VDBOX_NODE_INVALID == cmdBuffer->iVdboxNodeIndex)
843        {
844            cmdBuffer->iVdboxNodeIndex = (gpuNode == MOS_GPU_NODE_VIDEO)?
845                MOS_VDBOX_NODE_1: MOS_VDBOX_NODE_2;
846        }
847      }
848 
849      if (MOS_VDBOX_NODE_1 == cmdBuffer->iVdboxNodeIndex)
850      {
851          vcsExecFlag = I915_EXEC_BSD | I915_EXEC_BSD_RING1;
852      }
853      else if (MOS_VDBOX_NODE_2 == cmdBuffer->iVdboxNodeIndex)
854      {
855          vcsExecFlag = I915_EXEC_BSD | I915_EXEC_BSD_RING2;
856      }
857 
858      return vcsExecFlag;
859 }
860 
MapResourcesToAuxTable(mos_linux_bo * cmd_bo)861 MOS_STATUS GpuContextSpecific::MapResourcesToAuxTable(mos_linux_bo *cmd_bo)
862 {
863     MOS_OS_CHK_NULL_RETURN(cmd_bo);
864 
865     OsContextSpecific *osCtx = static_cast<OsContextSpecific*>(m_osContext);
866     MOS_OS_CHK_NULL_RETURN(osCtx);
867 
868     AuxTableMgr *auxTableMgr = osCtx->GetAuxTableMgr();
869     if (auxTableMgr)
870     {
871         // Map compress allocations to aux table if it is not mapped.
872         for (uint32_t i = 0; i < m_numAllocations; i++)
873         {
874             auto res = (PMOS_RESOURCE)m_allocationList[i].hAllocation;
875             MOS_OS_CHK_NULL_RETURN(res);
876             MOS_OS_CHK_STATUS_RETURN(auxTableMgr->MapResource(res->pGmmResInfo, res->bo));
877         }
878         MOS_OS_CHK_STATUS_RETURN(auxTableMgr->EmitAuxTableBOList(cmd_bo));
879     }
880     return MOS_STATUS_SUCCESS;
881 }
882 
SubmitCommandBuffer(PMOS_INTERFACE osInterface,PMOS_COMMAND_BUFFER cmdBuffer,bool nullRendering)883 MOS_STATUS GpuContextSpecific::SubmitCommandBuffer(
884     PMOS_INTERFACE      osInterface,
885     PMOS_COMMAND_BUFFER cmdBuffer,
886     bool                nullRendering)
887 {
888     MOS_OS_FUNCTION_ENTER;
889 
890     MOS_TraceEventExt(EVENT_MOS_BATCH_SUBMIT, EVENT_TYPE_START, nullptr, 0, nullptr, 0);
891 
892     MOS_OS_CHK_NULL_RETURN(osInterface);
893     PMOS_CONTEXT osContext = osInterface->pOsContext;
894     MOS_OS_CHK_NULL_RETURN(osContext);
895     MOS_OS_CHK_NULL_RETURN(cmdBuffer);
896     MOS_OS_CHK_NULL_RETURN(m_patchLocationList);
897 
898     MOS_GPU_NODE gpuNode  = OSKMGetGpuNode(m_gpuContext);
899     uint32_t     execFlag = gpuNode;
900     MOS_STATUS   eStatus  = MOS_STATUS_SUCCESS;
901     int32_t      ret      = 0;
902     bool         scalaEnabled = false;
903     auto         it           = m_secondaryCmdBufs.begin();
904 
905     // Command buffer object DRM pointer
906     m_cmdBufFlushed = true;
907     auto cmd_bo     = cmdBuffer->OsResource.bo;
908 
909     // Map Resource to Aux if needed
910     MapResourcesToAuxTable(cmd_bo);
911     for(auto it : m_secondaryCmdBufs)
912     {
913         MapResourcesToAuxTable(it.second->OsResource.bo);
914     }
915 
916     if (m_secondaryCmdBufs.size() >= 2)
917     {
918         scalaEnabled = true;
919         cmdBuffer->iSubmissionType = SUBMISSION_TYPE_MULTI_PIPE_MASTER;
920     }
921 
922     std::vector<PMOS_RESOURCE> mappedResList;
923     std::vector<MOS_LINUX_BO *> skipSyncBoList;
924 
925     // Now, the patching will be done, based on the patch list.
926     for (uint32_t patchIndex = 0; patchIndex < m_currentNumPatchLocations; patchIndex++)
927     {
928         auto currentPatch = &m_patchLocationList[patchIndex];
929         MOS_OS_CHK_NULL_RETURN(currentPatch);
930 
931         auto tempCmdBo = currentPatch->cmdBo == nullptr ? cmd_bo : currentPatch->cmdBo;
932 
933         // Following are for Nested BB buffer, if it's nested BB, we need to ensure it's locked.
934         if (tempCmdBo != cmd_bo)
935         {
936             bool isSecondaryCmdBuf = false;
937             it = m_secondaryCmdBufs.begin();
938             while(it != m_secondaryCmdBufs.end())
939             {
940                 if (it->second->OsResource.bo == tempCmdBo)
941                 {
942                     isSecondaryCmdBuf = true;
943                     break;
944                 }
945                 it++;
946             }
947 
948             for(auto allocIdx = 0; allocIdx < m_numAllocations && (!isSecondaryCmdBuf); allocIdx++)
949             {
950                 auto tempRes = (PMOS_RESOURCE)m_allocationList[allocIdx].hAllocation;
951                 if (tempCmdBo == tempRes->bo)
952                 {
953                     GraphicsResource::LockParams param;
954                     param.m_writeRequest = true;
955                     tempRes->pGfxResource->Lock(m_osContext, param);
956                     mappedResList.push_back(tempRes);
957                     break;
958                 }
959             }
960         }
961 
962         // This is the resource for which patching will be done
963         auto resource = (PMOS_RESOURCE)m_allocationList[currentPatch->AllocationIndex].hAllocation;
964         MOS_OS_CHK_NULL_RETURN(resource);
965 
966         // For now, we'll assume the system memory's DRM bo pointer
967         // is NULL.  If nullptr is detected, then the resource has been
968         // placed inside the command buffer's indirect state area.
969         // We'll simply set alloc_bo to the command buffer's bo pointer.
970         MOS_OS_ASSERT(resource->bo);
971 
972         auto alloc_bo = (resource->bo) ? resource->bo : tempCmdBo;
973 
974         MOS_OS_CHK_STATUS_RETURN(osInterface->osCpInterface->PermeatePatchForHM(
975             tempCmdBo->virt,
976             currentPatch,
977             resource));
978 
979         uint64_t boOffset = alloc_bo->offset64;
980         if (alloc_bo != tempCmdBo)
981         {
982             auto item_ctx = osContext->contextOffsetList.begin();
983             for (; item_ctx != osContext->contextOffsetList.end(); item_ctx++)
984             {
985                 if (item_ctx->intel_context == osContext->intel_context && item_ctx->target_bo == alloc_bo)
986                 {
987                     boOffset = item_ctx->offset64;
988                     break;
989                 }
990             }
991         }
992 
993         MOS_OS_CHK_NULL_RETURN(tempCmdBo->virt);
994         if (osContext->bUse64BitRelocs)
995         {
996             *((uint64_t *)((uint8_t *)tempCmdBo->virt + currentPatch->PatchOffset)) =
997                     boOffset + currentPatch->AllocationOffset;
998         }
999         else
1000         {
1001             *((uint32_t *)((uint8_t *)tempCmdBo->virt + currentPatch->PatchOffset)) =
1002                     boOffset + currentPatch->AllocationOffset;
1003         }
1004 
1005         if (scalaEnabled)
1006         {
1007             it = m_secondaryCmdBufs.begin();
1008             while(it != m_secondaryCmdBufs.end())
1009             {
1010                 if (it->second->OsResource.bo == tempCmdBo &&
1011                     it->second->iSubmissionType & SUBMISSION_TYPE_MULTI_PIPE_SLAVE &&
1012                     !mos_bo_is_exec_object_async(alloc_bo))
1013                 {
1014                     skipSyncBoList.push_back(alloc_bo);
1015                     break;
1016                 }
1017                 it++;
1018             }
1019         }
1020         else if (cmdBuffer->iSubmissionType & SUBMISSION_TYPE_MULTI_PIPE_SLAVE &&
1021                 !mos_bo_is_exec_object_async(alloc_bo))
1022         {
1023             skipSyncBoList.push_back(alloc_bo);
1024         }
1025 
1026 #if (_DEBUG || _RELEASE_INTERNAL)
1027         {
1028             uint32_t evtData[] = {alloc_bo->handle, currentPatch->uiWriteOperation, currentPatch->AllocationOffset};
1029             MOS_TraceEventExt(EVENT_MOS_BATCH_SUBMIT, EVENT_TYPE_INFO,
1030                               evtData, sizeof(evtData),
1031                               &boOffset, sizeof(boOffset));
1032         }
1033 #endif
1034         if(mos_bo_is_softpin(alloc_bo))
1035         {
1036             if (alloc_bo != tempCmdBo)
1037             {
1038                 ret = mos_bo_add_softpin_target(tempCmdBo, alloc_bo, currentPatch->uiWriteOperation);
1039             }
1040         }
1041         else
1042         {
1043             // This call will patch the command buffer with the offsets of the indirect state region of the command buffer
1044             ret = mos_bo_emit_reloc(
1045                 tempCmdBo,                                                         // Command buffer
1046                 currentPatch->PatchOffset,                                         // Offset in the command buffer
1047                 alloc_bo,                                                          // Allocation object for which the patch will be made.
1048                 currentPatch->AllocationOffset,                                    // Offset to the indirect state
1049                 I915_GEM_DOMAIN_RENDER,                                            // Read domain
1050                 (currentPatch->uiWriteOperation) ? I915_GEM_DOMAIN_RENDER : 0x0,   // Write domain
1051                 boOffset);
1052         }
1053 
1054         if (ret != 0)
1055         {
1056             MOS_OS_ASSERTMESSAGE("Error patching alloc_bo = 0x%x, cmd_bo = 0x%x.",
1057                 (uintptr_t)alloc_bo,
1058                 (uintptr_t)tempCmdBo);
1059             return MOS_STATUS_UNKNOWN;
1060         }
1061     }
1062 
1063     for(auto res: mappedResList)
1064     {
1065         res->pGfxResource->Unlock(m_osContext);
1066     }
1067     mappedResList.clear();
1068 
1069     if (scalaEnabled)
1070     {
1071          it = m_secondaryCmdBufs.begin();
1072          while(it != m_secondaryCmdBufs.end())
1073          {
1074              //Add Batch buffer End Command
1075              uint32_t batchBufferEndCmd = MI_BATCHBUFFER_END;
1076              if (MOS_FAILED(Mos_AddCommand(
1077                      it->second,
1078                      &batchBufferEndCmd,
1079                      sizeof(uint32_t))))
1080              {
1081                  MOS_OS_ASSERTMESSAGE("Inserting BB_END failed!");
1082                  return MOS_STATUS_UNKNOWN;
1083              }
1084              it++;
1085          }
1086     }
1087     else
1088     {
1089         //Add Batch buffer End Command
1090         uint32_t batchBufferEndCmd = MI_BATCHBUFFER_END;
1091         if (MOS_FAILED(Mos_AddCommand(
1092                 cmdBuffer,
1093                 &batchBufferEndCmd,
1094                 sizeof(uint32_t))))
1095         {
1096             MOS_OS_ASSERTMESSAGE("Inserting BB_END failed!");
1097             return MOS_STATUS_UNKNOWN;
1098         }
1099     }
1100     // dump before cmd buffer unmap
1101     MOS_TraceDumpExt("CmdBuffer", m_gpuContext, cmdBuffer->pCmdBase, cmdBuffer->iOffset);
1102 
1103     // Now, we can unmap the video command buffer, since we don't need CPU access anymore.
1104     MOS_OS_CHK_NULL_RETURN(cmdBuffer->OsResource.pGfxResource);
1105     cmdBuffer->OsResource.pGfxResource->Unlock(m_osContext);
1106 
1107     it = m_secondaryCmdBufs.begin();
1108     while(it != m_secondaryCmdBufs.end())
1109     {
1110         MOS_OS_CHK_NULL_RETURN(it->second->OsResource.pGfxResource);
1111         it->second->OsResource.pGfxResource->Unlock(m_osContext);
1112 
1113         it++;
1114     }
1115 
1116     int32_t perfData;
1117     if (osContext->pPerfData != nullptr)
1118     {
1119         perfData = *(int32_t *)(osContext->pPerfData);
1120     }
1121     else
1122     {
1123         perfData = 0;
1124     }
1125 
1126     drm_clip_rect_t *cliprects     = nullptr;
1127     int32_t          num_cliprects = 0;
1128     int32_t          DR4           = osContext->uEnablePerfTag ? perfData : 0;
1129 
1130     //Since CB2 command is not supported, remove it and set cliprects to nullprt as default.
1131     if ((gpuNode == MOS_GPU_NODE_VIDEO || gpuNode == MOS_GPU_NODE_VIDEO2) &&
1132         (cmdBuffer->iSubmissionType & SUBMISSION_TYPE_SINGLE_PIPE_MASK))
1133     {
1134         if (osContext->bKMDHasVCS2)
1135         {
1136             if (osContext->bPerCmdBufferBalancing && osInterface->pfnGetVdboxNodeId)
1137             {
1138                 execFlag = GetVcsExecFlag(osInterface, cmdBuffer, gpuNode);
1139             }
1140             else if (gpuNode == MOS_GPU_NODE_VIDEO)
1141             {
1142                 execFlag = I915_EXEC_BSD | I915_EXEC_BSD_RING1;
1143             }
1144             else if (gpuNode == MOS_GPU_NODE_VIDEO2)
1145             {
1146                 execFlag = I915_EXEC_BSD | I915_EXEC_BSD_RING2;
1147             }
1148             else
1149             {
1150                 MOS_OS_ASSERTMESSAGE("Invalid gpuNode.");
1151             }
1152         }
1153         else
1154         {
1155             execFlag = I915_EXEC_BSD | I915_EXEC_BSD_RING1;
1156         }
1157     }
1158 
1159 #if (_DEBUG || _RELEASE_INTERNAL)
1160 
1161     MOS_LINUX_BO *bad_cmd_bo = nullptr;
1162     MOS_LINUX_BO *nop_cmd_bo = nullptr;
1163     uint32_t      dwComponentTag = 0;
1164     uint32_t      dwCallType = 0;
1165 
1166     //dwComponentTag 3: decode,5: vpp,6: encode
1167     //dwCallType     8: PAK(CODECHAL_ENCODE_PERFTAG_CALL_PAK_ENGINE)
1168     //             34: PREENC
1169     //             5: VPP
1170     dwComponentTag = (perfData & 0xF000) >> 12;
1171     dwCallType     = (perfData & 0xFC) >> 2;
1172 
1173     if (osInterface->bTriggerCodecHang &&
1174         (dwComponentTag == 3 || (dwComponentTag == 6 && dwCallType == 8) ||
1175             (dwComponentTag == 6 && dwCallType == 34) ||
1176             (dwComponentTag == 5 && dwCallType == 5)))
1177     {
1178         bad_cmd_bo = Mos_GetBadCommandBuffer_Linux(osInterface);
1179         if (bad_cmd_bo)
1180         {
1181             ret = mos_bo_mrb_exec(bad_cmd_bo,
1182                 4096,
1183                 nullptr,
1184                 0,
1185                 0,
1186                 execFlag);
1187         }
1188         else
1189         {
1190             MOS_OS_ASSERTMESSAGE("Mos_GetBadCommandBuffer_Linux failed!");
1191         }
1192     }
1193     else if (osInterface->bTriggerVPHang == true)
1194     {
1195         bad_cmd_bo = Mos_GetBadCommandBuffer_Linux(osInterface);
1196 
1197         if (bad_cmd_bo)
1198         {
1199             ret = mos_bo_mrb_exec(bad_cmd_bo,
1200                 4096,
1201                 nullptr,
1202                 0,
1203                 0,
1204                 execFlag);
1205         }
1206         else
1207         {
1208             MOS_OS_ASSERTMESSAGE("Mos_GetBadCommandBuffer_Linux failed!");
1209         }
1210 
1211         osInterface->bTriggerVPHang = false;
1212     }
1213 
1214     nop_cmd_bo = nullptr;
1215     if (nullRendering == true)
1216     {
1217         nop_cmd_bo = Mos_GetNopCommandBuffer_Linux(osInterface);
1218 
1219         if (nop_cmd_bo)
1220         {
1221             ret = mos_bo_mrb_exec(nop_cmd_bo,
1222                 4096,
1223                 nullptr,
1224                 0,
1225                 0,
1226                 execFlag);
1227         }
1228         else
1229         {
1230             MOS_OS_ASSERTMESSAGE("Mos_GetNopCommandBuffer_Linux failed!");
1231         }
1232     }
1233 
1234 #endif  //(_DEBUG || _RELEASE_INTERNAL)
1235 
1236     if (gpuNode != I915_EXEC_RENDER &&
1237         osInterface->osCpInterface->IsTearDownHappen())
1238     {
1239         // skip PAK command when CP tear down happen to avoid of GPU hang
1240         // conditonal batch buffer start PoC is in progress
1241     }
1242     else if (nullRendering == false)
1243     {
1244         UnlockPendingOcaBuffers(cmdBuffer, osContext);
1245         if (osInterface->ctxBasedScheduling && m_i915Context[0] != nullptr)
1246         {
1247             if (cmdBuffer->iSubmissionType & SUBMISSION_TYPE_MULTI_PIPE_MASK)
1248             {
1249                 if (scalaEnabled && !osInterface->bParallelSubmission)
1250                 {
1251                     uint32_t secondaryIndex = 0;
1252                     it = m_secondaryCmdBufs.begin();
1253                     while(it != m_secondaryCmdBufs.end())
1254                     {
1255                         if (it->second->iSubmissionType & SUBMISSION_TYPE_MULTI_PIPE_SLAVE)
1256                         {
1257                             if(execFlag == MOS_GPU_NODE_VE)
1258                             {
1259                                 // decode excluded since init in other place
1260                                 it->second->iSubmissionType |= (secondaryIndex << SUBMISSION_TYPE_MULTI_PIPE_SLAVE_INDEX_SHIFT);
1261                                 secondaryIndex++;
1262                             }
1263                         }
1264 
1265                         ret = SubmitPipeCommands(it->second,
1266                                                  it->second->OsResource.bo,
1267                                                  osContext,
1268                                                  skipSyncBoList,
1269                                                  execFlag,
1270                                                  DR4);
1271                         it++;
1272                     }
1273                 }
1274                 else if(scalaEnabled && osInterface->bParallelSubmission)
1275                 {
1276                     ret = ParallelSubmitCommands(m_secondaryCmdBufs,
1277                                          osContext,
1278                                          execFlag,
1279                                          DR4);
1280                 }
1281                 else
1282                 {
1283                     ret = SubmitPipeCommands(cmdBuffer,
1284                                              cmd_bo,
1285                                              osContext,
1286                                              skipSyncBoList,
1287                                              execFlag,
1288                                              DR4);
1289                 }
1290             }
1291             else
1292             {
1293                 ret = mos_bo_context_exec2(cmd_bo,
1294                     m_commandBufferSize,
1295                     m_i915Context[0],
1296                     cliprects,
1297                     num_cliprects,
1298                     DR4,
1299                     m_i915ExecFlag,
1300                     nullptr);
1301             }
1302         }
1303         else
1304         {
1305             ret = mos_bo_context_exec2(cmd_bo,
1306                 m_commandBufferSize,
1307                 osContext->intel_context,
1308                 cliprects,
1309                 num_cliprects,
1310                 DR4,
1311                 execFlag,
1312                 nullptr);
1313         }
1314         if (ret != 0)
1315         {
1316             eStatus = MOS_STATUS_UNKNOWN;
1317         }
1318     }
1319 
1320     if (eStatus != MOS_STATUS_SUCCESS)
1321     {
1322         MOS_OS_ASSERTMESSAGE("Command buffer submission failed!");
1323     }
1324 
1325     MOS_DEVULT_FuncCall(pfnUltGetCmdBuf, cmdBuffer);
1326 
1327 #if MOS_COMMAND_BUFFER_DUMP_SUPPORTED
1328 pthread_mutex_lock(&command_dump_mutex);
1329 if (osInterface->bDumpCommandBuffer)
1330     {
1331         if (scalaEnabled)
1332         {
1333             it = m_secondaryCmdBufs.begin();
1334             while(it != m_secondaryCmdBufs.end())
1335             {
1336                 mos_bo_map(it->second->OsResource.bo, 0);
1337                 osInterface->pfnDumpCommandBuffer(osInterface, it->second);
1338                 mos_bo_unmap(it->second->OsResource.bo);
1339                 it++;
1340             }
1341         }
1342         else
1343         {
1344             mos_bo_map(cmd_bo, 0);
1345             osInterface->pfnDumpCommandBuffer(osInterface, cmdBuffer);
1346             mos_bo_unmap(cmd_bo);
1347         }
1348     }
1349     pthread_mutex_unlock(&command_dump_mutex);
1350 #endif  // MOS_COMMAND_BUFFER_DUMP_SUPPORTED
1351 
1352 #if (_DEBUG || _RELEASE_INTERNAL)
1353     if (bad_cmd_bo)
1354     {
1355         mos_bo_wait_rendering(bad_cmd_bo);
1356         mos_bo_unreference(bad_cmd_bo);
1357     }
1358     if (nop_cmd_bo)
1359     {
1360         mos_bo_unreference(nop_cmd_bo);
1361     }
1362 #endif  //(_DEBUG || _RELEASE_INTERNAL)
1363 
1364     //clear command buffer relocations to fix memory leak issue
1365     mos_bo_clear_relocs(cmd_bo, 0);
1366     it = m_secondaryCmdBufs.begin();
1367     while(it != m_secondaryCmdBufs.end())
1368     {
1369         mos_bo_clear_relocs(it->second->OsResource.bo, 0);
1370         MOS_FreeMemory(it->second);
1371         it++;
1372     }
1373     m_secondaryCmdBufs.clear();
1374     skipSyncBoList.clear();
1375 
1376     // Reset resource allocation
1377     m_numAllocations = 0;
1378     MOS_ZeroMemory(m_allocationList, sizeof(ALLOCATION_LIST) * m_maxNumAllocations);
1379     m_currentNumPatchLocations = 0;
1380     MOS_ZeroMemory(m_patchLocationList, sizeof(PATCHLOCATIONLIST) * m_maxNumAllocations);
1381     m_resCount = 0;
1382 
1383     MOS_ZeroMemory(m_writeModeList, sizeof(bool) * m_maxNumAllocations);
1384 finish:
1385     MOS_TraceEventExt(EVENT_MOS_BATCH_SUBMIT, EVENT_TYPE_END, &eStatus, sizeof(eStatus), nullptr, 0);
1386     return eStatus;
1387 }
1388 
UnlockPendingOcaBuffers(PMOS_COMMAND_BUFFER cmdBuffer,PMOS_CONTEXT mosContext)1389 void GpuContextSpecific::UnlockPendingOcaBuffers(PMOS_COMMAND_BUFFER cmdBuffer, PMOS_CONTEXT mosContext)
1390 {
1391     MOS_OS_CHK_NULL_NO_STATUS_RETURN(cmdBuffer);
1392     MOS_OS_CHK_NULL_NO_STATUS_RETURN(mosContext);
1393     MosOcaInterface *pOcaInterface         = &MosOcaInterfaceSpecific::GetInstance();
1394     if (nullptr == pOcaInterface || !((MosOcaInterfaceSpecific*)pOcaInterface)->IsOcaEnabled())
1395     {
1396         // Will come here for UMD_OCA not being enabled case.
1397         return;
1398     }
1399 
1400     int count = 0;
1401     struct MOS_OCA_EXEC_LIST_INFO *info = nullptr;
1402     if ((cmdBuffer->iSubmissionType & SUBMISSION_TYPE_SINGLE_PIPE_MASK) && ((MosOcaInterfaceSpecific*)pOcaInterface)->IsOcaDumpExecListInfoEnabled())
1403     {
1404         info = mos_bo_get_softpin_targets_info(cmdBuffer->OsResource.bo, &count);
1405     }
1406 
1407     pOcaInterface->UnlockPendingOcaBuffers(mosContext, info, count);
1408 
1409     if(info)
1410     {
1411         free(info);
1412     }
1413 }
1414 
SubmitPipeCommands(MOS_COMMAND_BUFFER * cmdBuffer,MOS_LINUX_BO * cmdBo,PMOS_CONTEXT osContext,const std::vector<MOS_LINUX_BO * > & skipSyncBoList,uint32_t execFlag,int32_t dr4)1415 int32_t GpuContextSpecific::SubmitPipeCommands(
1416     MOS_COMMAND_BUFFER *cmdBuffer,
1417     MOS_LINUX_BO *cmdBo,
1418     PMOS_CONTEXT osContext,
1419     const std::vector<MOS_LINUX_BO *> &skipSyncBoList,
1420     uint32_t execFlag,
1421     int32_t dr4)
1422 {
1423     int32_t      ret        = 0;
1424     int          fence      = -1;
1425     unsigned int fenceFlag = 0;
1426 
1427     MOS_LINUX_CONTEXT *queue = m_i915Context[0];
1428     bool isVeboxSubmission   = false;
1429 
1430     if (execFlag == MOS_GPU_NODE_VIDEO || execFlag == MOS_GPU_NODE_VIDEO2)
1431     {
1432         execFlag = I915_EXEC_DEFAULT;
1433     }
1434     if (execFlag == MOS_GPU_NODE_VE)
1435     {
1436         execFlag = I915_EXEC_DEFAULT;
1437         isVeboxSubmission = true;
1438     }
1439 
1440     if(cmdBuffer->iSubmissionType & SUBMISSION_TYPE_MULTI_PIPE_SLAVE)
1441     {
1442         fence = osContext->submit_fence;
1443         fenceFlag = I915_EXEC_FENCE_SUBMIT;
1444         int slaveIndex = (cmdBuffer->iSubmissionType & SUBMISSION_TYPE_MULTI_PIPE_SLAVE_INDEX_MASK) >> SUBMISSION_TYPE_MULTI_PIPE_SLAVE_INDEX_SHIFT;
1445         if(slaveIndex < 7)
1446         {
1447             queue = m_i915Context[2 + slaveIndex]; //0 is for single pipe, 1 is for master, slave starts from 2
1448         }
1449         else
1450         {
1451             MOS_OS_ASSERTMESSAGE("slaveIndex value: %s is invalid!", slaveIndex);
1452             return -1;
1453         }
1454 
1455         if (isVeboxSubmission)
1456         {
1457             queue = m_i915Context[cmdBuffer->iVeboxNodeIndex + 1];
1458         }
1459 
1460         for(auto bo: skipSyncBoList)
1461         {
1462             mos_bo_set_exec_object_async(cmdBo, bo);
1463         }
1464     }
1465 
1466     if(cmdBuffer->iSubmissionType & SUBMISSION_TYPE_MULTI_PIPE_MASTER)
1467     {
1468         //Only master pipe needs fence out flag
1469         fenceFlag = I915_EXEC_FENCE_OUT;
1470         queue = m_i915Context[1];
1471     }
1472 
1473     ret = mos_bo_context_exec2(cmdBo,
1474                                   cmdBo->size,
1475                                   queue,
1476                                   nullptr,
1477                                   0,
1478                                   dr4,
1479                                   execFlag | fenceFlag,
1480                                   &fence);
1481 
1482     if(cmdBuffer->iSubmissionType & SUBMISSION_TYPE_MULTI_PIPE_MASTER)
1483     {
1484         osContext->submit_fence = fence;
1485     }
1486 
1487     if(cmdBuffer->iSubmissionType & SUBMISSION_TYPE_MULTI_PIPE_FLAGS_LAST_PIPE)
1488     {
1489         close(fence);
1490     }
1491 
1492     return ret;
1493 }
1494 
ParallelSubmitCommands(std::map<uint32_t,PMOS_COMMAND_BUFFER> secondaryCmdBufs,PMOS_CONTEXT osContext,uint32_t execFlag,int32_t dr4)1495 int32_t GpuContextSpecific::ParallelSubmitCommands(
1496     std::map<uint32_t, PMOS_COMMAND_BUFFER> secondaryCmdBufs,
1497     PMOS_CONTEXT osContext,
1498     uint32_t execFlag,
1499     int32_t dr4)
1500 {
1501     int32_t      ret        = 0;
1502     int          fence      = -1;
1503     unsigned int fenceFlag  = 0;
1504     auto         it         = m_secondaryCmdBufs.begin();
1505     MOS_LINUX_BO *cmdBos[MAX_PARALLEN_CMD_BO_NUM];
1506     int          numBos     = 0; // exclude FE bo
1507 
1508     MOS_LINUX_CONTEXT *queue = m_i915Context[0];
1509     bool isVeboxSubmission   = false;
1510 
1511     if (execFlag == MOS_GPU_NODE_VIDEO || execFlag == MOS_GPU_NODE_VIDEO2)
1512     {
1513         execFlag = I915_EXEC_DEFAULT;
1514     }
1515     if (execFlag == MOS_GPU_NODE_VE)
1516     {
1517         execFlag = I915_EXEC_DEFAULT;
1518         isVeboxSubmission = true;
1519     }
1520 
1521     while(it != m_secondaryCmdBufs.end())
1522     {
1523         if(it->second->iSubmissionType & SUBMISSION_TYPE_MULTI_PIPE_ALONE)
1524         {
1525             fenceFlag = I915_EXEC_FENCE_OUT;
1526             queue = m_i915Context[0];
1527 
1528             ret = mos_bo_context_exec2(it->second->OsResource.bo,
1529                                   it->second->OsResource.bo->size,
1530                                   queue,
1531                                   nullptr,
1532                                   0,
1533                                   dr4,
1534                                   execFlag | fenceFlag,
1535                                   &fence);
1536 
1537             osContext->submit_fence = fence;
1538         }
1539 
1540         if((it->second->iSubmissionType & SUBMISSION_TYPE_MULTI_PIPE_MASTER)
1541             || (it->second->iSubmissionType & SUBMISSION_TYPE_MULTI_PIPE_SLAVE))
1542         {
1543             cmdBos[numBos++] = it->second->OsResource.bo;
1544 
1545             if(it->second->iSubmissionType & SUBMISSION_TYPE_MULTI_PIPE_FLAGS_LAST_PIPE)
1546             {
1547                 queue = m_i915Context[numBos - 1];
1548                 MOS_OS_CHK_NULL_RETURN(queue);
1549                 if(-1 != fence)
1550                 {
1551                     fenceFlag = I915_EXEC_FENCE_IN;
1552                 }
1553 
1554                 ret = mos_bo_context_exec3(cmdBos,
1555                                               numBos,
1556                                               queue,
1557                                               nullptr,
1558                                               0,
1559                                               dr4,
1560                                               execFlag | fenceFlag,
1561                                               &fence);
1562 
1563                 for(int i = 0; i < numBos; i++)
1564                 {
1565                     cmdBos[i] = nullptr;
1566                 }
1567                 numBos = 0;
1568 
1569                 if(-1 != fence)
1570                 {
1571                     close(fence);
1572                 }
1573             }
1574         }
1575 
1576         it++;
1577     }
1578 
1579     return ret;
1580 }
1581 
IncrementGpuStatusTag()1582 void GpuContextSpecific::IncrementGpuStatusTag()
1583 {
1584     m_GPUStatusTag = m_GPUStatusTag % UINT_MAX + 1;
1585     if (m_GPUStatusTag == 0)
1586     {
1587         m_GPUStatusTag = 1;
1588     }
1589 }
1590 
ResetGpuContextStatus()1591 void GpuContextSpecific::ResetGpuContextStatus()
1592 {
1593     MOS_ZeroMemory(m_allocationList, sizeof(ALLOCATION_LIST) * ALLOCATIONLIST_SIZE);
1594     m_numAllocations = 0;
1595     MOS_ZeroMemory(m_patchLocationList, sizeof(PATCHLOCATIONLIST) * PATCHLOCATIONLIST_SIZE);
1596     m_currentNumPatchLocations = 0;
1597 
1598     MOS_ZeroMemory(m_attachedResources, sizeof(MOS_RESOURCE) * ALLOCATIONLIST_SIZE);
1599     m_resCount = 0;
1600 
1601     MOS_ZeroMemory(m_writeModeList, sizeof(bool) * ALLOCATIONLIST_SIZE);
1602 
1603     if ((m_cmdBufFlushed == true) && m_commandBuffer->OsResource.bo)
1604     {
1605         m_commandBuffer->OsResource.bo = nullptr;
1606     }
1607 }
1608 
AllocateGPUStatusBuf()1609 MOS_STATUS GpuContextSpecific::AllocateGPUStatusBuf()
1610 {
1611     MOS_OS_FUNCTION_ENTER;
1612 
1613     m_statusBufferMosResource = (MOS_RESOURCE_HANDLE)MOS_AllocAndZeroMemory(sizeof(MOS_RESOURCE));
1614     MOS_OS_CHK_NULL_RETURN(m_statusBufferMosResource);
1615 
1616     GraphicsResource::CreateParams params;
1617     params.m_tileType  = MOS_TILE_LINEAR;
1618     params.m_type      = MOS_GFXRES_BUFFER;
1619     params.m_format    = Format_Buffer;
1620     params.m_width     = sizeof(MOS_GPU_STATUS_DATA);
1621     params.m_height    = 1;
1622     params.m_depth     = 1;
1623     params.m_arraySize = 1;
1624     params.m_name      = "GPU Status Buffer";
1625 
1626     GraphicsResource *graphicsResource = GraphicsResource::CreateGraphicResource(GraphicsResource::osSpecificResource);
1627     MOS_OS_CHK_NULL_RETURN(graphicsResource);
1628 
1629     MOS_OS_CHK_STATUS_RETURN(graphicsResource->Allocate(m_osContext, params));
1630 
1631     GraphicsResource::LockParams lockParams;
1632     lockParams.m_writeRequest = true;
1633     auto gpuStatusData       = (MOS_GPU_STATUS_DATA *)graphicsResource->Lock(m_osContext, lockParams);
1634     if (gpuStatusData == nullptr)
1635     {
1636         MOS_OS_ASSERTMESSAGE("Unable to lock gpu eStatus buffer for read.");
1637         graphicsResource->Free(m_osContext);
1638         MOS_Delete(graphicsResource);
1639         return MOS_STATUS_UNKNOWN;
1640     }
1641 
1642     m_statusBufferResource = graphicsResource;
1643     return MOS_STATUS_SUCCESS;
1644 }
1645 
1646 #if (_DEBUG || _RELEASE_INTERNAL)
SelectEngineInstanceByUser(struct i915_engine_class_instance * engineMap,uint32_t * engineNum,uint32_t userEngineInstance,MOS_GPU_NODE gpuNode)1647 bool GpuContextSpecific::SelectEngineInstanceByUser(struct i915_engine_class_instance *engineMap,
1648         uint32_t *engineNum, uint32_t userEngineInstance, MOS_GPU_NODE gpuNode)
1649 {
1650     uint32_t engineInstance     = 0x0;
1651 
1652     if(gpuNode == MOS_GPU_NODE_COMPUTE)
1653     {
1654         engineInstance  = (userEngineInstance >> ENGINE_INSTANCE_SELECT_COMPUTE_INSTANCE_SHIFT)
1655             & (ENGINE_INSTANCE_SELECT_ENABLE_MASK >> (MAX_ENGINE_INSTANCE_NUM - *engineNum));
1656     }
1657     else if(gpuNode == MOS_GPU_NODE_VE)
1658     {
1659         engineInstance  = (userEngineInstance >> ENGINE_INSTANCE_SELECT_VEBOX_INSTANCE_SHIFT)
1660             & (ENGINE_INSTANCE_SELECT_ENABLE_MASK >> (MAX_ENGINE_INSTANCE_NUM - *engineNum));
1661     }
1662     else if(gpuNode == MOS_GPU_NODE_VIDEO || gpuNode == MOS_GPU_NODE_VIDEO2)
1663     {
1664         engineInstance  = (userEngineInstance >> ENGINE_INSTANCE_SELECT_VDBOX_INSTANCE_SHIFT)
1665             & (ENGINE_INSTANCE_SELECT_ENABLE_MASK >> (MAX_ENGINE_INSTANCE_NUM - *engineNum));
1666     }
1667     else
1668     {
1669         MOS_OS_NORMALMESSAGE("Invalid gpu node in use.");
1670     }
1671 
1672     if(engineInstance)
1673     {
1674         auto unSelectIndex = 0;
1675         for(auto bit = 0; bit < *engineNum; bit++)
1676         {
1677             if(((engineInstance >> bit) & 0x1) && (bit > unSelectIndex))
1678             {
1679                 engineMap[unSelectIndex].engine_class = engineMap[bit].engine_class;
1680                 engineMap[unSelectIndex].engine_instance = engineMap[bit].engine_instance;
1681                 engineMap[bit].engine_class = 0;
1682                 engineMap[bit].engine_instance = 0;
1683                 unSelectIndex++;
1684             }
1685             else if(((engineInstance >> bit) & 0x1) && (bit == unSelectIndex))
1686             {
1687                 unSelectIndex++;
1688             }
1689             else if(!((engineInstance >> bit) & 0x1))
1690             {
1691                 engineMap[bit].engine_class = 0;
1692                 engineMap[bit].engine_instance = 0;
1693             }
1694         }
1695         *engineNum = unSelectIndex;
1696     }
1697     return engineInstance;
1698 }
1699 #endif
1700