1 /* 2 * Copyright (c) 2015-2018, 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_generic.h 24 //! \brief MHW interface templates for MI and generic flush commands across all engines 25 //! \details Impelements shared HW command construction functions across all platforms as templates 26 //! 27 28 #ifndef __MHW_MI_GENERIC_H__ 29 #define __MHW_MI_GENERIC_H__ 30 31 #include "mhw_mi.h" 32 #include "mhw_cp_interface.h" 33 #include "mos_os_cp_interface_specific.h" 34 35 template <class TMiCmds> 36 class MhwMiInterfaceGeneric : public MhwMiInterface 37 { 38 private: 39 enum AtomicOpCode 40 { 41 atomicInvalid = 0, 42 atomicAnd = 1, 43 atomicOr = 2, 44 atomicXor = 3, 45 atomicMove = 4, 46 atomicInc = 5, 47 atomicDec = 6, 48 atomicAdd = 7, 49 atomicSub = 8, 50 atomicRSub = 9, 51 atomicIMax = 10, 52 atomicIMin = 11, 53 atomicUMax = 12, 54 atomicUMin = 13, 55 atomicCmp = 14, 56 atomicDword = 0, 57 atomicQword = 0x20, 58 atomicOctword = 0x40, 59 }; 60 61 //! 62 //! \brief Helper function to compose opcode for MI_ATOMIC 63 //! \return uint32_t 64 //! Composed opcode for MI_ATOMIC or 0 65 //! CreateMiAtomicOpcode(uint32_t dataSize,MHW_COMMON_MI_ATOMIC_OPCODE opCode)66 uint32_t CreateMiAtomicOpcode( 67 uint32_t dataSize, 68 MHW_COMMON_MI_ATOMIC_OPCODE opCode) 69 { 70 uint32_t formattedOpCode = dataSize; 71 72 switch (opCode) { 73 case MHW_MI_ATOMIC_AND: 74 formattedOpCode += atomicAnd; 75 break; 76 case MHW_MI_ATOMIC_OR: 77 formattedOpCode += atomicOr; 78 break; 79 case MHW_MI_ATOMIC_XOR: 80 formattedOpCode += atomicXor; 81 break; 82 case MHW_MI_ATOMIC_MOVE: 83 formattedOpCode += atomicMove; 84 break; 85 case MHW_MI_ATOMIC_INC: 86 formattedOpCode += atomicInc; 87 break; 88 case MHW_MI_ATOMIC_DEC: 89 formattedOpCode += atomicDec; 90 break; 91 case MHW_MI_ATOMIC_ADD: 92 formattedOpCode += atomicAdd; 93 break; 94 case MHW_MI_ATOMIC_SUB: 95 formattedOpCode += atomicSub; 96 break; 97 case MHW_MI_ATOMIC_RSUB: 98 formattedOpCode += atomicRSub; 99 break; 100 case MHW_MI_ATOMIC_IMAX: 101 formattedOpCode += atomicIMax; 102 break; 103 case MHW_MI_ATOMIC_IMIN: 104 formattedOpCode += atomicIMin; 105 break; 106 case MHW_MI_ATOMIC_UMAX: 107 formattedOpCode += atomicUMax; 108 break; 109 case MHW_MI_ATOMIC_UMIN: 110 formattedOpCode += atomicUMin; 111 break; 112 case MHW_MI_ATOMIC_CMP: 113 formattedOpCode += atomicCmp; 114 break; 115 default: 116 formattedOpCode = atomicInvalid; 117 break; 118 } 119 120 return formattedOpCode; 121 } 122 SendMarkerCommand(PMOS_COMMAND_BUFFER cmdBuffer,bool isRender)123 MOS_STATUS SendMarkerCommand( 124 PMOS_COMMAND_BUFFER cmdBuffer, 125 bool isRender) 126 { 127 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 128 PMOS_RESOURCE resMarker = nullptr; 129 130 MHW_FUNCTION_ENTER; 131 132 resMarker = m_osInterface->pfnGetMarkerResource(m_osInterface); 133 MHW_CHK_NULL_RETURN(resMarker); 134 135 if (isRender) 136 { 137 // Send pipe_control to get the timestamp 138 MHW_PIPE_CONTROL_PARAMS pipeControlParams; 139 MOS_ZeroMemory(&pipeControlParams, sizeof(pipeControlParams)); 140 pipeControlParams.presDest = resMarker; 141 pipeControlParams.dwResourceOffset = sizeof(uint64_t); 142 pipeControlParams.dwPostSyncOp = MHW_FLUSH_WRITE_TIMESTAMP_REG; 143 pipeControlParams.dwFlushMode = MHW_FLUSH_WRITE_CACHE; 144 145 MHW_MI_CHK_STATUS(AddPipeControl(cmdBuffer, NULL, &pipeControlParams)); 146 } 147 else 148 { 149 // Send flush_dw to get the timestamp 150 MHW_MI_FLUSH_DW_PARAMS flushDwParams; 151 MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams)); 152 flushDwParams.pOsResource = resMarker; 153 flushDwParams.dwResourceOffset = sizeof(uint64_t); 154 flushDwParams.postSyncOperation = MHW_FLUSH_WRITE_TIMESTAMP_REG; 155 flushDwParams.bQWordEnable = 1; 156 157 MHW_MI_CHK_STATUS(AddMiFlushDwCmd(cmdBuffer, &flushDwParams)); 158 } 159 if (!m_osInterface->apoMosEnabled) 160 { 161 MOS_SafeFreeMemory(resMarker); 162 } 163 return eStatus; 164 } 165 166 protected: MhwMiInterfaceGeneric(MhwCpInterface * cpInterface,PMOS_INTERFACE osInterface)167 MhwMiInterfaceGeneric( 168 MhwCpInterface *cpInterface, 169 PMOS_INTERFACE osInterface) : MhwMiInterface(cpInterface, osInterface) {} 170 171 public: ~MhwMiInterfaceGeneric()172 virtual ~MhwMiInterfaceGeneric() { MHW_FUNCTION_ENTER; } 173 AddMiNoop(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_BATCH_BUFFER batchBuffer)174 MOS_STATUS AddMiNoop( 175 PMOS_COMMAND_BUFFER cmdBuffer, 176 PMHW_BATCH_BUFFER batchBuffer) 177 { 178 MHW_FUNCTION_ENTER; 179 180 if (cmdBuffer == nullptr && batchBuffer == nullptr) 181 { 182 MHW_ASSERTMESSAGE("There was no valid buffer to add the HW command to."); 183 return MOS_STATUS_NULL_POINTER; 184 } 185 186 typename TMiCmds::MI_NOOP_CMD cmd; 187 MHW_MI_CHK_STATUS(Mhw_AddCommandCmdOrBB( 188 m_osInterface, 189 cmdBuffer, 190 batchBuffer, 191 &cmd, 192 cmd.byteSize)); 193 194 return MOS_STATUS_SUCCESS; 195 } 196 AddMiBatchBufferEnd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_BATCH_BUFFER batchBuffer)197 MOS_STATUS AddMiBatchBufferEnd( 198 PMOS_COMMAND_BUFFER cmdBuffer, 199 PMHW_BATCH_BUFFER batchBuffer) 200 { 201 MHW_FUNCTION_ENTER; 202 203 if (cmdBuffer == nullptr && batchBuffer == nullptr) 204 { 205 MHW_ASSERTMESSAGE("There was no valid buffer to add the HW command to."); 206 return MOS_STATUS_NULL_POINTER; 207 } 208 209 auto waTable = m_osInterface->pfnGetWaTable(m_osInterface); 210 MHW_MI_CHK_NULL(waTable); 211 212 // This WA does not apply for video or other engines, render requirement only 213 bool isRender = 214 MOS_RCS_ENGINE_USED(m_osInterface->pfnGetGpuContext(m_osInterface)); 215 216 if (isRender && 217 (MEDIA_IS_WA(waTable, WaMSFWithNoWatermarkTSGHang) || 218 MEDIA_IS_WA(waTable, WaAddMediaStateFlushCmd))) 219 { 220 MHW_MI_CHK_STATUS(AddMediaStateFlush(cmdBuffer, batchBuffer)); 221 } 222 223 // Mhw_CommonMi_AddMiBatchBufferEnd() is designed to handle both 1st level 224 // and 2nd level BB. It inserts MI_BATCH_BUFFER_END in both cases. 225 // However, since the 2nd level BB always returens to the 1st level BB and 226 // no chained BB scenario in Media, Epilog is only needed in the 1st level BB. 227 // Therefre, here only the 1st level BB case needs an Epilog inserted. 228 if (cmdBuffer && cmdBuffer->is1stLvlBB) 229 { 230 MHW_MI_CHK_STATUS(m_cpInterface->AddEpilog(m_osInterface, cmdBuffer)); 231 } 232 233 typename TMiCmds::MI_BATCH_BUFFER_END_CMD cmd; 234 MHW_MI_CHK_STATUS(Mhw_AddCommandCmdOrBB( 235 m_osInterface, 236 cmdBuffer, 237 batchBuffer, 238 &cmd, 239 cmd.byteSize)); 240 241 if (!cmdBuffer) // Don't need BB not nullptr chk b/c if both are nullptr it won't get this far 242 { 243 #if (_DEBUG || _RELEASE_INTERNAL) 244 batchBuffer->iLastCurrent = batchBuffer->iCurrent; 245 #endif 246 } 247 248 // Send End Marker command 249 if (m_osInterface->pfnIsSetMarkerEnabled(m_osInterface) && cmdBuffer && cmdBuffer->is1stLvlBB) 250 { 251 MHW_MI_CHK_STATUS(SendMarkerCommand( 252 cmdBuffer, MOS_RCS_ENGINE_USED(m_osInterface->pfnGetGpuContext(m_osInterface)))); 253 } 254 255 MHW_MI_CHK_STATUS(m_osInterface->osCpInterface->PermeateBBPatchForHM()); 256 257 return MOS_STATUS_SUCCESS; 258 } 259 AddMiBatchBufferEndOnly(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_BATCH_BUFFER batchBuffer)260 MOS_STATUS AddMiBatchBufferEndOnly( 261 PMOS_COMMAND_BUFFER cmdBuffer, 262 PMHW_BATCH_BUFFER batchBuffer) 263 { 264 MHW_FUNCTION_ENTER; 265 266 if (cmdBuffer == nullptr && batchBuffer == nullptr) 267 { 268 MHW_ASSERTMESSAGE("There was no valid buffer to add the HW command to."); 269 return MOS_STATUS_NULL_POINTER; 270 } 271 272 // Mhw_CommonMi_AddMiBatchBufferEnd() is designed to handle both 1st level 273 // and 2nd level BB. It inserts MI_BATCH_BUFFER_END in both cases. 274 // However, since the 2nd level BB always returens to the 1st level BB and 275 // no chained BB scenario in Media, Epilog is only needed in the 1st level BB. 276 // Therefre, here only the 1st level BB case needs an Epilog inserted. 277 if (cmdBuffer && cmdBuffer->is1stLvlBB) 278 { 279 MHW_MI_CHK_STATUS(m_cpInterface->AddEpilog(m_osInterface, cmdBuffer)); 280 } 281 282 typename TMiCmds::MI_BATCH_BUFFER_END_CMD cmd; 283 MHW_MI_CHK_STATUS(Mhw_AddCommandCmdOrBB( 284 m_osInterface, 285 cmdBuffer, 286 batchBuffer, 287 &cmd, 288 cmd.byteSize)); 289 290 if (!cmdBuffer) // Don't need BB not nullptr chk b/c if both are nullptr it won't get this far 291 { 292 #if (_DEBUG || _RELEASE_INTERNAL) 293 batchBuffer->iLastCurrent = batchBuffer->iCurrent; 294 #endif 295 } 296 297 // Send End Marker command 298 if (m_osInterface->pfnIsSetMarkerEnabled(m_osInterface) && cmdBuffer && cmdBuffer->is1stLvlBB) 299 { 300 MHW_MI_CHK_STATUS(SendMarkerCommand( 301 cmdBuffer, MOS_RCS_ENGINE_USED(m_osInterface->pfnGetGpuContext(m_osInterface)))); 302 } 303 304 return MOS_STATUS_SUCCESS; 305 } 306 AddMiStoreDataImmCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_MI_STORE_DATA_PARAMS params)307 MOS_STATUS AddMiStoreDataImmCmd( 308 PMOS_COMMAND_BUFFER cmdBuffer, 309 PMHW_MI_STORE_DATA_PARAMS params) 310 { 311 MHW_FUNCTION_ENTER; 312 313 MHW_MI_CHK_NULL(m_osInterface); 314 MHW_MI_CHK_NULL(cmdBuffer); 315 MHW_MI_CHK_NULL(params); 316 MHW_MI_CHK_NULL(params->pOsResource); 317 318 typename TMiCmds::MI_STORE_DATA_IMM_CMD cmd; 319 MHW_RESOURCE_PARAMS resourceParams; 320 MOS_ZeroMemory(&resourceParams, sizeof(resourceParams)); 321 resourceParams.presResource = params->pOsResource; 322 resourceParams.dwOffset = params->dwResourceOffset; 323 resourceParams.pdwCmd = cmd.DW1_2.Value; 324 resourceParams.dwLocationInCmd = 1; 325 resourceParams.dwLsbNum = MHW_COMMON_MI_STORE_DATA_DW_SHIFT; 326 resourceParams.HwCommandType = MOS_MI_STORE_DATA_IMM; 327 resourceParams.bIsWritable = true; 328 329 MHW_MI_CHK_STATUS(AddResourceToCmd( 330 m_osInterface, 331 cmdBuffer, 332 &resourceParams)); 333 334 cmd.DW0.UseGlobalGtt = IsGlobalGttInUse(); 335 // Force single DW write, driver never writes a QW 336 cmd.DW0.StoreQword = 0; 337 cmd.DW0.DwordLength--; 338 339 cmd.DW3.DataDword0 = params->dwValue; 340 341 MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, cmd.byteSize)); 342 343 return MOS_STATUS_SUCCESS; 344 } 345 AddMiFlushDwCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_MI_FLUSH_DW_PARAMS params)346 MOS_STATUS AddMiFlushDwCmd( 347 PMOS_COMMAND_BUFFER cmdBuffer, 348 PMHW_MI_FLUSH_DW_PARAMS params) 349 { 350 MHW_FUNCTION_ENTER; 351 352 MHW_MI_CHK_NULL(cmdBuffer); 353 MHW_MI_CHK_NULL(params); 354 355 return MOS_STATUS_SUCCESS; 356 } 357 AddMiCopyMemMemCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_MI_COPY_MEM_MEM_PARAMS params)358 MOS_STATUS AddMiCopyMemMemCmd( 359 PMOS_COMMAND_BUFFER cmdBuffer, 360 PMHW_MI_COPY_MEM_MEM_PARAMS params) 361 { 362 MHW_FUNCTION_ENTER; 363 364 MHW_MI_CHK_NULL(m_osInterface); 365 MHW_MI_CHK_NULL(cmdBuffer); 366 MHW_MI_CHK_NULL(params); 367 MHW_MI_CHK_NULL(params->presSrc); 368 MHW_MI_CHK_NULL(params->presDst); 369 370 typename TMiCmds::MI_COPY_MEM_MEM_CMD cmd; 371 cmd.DW0.UseGlobalGttDestination = IsGlobalGttInUse(); 372 cmd.DW0.UseGlobalGttSource = IsGlobalGttInUse(); 373 374 MHW_RESOURCE_PARAMS resourceParams; 375 MOS_ZeroMemory(&resourceParams, sizeof(resourceParams)); 376 resourceParams.presResource = params->presDst; 377 resourceParams.dwOffset = params->dwDstOffset; 378 resourceParams.pdwCmd = cmd.DW1_2.Value; 379 resourceParams.dwLocationInCmd = 1; 380 resourceParams.dwLsbNum = MHW_COMMON_MI_GENERAL_SHIFT; 381 resourceParams.HwCommandType = MOS_MI_COPY_MEM_MEM; 382 resourceParams.bIsWritable = true; 383 384 MHW_MI_CHK_STATUS(AddResourceToCmd( 385 m_osInterface, 386 cmdBuffer, 387 &resourceParams)); 388 389 MOS_ZeroMemory(&resourceParams, sizeof(resourceParams)); 390 resourceParams.presResource = params->presSrc; 391 resourceParams.dwOffset = params->dwSrcOffset; 392 resourceParams.pdwCmd = cmd.DW3_4.Value; 393 resourceParams.dwLocationInCmd = 3; 394 resourceParams.dwLsbNum = MHW_COMMON_MI_GENERAL_SHIFT; 395 resourceParams.HwCommandType = MOS_MI_COPY_MEM_MEM; 396 resourceParams.bIsWritable = false; 397 398 MHW_MI_CHK_STATUS(AddResourceToCmd( 399 m_osInterface, 400 cmdBuffer, 401 &resourceParams)); 402 403 MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, cmd.byteSize)); 404 405 return MOS_STATUS_SUCCESS; 406 } 407 AddMiStoreRegisterMemCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_MI_STORE_REGISTER_MEM_PARAMS params)408 MOS_STATUS AddMiStoreRegisterMemCmd( 409 PMOS_COMMAND_BUFFER cmdBuffer, 410 PMHW_MI_STORE_REGISTER_MEM_PARAMS params) 411 { 412 MHW_FUNCTION_ENTER; 413 414 MHW_MI_CHK_NULL(m_osInterface); 415 MHW_MI_CHK_NULL(cmdBuffer); 416 MHW_MI_CHK_NULL(params); 417 MHW_MI_CHK_NULL(params->presStoreBuffer); 418 419 typename TMiCmds::MI_STORE_REGISTER_MEM_CMD cmd; 420 MHW_RESOURCE_PARAMS resourceParams; 421 MOS_ZeroMemory(&resourceParams, sizeof(resourceParams)); 422 resourceParams.presResource = params->presStoreBuffer; 423 resourceParams.dwOffset = params->dwOffset; 424 resourceParams.pdwCmd = cmd.DW2_3.Value; 425 resourceParams.dwLocationInCmd = 2; 426 resourceParams.dwLsbNum = MHW_COMMON_MI_GENERAL_SHIFT; 427 resourceParams.HwCommandType = MOS_MI_STORE_REGISTER_MEM; 428 resourceParams.bIsWritable = true; 429 430 MHW_MI_CHK_STATUS(AddResourceToCmd( 431 m_osInterface, 432 cmdBuffer, 433 &resourceParams)); 434 435 cmd.DW0.UseGlobalGtt = IsGlobalGttInUse(); 436 cmd.DW1.RegisterAddress = params->dwRegister >> 2; 437 438 MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, cmd.byteSize)); 439 440 return MOS_STATUS_SUCCESS; 441 } 442 AddMiLoadRegisterMemCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_MI_LOAD_REGISTER_MEM_PARAMS params)443 MOS_STATUS AddMiLoadRegisterMemCmd( 444 PMOS_COMMAND_BUFFER cmdBuffer, 445 PMHW_MI_LOAD_REGISTER_MEM_PARAMS params) 446 { 447 MHW_FUNCTION_ENTER; 448 449 MHW_MI_CHK_NULL(m_osInterface); 450 MHW_MI_CHK_NULL(cmdBuffer); 451 MHW_MI_CHK_NULL(params); 452 MHW_MI_CHK_NULL(params->presStoreBuffer); 453 454 typename TMiCmds::MI_LOAD_REGISTER_MEM_CMD cmd; 455 MHW_RESOURCE_PARAMS resourceParams; 456 MOS_ZeroMemory(&resourceParams, sizeof(resourceParams)); 457 resourceParams.presResource = params->presStoreBuffer; 458 resourceParams.dwOffset = params->dwOffset; 459 resourceParams.pdwCmd = cmd.DW2_3.Value; 460 resourceParams.dwLocationInCmd = 2; 461 resourceParams.dwLsbNum = MHW_COMMON_MI_GENERAL_SHIFT; 462 resourceParams.HwCommandType = MOS_MI_LOAD_REGISTER_MEM; 463 resourceParams.bIsWritable = true; 464 465 MHW_MI_CHK_STATUS(AddResourceToCmd( 466 m_osInterface, 467 cmdBuffer, 468 &resourceParams)); 469 470 cmd.DW0.UseGlobalGtt = IsGlobalGttInUse(); 471 cmd.DW1.RegisterAddress = params->dwRegister >> 2; 472 473 MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, cmd.byteSize)); 474 475 return MOS_STATUS_SUCCESS; 476 } 477 AddMiLoadRegisterImmCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_MI_LOAD_REGISTER_IMM_PARAMS params)478 MOS_STATUS AddMiLoadRegisterImmCmd( 479 PMOS_COMMAND_BUFFER cmdBuffer, 480 PMHW_MI_LOAD_REGISTER_IMM_PARAMS params) 481 { 482 MHW_FUNCTION_ENTER; 483 484 MHW_MI_CHK_NULL(m_osInterface); 485 MHW_MI_CHK_NULL(cmdBuffer); 486 MHW_MI_CHK_NULL(params); 487 488 typename TMiCmds::MI_LOAD_REGISTER_IMM_CMD cmd; 489 cmd.DW1.RegisterOffset = params->dwRegister >> 2; 490 cmd.DW2.DataDword = params->dwData; 491 492 MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, cmd.byteSize)); 493 494 return MOS_STATUS_SUCCESS; 495 } 496 AddMiLoadRegisterRegCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_MI_LOAD_REGISTER_REG_PARAMS params)497 MOS_STATUS AddMiLoadRegisterRegCmd( 498 PMOS_COMMAND_BUFFER cmdBuffer, 499 PMHW_MI_LOAD_REGISTER_REG_PARAMS params) 500 { 501 MHW_FUNCTION_ENTER; 502 503 MHW_MI_CHK_NULL(m_osInterface); 504 MHW_MI_CHK_NULL(cmdBuffer); 505 MHW_MI_CHK_NULL(params); 506 507 typename TMiCmds::MI_LOAD_REGISTER_REG_CMD cmd; 508 cmd.DW1.SourceRegisterAddress = params->dwSrcRegister >> 2; 509 cmd.DW2.DestinationRegisterAddress = params->dwDstRegister >> 2; 510 511 MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, cmd.byteSize)); 512 513 return MOS_STATUS_SUCCESS; 514 } 515 AddMiMathCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_MI_MATH_PARAMS params)516 MOS_STATUS AddMiMathCmd( 517 PMOS_COMMAND_BUFFER cmdBuffer, 518 PMHW_MI_MATH_PARAMS params) 519 { 520 MHW_FUNCTION_ENTER; 521 522 MHW_MI_CHK_NULL(m_osInterface); 523 MHW_MI_CHK_NULL(cmdBuffer); 524 MHW_MI_CHK_NULL(params); 525 526 if (params->dwNumAluParams == 0 || params->pAluPayload == nullptr) 527 { 528 MHW_ASSERTMESSAGE("MI_MATH requires a valid payload"); 529 return MOS_STATUS_INVALID_PARAMETER; 530 } 531 532 typename TMiCmds::MI_MATH_CMD cmd; 533 cmd.DW0.DwordLength = params->dwNumAluParams - 1; 534 535 MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, cmd.byteSize)); 536 537 MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand( 538 cmdBuffer, 539 ¶ms->pAluPayload[0], 540 sizeof(MHW_MI_ALU_PARAMS)* params->dwNumAluParams)); 541 542 return MOS_STATUS_SUCCESS; 543 } 544 AddMiSetPredicateCmd(PMOS_COMMAND_BUFFER cmdBuffer,MHW_MI_SET_PREDICATE_ENABLE enableFlag)545 MOS_STATUS AddMiSetPredicateCmd( 546 PMOS_COMMAND_BUFFER cmdBuffer, 547 MHW_MI_SET_PREDICATE_ENABLE enableFlag) 548 { 549 MHW_FUNCTION_ENTER; 550 551 MHW_MI_CHK_NULL(m_osInterface); 552 MHW_MI_CHK_NULL(cmdBuffer); 553 554 typename TMiCmds::MI_SET_PREDICATE_CMD cmd; 555 cmd.DW0.PredicateEnable = enableFlag; 556 MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, cmd.byteSize)); 557 558 return MOS_STATUS_SUCCESS; 559 } 560 AddMiAtomicCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_MI_ATOMIC_PARAMS params)561 MOS_STATUS AddMiAtomicCmd( 562 PMOS_COMMAND_BUFFER cmdBuffer, 563 PMHW_MI_ATOMIC_PARAMS params) 564 { 565 MHW_FUNCTION_ENTER; 566 567 MHW_MI_CHK_NULL(m_osInterface); 568 MHW_MI_CHK_NULL(cmdBuffer); 569 MHW_MI_CHK_NULL(params); 570 MHW_MI_CHK_NULL(params->pOsResource); 571 572 typename TMiCmds::MI_ATOMIC_CMD cmd; 573 MHW_RESOURCE_PARAMS resourceParams; 574 MOS_ZeroMemory(&resourceParams, sizeof(resourceParams)); 575 resourceParams.presResource = params->pOsResource; 576 resourceParams.dwOffset = params->dwResourceOffset; 577 resourceParams.pdwCmd = &(cmd.DW1.Value); 578 resourceParams.dwLocationInCmd = 1; 579 resourceParams.dwLsbNum = MHW_COMMON_MI_GENERAL_SHIFT; 580 resourceParams.HwCommandType = MOS_MI_ATOMIC; 581 resourceParams.bIsWritable = true; 582 583 MHW_MI_CHK_STATUS(AddResourceToCmd( 584 m_osInterface, 585 cmdBuffer, 586 &resourceParams)); 587 588 cmd.DW0.DwordLength = params->bInlineData ? 1 : 9; 589 cmd.DW0.MemoryType = IsGlobalGttInUse(); 590 cmd.DW0.ReturnDataControl = params->bReturnData; 591 if (params->dwDataSize == sizeof(uint32_t)) 592 { 593 cmd.DW0.DataSize = cmd.DATA_SIZE_DWORD; 594 } 595 else if (params->dwDataSize == sizeof(uint64_t)) 596 { 597 cmd.DW0.DataSize = cmd.DATA_SIZE_QWORD; 598 } 599 else if (params->dwDataSize == sizeof(uint64_t)* 2) 600 { 601 cmd.DW0.DataSize = cmd.DATA_SIZE_OCTWORD; 602 } 603 else 604 { 605 MHW_ASSERTMESSAGE("Invalid data size provided"); 606 return MOS_STATUS_INVALID_PARAMETER; 607 } 608 609 if (cmd.DW0.DataSize == cmd.DATA_SIZE_QWORD) 610 { 611 cmd.DW0.AtomicOpcode = atomicQword; 612 } 613 else if (cmd.DW0.DataSize == cmd.DATA_SIZE_OCTWORD) 614 { 615 if (params->Operation != MHW_MI_ATOMIC_CMP) 616 { 617 MHW_ASSERTMESSAGE("An OCTWORD may only be used in the case of a compare operation!"); 618 return MOS_STATUS_INVALID_PARAMETER; 619 } 620 cmd.DW0.AtomicOpcode = atomicOctword; 621 } 622 cmd.DW0.AtomicOpcode = CreateMiAtomicOpcode( 623 cmd.DW0.AtomicOpcode, 624 params->Operation); 625 if (cmd.DW0.AtomicOpcode == atomicInvalid) 626 { 627 MHW_ASSERTMESSAGE("No MI_ATOMIC opcode could be generated"); 628 return MOS_STATUS_INVALID_PARAMETER; 629 } 630 631 cmd.DW0.InlineData = params->bInlineData; 632 cmd.DW0.DwordLength = params->bInlineData ? 9 : 1; 633 634 if (params->bInlineData) 635 { 636 cmd.DW3.Operand1DataDword0 = params->dwOperand1Data[0]; 637 cmd.DW4.Operand2DataDword0 = params->dwOperand2Data[0]; 638 cmd.DW5.Operand1DataDword1 = params->dwOperand1Data[1]; 639 cmd.DW6.Operand2DataDword1 = params->dwOperand2Data[1]; 640 cmd.DW7.Operand1DataDword2 = params->dwOperand1Data[2]; 641 cmd.DW8.Operand2DataDword2 = params->dwOperand2Data[3]; 642 cmd.DW9.Operand1DataDword3 = params->dwOperand1Data[3]; 643 cmd.DW10.Operand2DataDword3 = params->dwOperand2Data[3]; 644 } 645 646 MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, cmd.byteSize)); 647 648 return MOS_STATUS_SUCCESS; 649 } 650 AddMiSemaphoreWaitCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_MI_SEMAPHORE_WAIT_PARAMS params)651 MOS_STATUS AddMiSemaphoreWaitCmd( 652 PMOS_COMMAND_BUFFER cmdBuffer, 653 PMHW_MI_SEMAPHORE_WAIT_PARAMS params) 654 { 655 MHW_FUNCTION_ENTER; 656 657 MHW_MI_CHK_NULL(m_osInterface); 658 MHW_MI_CHK_NULL(cmdBuffer); 659 MHW_MI_CHK_NULL(params); 660 MHW_MI_CHK_NULL(params->presSemaphoreMem); 661 662 typename TMiCmds::MI_SEMAPHORE_WAIT_CMD cmd; 663 MHW_RESOURCE_PARAMS resourceParams; 664 MOS_ZeroMemory(&resourceParams, sizeof(resourceParams)); 665 resourceParams.presResource = params->presSemaphoreMem; 666 resourceParams.dwOffset = params->dwResourceOffset; 667 resourceParams.pdwCmd = cmd.DW2_3.Value; 668 resourceParams.dwLocationInCmd = 2; 669 resourceParams.dwLsbNum = MHW_COMMON_MI_GENERAL_SHIFT; 670 resourceParams.HwCommandType = MOS_MI_SEMAPHORE_WAIT; 671 672 MHW_MI_CHK_STATUS(AddResourceToCmd( 673 m_osInterface, 674 cmdBuffer, 675 &resourceParams)); 676 677 cmd.DW0.MemoryType = IsGlobalGttInUse(); 678 cmd.DW0.WaitMode = params->bPollingWaitMode; 679 680 cmd.DW0.CompareOperation = params->CompareOperation; 681 cmd.DW1.SemaphoreDataDword = params->dwSemaphoreData; 682 683 MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, cmd.byteSize)); 684 685 return MOS_STATUS_SUCCESS; 686 } 687 AddMiArbCheckCmd(PMOS_COMMAND_BUFFER cmdBuffer)688 MOS_STATUS AddMiArbCheckCmd( 689 PMOS_COMMAND_BUFFER cmdBuffer) 690 { 691 MHW_FUNCTION_ENTER; 692 693 MHW_MI_CHK_NULL(m_osInterface); 694 MHW_MI_CHK_NULL(cmdBuffer); 695 696 typename TMiCmds::MI_ARB_CHECK_CMD cmd; 697 MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, cmd.byteSize)); 698 699 return MOS_STATUS_SUCCESS; 700 } 701 AddPipeControl(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_BATCH_BUFFER batchBuffer,PMHW_PIPE_CONTROL_PARAMS params)702 MOS_STATUS AddPipeControl( 703 PMOS_COMMAND_BUFFER cmdBuffer, 704 PMHW_BATCH_BUFFER batchBuffer, 705 PMHW_PIPE_CONTROL_PARAMS params) 706 { 707 MHW_FUNCTION_ENTER; 708 709 MHW_MI_CHK_NULL(params); 710 711 if (cmdBuffer == nullptr && batchBuffer == nullptr) 712 { 713 MHW_ASSERTMESSAGE("There was no valid buffer to add the HW command to."); 714 return MOS_STATUS_NULL_POINTER; 715 } 716 717 typename TMiCmds::PIPE_CONTROL_CMD cmd; 718 cmd.DW1.PipeControlFlushEnable = true; 719 cmd.DW1.CommandStreamerStallEnable = !params->bDisableCSStall; 720 cmd.DW4_5.Value[0] = params->dwDataDW1; 721 cmd.DW4_5.Value[1] = params->dwDataDW2; 722 723 if (params->presDest) 724 { 725 cmd.DW1.PostSyncOperation = params->dwPostSyncOp; 726 cmd.DW1.DestinationAddressType = UseGlobalGtt.m_cs; 727 728 MHW_RESOURCE_PARAMS resourceParams; 729 MOS_ZeroMemory(&resourceParams, sizeof(resourceParams)); 730 resourceParams.presResource = params->presDest; 731 resourceParams.dwOffset = params->dwResourceOffset; 732 resourceParams.pdwCmd = &(cmd.DW2.Value); 733 resourceParams.dwLocationInCmd = 2; 734 resourceParams.dwLsbNum = MHW_COMMON_MI_PIPE_CONTROL_SHIFT; 735 resourceParams.bIsWritable = true; 736 resourceParams.HwCommandType = MOS_PIPE_CONTROL; 737 738 MHW_MI_CHK_STATUS(AddResourceToCmd( 739 m_osInterface, 740 cmdBuffer, 741 &resourceParams)); 742 } 743 else 744 { 745 cmd.DW1.StateCacheInvalidationEnable = true; 746 cmd.DW1.ConstantCacheInvalidationEnable = true; 747 cmd.DW1.VfCacheInvalidationEnable = true; 748 cmd.DW1.InstructionCacheInvalidateEnable = true; 749 cmd.DW1.RenderTargetCacheFlushEnable = true; 750 cmd.DW1.PostSyncOperation = cmd.POST_SYNC_OPERATION_NOWRITE; 751 } 752 753 // Cache flush mode 754 switch (params->dwFlushMode) 755 { 756 // Flush all Write caches 757 case MHW_FLUSH_WRITE_CACHE: 758 cmd.DW1.RenderTargetCacheFlushEnable = true; 759 cmd.DW1.DcFlushEnable = true; 760 break; 761 762 // Invalidate all Read-only caches 763 case MHW_FLUSH_READ_CACHE: 764 cmd.DW1.RenderTargetCacheFlushEnable = false; 765 cmd.DW1.StateCacheInvalidationEnable = true; 766 cmd.DW1.ConstantCacheInvalidationEnable = true; 767 cmd.DW1.VfCacheInvalidationEnable = true; 768 cmd.DW1.InstructionCacheInvalidateEnable = true; 769 break; 770 771 // Custom flush parameters 772 case MHW_FLUSH_CUSTOM: 773 cmd.DW1.RenderTargetCacheFlushEnable = params->bFlushRenderTargetCache; 774 cmd.DW1.DcFlushEnable = params->bFlushRenderTargetCache; // same as above 775 cmd.DW1.StateCacheInvalidationEnable = params->bInvalidateStateCache; 776 cmd.DW1.ConstantCacheInvalidationEnable = params->bInvalidateConstantCache; 777 cmd.DW1.VfCacheInvalidationEnable = params->bInvalidateVFECache; 778 cmd.DW1.InstructionCacheInvalidateEnable = params->bInvalidateInstructionCache; 779 cmd.DW1.TlbInvalidate = params->bTlbInvalidate; 780 cmd.DW1.TextureCacheInvalidationEnable = params->bInvalidateTextureCache; 781 break; 782 783 // No-flush operation requested 784 case MHW_FLUSH_NONE: 785 default: 786 cmd.DW1.RenderTargetCacheFlushEnable = false; 787 break; 788 } 789 790 // When PIPE_CONTROL stall bit is set, one of the following must also be set, otherwise set stall bit to 0 791 if (cmd.DW1.CommandStreamerStallEnable && 792 (cmd.DW1.DcFlushEnable == 0 && cmd.DW1.NotifyEnable == 0 && cmd.DW1.PostSyncOperation == 0 && 793 cmd.DW1.DepthStallEnable == 0 && cmd.DW1.StallAtPixelScoreboard == 0 && cmd.DW1.DepthCacheFlushEnable == 0 && 794 cmd.DW1.RenderTargetCacheFlushEnable == 0)) 795 { 796 cmd.DW1.CommandStreamerStallEnable = 0; 797 } 798 799 if (params->bGenericMediaStateClear) 800 { 801 cmd.DW1.GenericMediaStateClear = true; 802 } 803 804 if (params->bIndirectStatePointersDisable) 805 { 806 cmd.DW1.IndirectStatePointersDisable = true; 807 } 808 809 MHW_MI_CHK_STATUS(Mhw_AddCommandCmdOrBB(m_osInterface, cmdBuffer, batchBuffer, &cmd, cmd.byteSize)); 810 811 return MOS_STATUS_SUCCESS; 812 } 813 AddMfxWaitCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_BATCH_BUFFER batchBuffer,bool stallVdboxPipeline)814 MOS_STATUS AddMfxWaitCmd( 815 PMOS_COMMAND_BUFFER cmdBuffer, 816 PMHW_BATCH_BUFFER batchBuffer, 817 bool stallVdboxPipeline) 818 { 819 MHW_FUNCTION_ENTER; 820 821 if (cmdBuffer == nullptr && batchBuffer == nullptr) 822 { 823 MHW_ASSERTMESSAGE("There was no valid buffer to add the HW command to."); 824 return MOS_STATUS_NULL_POINTER; 825 } 826 827 typename TMiCmds::MFX_WAIT_CMD cmd; 828 cmd.DW0.MfxSyncControlFlag = stallVdboxPipeline; 829 830 // set the protection bit based on CP status 831 MHW_MI_CHK_STATUS(m_cpInterface->SetProtectionSettingsForMfxWait(m_osInterface, &cmd)); 832 833 MHW_MI_CHK_STATUS(Mhw_AddCommandCmdOrBB(m_osInterface, cmdBuffer, batchBuffer, &cmd, cmd.byteSize)); 834 835 return MOS_STATUS_SUCCESS; 836 } 837 838 MOS_STATUS AddMediaStateFlush( 839 PMOS_COMMAND_BUFFER cmdBuffer, 840 PMHW_BATCH_BUFFER batchBuffer, 841 PMHW_MEDIA_STATE_FLUSH_PARAM params = nullptr) 842 { 843 MHW_FUNCTION_ENTER; 844 845 if (cmdBuffer == nullptr && batchBuffer == nullptr) 846 { 847 MHW_ASSERTMESSAGE("There was no valid buffer to add the HW command to."); 848 return MOS_STATUS_NULL_POINTER; 849 } 850 851 return MOS_STATUS_SUCCESS; 852 } 853 SkipMiBatchBufferEndBb(PMHW_BATCH_BUFFER batchBuffer)854 MOS_STATUS SkipMiBatchBufferEndBb( 855 PMHW_BATCH_BUFFER batchBuffer) 856 { 857 MHW_FUNCTION_ENTER; 858 859 MHW_MI_CHK_NULL(batchBuffer); 860 861 return MOS_STATUS_SUCCESS; 862 } 863 GetMiFlushDwCmdSize()864 inline uint32_t GetMiFlushDwCmdSize() 865 { 866 return TMiCmds::MI_FLUSH_DW_CMD::byteSize; 867 } 868 GetMiBatchBufferStartCmdSize()869 inline uint32_t GetMiBatchBufferStartCmdSize() 870 { 871 return TMiCmds::MI_BATCH_BUFFER_START_CMD::byteSize; 872 } 873 GetMiBatchBufferEndCmdSize()874 inline uint32_t GetMiBatchBufferEndCmdSize() 875 { 876 return TMiCmds::MI_BATCH_BUFFER_END_CMD::byteSize; 877 } 878 AddBatchBufferEndInsertionFlag(MOS_COMMAND_BUFFER & constructedCmdBuf)879 MOS_STATUS AddBatchBufferEndInsertionFlag( 880 MOS_COMMAND_BUFFER &constructedCmdBuf) 881 { 882 MHW_FUNCTION_ENTER; 883 884 typename TMiCmds::MI_BATCH_BUFFER_END_CMD cmd; 885 886 MHW_CHK_NULL_RETURN(constructedCmdBuf.pCmdPtr); 887 *((typename TMiCmds::MI_BATCH_BUFFER_END_CMD *)(constructedCmdBuf.pCmdPtr)) = cmd; 888 889 return MOS_STATUS_SUCCESS; 890 } 891 SetWatchdogTimerThreshold(uint32_t frameWidth,uint32_t frameHeight,bool isEncoder)892 MOS_STATUS SetWatchdogTimerThreshold( 893 uint32_t frameWidth, 894 uint32_t frameHeight, 895 bool isEncoder) 896 { 897 MHW_FUNCTION_ENTER; 898 899 return MOS_STATUS_SUCCESS; 900 } 901 SetWatchdogTimerRegisterOffset(MOS_GPU_CONTEXT gpuContext)902 MOS_STATUS SetWatchdogTimerRegisterOffset( 903 MOS_GPU_CONTEXT gpuContext) 904 { 905 MHW_FUNCTION_ENTER; 906 907 return MOS_STATUS_SUCCESS; 908 } 909 AddWatchdogTimerStartCmd(PMOS_COMMAND_BUFFER cmdBuffer)910 MOS_STATUS AddWatchdogTimerStartCmd( 911 PMOS_COMMAND_BUFFER cmdBuffer) 912 { 913 MHW_FUNCTION_ENTER; 914 915 return MOS_STATUS_SUCCESS; 916 } 917 AddWatchdogTimerStopCmd(PMOS_COMMAND_BUFFER cmdBuffer)918 MOS_STATUS AddWatchdogTimerStopCmd( 919 PMOS_COMMAND_BUFFER cmdBuffer) 920 { 921 MHW_FUNCTION_ENTER; 922 923 return MOS_STATUS_SUCCESS; 924 } 925 }; 926 927 #endif // __MHW_MI_GENERIC_H__ 928