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