1 /*
2 * Copyright (c) 2020-2023, 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     vp_scalability_multipipe.cpp
25 //! \brief    Defines the common interface for vp scalability multipipe mode.
26 //!
27 
28 #include "vp_scalability_multipipe.h"
29 #include "mos_os_virtualengine_scalability.h"
30 #include "media_context.h"
31 #include "media_status_report.h"
32 #include "mhw_utilities.h"
33 #include "mhw_mi_cmdpar.h"
34 
35 namespace vp
36 {
VpScalabilityMultiPipe(void * hwInterface,MediaContext * mediaContext,uint8_t componentType)37 VpScalabilityMultiPipe::VpScalabilityMultiPipe(void *hwInterface, MediaContext *mediaContext, uint8_t componentType)
38     : VpScalabilityMultiPipeNext(hwInterface, mediaContext, componentType)
39 {
40 }
41 
~VpScalabilityMultiPipe()42 VpScalabilityMultiPipe::~VpScalabilityMultiPipe()
43 {
44 
45 }
46 
Destroy()47 MOS_STATUS VpScalabilityMultiPipe::Destroy()
48 {
49     VP_FUNC_CALL();
50 
51     SCALABILITY_FUNCTION_ENTER;
52 
53     SCALABILITY_CHK_STATUS_RETURN(VpScalabilityMultiPipeNext::Destroy());
54 
55     if (m_veInterface)
56     {
57         if (m_veInterface->pfnVEDestroy)
58         {
59             m_veInterface->pfnVEDestroy(m_veInterface);
60         }
61         MOS_FreeMemAndSetNull(m_veInterface);
62     }
63     else
64     {
65         if (!m_osInterface->apoMosEnabled)
66         {
67             // For VE not enabled/supported case, such as vp vebox on some platform, m_veInterface is nullptr.
68             // MOS_STATUS_SUCCESS should be returned for such case.
69             if (MOS_VE_SUPPORTED(m_osInterface))
70             {
71                 SCALABILITY_CHK_NULL_RETURN(m_veInterface);
72             }
73         }
74     }
75 
76     return MOS_STATUS_SUCCESS;
77 }
78 
Initialize(const MediaScalabilityOption & option)79 MOS_STATUS VpScalabilityMultiPipe::Initialize(const MediaScalabilityOption &option)
80 {
81     VP_FUNC_CALL();
82 
83     SCALABILITY_FUNCTION_ENTER;
84 
85     SCALABILITY_CHK_NULL_RETURN(m_hwInterface);
86 
87     m_osInterface = m_hwInterface->m_osInterface;
88     SCALABILITY_CHK_NULL_RETURN(m_osInterface);
89     SCALABILITY_CHK_NULL_RETURN(m_hwInterface->m_vpPlatformInterface);
90     m_miItf = m_hwInterface->m_vpPlatformInterface->GetMhwMiItf();
91 
92     VpScalabilityOption *vpScalabilityOption = MOS_New(VpScalabilityOption, (const VpScalabilityOption &)option);
93     SCALABILITY_CHK_NULL_RETURN(vpScalabilityOption);
94     m_scalabilityOption = vpScalabilityOption;
95 
96     m_frameTrackingEnabled = m_osInterface->bEnableKmdMediaFrameTracking ? true : false;
97 
98     //virtual engine init with scalability
99     MOS_VIRTUALENGINE_INIT_PARAMS veInitParms;
100     MOS_ZeroMemory(&veInitParms, sizeof(veInitParms));
101     veInitParms.bScalabilitySupported          = true;
102     veInitParms.ucNumOfSdryCmdBufSets          = m_maxCmdBufferSetsNum;
103     veInitParms.ucMaxNumPipesInUse             = vpScalabilityOption->GetMaxMultiPipeNum();
104     veInitParms.ucMaxNumOfSdryCmdBufInOneFrame = veInitParms.ucMaxNumPipesInUse;
105 
106     if (m_osInterface->apoMosEnabled)
107     {
108         SCALABILITY_CHK_NULL_RETURN(m_osInterface->osStreamState);
109         m_osInterface->osStreamState->component = COMPONENT_VPCommon;
110         SCALABILITY_CHK_STATUS_RETURN(m_osInterface->pfnVirtualEngineInit(m_osInterface, &m_veHitParams, veInitParms));
111         m_veState = m_osInterface->osStreamState->virtualEngineInterface;
112         SCALABILITY_CHK_NULL_RETURN(m_veState);
113         SCALABILITY_CHK_NULL_RETURN(m_veHitParams);
114     }
115     else
116     {
117         SCALABILITY_CHK_STATUS_RETURN(m_osInterface->pfnVirtualEngineInit(m_osInterface, &m_veHitParams, veInitParms));
118         m_veInterface = m_osInterface->pVEInterf;
119         SCALABILITY_CHK_NULL_RETURN(m_veInterface);
120         if (m_veInterface->pfnVEGetHintParams != nullptr)
121         {
122             SCALABILITY_CHK_NULL_RETURN(m_veHitParams);
123         }
124     }
125     m_pipeNum            = m_scalabilityOption->GetNumPipe();
126     m_pipeIndexForSubmit = m_pipeNum;
127 
128     PMOS_GPUCTX_CREATOPTIONS_ENHANCED gpuCtxCreateOption = MOS_New(MOS_GPUCTX_CREATOPTIONS_ENHANCED);
129     SCALABILITY_CHK_NULL_RETURN(gpuCtxCreateOption);
130     gpuCtxCreateOption->LRCACount = vpScalabilityOption->GetLRCACount();
131     gpuCtxCreateOption->UsingSFC  = vpScalabilityOption->IsUsingSFC();
132 
133 #if (_DEBUG || _RELEASE_INTERNAL)
134     if (m_osInterface->bEnableDbgOvrdInVE)
135     {
136         if (m_osInterface->apoMosEnabled)
137         {
138             for (uint32_t i = 0; i < m_osInterface->pfnGetVeEngineCount(m_osInterface->osStreamState); i++)
139             {
140                 gpuCtxCreateOption->EngineInstance[i] =
141                     m_osInterface->pfnGetEngineLogicIdByIdx(m_osInterface->osStreamState, i);
142             }
143         }
144         else
145         {
146             for (uint32_t i = 0; i < m_veInterface->ucEngineCount; i++)
147             {
148                 gpuCtxCreateOption->EngineInstance[i] = m_veInterface->EngineLogicId[i];
149             }
150         }
151     }
152 #endif
153     m_gpuCtxCreateOption = (PMOS_GPUCTX_CREATOPTIONS)(gpuCtxCreateOption);
154 
155     //Allocate and init for semaphores
156     SCALABILITY_CHK_STATUS_RETURN(AllocateSemaphore());
157     return MOS_STATUS_SUCCESS;
158 }
159 
160 //!
161 //! \brief    Send hw semphore wait cmd
162 //! \details  Send hw semphore wait cmd for sync perpose
163 //!
164 //! \param    [in] semaMem
165 //!           Reource of Hw semphore
166 //! \param    [in] offset
167 //!           offset of semMem
168 //! \param    [in] semaData
169 //!           Data of Hw semphore
170 //! \param    [in] opCode
171 //!           Operation code
172 //! \param    [in,out] cmdBuffer
173 //!           command buffer
174 //!
175 //! \return   MOS_STATUS
176 //!           MOS_STATUS_SUCCESS if success, else fail reason
177 //!
SendHwSemaphoreWaitCmd(PMOS_RESOURCE semaMem,uint32_t offset,uint32_t semaData,MHW_COMMON_MI_SEMAPHORE_COMPARE_OPERATION opCode,PMOS_COMMAND_BUFFER cmdBuffer)178 MOS_STATUS VpScalabilityMultiPipe::SendHwSemaphoreWaitCmd(
179     PMOS_RESOURCE                             semaMem,
180     uint32_t                                  offset,
181     uint32_t                                  semaData,
182     MHW_COMMON_MI_SEMAPHORE_COMPARE_OPERATION opCode,
183     PMOS_COMMAND_BUFFER                       cmdBuffer)
184 {
185     VP_FUNC_CALL();
186 
187     MOS_STATUS                   eStatus = MOS_STATUS_SUCCESS;
188     PMHW_MI_INTERFACE            pMhwMiInterface;
189     MHW_MI_SEMAPHORE_WAIT_PARAMS miSemaphoreWaitParams;
190 
191     MHW_CHK_NULL(m_hwInterface);
192     MHW_CHK_NULL(m_hwInterface->m_mhwMiInterface);
193 
194     pMhwMiInterface = m_hwInterface->m_mhwMiInterface;
195 
196     if (m_miItf)
197     {
198         auto &params             = m_miItf->MHW_GETPAR_F(MI_SEMAPHORE_WAIT)();
199         params                   = {};
200         params.presSemaphoreMem = semaMem;
201         params.dwResourceOffset = offset;
202         params.bPollingWaitMode = true;
203         params.dwSemaphoreData  = semaData;
204         params.CompareOperation = (mhw::mi::MHW_COMMON_MI_SEMAPHORE_COMPARE_OPERATION) opCode;
205         eStatus                 = m_miItf->MHW_ADDCMD_F(MI_SEMAPHORE_WAIT)(cmdBuffer);
206     }
207     else
208     {
209         MOS_ZeroMemory((&miSemaphoreWaitParams), sizeof(miSemaphoreWaitParams));
210         miSemaphoreWaitParams.presSemaphoreMem = semaMem;
211         miSemaphoreWaitParams.dwResourceOffset = offset;
212         miSemaphoreWaitParams.bPollingWaitMode = true;
213         miSemaphoreWaitParams.dwSemaphoreData  = semaData;
214         miSemaphoreWaitParams.CompareOperation = opCode;
215         eStatus                                = pMhwMiInterface->AddMiSemaphoreWaitCmd(cmdBuffer, &miSemaphoreWaitParams);
216     }
217 
218 finish:
219     return eStatus;
220 }
221 
222 //!
223 //! \brief    Send mi atomic dword cmd
224 //! \details  Send mi atomic dword cmd for sync perpose
225 //!
226 //! \param    [in] resource
227 //!           Reource used in mi atomic dword cmd
228 //! \param    [in] offset
229 //!           offset of resource
230 //! \param    [in] immData
231 //!           Immediate data
232 //! \param    [in] opCode
233 //!           Operation code
234 //! \param    [in,out] cmdBuffer
235 //!           command buffer
236 //!
237 //! \return   MOS_STATUS
238 //!           MOS_STATUS_SUCCESS if success, else fail reason
239 //!
SendMiAtomicDwordCmd(PMOS_RESOURCE resource,uint32_t offset,uint32_t immData,MHW_COMMON_MI_ATOMIC_OPCODE opCode,PMOS_COMMAND_BUFFER cmdBuffer)240 MOS_STATUS VpScalabilityMultiPipe::SendMiAtomicDwordCmd(
241     PMOS_RESOURCE               resource,
242     uint32_t                    offset,
243     uint32_t                    immData,
244     MHW_COMMON_MI_ATOMIC_OPCODE opCode,
245     PMOS_COMMAND_BUFFER         cmdBuffer)
246 {
247     VP_FUNC_CALL();
248 
249     MOS_STATUS           eStatus = MOS_STATUS_SUCCESS;
250     PMHW_MI_INTERFACE    pMhwMiInterface;
251     MHW_MI_ATOMIC_PARAMS atomicParams;
252 
253     VP_RENDER_CHK_NULL_RETURN(m_hwInterface);
254     VP_RENDER_CHK_NULL_RETURN(m_hwInterface->m_mhwMiInterface);
255 
256     pMhwMiInterface = m_hwInterface->m_mhwMiInterface;
257 
258     if (m_miItf)
259     {
260         auto &params             = m_miItf->MHW_GETPAR_F(MI_ATOMIC)();
261         params                   = {};
262         params.pOsResource       = resource;
263         params.dwResourceOffset  = offset;
264         params.dwDataSize        = sizeof(uint32_t);
265         params.Operation         = (mhw::mi::MHW_COMMON_MI_ATOMIC_OPCODE) opCode;
266         params.bInlineData       = true;
267         params.dwOperand1Data[0] = immData;
268         eStatus                  = m_miItf->MHW_ADDCMD_F(MI_ATOMIC)(cmdBuffer);
269     }
270     else
271     {
272         MOS_ZeroMemory((&atomicParams), sizeof(atomicParams));
273         atomicParams.pOsResource       = resource;
274         atomicParams.dwResourceOffset  = offset;
275         atomicParams.dwDataSize        = sizeof(uint32_t);
276         atomicParams.Operation         = opCode;
277         atomicParams.bInlineData       = true;
278         atomicParams.dwOperand1Data[0] = immData;
279         eStatus = pMhwMiInterface->AddMiAtomicCmd(cmdBuffer, &atomicParams);
280     }
281 
282     return eStatus;
283 }
284 
285 //!
286 //! \brief    Send mi flush dword cmd
287 //! \details  Send mi flush dword cmd for sync perpose
288 //!
289 //! \param    [in] semMem
290 //!           Reource used in mi flush dword cmd
291 //! \param    [in] semaData
292 //!           Immediate data
293 //! \param    [in,out] cmdBuffer
294 //!           command buffer
295 //!
296 //! \return   MOS_STATUS
297 //!           MOS_STATUS_SUCCESS if success, else fail reason
298 //!
AddMiFlushDwCmd(PMOS_RESOURCE semaMem,uint32_t semaData,PMOS_COMMAND_BUFFER cmdBuffer)299 MOS_STATUS VpScalabilityMultiPipe::AddMiFlushDwCmd(
300     PMOS_RESOURCE                             semaMem,
301     uint32_t                                  semaData,
302     PMOS_COMMAND_BUFFER                       cmdBuffer)
303 {
304     MOS_STATUS           eStatus = MOS_STATUS_SUCCESS;
305     PMHW_MI_INTERFACE    pMhwMiInterface;
306     MHW_MI_ATOMIC_PARAMS atomicParams;
307 
308     VP_RENDER_CHK_NULL_RETURN(m_hwInterface);
309     VP_RENDER_CHK_NULL_RETURN(m_hwInterface->m_mhwMiInterface);
310 
311     pMhwMiInterface = m_hwInterface->m_mhwMiInterface;
312 
313     // Send MI_FLUSH command
314     if (m_miItf)
315     {
316         auto& parFlush = m_miItf->MHW_GETPAR_F(MI_FLUSH_DW)();
317         parFlush = {};
318         parFlush.bVideoPipelineCacheInvalidate = true;
319         if (!Mos_ResourceIsNull(semaMem))
320         {
321             parFlush.pOsResource = semaMem;
322             parFlush.dwDataDW1   = semaData + 1;
323         }
324         SCALABILITY_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_FLUSH_DW)(cmdBuffer));
325     }
326     else
327     {
328         MHW_MI_FLUSH_DW_PARAMS flushDwParams;
329         MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
330         flushDwParams.bVideoPipelineCacheInvalidate = true;
331         if (!Mos_ResourceIsNull(semaMem))
332         {
333             flushDwParams.pOsResource = semaMem;
334             flushDwParams.dwDataDW1   = semaData + 1;
335         }
336         SCALABILITY_CHK_STATUS_RETURN(pMhwMiInterface->AddMiFlushDwCmd(cmdBuffer, &flushDwParams));
337     }
338 
339     return eStatus;
340 }
341 
342 //!
343 //! \brief    Send mi store data dword cmd
344 //! \details  Send mi store dat dword cmd for sync perpose
345 //!
346 //! \param    [in] resource
347 //!           Reource used in mi store dat dword cmd
348 //! \param    [in] offset
349 //!           offset of resource
350 //! \param    [in,out] cmdBuffer
351 //!           command buffer
352 //!
353 //! \return   MOS_STATUS
354 //!           MOS_STATUS_SUCCESS if success, else fail reason
355 //!
AddMiStoreDataImmCmd(PMOS_RESOURCE resource,uint32_t offset,PMOS_COMMAND_BUFFER cmdBuffer)356 MOS_STATUS VpScalabilityMultiPipe::AddMiStoreDataImmCmd(
357     PMOS_RESOURCE               resource,
358     uint32_t                    offset,
359     PMOS_COMMAND_BUFFER         cmdBuffer)
360 {
361     VP_FUNC_CALL();
362 
363     MOS_STATUS           eStatus = MOS_STATUS_SUCCESS;
364     PMHW_MI_INTERFACE    pMhwMiInterface;
365     MHW_MI_ATOMIC_PARAMS atomicParams;
366 
367     VP_RENDER_CHK_NULL_RETURN(m_hwInterface);
368     VP_RENDER_CHK_NULL_RETURN(m_hwInterface->m_mhwMiInterface);
369 
370     pMhwMiInterface = m_hwInterface->m_mhwMiInterface;
371 
372     if (m_miItf)
373     {
374         auto &params             = m_miItf->MHW_GETPAR_F(MI_STORE_DATA_IMM)();
375         params                   = {};
376         params.pOsResource       = resource;
377         params.dwResourceOffset  = offset;
378         params.dwValue           = 0;
379         eStatus                  = m_miItf->MHW_ADDCMD_F(MI_STORE_DATA_IMM)(cmdBuffer);
380     }
381     else
382     {
383         MHW_MI_STORE_DATA_PARAMS dataParams = {};
384         dataParams.pOsResource      = resource;
385         dataParams.dwResourceOffset = offset;
386         dataParams.dwValue          = 0;
387 
388         // Reset current pipe semaphore
389         SCALABILITY_CHK_STATUS_RETURN(pMhwMiInterface->AddMiStoreDataImmCmd(
390             cmdBuffer, &dataParams));
391     }
392 
393     return eStatus;
394 }
395 
GetCmdBuffer(PMOS_COMMAND_BUFFER cmdBuffer,bool frameTrackingRequested)396 MOS_STATUS VpScalabilityMultiPipe::GetCmdBuffer(PMOS_COMMAND_BUFFER cmdBuffer, bool frameTrackingRequested)
397 {
398     VP_FUNC_CALL();
399 
400     MOS_STATUS          eStatus = MOS_STATUS_SUCCESS;
401     PMOS_COMMAND_BUFFER scdryCmdBuffer;
402 
403     SCALABILITY_FUNCTION_ENTER;
404     SCALABILITY_CHK_NULL_RETURN(cmdBuffer);
405     SCALABILITY_CHK_NULL_RETURN(m_osInterface);
406 
407     if (m_currentPipe >= m_pipeNum)
408     {
409         eStatus = MOS_STATUS_INVALID_PARAMETER;
410         SCALABILITY_ASSERTMESSAGE("Verify Command buffer failed with invalid parameter:currentPipe!");
411         return eStatus;
412     }
413 
414     // Get primary cmd buffer
415     if (Mos_ResourceIsNull(&m_primaryCmdBuffer.OsResource))
416     {
417         SCALABILITY_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &m_primaryCmdBuffer, 0));
418     }
419 
420     // Get Secondary cmd buffer
421     uint32_t bufIdx      = m_currentPipe;  //Make CMD buffer one next to one.
422     uint32_t bufIdxPlus1 = bufIdx + 1;
423 
424     if (Mos_ResourceIsNull(&m_secondaryCmdBuffers[bufIdx].OsResource))
425     {
426         m_osInterface->pfnGetCommandBuffer(m_osInterface, &m_secondaryCmdBuffers[bufIdx], bufIdxPlus1);
427     }
428 
429     if (m_osInterface->apoMosEnabled)
430     {
431         int32_t submissionType = IsFirstPipe() ? SUBMISSION_TYPE_MULTI_PIPE_MASTER : SUBMISSION_TYPE_MULTI_PIPE_SLAVE;
432         if (IsLastPipe())
433         {
434             submissionType |= SUBMISSION_TYPE_MULTI_PIPE_FLAGS_LAST_PIPE;
435         }
436         SCALABILITY_CHK_NULL_RETURN(m_osInterface->osStreamState);
437         SCALABILITY_CHK_NULL_RETURN(m_osInterface->osStreamState->virtualEngineInterface);
438         SCALABILITY_CHK_STATUS_RETURN(m_osInterface->osStreamState->virtualEngineInterface->SetSubmissionType(&(m_secondaryCmdBuffers[bufIdx]), submissionType));
439     }
440     else
441     {
442         m_secondaryCmdBuffers[bufIdx].iSubmissionType =
443             IsFirstPipe() ? SUBMISSION_TYPE_MULTI_PIPE_MASTER : SUBMISSION_TYPE_MULTI_PIPE_SLAVE;
444 
445         if (IsLastPipe())
446         {
447             m_secondaryCmdBuffers[bufIdx].iSubmissionType |= SUBMISSION_TYPE_MULTI_PIPE_FLAGS_LAST_PIPE;
448         }
449     }
450 
451     *cmdBuffer                            = m_secondaryCmdBuffers[bufIdx];
452     m_secondaryCmdBuffersReturned[bufIdx] = false;
453 
454     SCALABILITY_CHK_NULL_RETURN(m_hwInterface);
455 
456     if (!m_attrReady)
457     {
458         SCALABILITY_CHK_STATUS_RETURN(SendAttrWithFrameTracking(m_primaryCmdBuffer, frameTrackingRequested));
459         m_attrReady = true;
460     }
461 
462     return eStatus;
463 }
464 
SetHintParams()465 MOS_STATUS VpScalabilityMultiPipe::SetHintParams()
466 {
467     VP_FUNC_CALL();
468 
469     SCALABILITY_FUNCTION_ENTER;
470     SCALABILITY_CHK_NULL_RETURN(m_osInterface);
471     if (m_osInterface->apoMosEnabled)
472     {
473         SCALABILITY_CHK_NULL_RETURN(m_osInterface->osStreamState);
474     }
475     else
476     {
477         SCALABILITY_CHK_NULL_RETURN(m_veInterface);
478     }
479 
480     VpScalabilityOption *vpScalabilityOption = dynamic_cast<VpScalabilityOption *>(m_scalabilityOption);
481     SCALABILITY_CHK_NULL_RETURN(vpScalabilityOption);
482 
483     MOS_VIRTUALENGINE_SET_PARAMS veParams;
484     MOS_ZeroMemory(&veParams, sizeof(veParams));
485 
486     veParams.ucScalablePipeNum = m_pipeNum;
487     veParams.bScalableMode     = true;
488 
489     SCALABILITY_CHK_STATUS_RETURN(m_osInterface->pfnSetHintParams(m_osInterface, &veParams));
490 
491     return MOS_STATUS_SUCCESS;
492 }
493 
SubmitCmdBuffer(PMOS_COMMAND_BUFFER cmdBuffer)494 MOS_STATUS VpScalabilityMultiPipe::SubmitCmdBuffer(PMOS_COMMAND_BUFFER cmdBuffer)
495 {
496     VP_FUNC_CALL();
497 
498     SCALABILITY_FUNCTION_ENTER;
499     SCALABILITY_CHK_NULL_RETURN(m_osInterface);
500 
501     m_attrReady = false;
502 
503     if (m_osInterface->apoMosEnabled || (m_veInterface && m_veInterface->pfnVESetHintParams != nullptr))
504     {
505         SCALABILITY_CHK_STATUS_RETURN(SetHintParams());
506         SCALABILITY_CHK_STATUS_RETURN(PopulateHintParams(&m_primaryCmdBuffer));
507     }
508 
509 #if MOS_COMMAND_BUFFER_DUMP_SUPPORTED
510     if (m_osInterface->bDumpCommandBuffer)
511     {
512         for (uint32_t i = 0; i < m_pipeNum; i++)
513         {
514             SCALABILITY_CHK_STATUS_RETURN(m_osInterface->pfnDumpCommandBuffer(m_osInterface, &m_secondaryCmdBuffers[i]));
515         }
516     }
517 #endif  // MOS_COMMAND_BUFFER_DUMP_SUPPORTED
518 
519     SCALABILITY_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &m_primaryCmdBuffer, false));
520 
521     MOS_ZeroMemory(&m_primaryCmdBuffer.OsResource, sizeof(m_primaryCmdBuffer.OsResource));
522     for (uint32_t i = 0; i < m_pipeNum; i++)
523     {
524         MOS_ZeroMemory(&m_secondaryCmdBuffers[i].OsResource, sizeof(m_secondaryCmdBuffers[i].OsResource));
525     }
526 
527     return MOS_STATUS_SUCCESS;
528 }
529 
CreateMultiPipe(void * hwInterface,MediaContext * mediaContext,uint8_t componentType)530 MOS_STATUS VpScalabilityMultiPipe::CreateMultiPipe(void *hwInterface, MediaContext *mediaContext, uint8_t componentType)
531 {
532     SCALABILITY_CHK_NULL_RETURN(hwInterface);
533     SCALABILITY_CHK_NULL_RETURN(mediaContext);
534 
535     ((PVP_MHWINTERFACE)hwInterface)->m_multiPipeScalability = MOS_New(VpScalabilityMultiPipe, hwInterface, mediaContext, scalabilityVp);
536     SCALABILITY_CHK_NULL_RETURN(((PVP_MHWINTERFACE)hwInterface)->m_multiPipeScalability);
537     return MOS_STATUS_SUCCESS;
538 }
539 }
540