1 /*
2 * Copyright (c) 2022, 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 decode_scalability_multipipe_next.cpp
25 //! \brief Defines the common interface for decode scalability multipipe mode.
26 //!
27
28 #include "decode_scalability_multipipe_next.h"
29
30 #include "media_context.h"
31 #include "media_status_report.h"
32 #include "mhw_utilities.h"
33 #include "decode_status_report_defs.h"
34 #include "mos_interface.h"
35 #include "mos_os_virtualengine_next.h"
36
37 namespace decode
38 {
DecodeScalabilityMultiPipeNext(void * hwInterface,MediaContext * mediaContext,uint8_t componentType)39 DecodeScalabilityMultiPipeNext::DecodeScalabilityMultiPipeNext(void *hwInterface, MediaContext *mediaContext, uint8_t componentType)
40 : MediaScalabilityMultiPipe(mediaContext)
41 {
42 m_hwInterface = (CodechalHwInterfaceNext *)hwInterface;
43 m_componentType = componentType;
44 m_secondaryCmdBuffers.clear();
45 m_resSemaphoreAllPipes.clear();
46 m_resSemaphoreOnePipeWait.clear();
47 }
48
~DecodeScalabilityMultiPipeNext()49 DecodeScalabilityMultiPipeNext::~DecodeScalabilityMultiPipeNext()
50 {
51 }
52
AllocateSemaphore()53 MOS_STATUS DecodeScalabilityMultiPipeNext::AllocateSemaphore()
54 {
55 SCALABILITY_FUNCTION_ENTER;
56 SCALABILITY_CHK_NULL_RETURN(m_osInterface);
57
58 m_secondaryCmdBuffers.resize(m_initSecondaryCmdBufNum);
59
60 MOS_LOCK_PARAMS lockFlagsWriteOnly;
61 MOS_ZeroMemory(&lockFlagsWriteOnly, sizeof(MOS_LOCK_PARAMS));
62 lockFlagsWriteOnly.WriteOnly = 1;
63 MOS_ALLOC_GFXRES_PARAMS allocParamsForBufferLinear;
64 MOS_ZeroMemory(&allocParamsForBufferLinear, sizeof(MOS_ALLOC_GFXRES_PARAMS));
65 allocParamsForBufferLinear.TileType = MOS_TILE_LINEAR;
66 allocParamsForBufferLinear.Format = Format_Buffer;
67 allocParamsForBufferLinear.Type = MOS_GFXRES_BUFFER;
68 allocParamsForBufferLinear.dwBytes = sizeof(uint32_t);
69 allocParamsForBufferLinear.pBufName = "Sync All Pipes SemaphoreMemory";
70
71 m_resSemaphoreAllPipes.resize(m_maxCmdBufferSetsNum);
72 for (auto &semaphoreBufferVec : m_resSemaphoreAllPipes)
73 {
74 semaphoreBufferVec.resize(m_scalabilityOption->GetNumPipe());
75 for (auto &semaphoreBuffer : semaphoreBufferVec)
76 {
77 memset(&semaphoreBuffer, 0, sizeof(MOS_RESOURCE));
78 SCALABILITY_CHK_STATUS_MESSAGE_RETURN(m_osInterface->pfnAllocateResource(
79 m_osInterface,
80 &allocParamsForBufferLinear,
81 &semaphoreBuffer),
82 "Cannot create HW semaphore for scalability all pipes sync.");
83 uint32_t *data = (uint32_t *)m_osInterface->pfnLockResource(
84 m_osInterface,
85 &semaphoreBuffer,
86 &lockFlagsWriteOnly);
87 SCALABILITY_CHK_NULL_RETURN(data);
88 *data = 0;
89 SCALABILITY_CHK_STATUS_RETURN(m_osInterface->pfnUnlockResource(
90 m_osInterface,
91 &semaphoreBuffer));
92 }
93 }
94
95 allocParamsForBufferLinear.pBufName = "Sync One Pipe Wait SemaphoreMemory";
96 m_resSemaphoreOnePipeWait.resize(m_maxCmdBufferSetsNum);
97 for (auto &semaphoreBufferVec : m_resSemaphoreOnePipeWait)
98 {
99 semaphoreBufferVec.resize(m_scalabilityOption->GetNumPipe());
100 for (auto &semaphoreBuffer : semaphoreBufferVec)
101 {
102 memset(&semaphoreBuffer, 0, sizeof(MOS_RESOURCE));
103 SCALABILITY_CHK_STATUS_MESSAGE_RETURN(m_osInterface->pfnAllocateResource(
104 m_osInterface,
105 &allocParamsForBufferLinear,
106 &semaphoreBuffer),
107 "Cannot create HW semaphore for scalability one pipe sync.");
108 uint32_t *data = (uint32_t *)m_osInterface->pfnLockResource(
109 m_osInterface,
110 &semaphoreBuffer,
111 &lockFlagsWriteOnly);
112 SCALABILITY_CHK_NULL_RETURN(data);
113 *data = 0;
114 SCALABILITY_CHK_STATUS_RETURN(m_osInterface->pfnUnlockResource(
115 m_osInterface,
116 &semaphoreBuffer));
117 }
118 }
119
120 m_semaphoreIndex = 0;
121
122 return MOS_STATUS_SUCCESS;
123 }
124
Initialize(const MediaScalabilityOption & option)125 MOS_STATUS DecodeScalabilityMultiPipeNext::Initialize(const MediaScalabilityOption &option)
126 {
127 SCALABILITY_FUNCTION_ENTER;
128
129 SCALABILITY_CHK_NULL_RETURN(m_hwInterface);
130 m_osInterface = m_hwInterface->GetOsInterface();
131 SCALABILITY_CHK_NULL_RETURN(m_osInterface);
132 m_miItf = m_hwInterface->GetMiInterfaceNext();
133 SCALABILITY_CHK_NULL_RETURN(m_miItf);
134
135 DecodeScalabilityOption *decodeScalabilityOption = MOS_New(DecodeScalabilityOption, (const DecodeScalabilityOption &)option);
136 SCALABILITY_CHK_NULL_RETURN(decodeScalabilityOption);
137 m_scalabilityOption = decodeScalabilityOption;
138
139 m_frameTrackingEnabled = m_osInterface->bEnableKmdMediaFrameTracking ? true : false;
140 //virtual engine init with scalability
141 MOS_VIRTUALENGINE_INIT_PARAMS veInitParms;
142 MOS_ZeroMemory(&veInitParms, sizeof(veInitParms));
143 veInitParms.bScalabilitySupported = true;
144 veInitParms.bFESeparateSubmit = decodeScalabilityOption->IsFESeparateSubmission();
145 veInitParms.ucMaxNumPipesInUse = decodeScalabilityOption->GetMaxMultiPipeNum();
146 veInitParms.ucNumOfSdryCmdBufSets = m_maxCmdBufferSetsNum;
147 veInitParms.ucMaxNumOfSdryCmdBufInOneFrame = decodeScalabilityOption->IsFESeparateSubmission() ?
148 veInitParms.ucMaxNumPipesInUse : (veInitParms.ucMaxNumPipesInUse + 1);
149 if (MOS_VE_SUPPORTED(m_osInterface))
150 {
151 MOS_STATUS status = m_osInterface->pfnVirtualEngineInit(m_osInterface, &m_veHitParams, veInitParms);
152 SCALABILITY_CHK_STATUS_MESSAGE_RETURN(status, "Virtual Engine Init failed");
153 m_veInterface = m_osInterface->pVEInterf;
154 if (m_osInterface->osStreamState && m_osInterface->osStreamState->virtualEngineInterface)
155 {
156 // we set m_veState here when pOsInterface->apoMosEnabled is true
157 m_veState = m_osInterface->osStreamState->virtualEngineInterface;
158 }
159 }
160
161 m_pipeNum = m_scalabilityOption->GetNumPipe();
162 m_pipeIndexForSubmit = m_pipeNum;
163
164 PMOS_GPUCTX_CREATOPTIONS_ENHANCED gpuCtxCreateOption = MOS_New(MOS_GPUCTX_CREATOPTIONS_ENHANCED);
165 SCALABILITY_CHK_NULL_RETURN(gpuCtxCreateOption);
166 gpuCtxCreateOption->LRCACount = decodeScalabilityOption->GetLRCACount();
167 gpuCtxCreateOption->UsingSFC = decodeScalabilityOption->IsUsingSFC();
168 if (decodeScalabilityOption->IsUsingSlimVdbox())
169 {
170 gpuCtxCreateOption->Flags |= (1 << 2);
171 }
172 #if (_DEBUG || _RELEASE_INTERNAL)
173 if (m_osInterface->bEnableDbgOvrdInVE)
174 {
175 gpuCtxCreateOption->DebugOverride = true;
176 uint8_t engineLogicId = 0;
177 if (m_osInterface->pfnGetEngineLogicId(m_osInterface, engineLogicId) == MOS_STATUS_SUCCESS)
178 {
179 gpuCtxCreateOption->EngineInstance[0] = engineLogicId;
180 }
181 }
182 #endif
183 m_gpuCtxCreateOption = (PMOS_GPUCTX_CREATOPTIONS)(gpuCtxCreateOption);
184
185 //Allocate and init for semaphores
186 SCALABILITY_CHK_STATUS_RETURN(AllocateSemaphore());
187 return MOS_STATUS_SUCCESS;
188 }
189
GetGpuCtxCreationOption(MOS_GPUCTX_CREATOPTIONS * gpuCtxCreateOption)190 MOS_STATUS DecodeScalabilityMultiPipeNext::GetGpuCtxCreationOption(MOS_GPUCTX_CREATOPTIONS *gpuCtxCreateOption)
191 {
192 SCALABILITY_FUNCTION_ENTER;
193 SCALABILITY_CHK_NULL_RETURN(gpuCtxCreateOption);
194 SCALABILITY_CHK_NULL_RETURN(m_gpuCtxCreateOption);
195
196 MOS_GPUCTX_CREATOPTIONS_ENHANCED *dest = dynamic_cast<MOS_GPUCTX_CREATOPTIONS_ENHANCED *>(gpuCtxCreateOption);
197 MOS_GPUCTX_CREATOPTIONS_ENHANCED *source = dynamic_cast<MOS_GPUCTX_CREATOPTIONS_ENHANCED *>(m_gpuCtxCreateOption);
198
199 SCALABILITY_CHK_NULL_RETURN(dest);
200 SCALABILITY_CHK_NULL_RETURN(source);
201
202 *dest = *source;
203 return MOS_STATUS_SUCCESS;
204 }
205
Destroy()206 MOS_STATUS DecodeScalabilityMultiPipeNext::Destroy()
207 {
208 SCALABILITY_FUNCTION_ENTER;
209
210 SCALABILITY_CHK_STATUS_RETURN(MediaScalability::Destroy());
211
212 if (m_gpuCtxCreateOption)
213 {
214 MOS_Delete(m_gpuCtxCreateOption);
215 }
216 if (m_scalabilityOption)
217 {
218 MOS_Delete(m_scalabilityOption);
219 }
220
221 m_osInterface->pfnDestroyVeInterface(&m_veInterface);
222
223 for (auto &semaphoreBufferVec : m_resSemaphoreAllPipes)
224 {
225 for (auto &semaphoreBuffer : semaphoreBufferVec)
226 {
227 m_osInterface->pfnFreeResource(m_osInterface, &semaphoreBuffer);
228 }
229 }
230 for (auto &semaphoreBufferVec : m_resSemaphoreOnePipeWait)
231 {
232 for (auto &semaphoreBuffer : semaphoreBufferVec)
233 {
234 m_osInterface->pfnFreeResource(m_osInterface, &semaphoreBuffer);
235 }
236 }
237
238 return MOS_STATUS_SUCCESS;
239 }
240
ResizeCommandBufferAndPatchList(uint32_t requestedCommandBufferSize,uint32_t requestedPatchListSize)241 MOS_STATUS DecodeScalabilityMultiPipeNext::ResizeCommandBufferAndPatchList(
242 uint32_t requestedCommandBufferSize,
243 uint32_t requestedPatchListSize)
244 {
245 SCALABILITY_FUNCTION_ENTER;
246 SCALABILITY_CHK_NULL_RETURN(m_hwInterface);
247
248 return m_hwInterface->ResizeCommandBufferAndPatchList(requestedCommandBufferSize, requestedPatchListSize);
249 }
250
VerifySpaceAvailable(uint32_t requestedSize,uint32_t requestedPatchListSize,bool & singleTaskPhaseSupportedInPak)251 MOS_STATUS DecodeScalabilityMultiPipeNext::VerifySpaceAvailable(uint32_t requestedSize, uint32_t requestedPatchListSize, bool &singleTaskPhaseSupportedInPak)
252 {
253 SCALABILITY_FUNCTION_ENTER;
254 SCALABILITY_CHK_NULL_RETURN(m_hwInterface);
255 SCALABILITY_CHK_NULL_RETURN(m_osInterface);
256
257 uint8_t looptimes = 3;
258 for(auto i = 0 ; i < looptimes ; i++)
259 {
260 bool bothPatchListAndCmdBufChkSuccess = false;
261 SCALABILITY_CHK_STATUS_RETURN(MediaScalability::VerifySpaceAvailable(
262 requestedSize, requestedPatchListSize, bothPatchListAndCmdBufChkSuccess));
263 if (bothPatchListAndCmdBufChkSuccess)
264 {
265 return MOS_STATUS_SUCCESS;
266 }
267
268 MOS_STATUS statusPatchList = MOS_STATUS_SUCCESS;
269 if (requestedPatchListSize)
270 {
271 statusPatchList = (MOS_STATUS)m_osInterface->pfnVerifyPatchListSize(
272 m_osInterface,
273 requestedPatchListSize);
274 }
275
276 MOS_STATUS statusCmdBuf = (MOS_STATUS)m_osInterface->pfnVerifyCommandBufferSize(
277 m_osInterface,
278 requestedSize,
279 0);
280
281 if (statusCmdBuf == MOS_STATUS_SUCCESS && statusPatchList == MOS_STATUS_SUCCESS)
282 {
283 return MOS_STATUS_SUCCESS;
284 }
285 }
286
287 SCALABILITY_ASSERTMESSAGE("Resize Command buffer failed with no space!");
288 return MOS_STATUS_NO_SPACE;
289 }
290
VerifyCmdBuffer(uint32_t requestedSize,uint32_t requestedPatchListSize,bool & singleTaskPhaseSupportedInPak)291 MOS_STATUS DecodeScalabilityMultiPipeNext::VerifyCmdBuffer(uint32_t requestedSize, uint32_t requestedPatchListSize, bool &singleTaskPhaseSupportedInPak)
292 {
293 SCALABILITY_FUNCTION_ENTER;
294 SCALABILITY_CHK_NULL_RETURN(m_hwInterface);
295 SCALABILITY_CHK_NULL_RETURN(m_osInterface);
296
297 // Verify Primary Cmd buffer.
298 SCALABILITY_CHK_STATUS_RETURN(VerifySpaceAvailable(
299 requestedSize, requestedPatchListSize, singleTaskPhaseSupportedInPak));
300
301 uint8_t looptimes = 3;
302 for (auto i = 0; i < looptimes; i++)
303 {
304 // Verify secondary cmd buffer
305 if (m_osInterface->pfnVerifyCommandBufferSize(
306 m_osInterface,
307 requestedSize,
308 MOS_VE_HAVE_SECONDARY_CMDBUFFER) == MOS_STATUS_SUCCESS)
309 {
310 return MOS_STATUS_SUCCESS;
311 }
312
313 SCALABILITY_CHK_STATUS_RETURN(m_osInterface->pfnResizeCommandBufferAndPatchList(
314 m_osInterface,
315 requestedSize,
316 0,
317 MOS_VE_HAVE_SECONDARY_CMDBUFFER));
318 }
319
320 SCALABILITY_ASSERTMESSAGE("Verify secondary command buffer failed with no space!");
321 return MOS_STATUS_NO_SPACE;
322 }
323
GetCmdBuffer(PMOS_COMMAND_BUFFER cmdBuffer,bool frameTrackingRequested)324 MOS_STATUS DecodeScalabilityMultiPipeNext::GetCmdBuffer(PMOS_COMMAND_BUFFER cmdBuffer, bool frameTrackingRequested)
325 {
326 SCALABILITY_FUNCTION_ENTER;
327 SCALABILITY_CHK_NULL_RETURN(cmdBuffer);
328 SCALABILITY_CHK_NULL_RETURN(m_osInterface);
329 SCALABILITY_CHK_NULL_RETURN(m_phase);
330
331 SCALABILITY_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &m_primaryCmdBuffer, 0));
332
333 uint32_t bufIdx = m_phase->GetCmdBufIndex();
334 SCALABILITY_ASSERT(bufIdx >= DecodePhase::m_secondaryCmdBufIdxBase);
335 uint32_t secondaryIdx = bufIdx - DecodePhase::m_secondaryCmdBufIdxBase;
336 if (secondaryIdx >= m_secondaryCmdBuffers.size())
337 {
338 m_secondaryCmdBuffers.resize(secondaryIdx + 1);
339 }
340 auto &scdryCmdBuffer = m_secondaryCmdBuffers[secondaryIdx];
341 SCALABILITY_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &scdryCmdBuffer, bufIdx));
342
343 if (m_osInterface->apoMosEnabled)
344 {
345 SCALABILITY_CHK_NULL_RETURN(m_osInterface->osStreamState);
346 SCALABILITY_CHK_NULL_RETURN(m_osInterface->osStreamState->virtualEngineInterface);
347 SCALABILITY_CHK_STATUS_RETURN(m_osInterface->osStreamState->virtualEngineInterface->SetSubmissionType(&scdryCmdBuffer, m_phase->GetSubmissionType()));
348 }
349 else
350 {
351 scdryCmdBuffer.iSubmissionType = m_phase->GetSubmissionType();
352 }
353 *cmdBuffer = scdryCmdBuffer;
354
355 if (!m_attrReady)
356 {
357 SCALABILITY_CHK_STATUS_RETURN(SendAttrWithFrameTracking(m_primaryCmdBuffer, frameTrackingRequested));
358 // Insert noop to primary command buffer, avoid zero length command buffer
359 SCALABILITY_CHK_STATUS_RETURN(m_miItf->ADDCMD_MI_NOOP(&m_primaryCmdBuffer, nullptr));
360 m_attrReady = true;
361 }
362 return MOS_STATUS_SUCCESS;
363 }
364
ReturnCmdBuffer(PMOS_COMMAND_BUFFER cmdBuffer)365 MOS_STATUS DecodeScalabilityMultiPipeNext::ReturnCmdBuffer(PMOS_COMMAND_BUFFER cmdBuffer)
366 {
367 SCALABILITY_FUNCTION_ENTER;
368 SCALABILITY_CHK_NULL_RETURN(cmdBuffer);
369 SCALABILITY_CHK_NULL_RETURN(m_osInterface);
370 SCALABILITY_CHK_NULL_RETURN(m_phase);
371
372 uint32_t bufIdx = m_phase->GetCmdBufIndex();
373 SCALABILITY_ASSERT(bufIdx >= DecodePhase::m_secondaryCmdBufIdxBase);
374 uint32_t secondaryIdx = bufIdx - DecodePhase::m_secondaryCmdBufIdxBase;
375 SCALABILITY_ASSERT(secondaryIdx < m_secondaryCmdBuffers.size());
376
377 m_secondaryCmdBuffers[secondaryIdx] = *cmdBuffer; //Need to record the iOffset, ptr and other data of CMD buffer, it's not maintain in the mos.
378 m_osInterface->pfnReturnCommandBuffer(m_osInterface, &m_secondaryCmdBuffers[secondaryIdx], bufIdx);
379 m_osInterface->pfnReturnCommandBuffer(m_osInterface, &m_primaryCmdBuffer, 0);
380 return MOS_STATUS_SUCCESS;
381 }
382
SetHintParams()383 MOS_STATUS DecodeScalabilityMultiPipeNext::SetHintParams()
384 {
385 SCALABILITY_FUNCTION_ENTER;
386 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
387 DecodeScalabilityOption *decodeScalabilityOption = dynamic_cast<DecodeScalabilityOption *>(m_scalabilityOption);
388 SCALABILITY_CHK_NULL_RETURN(decodeScalabilityOption);
389 SCALABILITY_CHK_NULL_RETURN(m_osInterface);
390
391 MOS_VIRTUALENGINE_SET_PARAMS veParams;
392 MOS_ZeroMemory(&veParams, sizeof(veParams));
393
394 veParams.ucScalablePipeNum = m_pipeNum;
395 veParams.bHaveFrontEndCmds = (decodeScalabilityOption->GetMode() == scalabilityVirtualTileMode) &&
396 (!decodeScalabilityOption->IsFESeparateSubmission());
397 veParams.bScalableMode = true;
398
399 m_osInterface->pVEInterf = m_veInterface;
400 eStatus = m_osInterface->pfnSetHintParams(m_osInterface, &veParams);
401
402 return eStatus;
403 }
404
PopulateHintParams(PMOS_COMMAND_BUFFER cmdBuffer)405 MOS_STATUS DecodeScalabilityMultiPipeNext::PopulateHintParams(PMOS_COMMAND_BUFFER cmdBuffer)
406 {
407 SCALABILITY_FUNCTION_ENTER;
408 SCALABILITY_CHK_NULL_RETURN(cmdBuffer);
409 SCALABILITY_CHK_NULL_RETURN(m_veHitParams);
410 SCALABILITY_CHK_NULL_RETURN(m_osInterface);
411
412 PMOS_CMD_BUF_ATTRI_VE attriVe = m_osInterface->pfnGetAttributeVeBuffer(cmdBuffer);
413 if (attriVe)
414 {
415 attriVe->VEngineHintParams = *(m_veHitParams);
416 attriVe->bUseVirtualEngineHint = true;
417 }
418 return MOS_STATUS_SUCCESS;
419 }
420
SubmitCmdBuffer(PMOS_COMMAND_BUFFER cmdBuffer)421 MOS_STATUS DecodeScalabilityMultiPipeNext::SubmitCmdBuffer(PMOS_COMMAND_BUFFER cmdBuffer)
422 {
423 SCALABILITY_FUNCTION_ENTER;
424 SCALABILITY_CHK_NULL_RETURN(m_osInterface);
425
426 // Hold the actual command buffer submission till pipes are ready
427 if (!IsPipeReadyToSubmit())
428 {
429 return MOS_STATUS_SUCCESS;
430 }
431
432 // Add BB end for every secondary cmd buf when ready for submit
433 for (uint32_t secondaryIdx = 0; secondaryIdx < m_pipeNum; secondaryIdx++)
434 {
435 MOS_COMMAND_BUFFER& scdryCmdBuffer = m_secondaryCmdBuffers[secondaryIdx];
436 uint32_t bufIdx = secondaryIdx + DecodePhase::m_secondaryCmdBufIdxBase;
437 SCALABILITY_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &scdryCmdBuffer, bufIdx));
438 SCALABILITY_CHK_STATUS_RETURN(m_miItf->AddMiBatchBufferEnd(&scdryCmdBuffer, nullptr));
439 m_osInterface->pfnReturnCommandBuffer(m_osInterface, &scdryCmdBuffer, bufIdx);
440 }
441
442 m_attrReady = false;
443
444 SCALABILITY_CHK_STATUS_RETURN(SetHintParams());
445 SCALABILITY_CHK_STATUS_RETURN(PopulateHintParams(&m_primaryCmdBuffer));
446
447 SCALABILITY_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &m_primaryCmdBuffer, false));
448
449 m_semaphoreIndex++;
450 if (m_semaphoreIndex >= m_maxCmdBufferSetsNum)
451 {
452 m_semaphoreIndex = 0;
453 }
454
455 return MOS_STATUS_SUCCESS;
456 }
457
SyncAllPipes(PMOS_COMMAND_BUFFER cmdBuffer)458 MOS_STATUS DecodeScalabilityMultiPipeNext::SyncAllPipes(PMOS_COMMAND_BUFFER cmdBuffer)
459 {
460 SCALABILITY_FUNCTION_ENTER;
461 SCALABILITY_CHK_NULL_RETURN(cmdBuffer);
462 SCALABILITY_CHK_NULL_RETURN(m_hwInterface);
463
464 SCALABILITY_ASSERT(m_semaphoreIndex < m_resSemaphoreAllPipes.size());
465 auto &semaphoreBufs = m_resSemaphoreAllPipes[m_semaphoreIndex];
466 SCALABILITY_ASSERT(semaphoreBufs.size() >= m_scalabilityOption->GetNumPipe());
467
468 //Not stop watch dog here, expect to stop it in the packet when needed.
469 //HW Semaphore cmd to make sure all pipes start encode at the same time
470
471 // Increment all pipe flags
472 for (uint32_t i = 0; i < m_pipeNum; i++)
473 {
474 if (!Mos_ResourceIsNull(&semaphoreBufs[i]))
475 {
476 SCALABILITY_CHK_STATUS_RETURN(m_hwInterface->SendMiAtomicDwordCmd(
477 &semaphoreBufs[i], 1, MHW_MI_ATOMIC_INC, cmdBuffer));
478 }
479 }
480
481 if (!Mos_ResourceIsNull(&semaphoreBufs[m_currentPipe]))
482 {
483 // Waiting current pipe flag euqal to pipe number which means other pipes are executing
484 SCALABILITY_CHK_STATUS_RETURN(m_hwInterface->SendHwSemaphoreWaitCmd(
485 &semaphoreBufs[m_currentPipe], m_pipeNum, MHW_MI_SAD_EQUAL_SDD, cmdBuffer));
486
487 // Reset current pipe flag for next frame
488 auto ¶ms = m_miItf->MHW_GETPAR_F(MI_STORE_DATA_IMM)();
489 params = {};
490 params.pOsResource = &semaphoreBufs[m_currentPipe];
491 params.dwResourceOffset = 0;
492 params.dwValue = 0;
493 SCALABILITY_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_STORE_DATA_IMM)(cmdBuffer));
494 }
495
496 return MOS_STATUS_SUCCESS;
497 }
498
SyncOnePipeWaitOthers(PMOS_COMMAND_BUFFER cmdBuffer,uint32_t pipeIdx)499 MOS_STATUS DecodeScalabilityMultiPipeNext::SyncOnePipeWaitOthers(PMOS_COMMAND_BUFFER cmdBuffer, uint32_t pipeIdx)
500 {
501 SCALABILITY_FUNCTION_ENTER;
502 SCALABILITY_CHK_NULL_RETURN(cmdBuffer);
503
504 SCALABILITY_ASSERT(m_semaphoreIndex < m_resSemaphoreOnePipeWait.size());
505 auto &semaphoreBufs = m_resSemaphoreOnePipeWait[m_semaphoreIndex];
506 SCALABILITY_ASSERT(semaphoreBufs.size() >= m_scalabilityOption->GetNumPipe());
507
508 // Send MI_FLUSH command
509 auto &parFlush = m_miItf->MHW_GETPAR_F(MI_FLUSH_DW)();
510 parFlush = {};
511 parFlush.bVideoPipelineCacheInvalidate = true;
512 if (!Mos_ResourceIsNull(&semaphoreBufs[m_currentPipe]))
513 {
514 parFlush.pOsResource = &semaphoreBufs[m_currentPipe];
515 parFlush.dwDataDW1 = m_currentPass + 1;
516 }
517 SCALABILITY_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_FLUSH_DW)(cmdBuffer));
518
519 if (m_currentPipe == pipeIdx)
520 {
521 // this pipe needs to ensure all other pipes are ready
522 for (uint32_t i = 0; i < m_pipeNum; i++)
523 {
524 if (!Mos_ResourceIsNull(&semaphoreBufs[i]))
525 {
526 SCALABILITY_CHK_STATUS_RETURN(m_hwInterface->SendHwSemaphoreWaitCmd(
527 &semaphoreBufs[i], m_currentPass + 1, MHW_MI_SAD_EQUAL_SDD, cmdBuffer));
528 }
529 }
530
531 // Reset all pipe flags for next frame
532 for (uint32_t i = 0; i < m_pipeNum; i++)
533 {
534 if (!Mos_ResourceIsNull(&semaphoreBufs[i]))
535 {
536 auto ¶ms = m_miItf->MHW_GETPAR_F(MI_STORE_DATA_IMM)();
537 params = {};
538 params.pOsResource = &semaphoreBufs[i];
539 params.dwResourceOffset = 0;
540 params.dwValue = 0;
541 SCALABILITY_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_STORE_DATA_IMM)(cmdBuffer));
542 }
543 }
544 }
545
546 return MOS_STATUS_SUCCESS;
547 }
548
SyncPipe(uint32_t syncType,uint32_t semaphoreId,PMOS_COMMAND_BUFFER cmdBuffer)549 MOS_STATUS DecodeScalabilityMultiPipeNext::SyncPipe(uint32_t syncType, uint32_t semaphoreId, PMOS_COMMAND_BUFFER cmdBuffer)
550 {
551 SCALABILITY_FUNCTION_ENTER;
552 if (syncType == syncAllPipes)
553 {
554 return SyncAllPipes(cmdBuffer);
555 }
556 else if (syncType == syncOnePipeWaitOthers)
557 {
558 return SyncOnePipeWaitOthers(cmdBuffer, semaphoreId);
559 }
560 else
561 {
562 return MOS_STATUS_INVALID_PARAMETER;
563 }
564 }
565
ResetSemaphore(uint32_t syncType,uint32_t semaphoreId,PMOS_COMMAND_BUFFER cmdBuffer)566 MOS_STATUS DecodeScalabilityMultiPipeNext::ResetSemaphore(uint32_t syncType, uint32_t semaphoreId, PMOS_COMMAND_BUFFER cmdBuffer)
567 {
568 SCALABILITY_FUNCTION_ENTER;
569 // Don't need to reset semaphore
570 return MOS_STATUS_SUCCESS;
571 }
572
UpdateState(void * statePars)573 MOS_STATUS DecodeScalabilityMultiPipeNext::UpdateState(void *statePars)
574 {
575 SCALABILITY_FUNCTION_ENTER;
576
577 StateParams *decodeStatePars = (StateParams *)statePars;
578 if (decodeStatePars->currentPipe >= m_pipeNum)
579 {
580 SCALABILITY_ASSERTMESSAGE("UpdateState failed with invalid parameter: currentPipe %d!",
581 decodeStatePars->currentPipe);
582 return MOS_STATUS_INVALID_PARAMETER;
583 }
584 m_currentPipe = decodeStatePars->currentPipe;
585 m_currentPass = decodeStatePars->currentPass;
586 m_pipeIndexForSubmit = decodeStatePars->pipeIndexForSubmit;
587 m_singleTaskPhaseSupported = decodeStatePars->singleTaskPhaseSupported;
588 m_statusReport = decodeStatePars->statusReport;
589 m_currentRow = decodeStatePars->currentRow;
590 m_currentSubPass = decodeStatePars->currentSubPass;
591 m_componentState = decodeStatePars->componentState;
592
593 m_phase = static_cast<DecodePhase *>(m_componentState);
594 SCALABILITY_CHK_NULL_RETURN(m_phase);
595
596 return MOS_STATUS_SUCCESS;
597 }
598
SendAttrWithFrameTracking(MOS_COMMAND_BUFFER & cmdBuffer,bool frameTrackingRequested)599 MOS_STATUS DecodeScalabilityMultiPipeNext::SendAttrWithFrameTracking(
600 MOS_COMMAND_BUFFER &cmdBuffer,
601 bool frameTrackingRequested)
602 {
603 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
604
605 SCALABILITY_FUNCTION_ENTER;
606
607 bool renderEngineUsed = m_mediaContext->IsRenderEngineUsed();
608
609 // initialize command buffer attributes
610 cmdBuffer.Attributes.bTurboMode = m_hwInterface->m_turboMode;
611 cmdBuffer.Attributes.bMediaPreemptionEnabled = renderEngineUsed ? m_hwInterface->GetRenderInterfaceNext()->IsPreemptionEnabled() : 0;
612
613 if (frameTrackingRequested && m_frameTrackingEnabled)
614 {
615 PMOS_RESOURCE resource = nullptr;
616 uint32_t offset = 0;
617 m_statusReport->GetAddress(decode::statusReportGlobalCount, resource, offset);
618
619 cmdBuffer.Attributes.bEnableMediaFrameTracking = true;
620 cmdBuffer.Attributes.resMediaFrameTrackingSurface = resource;
621 cmdBuffer.Attributes.dwMediaFrameTrackingTag = m_statusReport->GetSubmittedCount() + 1;
622 // Set media frame tracking address offset(the offset from the decode status buffer page)
623 cmdBuffer.Attributes.dwMediaFrameTrackingAddrOffset = offset;
624 }
625
626 return eStatus;
627 }
628
CreateDecodeMultiPipe(void * hwInterface,MediaContext * mediaContext,uint8_t componentType)629 MOS_STATUS DecodeScalabilityMultiPipeNext::CreateDecodeMultiPipe(void *hwInterface, MediaContext *mediaContext, uint8_t componentType)
630 {
631 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
632
633 SCALABILITY_FUNCTION_ENTER;
634 SCALABILITY_CHK_NULL_RETURN(hwInterface);
635 SCALABILITY_CHK_NULL_RETURN(mediaContext);
636
637 ((CodechalHwInterfaceNext *)hwInterface)->m_multiPipeScalability = MOS_New(DecodeScalabilityMultiPipeNext, hwInterface, mediaContext, scalabilityDecoder);
638 SCALABILITY_CHK_NULL_RETURN(((CodechalHwInterfaceNext *)hwInterface)->m_multiPipeScalability);
639 return eStatus;
640 }
641
642 }
643