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 //!
24 //! \file media_context.cpp
25 //! \brief Defines the common interface for media context
26 //! \details The media context interface is further sub-divided by component,
27 //! this file is for the base interface which is shared by all components.
28 //!
29
30 #include "media_context.h"
31 #include "mos_interface.h"
32 #include "mos_os_virtualengine_next.h"
33 #if !EMUL
34 #include "codec_hw_next.h"
35 #include "decode_scalability_defs.h"
36 #endif
37 #include "mos_os_cp_interface_specific.h"
MediaContext(uint8_t componentType,void * hwInterface,PMOS_INTERFACE osInterface)38 MediaContext::MediaContext(uint8_t componentType, void *hwInterface, PMOS_INTERFACE osInterface)
39 {
40 if (!hwInterface)
41 {
42 MOS_OS_ASSERTMESSAGE("null HW interface, failed to create Media Context");
43 return;
44 }
45
46 if (!osInterface)
47 {
48 MOS_OS_ASSERTMESSAGE("null OS interface, failed to create Media Context");
49 return;
50 }
51
52 if (componentType >= scalabilityTotal)
53 {
54 MOS_OS_ASSERTMESSAGE("Invalid component type, failed to create Media Context");
55 return;
56 }
57
58 m_hwInterface = hwInterface;
59 m_osInterface = osInterface;
60 m_userSettingPtr = osInterface->pfnGetUserSettingInstance(osInterface);
61 m_componentType = componentType;
62
63 m_streamId = m_osInterface->streamIndex;
64 m_gpuContextAttributeTable.clear();
65 }
66
~MediaContext()67 MediaContext::~MediaContext()
68 {
69 if (m_osInterface && m_osInterface->pfnWaitAllCmdCompletion)
70 {
71 m_osInterface->pfnWaitAllCmdCompletion(m_osInterface);
72 }
73
74 if ((MOS_VE_MULTINODESCALING_SUPPORTED(m_osInterface)) &&
75 (m_curNodeOrdinal == MOS_GPU_NODE_VIDEO || m_curNodeOrdinal == MOS_GPU_NODE_VIDEO2))
76 {
77 m_osInterface->pfnDestroyVideoNodeAssociation(m_osInterface, m_curNodeOrdinal);
78 if (m_osInterface->osStreamState && m_osInterface->osStreamState->component == COMPONENT_Encode)
79 {
80 m_osInterface->pfnSetLatestVirtualNode(m_osInterface, MOS_GPU_NODE_MAX);
81 }
82 }
83
84 for (auto& curAttribute : m_gpuContextAttributeTable)
85 {
86 if (curAttribute.scalabilityState)
87 {
88 MOS_STATUS status = curAttribute.scalabilityState->Destroy();
89 if (MOS_FAILED(status))
90 {
91 MOS_OS_ASSERTMESSAGE("scalabilityState destroy fail.");
92 }
93 MOS_Delete(curAttribute.scalabilityState);
94 // set legacy MOS ve interface to null to be compatible to legacy MOS
95 if (m_osInterface)
96 {
97 m_osInterface->pVEInterf = nullptr;
98 }
99 }
100 else
101 {
102 MOS_OS_ASSERTMESSAGE("scalabilityState is nullptr, something must be wrong");
103 return;
104 }
105
106 if (!m_osInterface || !m_osInterface->pOsContext)
107 {
108 MOS_OS_ASSERTMESSAGE("m_osInterface and OsContext cannot be nullptr");
109 return;
110 }
111
112 if (curAttribute.gpuContext != MOS_GPU_CONTEXT_INVALID_HANDLE)
113 {
114 if (m_osInterface->apoMosEnabled || m_osInterface->modularizedGpuCtxEnabled)
115 {
116 auto status = m_osInterface->pfnDestroyGpuContextByHandle(m_osInterface, curAttribute.gpuContext);
117
118 if (status != MOS_STATUS_SUCCESS)
119 {
120 MOS_OS_NORMALMESSAGE("Gpu Context destory failed, something must be wrong");
121 return;
122 }
123 }
124 else
125 {
126 auto status = m_osInterface->pfnDestroyGpuContext(
127 m_osInterface,
128 curAttribute.ctxForLegacyMos);
129 if (status != MOS_STATUS_SUCCESS)
130 {
131 MOS_OS_NORMALMESSAGE("Gpu Context destory failed, something must be wrong");
132 return;
133 }
134 }
135 }
136 else
137 {
138 MOS_OS_ASSERTMESSAGE("Invalid gpu Context handle in entry, something must be wrong");
139 return;
140 }
141 #if !EMUL
142 // Be compatible to legacy MOS
143 m_osInterface->pfnSetGpuContextHandle(m_osInterface, MOS_GPU_CONTEXT_INVALID_HANDLE, curAttribute.ctxForLegacyMos);
144 #endif
145 }
146
147 m_gpuContextAttributeTable.clear();
148 }
149
SwitchContext(MediaFunction func,ContextRequirement * requirement,MediaScalability ** scalabilityState)150 MOS_STATUS MediaContext::SwitchContext(MediaFunction func, ContextRequirement *requirement, MediaScalability **scalabilityState)
151 {
152 MOS_OS_FUNCTION_ENTER;
153 MOS_STATUS status = MOS_STATUS_SUCCESS;
154
155 MOS_OS_CHK_NULL_RETURN(m_osInterface);
156 MOS_OS_CHK_NULL_RETURN(m_osInterface->pOsContext);
157 MOS_OS_CHK_NULL_RETURN(scalabilityState);
158 MOS_OS_CHK_NULL_RETURN(requirement);
159
160 if (func >= INVALID_MEDIA_FUNCTION)
161 {
162 MOS_OS_ASSERTMESSAGE("Func required is invalid");
163 return MOS_STATUS_INVALID_PARAMETER;
164 }
165
166 MediaScalability * veStateProvided = nullptr;
167
168 if (IS_RENDER_ENGINE_FUNCTION(func))
169 {
170 auto scalPars = (ScalabilityPars *)requirement;
171 MOS_OS_CHK_NULL_RETURN(scalPars);
172 MOS_OS_CHK_NULL_RETURN(m_osInterface->osCpInterface);
173 scalPars->raMode = m_osInterface->osCpInterface->IsHMEnabled() ? MEDIA_IS_SKU(m_osInterface->pfnGetSkuTable(m_osInterface), FtrRAMode) : 0;
174 scalPars->protectMode = m_osInterface->osCpInterface->IsHMEnabled() ? MEDIA_IS_SKU(m_osInterface->pfnGetSkuTable(m_osInterface), FtrProtectedEnableBitRequired) : 0;
175 if (scalPars->raMode)
176 {
177 MOS_OS_NORMALMESSAGE("request RA mode context for protected render workload");
178 ReportUserSetting(m_userSettingPtr,
179 __MEDIA_USER_FEATURE_VALUE_RA_MODE_ENABLE,
180 uint32_t(1),
181 MediaUserSetting::Group::Device);
182 }
183 if (scalPars->protectMode)
184 {
185 MOS_OS_NORMALMESSAGE("request protect mode context for protected render workload");
186 ReportUserSetting(m_userSettingPtr,
187 __MEDIA_USER_FEATURE_VALUE_PROTECT_MODE_ENABLE,
188 uint32_t(1),
189 MediaUserSetting::Group::Device);
190 }
191 }
192
193 uint32_t index = m_invalidContextAttribute;
194 #if !EMUL
195 MOS_OS_CHK_STATUS_RETURN(SearchContext<ScalabilityPars*>(func, (ScalabilityPars*)requirement, index));
196 #endif
197 if (index == m_invalidContextAttribute)
198 {
199 MOS_OS_CHK_STATUS_RETURN(CreateContext<ScalabilityPars*>(func, (ScalabilityPars*)requirement, index));
200 }
201 if (index == m_invalidContextAttribute || index >= m_gpuContextAttributeTable.size())
202 {
203 MOS_OS_ASSERTMESSAGE("Incorrect index get from Context attribute table");
204 return MOS_STATUS_UNKNOWN;
205 }
206
207 // Be compatible to legacy MOS
208 MOS_OS_CHK_STATUS_RETURN(m_osInterface->pfnSetGpuContext(m_osInterface, m_gpuContextAttributeTable[index].ctxForLegacyMos));
209 veStateProvided = m_gpuContextAttributeTable[index].scalabilityState;
210 MOS_OS_NORMALMESSAGE("Switched to GpuContext %d, index %d", m_gpuContextAttributeTable[index].ctxForLegacyMos, index);
211
212 if (requirement->IsEnc)
213 {
214 m_osInterface->pfnSetEncodeEncContext(m_osInterface, m_gpuContextAttributeTable[index].ctxForLegacyMos);
215 }
216 if (requirement->IsPak)
217 {
218 m_osInterface->pfnSetEncodePakContext(m_osInterface, m_gpuContextAttributeTable[index].ctxForLegacyMos);
219 }
220
221 if (!requirement->IsContextSwitchBack)
222 {
223 m_osInterface->pfnResetOsStates(m_osInterface);
224 }
225
226 *scalabilityState = veStateProvided;
227
228 return status;
229 }
230
231 template<typename T>
SearchContext(MediaFunction func,T params,uint32_t & indexFound)232 MOS_STATUS MediaContext::SearchContext(MediaFunction func, T params, uint32_t& indexFound)
233 {
234 MOS_OS_FUNCTION_ENTER;
235
236 MOS_OS_CHK_NULL_RETURN(m_osInterface);
237
238 indexFound = m_invalidContextAttribute;
239 uint32_t index = 0;
240
241 for (auto& curAttribute : m_gpuContextAttributeTable)
242 {
243 if (curAttribute.func == func)
244 {
245 MOS_OS_CHK_NULL_RETURN(curAttribute.scalabilityState);
246
247 if (curAttribute.scalabilityState->IsScalabilityModeMatched(params))
248 {
249 // Found the matching GPU context and scalability state
250 indexFound = index;
251
252 // Be compatible to legacy MOS
253 MOS_OS_CHK_STATUS_RETURN(m_osInterface->pfnSetGpuContextHandle(m_osInterface, curAttribute.gpuContext, curAttribute.ctxForLegacyMos));
254 // set legacy MOS ve interface to current reused scalability state's ve interface
255 m_osInterface->pVEInterf = curAttribute.scalabilityState->m_veInterface;
256 if (m_osInterface->apoMosEnabled)
257 {
258 if (curAttribute.scalabilityState->m_veState)
259 {
260 MOS_OS_CHK_NULL_RETURN(m_osInterface->osStreamState);
261 m_osInterface->osStreamState->virtualEngineInterface = curAttribute.scalabilityState->m_veState;
262 }
263 }
264 break;
265 }
266 }
267
268 index++;
269 }
270
271 return MOS_STATUS_SUCCESS;
272 }
273
274 template<typename T>
CreateContext(MediaFunction func,T params,uint32_t & indexReturn)275 MOS_STATUS MediaContext::CreateContext(MediaFunction func, T params, uint32_t& indexReturn)
276 {
277 MOS_OS_FUNCTION_ENTER;
278
279 MOS_OS_CHK_NULL_RETURN(m_osInterface);
280
281 // Reach the max number of Gpu Context attr entries in current Media Context
282 if (m_gpuContextAttributeTable.size() == m_maxContextAttribute)
283 {
284 MOS_OS_ASSERTMESSAGE("Reached max num of entries of gpuContextAttributeTable: 4096. Cannot create more Gpu Contexts");
285 return MOS_STATUS_NOT_ENOUGH_BUFFER;
286 }
287
288 GpuContextAttribute newAttr;
289
290 // Setup func
291 newAttr.func = func;
292 if (newAttr.func >= INVALID_MEDIA_FUNCTION)
293 {
294 MOS_OS_ASSERTMESSAGE("Func required is invalid");
295 return MOS_STATUS_INVALID_PARAMETER;
296 }
297
298 // Create scalabilityState
299 MOS_GPUCTX_CREATOPTIONS_ENHANCED option;
300 MediaScalabilityFactory<T> scalabilityFactory;
301 newAttr.scalabilityState = scalabilityFactory.CreateScalability(
302 m_componentType, params, m_hwInterface, this, &option);
303 if (newAttr.scalabilityState == nullptr)
304 {
305 MOS_OS_ASSERTMESSAGE("Failed to create scalability state");
306 return MOS_STATUS_NO_SPACE;
307 }
308
309 // request to create or reuse gpuContext
310 MOS_GPU_NODE node = MOS_GPU_NODE_MAX;
311 MOS_OS_CHK_STATUS_RETURN(FunctionToNode(func, option, node));
312
313 // WA for legacy MOS
314 MOS_OS_CHK_STATUS_RETURN(FunctionToGpuContext(func, option, node, newAttr.ctxForLegacyMos));
315
316 if(m_osInterface->bSetHandleInvalid)
317 {
318 MOS_OS_NORMALMESSAGE("Force set INVALID_HANDLE for GpuContext %d", newAttr.ctxForLegacyMos);
319 MOS_OS_CHK_STATUS_RETURN(m_osInterface->pfnSetGpuContextHandle(m_osInterface, MOS_GPU_CONTEXT_INVALID_HANDLE, newAttr.ctxForLegacyMos));
320 }
321
322 MOS_OS_CHK_STATUS_RETURN(m_osInterface->pfnCreateGpuContext(m_osInterface, newAttr.ctxForLegacyMos, node, &option));
323 m_osInterface->pfnSetGpuContext(m_osInterface, newAttr.ctxForLegacyMos);
324 newAttr.gpuContext = m_osInterface->CurrentGpuContextHandle;
325 MOS_OS_NORMALMESSAGE("Create GpuContext %d, node %d, handle 0x%x, protectMode %d, raMode %d",
326 newAttr.ctxForLegacyMos, node, newAttr.gpuContext, option.ProtectMode, option.RAMode);
327
328 // Add entry to the table
329 indexReturn = m_gpuContextAttributeTable.size();
330 m_gpuContextAttributeTable.push_back(newAttr);
331
332 if (func == VeboxVppFunc || func == ComputeVppFunc)
333 {
334 m_osInterface->pfnRegisterBBCompleteNotifyEvent(
335 m_osInterface,
336 newAttr.ctxForLegacyMos);
337 }
338
339 return MOS_STATUS_SUCCESS;
340 }
341
SwitchContext(MediaFunction func,MediaScalabilityOption & scalabilityOption,MediaScalability ** scalabilityState,bool isEnc,bool isPak)342 MOS_STATUS MediaContext::SwitchContext(
343 MediaFunction func,
344 MediaScalabilityOption &scalabilityOption,
345 MediaScalability **scalabilityState,
346 bool isEnc,
347 bool isPak)
348 {
349 MOS_OS_FUNCTION_ENTER;
350
351 MOS_OS_CHK_NULL_RETURN(m_osInterface);
352 MOS_OS_CHK_NULL_RETURN(m_osInterface->pOsContext);
353 MOS_OS_CHK_NULL_RETURN(scalabilityState);
354
355 if (func >= INVALID_MEDIA_FUNCTION)
356 {
357 MOS_OS_ASSERTMESSAGE("Func required is invalid");
358 return MOS_STATUS_INVALID_PARAMETER;
359 }
360
361 MediaScalability * veStateProvided = nullptr;
362
363 uint32_t index = m_invalidContextAttribute;
364 #if !EMUL
365 MOS_OS_CHK_STATUS_RETURN(SearchContext<MediaScalabilityOption&>(func, scalabilityOption, index));
366 #endif
367 if (index == m_invalidContextAttribute)
368 {
369 MOS_OS_CHK_STATUS_RETURN(CreateContext<MediaScalabilityOption *>(func, &scalabilityOption, index));
370 }
371 if (index == m_invalidContextAttribute || index >= m_gpuContextAttributeTable.size())
372 {
373 MOS_OS_ASSERTMESSAGE("Incorrect index get from Context attribute table");
374 return MOS_STATUS_UNKNOWN;
375 }
376
377 // Be compatible to legacy MOS
378 MOS_OS_CHK_STATUS_RETURN(m_osInterface->pfnSetGpuContext(m_osInterface, m_gpuContextAttributeTable[index].ctxForLegacyMos));
379 veStateProvided = m_gpuContextAttributeTable[index].scalabilityState;
380
381 if (isEnc)
382 {
383 m_osInterface->pfnSetEncodeEncContext(m_osInterface, m_gpuContextAttributeTable[index].ctxForLegacyMos);
384 }
385 if (isPak)
386 {
387 m_osInterface->pfnSetEncodePakContext(m_osInterface, m_gpuContextAttributeTable[index].ctxForLegacyMos);
388 }
389
390 m_osInterface->pfnResetOsStates(m_osInterface);
391
392 *scalabilityState = veStateProvided;
393
394 return MOS_STATUS_SUCCESS;
395 }
396
FunctionToNode(MediaFunction func,const MOS_GPUCTX_CREATOPTIONS_ENHANCED & option,MOS_GPU_NODE & node)397 MOS_STATUS MediaContext::FunctionToNode(MediaFunction func, const MOS_GPUCTX_CREATOPTIONS_ENHANCED &option, MOS_GPU_NODE& node)
398 {
399 MOS_OS_FUNCTION_ENTER;
400 MOS_STATUS status = MOS_STATUS_SUCCESS;
401
402 if (func >= INVALID_MEDIA_FUNCTION)
403 {
404 MOS_OS_ASSERTMESSAGE("Func required is invalid");
405 return MOS_STATUS_INVALID_PARAMETER;
406 }
407
408 switch (func)
409 {
410 case RenderGenericFunc:
411 node = MOS_GPU_NODE_3D;
412 break;
413 case VdboxEncodeFunc:
414 case VdboxDecodeFunc:
415 case VdboxDecodeVirtualNode0Func:
416 case VdboxDecodeVirtualNode1Func:
417 if (option.LRCACount >= 2)
418 {
419 node = MOS_GPU_NODE_VIDEO; // multiple pipe decode or encode always using VIDEO node
420 if (MOS_VE_MULTINODESCALING_SUPPORTED(m_osInterface))
421 {
422 if (m_curNodeOrdinal == MOS_GPU_NODE_VIDEO || m_curNodeOrdinal == MOS_GPU_NODE_VIDEO2)
423 {
424 m_osInterface->pfnDestroyVideoNodeAssociation(m_osInterface, m_curNodeOrdinal);
425 if (func == VdboxEncodeFunc)
426 {
427 m_osInterface->pfnSetLatestVirtualNode(m_osInterface, MOS_GPU_NODE_MAX);
428 }
429 }
430 MOS_OS_CHK_STATUS_RETURN(m_osInterface->pfnCreateVideoNodeAssociation(
431 m_osInterface,
432 true,
433 &node));
434 if (func == VdboxDecodeFunc || func == VdboxDecodeVirtualNode0Func || func == VdboxDecodeVirtualNode1Func)
435 {
436 m_osInterface->pfnSetDecoderVirtualNodePerStream(m_osInterface, node);
437 }
438 else if (func == VdboxEncodeFunc)
439 {
440 m_osInterface->pfnSetLatestVirtualNode(m_osInterface, node);
441 }
442 }
443 m_curNodeOrdinal = node;
444 }
445 #if !EMUL
446 else
447 {
448 MOS_OS_CHK_STATUS_RETURN(FunctionToNodeCodec(func, node));
449 }
450 #endif
451 break;
452 case VdboxDecodeWaFunc:
453 case VdboxDecrpytFunc:
454 case VdboxCpFunc:
455 node = MOS_GPU_NODE_VIDEO;
456 break;
457 case VeboxVppFunc:
458 node = MOS_GPU_NODE_VE;
459 break;
460 case ComputeMdfFunc:
461 case ComputeVppFunc:
462 node = MOS_GPU_NODE_COMPUTE;
463 break;
464 default:
465 MOS_OS_ASSERTMESSAGE("Cannot find the GPU node by the func");
466 status = MOS_STATUS_INVALID_PARAMETER;
467 node = MOS_GPU_NODE_MAX;
468 break;
469 }
470
471 return status;
472 }
473 #if !EMUL
FunctionToNodeCodec(MediaFunction func,MOS_GPU_NODE & node)474 MOS_STATUS MediaContext::FunctionToNodeCodec(MediaFunction func, MOS_GPU_NODE& node)
475 {
476 MHW_VDBOX_GPUNODE_LIMIT gpuNodeLimit = {0};
477
478 MOS_OS_CHK_STATUS_RETURN(FindGpuNodeToUse(func , &gpuNodeLimit));
479
480 node = (MOS_GPU_NODE)(gpuNodeLimit.dwGpuNodeToUse);
481
482 return MOS_STATUS_SUCCESS;
483 }
484
485 #if (_DEBUG || _RELEASE_INTERNAL)
CheckScalabilityOverrideValidity()486 MOS_STATUS MediaContext::CheckScalabilityOverrideValidity()
487 {
488 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
489
490 MEDIA_SYSTEM_INFO *gtSystemInfo = nullptr;
491 uint32_t forceVdbox = 0;
492 bool scalableDecMode = false;
493 bool useVD1 = false;
494 bool useVD2 = false;
495
496 MHW_MI_CHK_NULL(m_osInterface);
497 scalableDecMode = m_osInterface->bHcpDecScalabilityMode ? true : false;
498 forceVdbox = m_osInterface->eForceVdbox;
499 gtSystemInfo = m_osInterface->pfnGetGtSystemInfo(m_osInterface);
500 MHW_MI_CHK_NULL(gtSystemInfo);
501
502 if (forceVdbox != MOS_FORCE_VDBOX_NONE &&
503 forceVdbox != MOS_FORCE_VDBOX_1 &&
504 forceVdbox != MOS_FORCE_VDBOX_2 &&
505 // 2 pipes, VDBOX1-BE1, VDBOX2-BE2
506 forceVdbox != MOS_FORCE_VDBOX_1_1_2 &&
507 forceVdbox != MOS_FORCE_VDBOX_2_1_2)
508 {
509 eStatus = MOS_STATUS_INVALID_PARAMETER;
510 MHW_ASSERTMESSAGE("user feature forceVdbox value is invalid.");
511 return eStatus;
512 }
513 if (!scalableDecMode &&
514 (forceVdbox == MOS_FORCE_VDBOX_1_1_2 ||
515 forceVdbox == MOS_FORCE_VDBOX_2_1_2))
516 {
517 eStatus = MOS_STATUS_INVALID_PARAMETER;
518 MHW_ASSERTMESSAGE("user feature forceVdbox valude does not consistent with regkey scalability mode.");
519 return eStatus;
520 }
521
522 if (scalableDecMode && !m_scalabilitySupported)
523 {
524 eStatus = MOS_STATUS_INVALID_PARAMETER;
525 MHW_ASSERTMESSAGE("user feature scalability mode is not allowed on current platform!");
526 return eStatus;
527 }
528
529 if (forceVdbox == 0)
530 {
531 useVD1 = true;
532 }
533 else
534 {
535 MHW_VDBOX_IS_VDBOX_SPECIFIED(forceVdbox, MOS_FORCE_VDBOX_1, MOS_FORCEVDBOX_VDBOXID_BITSNUM, MOS_FORCEVDBOX_MASK, useVD1);
536 MHW_VDBOX_IS_VDBOX_SPECIFIED(forceVdbox, MOS_FORCE_VDBOX_2, MOS_FORCEVDBOX_VDBOXID_BITSNUM, MOS_FORCEVDBOX_MASK, useVD2);
537 }
538 if (!gtSystemInfo->VDBoxInfo.IsValid ||
539 (useVD1 && !gtSystemInfo->VDBoxInfo.Instances.Bits.VDBox0Enabled) ||
540 (useVD2 && !gtSystemInfo->VDBoxInfo.Instances.Bits.VDBox1Enabled))
541 {
542 eStatus = MOS_STATUS_INVALID_PARAMETER;
543 MHW_ASSERTMESSAGE("the forced VDBOX is not enabled in current platform.");
544 return eStatus;
545 }
546
547 return eStatus;
548 }
549 #endif
550
FindGpuNodeToUse(MediaFunction func,PMHW_VDBOX_GPUNODE_LIMIT gpuNodeLimit)551 MOS_STATUS MediaContext::FindGpuNodeToUse(MediaFunction func, PMHW_VDBOX_GPUNODE_LIMIT gpuNodeLimit)
552 {
553 bool setVideoNode = false;
554 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
555
556 MOS_GPU_NODE videoGpuNode = MOS_GPU_NODE_VIDEO;
557
558 if (MOS_VE_MULTINODESCALING_SUPPORTED(m_osInterface))
559 {
560 if (GetNumVdbox() == 1)
561 {
562 videoGpuNode = MOS_GPU_NODE_VIDEO;
563 }
564 else
565 {
566 if (m_curNodeOrdinal == MOS_GPU_NODE_VIDEO || m_curNodeOrdinal == MOS_GPU_NODE_VIDEO2)
567 {
568 m_osInterface->pfnDestroyVideoNodeAssociation(m_osInterface, m_curNodeOrdinal);
569 if (func == VdboxEncodeFunc)
570 {
571 m_osInterface->pfnSetLatestVirtualNode(m_osInterface, MOS_GPU_NODE_MAX);
572 }
573 }
574 if (func == VdboxDecodeVirtualNode0Func)
575 {
576 setVideoNode = true;
577 videoGpuNode = MOS_GPU_NODE_VIDEO;
578 }
579 else if (func == VdboxDecodeVirtualNode1Func)
580 {
581 setVideoNode = true;
582 videoGpuNode = MOS_GPU_NODE_VIDEO2;
583 }
584 else if (func == VdboxEncodeFunc)
585 {
586 MOS_GPU_NODE node = m_osInterface->pfnGetLatestVirtualNode(m_osInterface, COMPONENT_Decode);
587 if (node != MOS_GPU_NODE_MAX)
588 {
589 setVideoNode = true;
590 videoGpuNode = (node == MOS_GPU_NODE_VIDEO) ? MOS_GPU_NODE_VIDEO2 : MOS_GPU_NODE_VIDEO;
591 }
592 }
593 MHW_MI_CHK_STATUS(m_osInterface->pfnCreateVideoNodeAssociation(
594 m_osInterface,
595 setVideoNode,
596 &videoGpuNode));
597 m_curNodeOrdinal = videoGpuNode;
598 if (func == VdboxDecodeFunc || func == VdboxDecodeVirtualNode0Func || func == VdboxDecodeVirtualNode1Func)
599 {
600 m_osInterface->pfnSetDecoderVirtualNodePerStream(m_osInterface, m_curNodeOrdinal);
601 }
602 else if (func == VdboxEncodeFunc)
603 {
604 m_osInterface->pfnSetLatestVirtualNode(m_osInterface, m_curNodeOrdinal);
605 }
606 }
607 }
608 #if (_DEBUG || _RELEASE_INTERNAL)
609 if (m_osInterface != nullptr && m_osInterface->bEnableDbgOvrdInVE &&
610 (!m_osInterface->bSupportVirtualEngine || !m_scalabilitySupported))
611 {
612 eStatus = MOS_STATUS_INVALID_PARAMETER;
613 MHW_ASSERTMESSAGE("not support DebugOverrid on current OS or Platform.");
614 return eStatus;
615 }
616
617 if (m_osInterface != nullptr && m_osInterface->bEnableDbgOvrdInVE)
618 {
619 MHW_MI_CHK_STATUS(CheckScalabilityOverrideValidity());
620 }
621 #endif
622 gpuNodeLimit->dwGpuNodeToUse = videoGpuNode;
623
624 return eStatus;
625 }
626 #endif
627
FunctionToGpuContext(MediaFunction func,const MOS_GPUCTX_CREATOPTIONS_ENHANCED & option,const MOS_GPU_NODE & node,MOS_GPU_CONTEXT & ctx)628 MOS_STATUS MediaContext::FunctionToGpuContext(MediaFunction func, const MOS_GPUCTX_CREATOPTIONS_ENHANCED &option, const MOS_GPU_NODE &node, MOS_GPU_CONTEXT &ctx)
629 {
630 MOS_OS_FUNCTION_ENTER;
631
632 if (func >= INVALID_MEDIA_FUNCTION)
633 {
634 MOS_OS_ASSERTMESSAGE("Func is invalid");
635 return MOS_STATUS_INVALID_PARAMETER;
636 }
637
638 switch (func)
639 {
640 case VdboxEncodeFunc:
641 MOS_OS_CHK_STATUS_RETURN(FunctionToGpuContextEncode(option, ctx));
642 break;
643 case VdboxDecodeFunc:
644 case VdboxDecodeVirtualNode0Func:
645 case VdboxDecodeVirtualNode1Func:
646 MOS_OS_CHK_STATUS_RETURN(FunctionToGpuContextDecode(option, node, ctx));
647 break;
648 case VdboxDecodeWaFunc:
649 ctx = MOS_GPU_CONTEXT_VIDEO2;
650 break;
651 case VdboxDecrpytFunc:
652 ctx = MOS_GPU_CONTEXT_VDBOX2_VIDEO2;
653 break;
654 case VeboxVppFunc:
655 ctx = MOS_GPU_CONTEXT_VEBOX;
656 break;
657 case RenderGenericFunc:
658 ctx = option.RAMode ? MOS_GPU_CONTEXT_RENDER_RA : MOS_GPU_CONTEXT_RENDER;
659 break;
660 case ComputeVppFunc:
661 ctx = option.RAMode ? MOS_GPU_CONTEXT_COMPUTE_RA : MOS_GPU_CONTEXT_COMPUTE;
662 break;
663 case ComputeMdfFunc:
664 ctx = MOS_GPU_CONTEXT_CM_COMPUTE;
665 break;
666 case VdboxCpFunc:
667 ctx = MOS_GPU_CONTEXT_VIDEO;
668 break;
669 default:
670 ctx = MOS_GPU_CONTEXT_MAX;
671 MOS_OS_ASSERTMESSAGE("Func is invalid");
672 return MOS_STATUS_INVALID_PARAMETER;
673 }
674
675 return MOS_STATUS_SUCCESS;
676 }
677
FunctionToGpuContextDecode(const MOS_GPUCTX_CREATOPTIONS_ENHANCED & option,const MOS_GPU_NODE & node,MOS_GPU_CONTEXT & ctx)678 MOS_STATUS MediaContext::FunctionToGpuContextDecode(const MOS_GPUCTX_CREATOPTIONS_ENHANCED &option, const MOS_GPU_NODE &node, MOS_GPU_CONTEXT &ctx)
679 {
680 if (option.UsingSFC)
681 {
682 ctx = MOS_GPU_CONTEXT_VIDEO4;
683 }
684 else
685 {
686 switch (option.LRCACount)
687 {
688 case 0:
689 case 1:
690 ctx = (node == MOS_GPU_NODE_VIDEO) ? MOS_GPU_CONTEXT_VIDEO : MOS_GPU_CONTEXT_VDBOX2_VIDEO;
691 break;
692 case 2:
693 ctx = MOS_GPU_CONTEXT_VIDEO5;
694 break;
695 case 3:
696 ctx = MOS_GPU_CONTEXT_VIDEO7;
697 break;
698 default:
699 ctx = MOS_GPU_CONTEXT_VIDEO;
700 break;
701 }
702 }
703
704 return MOS_STATUS_SUCCESS;
705 }
706
FunctionToGpuContextEncode(const MOS_GPUCTX_CREATOPTIONS_ENHANCED & option,MOS_GPU_CONTEXT & ctx)707 MOS_STATUS MediaContext::FunctionToGpuContextEncode(const MOS_GPUCTX_CREATOPTIONS_ENHANCED &option, MOS_GPU_CONTEXT &ctx)
708 {
709 switch (option.LRCACount)
710 {
711 case 0:
712 case 1:
713 ctx = MOS_GPU_CONTEXT_VIDEO3;
714 break;
715 case 2:
716 ctx = MOS_GPU_CONTEXT_VIDEO6;
717 break;
718 case 4:
719 ctx = MOS_GPU_CONTEXT_VIDEO6; //Change to proper slot when MOS_GPU_CONTEXT num extended
720 break;
721 default:
722 ctx = MOS_GPU_CONTEXT_VIDEO3;
723 break;
724 }
725
726 return MOS_STATUS_SUCCESS;
727 }
728
SetLatestDecoderVirtualNode()729 void MediaContext::SetLatestDecoderVirtualNode()
730 {
731 if (m_curNodeOrdinal == MOS_GPU_NODE_VIDEO || m_curNodeOrdinal == MOS_GPU_NODE_VIDEO2)
732 {
733 m_osInterface->pfnSetLatestVirtualNode(m_osInterface, m_curNodeOrdinal);
734 }
735 }
736
ReassignContextForDecoder(uint32_t frameNum,ContextRequirement * requirement,MediaScalability ** scalabilityState)737 MOS_STATUS MediaContext::ReassignContextForDecoder(uint32_t frameNum, ContextRequirement *requirement, MediaScalability **scalabilityState)
738 {
739 if (frameNum == 0)
740 {
741 // if encoder is working, always reassign decoder to different virtual node
742 MOS_GPU_NODE encoderNode = m_osInterface->pfnGetLatestVirtualNode(m_osInterface, COMPONENT_Encode);
743 if (encoderNode == MOS_GPU_NODE_VIDEO)
744 {
745 MOS_OS_CHK_STATUS_RETURN(SwitchContext(VdboxDecodeVirtualNode1Func, requirement, scalabilityState));
746 }
747 else if (encoderNode == MOS_GPU_NODE_VIDEO2)
748 {
749 MOS_OS_CHK_STATUS_RETURN(SwitchContext(VdboxDecodeVirtualNode0Func, requirement, scalabilityState));
750 }
751 else
752 {
753 // if only decoders are working, reassign decoder to different virtual node compared to latest used virtual node
754 MOS_GPU_NODE decoderNode = m_osInterface->pfnGetLatestVirtualNode(m_osInterface, COMPONENT_Decode);
755 if (decoderNode == MOS_GPU_NODE_VIDEO)
756 {
757 MOS_OS_CHK_STATUS_RETURN(SwitchContext(VdboxDecodeVirtualNode1Func, requirement, scalabilityState));
758 }
759 else if (decoderNode == MOS_GPU_NODE_VIDEO2)
760 {
761 MOS_OS_CHK_STATUS_RETURN(SwitchContext(VdboxDecodeVirtualNode0Func, requirement, scalabilityState));
762 }
763 else
764 {
765 MOS_OS_CHK_STATUS_RETURN(SwitchContext(VdboxDecodeFunc, requirement, scalabilityState));
766 }
767 }
768 }
769 else
770 {
771 // for remaining frames, don't change virtual node assignment
772 MOS_GPU_NODE decoderNode = m_osInterface->pfnGetDecoderVirtualNodePerStream(m_osInterface);
773 if (decoderNode == MOS_GPU_NODE_VIDEO)
774 {
775 MOS_OS_CHK_STATUS_RETURN(SwitchContext(VdboxDecodeVirtualNode0Func, requirement, scalabilityState));
776 }
777 else if (decoderNode == MOS_GPU_NODE_VIDEO2)
778 {
779 MOS_OS_CHK_STATUS_RETURN(SwitchContext(VdboxDecodeVirtualNode1Func, requirement, scalabilityState));
780 }
781 else
782 {
783 MOS_OS_CHK_STATUS_RETURN(SwitchContext(VdboxDecodeFunc, requirement, scalabilityState));
784 }
785 }
786
787 return MOS_STATUS_SUCCESS;
788 }
789
ReassignContextForDecoder(uint32_t frameNum,MediaScalabilityOption & scalabilityOption,MediaScalability ** scalabilityState)790 MOS_STATUS MediaContext::ReassignContextForDecoder(uint32_t frameNum, MediaScalabilityOption &scalabilityOption, MediaScalability **scalabilityState)
791 {
792 if (frameNum == 0)
793 {
794 // if encoder is working, always reassign decoder to different virtual node
795 MOS_GPU_NODE encoderNode = m_osInterface->pfnGetLatestVirtualNode(m_osInterface, COMPONENT_Encode);
796 if (encoderNode == MOS_GPU_NODE_VIDEO)
797 {
798 MOS_OS_CHK_STATUS_RETURN(SwitchContext(VdboxDecodeVirtualNode1Func, scalabilityOption, scalabilityState));
799 }
800 else if (encoderNode == MOS_GPU_NODE_VIDEO2)
801 {
802 MOS_OS_CHK_STATUS_RETURN(SwitchContext(VdboxDecodeVirtualNode0Func, scalabilityOption, scalabilityState));
803 }
804 else
805 {
806 // if only decoders are working, reassign decoder to different virtual node compared to latest used virtual node
807 MOS_GPU_NODE decoderNode = m_osInterface->pfnGetLatestVirtualNode(m_osInterface, COMPONENT_Decode);
808 if (decoderNode == MOS_GPU_NODE_VIDEO)
809 {
810 MOS_OS_CHK_STATUS_RETURN(SwitchContext(VdboxDecodeVirtualNode1Func, scalabilityOption, scalabilityState));
811 }
812 else if (decoderNode == MOS_GPU_NODE_VIDEO2)
813 {
814 MOS_OS_CHK_STATUS_RETURN(SwitchContext(VdboxDecodeVirtualNode0Func, scalabilityOption, scalabilityState));
815 }
816 else
817 {
818 MOS_OS_CHK_STATUS_RETURN(SwitchContext(VdboxDecodeFunc, scalabilityOption, scalabilityState));
819 }
820 }
821 }
822 else
823 {
824 // for remaining frames, don't change virtual node assignment
825 MOS_GPU_NODE decoderNode = m_osInterface->pfnGetDecoderVirtualNodePerStream(m_osInterface);
826 if (decoderNode == MOS_GPU_NODE_VIDEO)
827 {
828 MOS_OS_CHK_STATUS_RETURN(SwitchContext(VdboxDecodeVirtualNode0Func, scalabilityOption, scalabilityState));
829 }
830 else if (decoderNode == MOS_GPU_NODE_VIDEO2)
831 {
832 MOS_OS_CHK_STATUS_RETURN(SwitchContext(VdboxDecodeVirtualNode1Func, scalabilityOption, scalabilityState));
833 }
834 else
835 {
836 MOS_OS_CHK_STATUS_RETURN(SwitchContext(VdboxDecodeFunc, scalabilityOption, scalabilityState));
837 }
838 }
839
840 return MOS_STATUS_SUCCESS;
841 }
842