1 /* 2 * Copyright (c) 2020-2021, Intel Corporation 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included 12 * in all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 * OTHER DEALINGS IN THE SOFTWARE. 21 */ 22 //! 23 //! \file mhw_mi_impl.h 24 //! \brief MHW MI interface common base 25 //! \details 26 //! 27 28 #ifndef __MHW_MI_IMPL_H__ 29 #define __MHW_MI_IMPL_H__ 30 31 #include "mhw_mi_itf.h" 32 #include "mhw_impl.h" 33 34 #ifdef IGFX_MI_INTERFACE_EXT_SUPPORT 35 #include "mhw_mi_impl_ext.h" 36 #endif 37 38 namespace mhw 39 { 40 namespace mi 41 { 42 static constexpr uint32_t GENERAL_PURPOSE_REGISTER0_LO_OFFSET_NODE_1_INIT = 0x1C0600; 43 static constexpr uint32_t GENERAL_PURPOSE_REGISTER0_HI_OFFSET_NODE_1_INIT = 0x1C0604; 44 static constexpr uint32_t GENERAL_PURPOSE_REGISTER4_LO_OFFSET_NODE_1_INIT = 0x1C0620; 45 static constexpr uint32_t GENERAL_PURPOSE_REGISTER4_HI_OFFSET_NODE_1_INIT = 0x1C0624; 46 static constexpr uint32_t GENERAL_PURPOSE_REGISTER11_LO_OFFSET_NODE_1_INIT = 0x1C0658; 47 static constexpr uint32_t GENERAL_PURPOSE_REGISTER11_HI_OFFSET_NODE_1_INIT = 0x1C065C; 48 static constexpr uint32_t GENERAL_PURPOSE_REGISTER12_LO_OFFSET_NODE_1_INIT = 0x1C0660; 49 static constexpr uint32_t GENERAL_PURPOSE_REGISTER12_HI_OFFSET_NODE_1_INIT = 0x1C0664; 50 51 template <typename cmd_t> 52 class Impl : public Itf, public mhw::Impl 53 { 54 _MI_CMD_DEF(_MHW_CMD_ALL_DEF_FOR_IMPL); 55 56 public: 57 58 //! \brief Indicates the global GTT setting on each engine. 59 struct 60 { 61 bool m_cs = false; //!< GGTT in use for the render engine. 62 bool m_vcs = false; //!< GGTT in use for VDBOX. 63 bool m_vecs = false; //!< GGTT in use for VEBOX. 64 } UseGlobalGtt; 65 IsGlobalGttInUse()66 bool IsGlobalGttInUse() 67 { 68 MOS_GPU_CONTEXT gpuContext = this->m_osItf->pfnGetGpuContext(this->m_osItf); 69 bool vcsEngineUsed = MOS_VCS_ENGINE_USED(gpuContext); 70 bool renderEngineUsed = MOS_RCS_ENGINE_USED(gpuContext); 71 72 bool globalGttInUse = renderEngineUsed ? UseGlobalGtt.m_cs : 73 (vcsEngineUsed ? UseGlobalGtt.m_vcs : UseGlobalGtt.m_vecs); 74 75 return globalGttInUse; 76 } 77 78 //! 79 //! \brief Helper function to compose opcode for MI_ATOMIC 80 //! \return uint32_t 81 //! Composed opcode for MI_ATOMIC or 0 82 //! CreateMiAtomicOpcode(uint32_t dataSize,MHW_COMMON_MI_ATOMIC_OPCODE opCode)83 uint32_t CreateMiAtomicOpcode( 84 uint32_t dataSize, 85 MHW_COMMON_MI_ATOMIC_OPCODE opCode) 86 { 87 uint32_t formattedOpCode = dataSize; 88 89 switch (opCode) { 90 case MHW_MI_ATOMIC_AND: 91 formattedOpCode += MHW_MI_ATOMIC_AND; 92 break; 93 case MHW_MI_ATOMIC_OR: 94 formattedOpCode += MHW_MI_ATOMIC_OR; 95 break; 96 case MHW_MI_ATOMIC_XOR: 97 formattedOpCode += MHW_MI_ATOMIC_XOR; 98 break; 99 case MHW_MI_ATOMIC_MOVE: 100 formattedOpCode += MHW_MI_ATOMIC_MOVE; 101 break; 102 case MHW_MI_ATOMIC_INC: 103 formattedOpCode += MHW_MI_ATOMIC_INC; 104 break; 105 case MHW_MI_ATOMIC_DEC: 106 formattedOpCode += MHW_MI_ATOMIC_DEC; 107 break; 108 case MHW_MI_ATOMIC_ADD: 109 formattedOpCode += MHW_MI_ATOMIC_ADD; 110 break; 111 case MHW_MI_ATOMIC_SUB: 112 formattedOpCode += MHW_MI_ATOMIC_SUB; 113 break; 114 case MHW_MI_ATOMIC_RSUB: 115 formattedOpCode += MHW_MI_ATOMIC_RSUB; 116 break; 117 case MHW_MI_ATOMIC_IMAX: 118 formattedOpCode += MHW_MI_ATOMIC_IMAX; 119 break; 120 case MHW_MI_ATOMIC_IMIN: 121 formattedOpCode += MHW_MI_ATOMIC_IMIN; 122 break; 123 case MHW_MI_ATOMIC_UMAX: 124 formattedOpCode += MHW_MI_ATOMIC_UMAX; 125 break; 126 case MHW_MI_ATOMIC_UMIN: 127 formattedOpCode += MHW_MI_ATOMIC_UMIN; 128 break; 129 case MHW_MI_ATOMIC_CMP: 130 formattedOpCode += MHW_MI_ATOMIC_CMP; 131 break; 132 default: 133 formattedOpCode = MHW_MI_ATOMIC_NONE; 134 break; 135 } 136 137 return formattedOpCode; 138 } 139 SetWatchdogTimerThreshold(uint32_t frameWidth,uint32_t frameHeight,bool isEncoder,uint32_t codecMode)140 MOS_STATUS SetWatchdogTimerThreshold(uint32_t frameWidth, uint32_t frameHeight, bool isEncoder, uint32_t codecMode) override 141 { 142 return MOS_STATUS_SUCCESS; 143 } 144 SetWatchdogTimerRegisterOffset(MOS_GPU_CONTEXT gpuContext)145 MOS_STATUS SetWatchdogTimerRegisterOffset(MOS_GPU_CONTEXT gpuContext) override 146 { 147 return MOS_STATUS_SUCCESS; 148 } 149 AddWatchdogTimerStartCmd(PMOS_COMMAND_BUFFER cmdBuffer)150 MOS_STATUS AddWatchdogTimerStartCmd(PMOS_COMMAND_BUFFER cmdBuffer) override 151 { 152 return MOS_STATUS_SUCCESS; 153 } 154 AddWatchdogTimerStopCmd(PMOS_COMMAND_BUFFER cmdBuffer)155 MOS_STATUS AddWatchdogTimerStopCmd(PMOS_COMMAND_BUFFER cmdBuffer) override 156 { 157 return MOS_STATUS_SUCCESS; 158 } 159 AddMiBatchBufferEnd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_BATCH_BUFFER batchBuffer)160 MOS_STATUS AddMiBatchBufferEnd( 161 PMOS_COMMAND_BUFFER cmdBuffer, 162 PMHW_BATCH_BUFFER batchBuffer) override 163 { 164 return MOS_STATUS_SUCCESS; 165 } 166 AddMiBatchBufferEndOnly(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_BATCH_BUFFER batchBuffer)167 MOS_STATUS AddMiBatchBufferEndOnly( 168 PMOS_COMMAND_BUFFER cmdBuffer, 169 PMHW_BATCH_BUFFER batchBuffer) override 170 { 171 MHW_FUNCTION_ENTER; 172 173 if (cmdBuffer == nullptr && batchBuffer == nullptr) 174 { 175 MHW_ASSERTMESSAGE("There was no valid buffer to add the HW command to."); 176 return MOS_STATUS_NULL_POINTER; 177 } 178 179 // This WA does not apply for video or other engines, render requirement only 180 bool isRender = 181 MOS_RCS_ENGINE_USED(this->m_osItf->pfnGetGpuContext(this->m_osItf)); 182 183 // Mhw_CommonMi_AddMiBatchBufferEnd() is designed to handle both 1st level 184 // and 2nd level BB. It inserts MI_BATCH_BUFFER_END in both cases. 185 // However, since the 2nd level BB always returens to the 1st level BB and 186 // no chained BB scenario in Media, Epilog is only needed in the 1st level BB. 187 // Therefre, here only the 1st level BB case needs an Epilog inserted. 188 if (cmdBuffer && cmdBuffer->is1stLvlBB) 189 { 190 MHW_MI_CHK_STATUS(m_cpInterface->AddEpilog(this->m_osItf, cmdBuffer)); 191 } 192 193 auto ¶ms = MHW_GETPAR_F(MI_BATCH_BUFFER_END)(); 194 params = {}; 195 MHW_ADDCMD_F(MI_BATCH_BUFFER_END) 196 (cmdBuffer, batchBuffer); 197 198 if (!cmdBuffer) // Don't need BB not nullptr chk b/c if both are nullptr it won't get this far 199 { 200 #if (_DEBUG || _RELEASE_INTERNAL) 201 batchBuffer->iLastCurrent = batchBuffer->iCurrent; 202 #endif 203 } 204 205 // Send End Marker command 206 if (this->m_osItf->pfnIsSetMarkerEnabled(this->m_osItf) && cmdBuffer && cmdBuffer->is1stLvlBB) 207 { 208 PMOS_RESOURCE resMarker = nullptr; 209 resMarker = this->m_osItf->pfnGetMarkerResource(this->m_osItf); 210 MHW_MI_CHK_NULL(resMarker); 211 212 if (isRender) 213 { 214 // Send pipe_control to get the timestamp 215 auto ¶ms = MHW_GETPAR_F(PIPE_CONTROL)(); 216 params = {}; 217 params.presDest = resMarker; 218 params.dwResourceOffset = sizeof(uint64_t); 219 params.dwPostSyncOp = MHW_FLUSH_WRITE_TIMESTAMP_REG; 220 params.dwFlushMode = MHW_FLUSH_WRITE_CACHE; 221 MHW_ADDCMD_F(PIPE_CONTROL) 222 (cmdBuffer, batchBuffer); 223 } 224 else 225 { 226 // Send flush_dw to get the timestamp 227 auto ¶ms = MHW_GETPAR_F(MI_FLUSH_DW)(); 228 params = {}; 229 params.pOsResource = resMarker; 230 params.dwResourceOffset = sizeof(uint64_t); 231 params.postSyncOperation = MHW_FLUSH_WRITE_TIMESTAMP_REG; 232 params.bQWordEnable = 1; 233 MHW_ADDCMD_F(MI_FLUSH_DW) 234 (cmdBuffer, batchBuffer); 235 } 236 237 if (!this->m_osItf->apoMosEnabled) 238 { 239 MOS_SafeFreeMemory(resMarker); 240 } 241 } 242 243 return MOS_STATUS_SUCCESS; 244 } 245 AddBatchBufferEndInsertionFlag(MOS_COMMAND_BUFFER & constructedCmdBuf)246 MOS_STATUS AddBatchBufferEndInsertionFlag(MOS_COMMAND_BUFFER &constructedCmdBuf) override 247 { 248 MHW_FUNCTION_ENTER; 249 250 typename cmd_t::MI_BATCH_BUFFER_END_CMD cmd; 251 252 MHW_CHK_NULL_RETURN(constructedCmdBuf.pCmdPtr); 253 *((typename cmd_t::MI_BATCH_BUFFER_END_CMD *)(constructedCmdBuf.pCmdPtr)) = cmd; 254 255 return MOS_STATUS_SUCCESS; 256 } 257 GetMmioRegisters()258 MHW_MI_MMIOREGISTERS* GetMmioRegisters() override 259 { 260 return &m_mmioRegisters; 261 } 262 SetCpInterface(MhwCpInterface * cpInterface,std::shared_ptr<mhw::mi::Itf> m_miItf)263 virtual MOS_STATUS SetCpInterface(MhwCpInterface *cpInterface, std::shared_ptr<mhw::mi::Itf> m_miItf) override 264 { 265 m_cpInterface = cpInterface; 266 MHW_CHK_NULL_RETURN(m_cpInterface); 267 MHW_MI_CHK_STATUS(m_cpInterface->RegisterMiInterfaceNext(m_miItf)); 268 return MOS_STATUS_SUCCESS; 269 } 270 271 virtual uint32_t GetMmioInterfaces(MHW_MMIO_REGISTER_OPCODE opCode) override = 0; 272 AddProtectedProlog(MOS_COMMAND_BUFFER * cmdBuffer)273 MOS_STATUS AddProtectedProlog(MOS_COMMAND_BUFFER *cmdBuffer) override 274 { 275 MHW_MI_CHK_NULL(cmdBuffer); 276 277 MHW_MI_CHK_STATUS(m_cpInterface->AddProlog(this->m_osItf, cmdBuffer)); 278 MHW_MI_CHK_STATUS(m_cpInterface->AddCheckForEarlyExit(this->m_osItf, cmdBuffer)); 279 280 return MOS_STATUS_SUCCESS; 281 } 282 AddVeboxMMIOPrologCmd(PMOS_COMMAND_BUFFER cmdBuffer)283 MOS_STATUS AddVeboxMMIOPrologCmd( 284 PMOS_COMMAND_BUFFER cmdBuffer) override 285 { 286 return MOS_STATUS_SUCCESS; 287 } 288 AddBLTMMIOPrologCmd(PMOS_COMMAND_BUFFER cmdBuffer)289 virtual MOS_STATUS AddBLTMMIOPrologCmd( 290 PMOS_COMMAND_BUFFER cmdBuffer) override 291 { 292 return MOS_STATUS_SUCCESS; 293 } 294 295 protected: 296 using base_t = Itf; 297 298 MHW_MI_MMIOREGISTERS m_mmioRegisters = {}; 299 MhwCpInterface *m_cpInterface = nullptr; 300 301 public: Impl(PMOS_INTERFACE osItf)302 Impl(PMOS_INTERFACE osItf) : mhw::Impl(osItf) 303 { 304 MHW_FUNCTION_ENTER; 305 } 306 _MHW_SETCMD_OVERRIDE_DECL(MI_SEMAPHORE_WAIT)307 _MHW_SETCMD_OVERRIDE_DECL(MI_SEMAPHORE_WAIT) 308 { 309 _MHW_SETCMD_CALLBASE(MI_SEMAPHORE_WAIT); 310 311 MHW_MI_CHK_NULL(this->m_currentCmdBuf); 312 MHW_MI_CHK_NULL(params.presSemaphoreMem); 313 314 MHW_RESOURCE_PARAMS resourceParams ={}; 315 resourceParams.presResource = params.presSemaphoreMem; 316 resourceParams.dwOffset = params.dwResourceOffset; 317 resourceParams.pdwCmd = cmd.DW2_3.Value; 318 resourceParams.dwLocationInCmd = _MHW_CMD_DW_LOCATION(DW2_3.Value);; 319 resourceParams.dwLsbNum = MHW_COMMON_MI_GENERAL_SHIFT; 320 resourceParams.HwCommandType = MOS_MI_SEMAPHORE_WAIT; 321 322 MHW_MI_CHK_STATUS(AddResourceToCmd( 323 this->m_osItf, 324 this->m_currentCmdBuf, 325 &resourceParams)); 326 327 cmd.DW0.MemoryType = IsGlobalGttInUse(); 328 cmd.DW0.WaitMode = params.bPollingWaitMode; 329 cmd.DW0.CompareOperation = params.CompareOperation; 330 cmd.DW1.SemaphoreDataDword = params.dwSemaphoreData; 331 332 return MOS_STATUS_SUCCESS; 333 } 334 _MHW_SETCMD_OVERRIDE_DECL(PIPE_CONTROL)335 _MHW_SETCMD_OVERRIDE_DECL(PIPE_CONTROL) 336 { 337 _MHW_SETCMD_CALLBASE(PIPE_CONTROL); 338 339 return MOS_STATUS_SUCCESS; 340 } 341 _MHW_SETCMD_OVERRIDE_DECL(MI_BATCH_BUFFER_START)342 _MHW_SETCMD_OVERRIDE_DECL(MI_BATCH_BUFFER_START) 343 { 344 _MHW_SETCMD_CALLBASE(MI_BATCH_BUFFER_START); 345 346 return MOS_STATUS_SUCCESS; 347 } 348 349 _MHW_SETCMD_OVERRIDE_DECL(MI_CONDITIONAL_BATCH_BUFFER_END)350 _MHW_SETCMD_OVERRIDE_DECL(MI_CONDITIONAL_BATCH_BUFFER_END) 351 { 352 _MHW_SETCMD_CALLBASE(MI_CONDITIONAL_BATCH_BUFFER_END); 353 354 return MOS_STATUS_SUCCESS; 355 } 356 _MHW_SETCMD_OVERRIDE_DECL(MI_SET_PREDICATE)357 _MHW_SETCMD_OVERRIDE_DECL(MI_SET_PREDICATE) 358 { 359 _MHW_SETCMD_CALLBASE(MI_SET_PREDICATE); 360 361 return MOS_STATUS_SUCCESS; 362 } 363 _MHW_SETCMD_OVERRIDE_DECL(MI_STORE_REGISTER_MEM)364 _MHW_SETCMD_OVERRIDE_DECL(MI_STORE_REGISTER_MEM) 365 { 366 _MHW_SETCMD_CALLBASE(MI_STORE_REGISTER_MEM); 367 368 MHW_MI_CHK_NULL(this->m_currentCmdBuf); 369 MHW_MI_CHK_NULL(params.presStoreBuffer); 370 371 MHW_RESOURCE_PARAMS resourceParams = {}; 372 resourceParams.presResource = params.presStoreBuffer; 373 resourceParams.dwOffset = params.dwOffset; 374 resourceParams.pdwCmd = cmd.DW2_3.Value; 375 resourceParams.dwLocationInCmd = _MHW_CMD_DW_LOCATION(DW2_3.Value);; 376 resourceParams.dwLsbNum = MHW_COMMON_MI_GENERAL_SHIFT; 377 resourceParams.HwCommandType = MOS_MI_STORE_REGISTER_MEM; 378 resourceParams.bIsWritable = true; 379 380 MHW_MI_CHK_STATUS(AddResourceToCmd( 381 this->m_osItf, 382 this->m_currentCmdBuf, 383 &resourceParams)); 384 385 cmd.DW0.UseGlobalGtt = IsGlobalGttInUse(); 386 cmd.DW1.RegisterAddress = params.dwRegister >> 2; 387 388 return MOS_STATUS_SUCCESS; 389 } 390 _MHW_SETCMD_OVERRIDE_DECL(MI_LOAD_REGISTER_MEM)391 _MHW_SETCMD_OVERRIDE_DECL(MI_LOAD_REGISTER_MEM) 392 { 393 _MHW_SETCMD_CALLBASE(MI_LOAD_REGISTER_MEM); 394 395 MHW_MI_CHK_NULL(this->m_currentCmdBuf); 396 MHW_MI_CHK_NULL(params.presStoreBuffer); 397 398 MHW_RESOURCE_PARAMS resourceParams = {}; 399 resourceParams.presResource = params.presStoreBuffer; 400 resourceParams.dwOffset = params.dwOffset; 401 resourceParams.pdwCmd = cmd.DW2_3.Value; 402 resourceParams.dwLocationInCmd = _MHW_CMD_DW_LOCATION(DW2_3.Value);; 403 resourceParams.dwLsbNum = MHW_COMMON_MI_GENERAL_SHIFT; 404 resourceParams.HwCommandType = MOS_MI_LOAD_REGISTER_MEM; 405 resourceParams.bIsWritable = true; 406 407 MHW_MI_CHK_STATUS(AddResourceToCmd( 408 this->m_osItf, 409 this->m_currentCmdBuf, 410 &resourceParams)); 411 412 cmd.DW0.UseGlobalGtt = IsGlobalGttInUse(); 413 cmd.DW1.RegisterAddress = params.dwRegister >> 2; 414 415 return MOS_STATUS_SUCCESS; 416 } 417 _MHW_SETCMD_OVERRIDE_DECL(MI_LOAD_REGISTER_IMM)418 _MHW_SETCMD_OVERRIDE_DECL(MI_LOAD_REGISTER_IMM) 419 { 420 _MHW_SETCMD_CALLBASE(MI_LOAD_REGISTER_IMM); 421 422 cmd.DW1.RegisterOffset = params.dwRegister >> 2; 423 cmd.DW2.DataDword = params.dwData; 424 425 return MOS_STATUS_SUCCESS; 426 } 427 _MHW_SETCMD_OVERRIDE_DECL(MI_LOAD_REGISTER_REG)428 _MHW_SETCMD_OVERRIDE_DECL(MI_LOAD_REGISTER_REG) 429 { 430 _MHW_SETCMD_CALLBASE(MI_LOAD_REGISTER_REG); 431 432 cmd.DW1.SourceRegisterAddress = params.dwSrcRegister >> 2; 433 cmd.DW2.DestinationRegisterAddress = params.dwDstRegister >> 2; 434 435 return MOS_STATUS_SUCCESS; 436 } 437 _MHW_SETCMD_OVERRIDE_DECL(MI_FORCE_WAKEUP)438 _MHW_SETCMD_OVERRIDE_DECL(MI_FORCE_WAKEUP) 439 { 440 _MHW_SETCMD_CALLBASE(MI_FORCE_WAKEUP); 441 442 return MOS_STATUS_SUCCESS; 443 } 444 _MHW_SETCMD_OVERRIDE_DECL(VD_CONTROL_STATE)445 _MHW_SETCMD_OVERRIDE_DECL(VD_CONTROL_STATE) 446 { 447 _MHW_SETCMD_CALLBASE(VD_CONTROL_STATE); 448 449 return MOS_STATUS_SUCCESS; 450 } 451 _MHW_SETCMD_OVERRIDE_DECL(MEDIA_STATE_FLUSH)452 _MHW_SETCMD_OVERRIDE_DECL(MEDIA_STATE_FLUSH) 453 { 454 _MHW_SETCMD_CALLBASE(MEDIA_STATE_FLUSH); 455 456 return MOS_STATUS_SUCCESS; 457 } 458 _MHW_SETCMD_OVERRIDE_DECL(MI_BATCH_BUFFER_END)459 _MHW_SETCMD_OVERRIDE_DECL(MI_BATCH_BUFFER_END) 460 { 461 _MHW_SETCMD_CALLBASE(MI_BATCH_BUFFER_END); 462 463 return MOS_STATUS_SUCCESS; 464 } 465 _MHW_SETCMD_OVERRIDE_DECL(MI_FLUSH_DW)466 _MHW_SETCMD_OVERRIDE_DECL(MI_FLUSH_DW) 467 { 468 _MHW_SETCMD_CALLBASE(MI_FLUSH_DW); 469 470 return MOS_STATUS_SUCCESS; 471 } 472 _MHW_SETCMD_OVERRIDE_DECL(MI_NOOP)473 _MHW_SETCMD_OVERRIDE_DECL(MI_NOOP) 474 { 475 _MHW_SETCMD_CALLBASE(MI_NOOP); 476 477 return MOS_STATUS_SUCCESS; 478 } 479 _MHW_SETCMD_OVERRIDE_DECL(MI_ATOMIC)480 _MHW_SETCMD_OVERRIDE_DECL(MI_ATOMIC) 481 { 482 _MHW_SETCMD_CALLBASE(MI_ATOMIC); 483 MHW_RESOURCE_PARAMS resourceParams = {}; 484 resourceParams.presResource = params.pOsResource; 485 resourceParams.dwOffset = params.dwResourceOffset; 486 resourceParams.pdwCmd = &(cmd.DW1.Value); 487 resourceParams.dwLocationInCmd = _MHW_CMD_DW_LOCATION(DW1.Value);; 488 resourceParams.dwLsbNum = MHW_COMMON_MI_GENERAL_SHIFT; 489 resourceParams.HwCommandType = MOS_MI_ATOMIC; 490 resourceParams.bIsWritable = true; 491 492 MHW_MI_CHK_STATUS(AddResourceToCmd( 493 this->m_osItf, 494 this->m_currentCmdBuf, 495 &resourceParams)); 496 497 cmd.DW0.DwordLength = params.bInlineData ? 1 : 9; 498 cmd.DW0.MemoryType = IsGlobalGttInUse(); 499 cmd.DW0.ReturnDataControl = params.bReturnData; 500 if (params.dwDataSize == sizeof(uint32_t)) 501 { 502 cmd.DW0.DataSize = cmd.DATA_SIZE_DWORD; 503 } 504 else if (params.dwDataSize == sizeof(uint64_t)) 505 { 506 cmd.DW0.DataSize = cmd.DATA_SIZE_QWORD; 507 } 508 else if (params.dwDataSize == sizeof(uint64_t) * 2) 509 { 510 cmd.DW0.DataSize = cmd.DATA_SIZE_OCTWORD; 511 } 512 else 513 { 514 MHW_ASSERTMESSAGE("Invalid data size provided"); 515 return MOS_STATUS_INVALID_PARAMETER; 516 } 517 518 if (cmd.DW0.DataSize == cmd.DATA_SIZE_QWORD) 519 { 520 cmd.DW0.AtomicOpcode = MHW_MI_ATOMIC_QWORD; 521 } 522 else if (cmd.DW0.DataSize == cmd.DATA_SIZE_OCTWORD) 523 { 524 if (params.Operation != MHW_MI_ATOMIC_CMP) 525 { 526 MHW_ASSERTMESSAGE("An OCTWORD may only be used in the case of a compare operation!"); 527 return MOS_STATUS_INVALID_PARAMETER; 528 } 529 cmd.DW0.AtomicOpcode = MHW_MI_ATOMIC_OCTWORD; 530 } 531 cmd.DW0.AtomicOpcode = CreateMiAtomicOpcode( 532 cmd.DW0.AtomicOpcode, 533 params.Operation); 534 if (cmd.DW0.AtomicOpcode == MHW_MI_ATOMIC_NONE) 535 { 536 MHW_ASSERTMESSAGE("No MI_ATOMIC opcode could be generated"); 537 return MOS_STATUS_INVALID_PARAMETER; 538 } 539 540 cmd.DW0.InlineData = params.bInlineData; 541 cmd.DW0.DwordLength = params.bInlineData ? 9 : 1; 542 543 if (params.bInlineData) 544 { 545 cmd.DW3.Operand1DataDword0 = params.dwOperand1Data[0]; 546 cmd.DW4.Operand2DataDword0 = params.dwOperand2Data[0]; 547 cmd.DW5.Operand1DataDword1 = params.dwOperand1Data[1]; 548 cmd.DW6.Operand2DataDword1 = params.dwOperand2Data[1]; 549 cmd.DW7.Operand1DataDword2 = params.dwOperand1Data[2]; 550 cmd.DW8.Operand2DataDword2 = params.dwOperand2Data[3]; 551 cmd.DW9.Operand1DataDword3 = params.dwOperand1Data[3]; 552 cmd.DW10.Operand2DataDword3 = params.dwOperand2Data[3]; 553 } 554 555 return MOS_STATUS_SUCCESS; 556 } 557 _MHW_SETCMD_OVERRIDE_DECL(MI_STORE_DATA_IMM)558 _MHW_SETCMD_OVERRIDE_DECL(MI_STORE_DATA_IMM) 559 { 560 _MHW_SETCMD_CALLBASE(MI_STORE_DATA_IMM); 561 MHW_MI_CHK_NULL(this->m_currentCmdBuf); 562 MHW_MI_CHK_NULL(params.pOsResource); 563 564 MHW_RESOURCE_PARAMS resourceParams = {}; 565 resourceParams.presResource = params.pOsResource; 566 resourceParams.dwOffset = params.dwResourceOffset; 567 resourceParams.pdwCmd = cmd.DW1_2.Value; 568 resourceParams.dwLocationInCmd = _MHW_CMD_DW_LOCATION(DW1_2.Value); 569 resourceParams.dwLsbNum = MHW_COMMON_MI_STORE_DATA_DW_SHIFT; 570 resourceParams.HwCommandType = MOS_MI_STORE_DATA_IMM; 571 resourceParams.bIsWritable = true; 572 573 MHW_MI_CHK_STATUS(AddResourceToCmd( 574 this->m_osItf, 575 this->m_currentCmdBuf, 576 &resourceParams)); 577 578 cmd.DW0.UseGlobalGtt = IsGlobalGttInUse(); 579 // Force single DW write, driver never writes a QW 580 cmd.DW0.StoreQword = 0; 581 cmd.DW0.DwordLength--; 582 583 cmd.DW3.DataDword0 = params.dwValue; 584 585 return MOS_STATUS_SUCCESS; 586 } 587 _MHW_SETCMD_OVERRIDE_DECL(MI_MATH)588 _MHW_SETCMD_OVERRIDE_DECL(MI_MATH) 589 { 590 _MHW_SETCMD_CALLBASE(MI_MATH); 591 MHW_MI_CHK_NULL(this->m_currentCmdBuf); 592 593 if (params.dwNumAluParams == 0 || params.pAluPayload == nullptr) 594 { 595 MHW_ASSERTMESSAGE("MI_MATH requires a valid payload"); 596 return MOS_STATUS_INVALID_PARAMETER; 597 } 598 599 cmd.DW0.DwordLength = params.dwNumAluParams - 1; 600 601 return MOS_STATUS_SUCCESS; 602 } 603 _MHW_SETCMD_OVERRIDE_DECL(MI_COPY_MEM_MEM)604 _MHW_SETCMD_OVERRIDE_DECL(MI_COPY_MEM_MEM) 605 { 606 _MHW_SETCMD_CALLBASE(MI_COPY_MEM_MEM); 607 608 MHW_MI_CHK_NULL(this->m_currentCmdBuf); 609 MHW_MI_CHK_NULL(params.presSrc); 610 MHW_MI_CHK_NULL(params.presDst); 611 612 cmd.DW0.UseGlobalGttDestination = IsGlobalGttInUse(); 613 cmd.DW0.UseGlobalGttSource = IsGlobalGttInUse(); 614 615 MHW_RESOURCE_PARAMS resourceParams = {}; 616 resourceParams.presResource = params.presDst; 617 resourceParams.dwOffset = params.dwDstOffset; 618 resourceParams.pdwCmd = cmd.DW1_2.Value; 619 resourceParams.dwLocationInCmd = _MHW_CMD_DW_LOCATION(DW1_2.Value); 620 resourceParams.dwLsbNum = MHW_COMMON_MI_GENERAL_SHIFT; 621 resourceParams.HwCommandType = MOS_MI_COPY_MEM_MEM; 622 resourceParams.bIsWritable = true; 623 624 MHW_MI_CHK_STATUS(AddResourceToCmd( 625 this->m_osItf, 626 this->m_currentCmdBuf, 627 &resourceParams)); 628 629 resourceParams = {}; 630 resourceParams.presResource = params.presSrc; 631 resourceParams.dwOffset = params.dwSrcOffset; 632 resourceParams.pdwCmd = cmd.DW3_4.Value; 633 resourceParams.dwLocationInCmd = _MHW_CMD_DW_LOCATION(DW3_4.Value); 634 resourceParams.dwLsbNum = MHW_COMMON_MI_GENERAL_SHIFT; 635 resourceParams.HwCommandType = MOS_MI_COPY_MEM_MEM; 636 resourceParams.bIsWritable = false; 637 638 MHW_MI_CHK_STATUS(AddResourceToCmd( 639 this->m_osItf, 640 this->m_currentCmdBuf, 641 &resourceParams)); 642 643 return MOS_STATUS_SUCCESS; 644 } 645 _MHW_SETCMD_OVERRIDE_DECL(MFX_WAIT)646 _MHW_SETCMD_OVERRIDE_DECL(MFX_WAIT) 647 { 648 _MHW_SETCMD_CALLBASE(MFX_WAIT); 649 650 cmd.DW0.MfxSyncControlFlag = params.iStallVdboxPipeline; 651 652 // set the protection bit based on CP status 653 MHW_MI_CHK_STATUS(m_cpInterface->SetProtectionSettingsForMfxWait(this->m_osItf, &cmd)); 654 655 return MOS_STATUS_SUCCESS; 656 } 657 MEDIA_CLASS_DEFINE_END(mhw__mi__Impl) 658 }; 659 } // namespace render 660 } // namespace mhw 661 662 #endif // __MHW_RENDER_IMPL_H__ 663