1 /* 2 * Copyright (c) 2020, 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 encode_av1_brc_update_packet.cpp 25 //! \brief Defines the implementation of av1 brc update packet 26 //! 27 28 #include "encode_av1_brc_update_packet.h" 29 #include "codechal_debug.h" 30 #include "encode_av1_brc.h" 31 #include "encode_av1_vdenc_packet.h" 32 #include "encode_av1_vdenc_lpla_enc.h" 33 #if _MEDIA_RESERVED 34 #include "encode_av1_scc.h" 35 #endif 36 37 namespace encode 38 { Init()39 MOS_STATUS Av1BrcUpdatePkt::Init() 40 { 41 ENCODE_FUNC_CALL(); 42 HUC_CHK_STATUS_RETURN(EncodeHucPkt::Init()); 43 44 ENCODE_CHK_NULL_RETURN(m_pipeline); 45 m_allocator = m_pipeline->GetEncodeAllocator(); 46 ENCODE_CHK_NULL_RETURN(m_allocator); 47 48 ENCODE_CHK_NULL_RETURN(m_featureManager); 49 m_basicFeature = dynamic_cast<Av1BasicFeature *>(m_featureManager->GetFeature(Av1FeatureIDs::basicFeature)); 50 ENCODE_CHK_NULL_RETURN(m_basicFeature); 51 52 return MOS_STATUS_SUCCESS; 53 } 54 CalculateCommandSize(uint32_t & commandBufferSize,uint32_t & requestedPatchListSize)55 MOS_STATUS Av1BrcUpdatePkt::CalculateCommandSize(uint32_t &commandBufferSize, uint32_t &requestedPatchListSize) 56 { 57 ENCODE_FUNC_CALL(); 58 59 auto osInterface = m_hwInterface->GetOsInterface(); 60 ENCODE_CHK_NULL_RETURN(osInterface); 61 62 uint32_t hucCommandsSize = 0; 63 uint32_t hucPatchListSize = 0; 64 MHW_VDBOX_STATE_CMDSIZE_PARAMS stateCmdSizeParams; 65 66 ENCODE_CHK_STATUS_RETURN(m_hwInterface->GetHucStateCommandSize( 67 m_basicFeature->m_mode, (uint32_t*)&hucCommandsSize, (uint32_t*)&hucPatchListSize, &stateCmdSizeParams)); 68 69 commandBufferSize = hucCommandsSize; 70 requestedPatchListSize = osInterface->bUsesPatchList ? hucPatchListSize : 0; 71 72 if (m_pipeline->IsSingleTaskPhaseSupported()) 73 { 74 commandBufferSize *= m_pipeline->GetPassNum(); 75 } 76 77 // 4K align since allocation is in chunks of 4K bytes. 78 commandBufferSize = MOS_ALIGN_CEIL(commandBufferSize, CODECHAL_PAGE_SIZE); 79 80 return MOS_STATUS_SUCCESS; 81 } 82 AllocateResources()83 MOS_STATUS Av1BrcUpdatePkt::AllocateResources() 84 { 85 ENCODE_FUNC_CALL(); 86 ENCODE_CHK_STATUS_RETURN(EncodeHucPkt::AllocateResources()); 87 88 MOS_ALLOC_GFXRES_PARAMS allocParamsForBufferLinear; 89 MOS_ZeroMemory(&allocParamsForBufferLinear, sizeof(MOS_ALLOC_GFXRES_PARAMS)); 90 allocParamsForBufferLinear.Type = MOS_GFXRES_BUFFER; 91 allocParamsForBufferLinear.TileType = MOS_TILE_LINEAR; 92 allocParamsForBufferLinear.Format = Format_Buffer; 93 94 MOS_RESOURCE *allocatedbuffer = nullptr; 95 96 for (auto k = 0; k < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; k++) 97 { 98 // Const Data buffer 99 allocParamsForBufferLinear.dwBytes = MOS_ALIGN_CEIL(m_vdencBrcConstDataBufferSize, CODECHAL_PAGE_SIZE); 100 allocParamsForBufferLinear.pBufName = "VDENC BRC Const Data Buffer"; 101 allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_WRITE; 102 allocatedbuffer = m_allocator->AllocateResource(allocParamsForBufferLinear, true); 103 ENCODE_CHK_NULL_RETURN(allocatedbuffer); 104 m_vdencBrcConstDataBuffer[k] = *allocatedbuffer; 105 106 // Pak insert buffer (input for HuC FW) 107 allocParamsForBufferLinear.dwBytes = CODECHAL_PAGE_SIZE; 108 allocParamsForBufferLinear.pBufName = "VDENC Read Batch Buffer"; 109 allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_WRITE; 110 allocatedbuffer = m_allocator->AllocateResource(allocParamsForBufferLinear, true); 111 ENCODE_CHK_NULL_RETURN(allocatedbuffer); 112 m_vdencPakInsertBatchBuffer[k] = *allocatedbuffer; 113 114 for (auto i = 0; i < VDENC_BRC_NUM_OF_PASSES; i++) 115 { 116 // VDEnc read batch buffer (input for HuC FW) 117 allocParamsForBufferLinear.dwBytes = MOS_ALIGN_CEIL(m_hwInterface->m_vdencReadBatchBufferSize, CODECHAL_PAGE_SIZE); 118 allocParamsForBufferLinear.pBufName = "VDENC Read Batch Buffer"; 119 allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_WRITE; 120 allocatedbuffer = m_allocator->AllocateResource(allocParamsForBufferLinear, true); 121 ENCODE_CHK_NULL_RETURN(allocatedbuffer); 122 m_vdencReadBatchBuffer[k][i] = *allocatedbuffer; 123 124 // BRC update DMEM 125 allocParamsForBufferLinear.dwBytes = MOS_ALIGN_CEIL(m_vdencBrcUpdateDmemBufferSize, CODECHAL_CACHELINE_SIZE); 126 allocParamsForBufferLinear.pBufName = "VDENC BrcUpdate DmemBuffer"; 127 allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_WRITE; 128 allocatedbuffer = m_allocator->AllocateResource(allocParamsForBufferLinear, true); 129 ENCODE_CHK_NULL_RETURN(allocatedbuffer); 130 m_vdencBrcUpdateDmemBuffer[k][i] = *allocatedbuffer; 131 } 132 } 133 134 return MOS_STATUS_SUCCESS; 135 } 136 SetConstDataHuCBrcUpdate()137 MOS_STATUS Av1BrcUpdatePkt::SetConstDataHuCBrcUpdate() 138 { 139 ENCODE_FUNC_CALL(); 140 141 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 142 143 auto hucConstData = (VdencAv1HucBrcConstantData *)m_allocator->LockResourceForWrite(&m_vdencBrcConstDataBuffer[m_pipeline->m_currRecycledBufIdx]); 144 ENCODE_CHK_NULL_RETURN(hucConstData); 145 146 RUN_FEATURE_INTERFACE_RETURN(Av1Brc, Av1FeatureIDs::av1BrcFeature, SetConstForUpdate, hucConstData); 147 148 m_allocator->UnLock(&m_vdencBrcConstDataBuffer[m_pipeline->m_currRecycledBufIdx]); 149 150 return eStatus; 151 } 152 Submit(MOS_COMMAND_BUFFER * commandBuffer,uint8_t packetPhase)153 MOS_STATUS Av1BrcUpdatePkt::Submit(MOS_COMMAND_BUFFER *commandBuffer, uint8_t packetPhase) 154 { 155 ENCODE_FUNC_CALL(); 156 157 ENCODE_CHK_NULL_RETURN(m_basicFeature); 158 ENCODE_CHK_NULL_RETURN(m_basicFeature->m_recycleBuf); 159 160 ENCODE_CHK_STATUS_RETURN(ConstructBatchBufferHuCBRC(&m_vdencReadBatchBuffer[m_pipeline->m_currRecycledBufIdx][m_pipeline->GetCurrentPass()])); 161 ENCODE_CHK_STATUS_RETURN(ConstructPakInsertHucBRC(&m_vdencPakInsertBatchBuffer[m_pipeline->m_currRecycledBufIdx])); 162 163 bool firstTaskInPhase = packetPhase & firstPacket; 164 bool requestProlog = false; 165 166 auto brcFeature = dynamic_cast<Av1Brc *>(m_featureManager->GetFeature(Av1FeatureIDs::av1BrcFeature)); 167 ENCODE_CHK_NULL_RETURN(brcFeature); 168 169 uint16_t perfTag = m_pipeline->IsFirstPass() ? CODECHAL_ENCODE_PERFTAG_CALL_BRC_UPDATE : CODECHAL_ENCODE_PERFTAG_CALL_BRC_UPDATE_SECOND_PASS; 170 uint16_t pictureType = (m_basicFeature->m_pictureCodingType == I_TYPE) ? 0 : (m_basicFeature->m_ref.IsLowDelay() ? (m_basicFeature->m_ref.IsPFrame() ? 1 : 3) : 2); 171 SetPerfTag(perfTag, (uint16_t)m_basicFeature->m_mode, pictureType); 172 173 if (!m_pipeline->IsSingleTaskPhaseSupported() || firstTaskInPhase) 174 { 175 // Send command buffer header at the beginning (OS dependent) 176 requestProlog = true; 177 } 178 179 ENCODE_CHK_STATUS_RETURN(Execute(commandBuffer, true, requestProlog, BRC_UPDATE)); 180 181 if (!IsHuCStsUpdNeeded()) 182 { 183 // Write HUC_STATUS mask: DW1 (mask value) 184 auto &storeDataParams = m_miItf->MHW_GETPAR_F(MI_STORE_DATA_IMM)(); 185 storeDataParams = {}; 186 storeDataParams.pOsResource = m_basicFeature->m_recycleBuf->GetBuffer(VdencBrcPakMmioBuffer, 0); 187 storeDataParams.dwResourceOffset = sizeof(uint32_t); 188 storeDataParams.dwValue = AV1_BRC_HUC_STATUS_REENCODE_MASK; 189 ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_STORE_DATA_IMM)(commandBuffer)); 190 191 // store HUC_STATUS register: DW0 (actual value) 192 ENCODE_CHK_COND_RETURN((m_vdboxIndex > MHW_VDBOX_NODE_1), "ERROR - vdbox index exceed the maximum"); 193 auto mmioRegisters = m_hucItf->GetMmioRegisters(m_vdboxIndex); 194 auto &storeRegParams = m_miItf->MHW_GETPAR_F(MI_STORE_REGISTER_MEM)(); 195 storeDataParams = {}; 196 storeRegParams.presStoreBuffer = m_basicFeature->m_recycleBuf->GetBuffer(VdencBrcPakMmioBuffer, 0); 197 storeRegParams.dwOffset = 0; 198 storeRegParams.dwRegister = mmioRegisters->hucStatusRegOffset; 199 ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_STORE_REGISTER_MEM)(commandBuffer)); 200 } 201 202 return MOS_STATUS_SUCCESS; 203 } 204 AddBBEnd(std::shared_ptr<mhw::mi::Itf> m_miItf,MOS_COMMAND_BUFFER & cmdBuffer)205 inline MOS_STATUS AddBBEnd(std::shared_ptr<mhw::mi::Itf> m_miItf, MOS_COMMAND_BUFFER& cmdBuffer) 206 { 207 ENCODE_FUNC_CALL(); 208 ENCODE_CHK_NULL_RETURN(m_miItf); 209 210 MHW_BATCH_BUFFER TempBatchBuffer = {}; 211 TempBatchBuffer.iSize = CODECHAL_PAGE_SIZE; 212 TempBatchBuffer.pData = (uint8_t *)cmdBuffer.pCmdBase; 213 TempBatchBuffer.iCurrent = cmdBuffer.iOffset; 214 TempBatchBuffer.iRemaining = cmdBuffer.iRemaining; 215 216 ENCODE_CHK_STATUS_RETURN(m_miItf->AddMiBatchBufferEnd(nullptr, &TempBatchBuffer)); 217 218 cmdBuffer.pCmdPtr += (TempBatchBuffer.iCurrent - cmdBuffer.iOffset) / 4; 219 cmdBuffer.iOffset = TempBatchBuffer.iCurrent; 220 cmdBuffer.iRemaining = TempBatchBuffer.iRemaining; 221 222 return MOS_STATUS_SUCCESS; 223 } 224 ConstructBatchBufferHuCBRC(PMOS_RESOURCE batchBuffer)225 MOS_STATUS Av1BrcUpdatePkt::ConstructBatchBufferHuCBRC(PMOS_RESOURCE batchBuffer) 226 { 227 ENCODE_FUNC_CALL(); 228 229 ENCODE_CHK_NULL_RETURN(batchBuffer); 230 231 auto batchbufferAddr = (uint8_t *)m_allocator->LockResourceForWrite(batchBuffer); 232 ENCODE_CHK_NULL_RETURN(batchbufferAddr); 233 MOS_COMMAND_BUFFER constructedCmdBuf; 234 MOS_ZeroMemory(&constructedCmdBuf, sizeof(constructedCmdBuf)); 235 constructedCmdBuf.pCmdBase = constructedCmdBuf.pCmdPtr = (uint32_t *)batchbufferAddr; 236 constructedCmdBuf.iRemaining = MOS_ALIGN_CEIL(m_hwInterface->m_vdencReadBatchBufferSize, CODECHAL_PAGE_SIZE); 237 238 /*--------------SLBB layout--------------------*/ 239 /*----Group1----*/ 240 //AVP_SEGMENT_STATE 241 //AVP_INLOOP_FILTER_STATE 242 //BB_END 243 // 244 /*----Group2----*/ 245 //VDENC_CMD1 246 //BB_END 247 // 248 /*----Group3----*/ 249 //VDENC_CMD2 250 //BB_END 251 // 252 /*----Group4----*/ 253 //AVP_PIC_STATE 254 //BB_END 255 //AVP_PIC_STATE (if multi tile) 256 //BB_END (if multi tile) 257 // 258 /*--------------End of SLBB layout--------------------*/ 259 260 SlbData slbData; 261 /*----Group1----*/ 262 slbData.avpSegmentStateOffset = (uint16_t)constructedCmdBuf.iOffset; 263 ENCODE_CHK_STATUS_RETURN(AddAllCmds_AVP_SEGMENT_STATE(&constructedCmdBuf)); 264 slbData.avpInloopFilterStateOffset = (uint16_t)constructedCmdBuf.iOffset; 265 SETPAR_AND_ADDCMD(AVP_INLOOP_FILTER_STATE, m_avpItf, &constructedCmdBuf); 266 ENCODE_CHK_STATUS_RETURN(AddBBEnd(m_miItf, constructedCmdBuf)); 267 /*----Group2----*/ 268 slbData.vdencCmd1Offset = (uint16_t)constructedCmdBuf.iOffset; 269 SETPAR_AND_ADDCMD(VDENC_CMD1, m_vdencItf, &constructedCmdBuf); 270 ENCODE_CHK_STATUS_RETURN(AddBBEnd(m_miItf, constructedCmdBuf)); 271 /*----Group3----*/ 272 slbData.vdencCmd2Offset = (uint16_t)constructedCmdBuf.iOffset; 273 SETPAR_AND_ADDCMD(VDENC_CMD2, m_vdencItf, &constructedCmdBuf); 274 ENCODE_CHK_STATUS_RETURN(AddBBEnd(m_miItf, constructedCmdBuf)); 275 /*----Group4----*/ 276 slbData.avpPicStateOffset = (uint16_t)constructedCmdBuf.iOffset; 277 ENCODE_CHK_STATUS_RETURN(AddAvpPicStateBaseOnTile(constructedCmdBuf, slbData)); 278 279 /*----Group5----*/ 280 if (m_basicFeature->m_av1PicParams->PicFlags.fields.PaletteModeEnable) 281 { 282 slbData.vdencTileSliceStateOffset = (uint16_t)constructedCmdBuf.iOffset; 283 ENCODE_CHK_STATUS_RETURN(AddVdencTileSliceBaseOnTile(constructedCmdBuf, slbData)); 284 } 285 286 slbData.slbSize = (uint16_t)constructedCmdBuf.iOffset - slbData.avpSegmentStateOffset; 287 288 RUN_FEATURE_INTERFACE_NO_RETURN(Av1Brc, Av1FeatureIDs::av1BrcFeature, SetSLBData, slbData); 289 290 m_allocator->UnLock(batchBuffer); 291 292 return MOS_STATUS_SUCCESS; 293 } 294 ConstructPakInsertHucBRC(PMOS_RESOURCE batchBuffer)295 MOS_STATUS Av1BrcUpdatePkt::ConstructPakInsertHucBRC(PMOS_RESOURCE batchBuffer) 296 { 297 ENCODE_FUNC_CALL(); 298 299 ENCODE_CHK_NULL_RETURN(batchBuffer); 300 301 RUN_FEATURE_INTERFACE_RETURN(Av1EncodeTile, Av1FeatureIDs::encodeTile, SetCurrentTile, 0, 0, m_pipeline); 302 303 auto batchbufferAddr = (uint8_t *)m_allocator->LockResourceForWrite(batchBuffer); 304 ENCODE_CHK_NULL_RETURN(batchbufferAddr); 305 306 MOS_COMMAND_BUFFER constructedCmdBuf; 307 MOS_ZeroMemory(&constructedCmdBuf, sizeof(constructedCmdBuf)); 308 constructedCmdBuf.pCmdBase = constructedCmdBuf.pCmdPtr = (uint32_t *)batchbufferAddr; 309 constructedCmdBuf.iRemaining = MOS_ALIGN_CEIL(m_hwInterface->m_vdencReadBatchBufferSize, CODECHAL_PAGE_SIZE); 310 311 auto brcFeature = dynamic_cast<Av1Brc *>(m_featureManager->GetFeature(Av1FeatureIDs::av1BrcFeature)); 312 ENCODE_CHK_NULL_RETURN(brcFeature); 313 auto slbData = brcFeature->GetSLBData(); 314 315 ENCODE_CHK_STATUS_RETURN(AddAllCmds_AVP_PAK_INSERT_OBJECT(&constructedCmdBuf)); 316 ENCODE_CHK_STATUS_RETURN(AddBBEnd(m_miItf, constructedCmdBuf)); 317 318 slbData.pakInsertSlbSize = (uint16_t)constructedCmdBuf.iOffset; 319 RUN_FEATURE_INTERFACE_NO_RETURN(Av1Brc, Av1FeatureIDs::av1BrcFeature, SetSLBData, slbData); 320 321 return MOS_STATUS_SUCCESS; 322 } 323 AddAvpPicStateBaseOnTile(MOS_COMMAND_BUFFER & cmdBuffer,SlbData & slbData)324 MOS_STATUS Av1BrcUpdatePkt::AddAvpPicStateBaseOnTile(MOS_COMMAND_BUFFER& cmdBuffer, SlbData &slbData) 325 { 326 ENCODE_FUNC_CALL(); 327 328 uint16_t numTileColumns = 1; 329 uint16_t numTileRows = 1; 330 bool firstTileInGroup = false; 331 uint32_t tileGroupIdx = 0; 332 RUN_FEATURE_INTERFACE_RETURN(Av1EncodeTile, Av1FeatureIDs::encodeTile, GetTileRowColumns, numTileRows, numTileColumns); 333 slbData.tileNum = numTileRows * numTileColumns; 334 335 for (uint32_t tileRow = 0; tileRow < numTileRows; tileRow++) 336 { 337 for (uint32_t tileCol = 0; tileCol < numTileColumns; tileCol++) 338 { 339 RUN_FEATURE_INTERFACE_RETURN(Av1EncodeTile, Av1FeatureIDs::encodeTile, SetCurrentTile, tileRow, tileCol, m_pipeline); 340 RUN_FEATURE_INTERFACE_NO_RETURN(Av1EncodeTile, Av1FeatureIDs::encodeTile, IsFirstTileInGroup, firstTileInGroup, tileGroupIdx); 341 #if _MEDIA_RESERVED 342 RUN_FEATURE_INTERFACE_RETURN(Av1Scc, Av1FeatureIDs::av1Scc, UpdateIBCStatusForCurrentTile); 343 #endif 344 if (firstTileInGroup) 345 { 346 SETPAR_AND_ADDCMD(AVP_PIC_STATE, m_avpItf, &cmdBuffer); 347 ENCODE_CHK_STATUS_RETURN(AddBBEnd(m_miItf, cmdBuffer)); 348 } 349 else 350 { 351 slbData.avpPicStateCmdNum = 2; 352 slbData.secondAvpPicStateOffset = (uint16_t)cmdBuffer.iOffset; 353 SETPAR_AND_ADDCMD(AVP_PIC_STATE, m_avpItf, &cmdBuffer); 354 ENCODE_CHK_STATUS_RETURN(AddBBEnd(m_miItf, cmdBuffer)); 355 break; 356 } 357 } 358 359 if (slbData.avpPicStateCmdNum == 2) 360 { 361 break; 362 } 363 } 364 365 // Add MI_NOOPs to align with CODECHAL_CACHELINE_SIZE 366 uint32_t size = (MOS_ALIGN_CEIL(cmdBuffer.iOffset, CODECHAL_CACHELINE_SIZE) - cmdBuffer.iOffset) / sizeof(uint32_t); 367 for (uint32_t i = 0; i < size; i++) 368 ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_NOOP)(&cmdBuffer)); 369 370 return MOS_STATUS_SUCCESS; 371 } 372 AddVdencTileSliceBaseOnTile(MOS_COMMAND_BUFFER & cmdBuffer,SlbData & slbData)373 MOS_STATUS Av1BrcUpdatePkt::AddVdencTileSliceBaseOnTile(MOS_COMMAND_BUFFER& cmdBuffer, SlbData& slbData) 374 { 375 ENCODE_FUNC_CALL(); 376 377 uint16_t numTileColumns = 1; 378 uint16_t numTileRows = 1; 379 RUN_FEATURE_INTERFACE_RETURN(Av1EncodeTile, Av1FeatureIDs::encodeTile, GetTileRowColumns, numTileRows, numTileColumns); 380 381 auto& par = m_vdencItf->MHW_GETPAR_F(VDENC_HEVC_VP9_TILE_SLICE_STATE)(); 382 par = {}; 383 384 for (uint32_t tileRow = 0; tileRow < numTileRows; tileRow++) 385 { 386 for (uint32_t tileCol = 0; tileCol < numTileColumns; tileCol++) 387 { 388 RUN_FEATURE_INTERFACE_RETURN(Av1EncodeTile, Av1FeatureIDs::encodeTile, SetCurrentTile, tileRow, tileCol, m_pipeline); 389 auto tileIdx = tileRow * numTileColumns + tileCol; 390 391 m_basicFeature->m_vdencTileSliceStart[tileIdx] = cmdBuffer.iOffset; 392 SETPAR_AND_ADDCMD(VDENC_HEVC_VP9_TILE_SLICE_STATE, m_vdencItf, &cmdBuffer); 393 ENCODE_CHK_STATUS_RETURN(AddBBEnd(m_miItf, cmdBuffer)); 394 395 // Add MI_NOOPs to align with CODECHAL_CACHELINE_SIZE 396 uint32_t size = (MOS_ALIGN_CEIL(cmdBuffer.iOffset, CODECHAL_CACHELINE_SIZE) - cmdBuffer.iOffset) / sizeof(uint32_t); 397 for (uint32_t i = 0; i < size; i++) 398 ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_NOOP)(&cmdBuffer)); 399 } 400 } 401 402 return MOS_STATUS_SUCCESS; 403 } 404 AddAllCmds_AVP_SEGMENT_STATE(PMOS_COMMAND_BUFFER cmdBuffer) const405 MOS_STATUS Av1BrcUpdatePkt::AddAllCmds_AVP_SEGMENT_STATE(PMOS_COMMAND_BUFFER cmdBuffer) const 406 { 407 ENCODE_FUNC_CALL(); 408 409 ENCODE_CHK_NULL_RETURN(m_featureManager); 410 411 auto& par = m_avpItf->MHW_GETPAR_F(AVP_SEGMENT_STATE)(); 412 par = {}; 413 414 auto segmentFeature = dynamic_cast<Av1Segmentation *>(m_featureManager->GetFeature(Av1FeatureIDs::av1Segmentation)); 415 ENCODE_CHK_NULL_RETURN(segmentFeature); 416 417 MHW_CHK_STATUS_RETURN(segmentFeature->MHW_SETPAR_F(AVP_SEGMENT_STATE)(par)); 418 419 const bool segmentEnabled = par.av1SegmentParams.m_enabled; 420 421 for (uint8_t i = 0; i < av1MaxSegments; i++) 422 { 423 par.currentSegmentId = i; 424 m_avpItf->MHW_ADDCMD_F(AVP_SEGMENT_STATE)(cmdBuffer); 425 426 // If segmentation is not enabled, then AV1_SEGMENT_STATE must still be sent once for SegmentID = 0 427 // If i == numSegments -1, means all segments are issued, break the loop 428 if (!segmentEnabled || (i == par.numSegments - 1)) 429 { 430 break; 431 } 432 } 433 434 return MOS_STATUS_SUCCESS; 435 } 436 AddAllCmds_AVP_PAK_INSERT_OBJECT(PMOS_COMMAND_BUFFER cmdBuffer) const437 MOS_STATUS Av1BrcUpdatePkt::AddAllCmds_AVP_PAK_INSERT_OBJECT(PMOS_COMMAND_BUFFER cmdBuffer) const 438 { 439 ENCODE_FUNC_CALL(); 440 441 ENCODE_CHK_NULL_RETURN(m_osInterface); 442 auto& params = m_avpItf->MHW_GETPAR_F(AVP_PAK_INSERT_OBJECT)(); 443 params = {}; 444 445 auto GetExtraData = [&]() { return params.bsBuffer->pBase + params.offset; }; 446 auto GetExtraSize = [&]() { return (params.bitSize + 7) >> 3; }; 447 448 // First, Send all other OBU bit streams other than tile group OBU when it's first tile in frame 449 uint32_t tileIdx = 0; 450 bool tgOBUValid = m_basicFeature->m_slcData[0].BitSize > 0 ? true : false; 451 452 RUN_FEATURE_INTERFACE_RETURN(Av1EncodeTile, Av1FeatureIDs::encodeTile, GetTileIdx, tileIdx); 453 454 if (tileIdx == 0) 455 { 456 uint32_t nalNum = 0; 457 for (uint32_t i = 0; i < MAX_NUM_OBU_TYPES && m_basicFeature->m_nalUnitParams[i]->uiSize > 0; i++) 458 { 459 nalNum++; 460 } 461 462 params.bsBuffer = &m_basicFeature->m_bsBuffer; 463 params.endOfHeaderInsertion = false; 464 465 // Support multiple packed header buffer 466 for (uint32_t i = 0; i < nalNum; i++) 467 { 468 uint32_t nalUnitSize = m_basicFeature->m_nalUnitParams[i]->uiSize; 469 uint32_t nalUnitOffset = m_basicFeature->m_nalUnitParams[i]->uiOffset; 470 471 ENCODE_ASSERT(nalUnitSize < CODECHAL_ENCODE_AV1_PAK_INSERT_UNCOMPRESSED_HEADER); 472 473 if (IsFrameHeader(*(m_basicFeature->m_bsBuffer.pBase + nalUnitOffset))) 474 { 475 params.bitSize = nalUnitSize * 8; 476 params.offset = nalUnitOffset; 477 params.lastHeader = !tgOBUValid && (i+1 == nalNum); 478 479 m_avpItf->MHW_ADDCMD_F(AVP_PAK_INSERT_OBJECT)(cmdBuffer); 480 m_osInterface->pfnAddCommand(cmdBuffer, GetExtraData(), GetExtraSize()); 481 } 482 } 483 } 484 485 return MOS_STATUS_SUCCESS; 486 } 487 488 #if USE_CODECHAL_DEBUG_TOOL DumpInput()489 MOS_STATUS Av1BrcUpdatePkt::DumpInput() 490 { 491 ENCODE_FUNC_CALL(); 492 int32_t currentPass = m_pipeline->GetCurrentPass(); 493 494 CodechalDebugInterface *debugInterface = m_pipeline->GetDebugInterface(); 495 ENCODE_CHK_NULL_RETURN(debugInterface); 496 497 ENCODE_CHK_STATUS_RETURN(debugInterface->DumpHucDmem( 498 &m_vdencBrcUpdateDmemBuffer[m_pipeline->m_currRecycledBufIdx][m_pipeline->GetCurrentPass()], 499 m_vdencBrcUpdateDmemBufferSize, 500 currentPass, 501 hucRegionDumpUpdate)); 502 503 ENCODE_CHK_STATUS_RETURN(DumpRegion(0, "_BrcHistory", true, hucRegionDumpUpdate, 6080)); 504 ENCODE_CHK_STATUS_RETURN(DumpRegion(1, "_VdencStats", true, hucRegionDumpUpdate, 48*4)); 505 ENCODE_CHK_STATUS_RETURN(DumpRegion(3, "_InputSLBB", true, hucRegionDumpUpdate, 600*4)); 506 ENCODE_CHK_STATUS_RETURN(DumpRegion(5, "_ConstData", true, hucRegionDumpUpdate, MOS_ALIGN_CEIL(m_vdencBrcConstDataBufferSize, CODECHAL_PAGE_SIZE))); 507 ENCODE_CHK_STATUS_RETURN(DumpRegion(7, "_PakMmio", true, hucRegionDumpUpdate, 16*4)); 508 ENCODE_CHK_STATUS_RETURN(DumpRegion(8, "_InputPakInsert", true, hucRegionDumpUpdate, 100)); 509 ENCODE_CHK_STATUS_RETURN(DumpRegion(10, "_InputCdfTable", true, hucRegionDumpUpdate, 4 * MOS_ALIGN_CEIL(m_basicFeature->m_cdfMaxNumBytes, CODECHAL_CACHELINE_SIZE))); 510 511 return MOS_STATUS_SUCCESS; 512 } 513 DumpOutput()514 MOS_STATUS Av1BrcUpdatePkt::DumpOutput() 515 { 516 ENCODE_FUNC_CALL(); 517 518 ENCODE_CHK_STATUS_RETURN(DumpRegion(0, "_BrcHistory", false, hucRegionDumpUpdate, 6080)); 519 ENCODE_CHK_STATUS_RETURN(DumpRegion(4, "_BrcData", false, hucRegionDumpUpdate, 32)); 520 ENCODE_CHK_STATUS_RETURN(DumpRegion(6, "_OutputSLBB", false, hucRegionDumpUpdate, 600 * 4)); 521 ENCODE_CHK_STATUS_RETURN(DumpRegion(9, "_OutputPakInsert", false, hucRegionDumpUpdate, 100)); 522 ENCODE_CHK_STATUS_RETURN(DumpRegion(11, "_OutputCdfTable", false, hucRegionDumpUpdate, MOS_ALIGN_CEIL(m_basicFeature->m_cdfMaxNumBytes, CODECHAL_CACHELINE_SIZE))); 523 524 return MOS_STATUS_SUCCESS; 525 } 526 #endif 527 MHW_SETPAR_DECL_SRC(HUC_IMEM_STATE,Av1BrcUpdatePkt)528 MHW_SETPAR_DECL_SRC(HUC_IMEM_STATE, Av1BrcUpdatePkt) 529 { 530 params.kernelDescriptor = m_vdboxHucAv1BrcUpdateKernelDescriptor; 531 532 return MOS_STATUS_SUCCESS; 533 } 534 MHW_SETPAR_DECL_SRC(HUC_DMEM_STATE,Av1BrcUpdatePkt)535 MHW_SETPAR_DECL_SRC(HUC_DMEM_STATE, Av1BrcUpdatePkt) 536 { 537 params.function = BRC_UPDATE; 538 params.passNum = static_cast<uint8_t>(m_pipeline->GetPassNum()); 539 params.currentPass = static_cast<uint8_t> (m_pipeline->GetCurrentPass()); 540 params.hucDataSource = const_cast<PMOS_RESOURCE> (& m_vdencBrcUpdateDmemBuffer[m_pipeline->m_currRecycledBufIdx][m_pipeline->GetCurrentPass()]); 541 params.dataLength = MOS_ALIGN_CEIL(m_vdencBrcUpdateDmemBufferSize, CODECHAL_CACHELINE_SIZE); 542 params.dmemOffset = HUC_DMEM_OFFSET_RTOS_GEMS; 543 544 return MOS_STATUS_SUCCESS; 545 } 546 MHW_SETPAR_DECL_SRC(VD_PIPELINE_FLUSH,Av1BrcUpdatePkt)547 MHW_SETPAR_DECL_SRC(VD_PIPELINE_FLUSH, Av1BrcUpdatePkt) 548 { 549 params.waitDoneVDCmdMsgParser = true; 550 params.waitDoneAV1 = true; 551 params.flushAV1 = true; 552 553 return MOS_STATUS_SUCCESS; 554 } 555 MHW_SETPAR_DECL_SRC(HUC_VIRTUAL_ADDR_STATE,Av1BrcUpdatePkt)556 MHW_SETPAR_DECL_SRC(HUC_VIRTUAL_ADDR_STATE, Av1BrcUpdatePkt) 557 { 558 ENCODE_FUNC_CALL(); 559 560 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 561 562 int32_t currentPass = m_pipeline->GetCurrentPass(); 563 if (currentPass < 0) 564 { 565 eStatus = MOS_STATUS_INVALID_PARAMETER; 566 return eStatus; 567 } 568 569 ENCODE_CHK_NULL_RETURN(m_basicFeature); 570 ENCODE_CHK_NULL_RETURN(m_basicFeature->m_recycleBuf); 571 572 params.function = BRC_UPDATE; 573 574 uint32_t prevBufIdx = 0; 575 RUN_FEATURE_INTERFACE_RETURN(Av1EncodeTile, Av1FeatureIDs::encodeTile, GetPrevStatisticsBufferIndex, prevBufIdx); 576 uint32_t statBufIdx = 0; 577 RUN_FEATURE_INTERFACE_RETURN(Av1EncodeTile, Av1FeatureIDs::encodeTile, GetStatisticsBufferIndex, statBufIdx); 578 MOS_RESOURCE *resTileBasedStatisticsBuffer = nullptr; 579 RUN_FEATURE_INTERFACE_RETURN(Av1EncodeTile, Av1FeatureIDs::encodeTile, GetTileBasedStatisticsBuffer, currentPass == 0? prevBufIdx : statBufIdx, resTileBasedStatisticsBuffer); 580 uint32_t offset = 0; 581 RUN_FEATURE_INTERFACE_RETURN(Av1EncodeTile, Av1FeatureIDs::encodeTile, GetTileStatsOffset, offset); 582 583 MOS_RESOURCE *resBrcDataBuffer = nullptr; 584 RUN_FEATURE_INTERFACE_RETURN(Av1Brc, Av1FeatureIDs::av1BrcFeature, GetBrcDataBuffer, resBrcDataBuffer); 585 586 const uint32_t bufIdx = m_pipeline->m_currRecycledBufIdx; 587 auto brcFeature = dynamic_cast<Av1Brc *>(m_featureManager->GetFeature(Av1FeatureIDs::av1BrcFeature)); 588 ENCODE_CHK_NULL_RETURN(brcFeature); 589 auto vdenc2ndLevelBatchBuffer = brcFeature->GetVdenc2ndLevelBatchBuffer(bufIdx); 590 ENCODE_CHK_NULL_RETURN(vdenc2ndLevelBatchBuffer); 591 592 auto pakInsertOutputBatchBuffer = brcFeature->GetPakInsertOutputBatchBuffer(bufIdx); 593 ENCODE_CHK_NULL_RETURN(pakInsertOutputBatchBuffer); 594 595 // Region 0 - History Buffer (Input/Output) 596 params.regionParams[0].presRegion = m_basicFeature->m_recycleBuf->GetBuffer(VdencBRCHistoryBuffer, 0); 597 params.regionParams[0].isWritable = true; 598 // Region 1 - VDenc Stats Buffer (Input) 599 params.regionParams[1].presRegion = resTileBasedStatisticsBuffer; 600 params.regionParams[1].dwOffset = offset; 601 // Region 3 - Input SLB Buffer (Input) 602 params.regionParams[3].presRegion = const_cast<PMOS_RESOURCE>(&m_vdencReadBatchBuffer[bufIdx][currentPass]); 603 // Region 4 - BRC Data for next frame's width/height - (Output) 604 params.regionParams[4].presRegion = resBrcDataBuffer; 605 params.regionParams[4].isWritable = true; 606 // Region 5 - Const Data (Input) 607 params.regionParams[5].presRegion = const_cast<PMOS_RESOURCE>(&m_vdencBrcConstDataBuffer[bufIdx]); 608 // Region 6 - Output SLBB - (Output) 609 params.regionParams[6].presRegion = &vdenc2ndLevelBatchBuffer->OsResource; 610 params.regionParams[6].isWritable = true; 611 // Region 7 - PAK MMIO for frame size (Input) 612 params.regionParams[7].presRegion = m_basicFeature->m_recycleBuf->GetBuffer(PakInfo, 0); 613 // Region 8 - PAK INSERT cmd with FrameHeader before back annotation (Input) 614 params.regionParams[8].presRegion = const_cast<PMOS_RESOURCE>(&m_vdencPakInsertBatchBuffer[bufIdx]); 615 // Region 9 - PAK INSERT cmd with FrameHeader after back annotation (Output) 616 params.regionParams[9].presRegion = &pakInsertOutputBatchBuffer->OsResource; 617 params.regionParams[9].isWritable = true; 618 // Region 10 - CDF table (Input) 619 params.regionParams[10].presRegion = m_basicFeature->m_defaultCdfBuffers; 620 // Region 11 - CDF (output) 621 params.regionParams[11].presRegion = m_basicFeature->m_defaultCdfBufferInUse; 622 params.regionParams[11].isWritable = true; 623 624 return MOS_STATUS_SUCCESS; 625 } 626 MHW_SETPAR_DECL_SRC(AVP_PIC_STATE,Av1BrcUpdatePkt)627 MHW_SETPAR_DECL_SRC(AVP_PIC_STATE, Av1BrcUpdatePkt) 628 { 629 params.notFirstPass = !m_pipeline->IsFirstPass(); 630 631 return MOS_STATUS_SUCCESS; 632 } 633 634 } 635