1 /*
2 * Copyright (c) 2020-2023, 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 encode_avc_huc_brc_update_packet.cpp
24 //! \brief Defines the implementation of avc huc update packet
25 //!
26
27 #include "encode_avc_huc_brc_update_packet.h"
28 #include "encode_avc_vdenc_stream_in_feature.h"
29 #include "encode_avc_basic_feature.h"
30 #include "encode_avc_brc.h"
31 #include "encode_avc_vdenc_const_settings.h"
32 #include "media_avc_feature_defs.h"
33 #include "mos_os_cp_interface_specific.h"
34
35 namespace encode {
36
37 #define VDENC_AVC_STATIC_FRAME_INTRACOSTSCLRatioP 240
38 #define VDENC_AVC_BRC_HUC_STATUS_REENCODE_MASK (1 << 31)
39
Init()40 MOS_STATUS AvcHucBrcUpdatePkt::Init()
41 {
42 ENCODE_FUNC_CALL();
43
44 ENCODE_CHK_NULL_RETURN(m_featureManager);
45 m_basicFeature = dynamic_cast<AvcBasicFeature *>(m_featureManager->GetFeature(FeatureIDs::basicFeature));
46 ENCODE_CHK_NULL_RETURN(m_basicFeature);
47
48 m_brcFeature = dynamic_cast<AvcEncodeBRC *>(m_featureManager->GetFeature(AvcFeatureIDs::avcBrcFeature));
49 ENCODE_CHK_NULL_RETURN(m_brcFeature);
50
51 ENCODE_CHK_STATUS_RETURN(EncodeHucPkt::Init());
52
53 return MOS_STATUS_SUCCESS;
54 }
55
CalculateCommandSize(uint32_t & commandBufferSize,uint32_t & requestedPatchListSize)56 MOS_STATUS AvcHucBrcUpdatePkt::CalculateCommandSize(uint32_t &commandBufferSize, uint32_t &requestedPatchListSize)
57 {
58 ENCODE_FUNC_CALL();
59
60 auto osInterface = m_hwInterface->GetOsInterface();
61 ENCODE_CHK_NULL_RETURN(osInterface);
62
63 uint32_t hucCommandsSize = 0;
64 uint32_t hucPatchListSize = 0;
65 MHW_VDBOX_STATE_CMDSIZE_PARAMS stateCmdSizeParams;
66
67 ENCODE_CHK_STATUS_RETURN(m_hwInterface->GetHucStateCommandSize(
68 m_basicFeature->m_mode, (uint32_t*)&hucCommandsSize, (uint32_t*)&hucPatchListSize, &stateCmdSizeParams));
69
70 commandBufferSize = hucCommandsSize;
71 requestedPatchListSize = osInterface->bUsesPatchList ? hucPatchListSize : 0;
72
73 if (m_pipeline->IsSingleTaskPhaseSupported())
74 {
75 commandBufferSize *= m_pipeline->GetPassNum();
76 }
77
78 // 4K align since allocation is in chunks of 4K bytes.
79 commandBufferSize = MOS_ALIGN_CEIL(commandBufferSize, CODECHAL_PAGE_SIZE);
80
81 return MOS_STATUS_SUCCESS;
82 }
83
SetDmemBuffer() const84 MOS_STATUS AvcHucBrcUpdatePkt::SetDmemBuffer()const
85 {
86 ENCODE_FUNC_CALL();
87
88 // Program update DMEM
89 auto hucVdencBrcUpdateDmem = (VdencAvcHucBrcUpdateDmem*)m_allocator->LockResourceForWrite(
90 m_vdencBrcUpdateDmemBuffer[m_pipeline->m_currRecycledBufIdx][m_pipeline->GetCurrentPass()]);
91 ENCODE_CHK_NULL_RETURN(hucVdencBrcUpdateDmem);
92
93 RUN_FEATURE_INTERFACE_RETURN(AvcEncodeBRC, AvcFeatureIDs::avcBrcFeature, SetDmemForUpdate, hucVdencBrcUpdateDmem, m_pipeline->GetCurrentPass(), m_pipeline->IsLastPass());
94
95 ENCODE_CHK_STATUS_RETURN(m_allocator->UnLock(
96 m_vdencBrcUpdateDmemBuffer[m_pipeline->m_currRecycledBufIdx][m_pipeline->GetCurrentPass()]));
97
98 return MOS_STATUS_SUCCESS;
99 }
100
DumpOutput()101 MOS_STATUS AvcHucBrcUpdatePkt::DumpOutput()
102 {
103 ENCODE_FUNC_CALL();
104
105 #if USE_CODECHAL_DEBUG_TOOL
106 ENCODE_CHK_STATUS_RETURN(DumpHucBrcUpdate(false));
107 ENCODE_CHK_STATUS_RETURN(DumpEncodeImgStats(nullptr));
108 #endif
109
110 return MOS_STATUS_SUCCESS;
111 }
112
AllocateResources()113 MOS_STATUS AvcHucBrcUpdatePkt::AllocateResources()
114 {
115 ENCODE_FUNC_CALL();
116
117 PMOS_RESOURCE allocatedbuffer;
118
119 MOS_ALLOC_GFXRES_PARAMS allocParamsForBufferLinear;
120 MOS_ZeroMemory(&allocParamsForBufferLinear, sizeof(MOS_ALLOC_GFXRES_PARAMS));
121 allocParamsForBufferLinear.Type = MOS_GFXRES_BUFFER;
122 allocParamsForBufferLinear.TileType = MOS_TILE_LINEAR;
123 allocParamsForBufferLinear.Format = Format_Buffer;
124
125 // Const Data buffer
126 allocParamsForBufferLinear.dwBytes = MOS_ALIGN_CEIL(m_vdencBrcConstDataBufferSize, CODECHAL_PAGE_SIZE);
127 allocParamsForBufferLinear.pBufName = "VDENC BRC Const Data Buffer";
128 allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_WRITE;
129 for (uint32_t i = 0; i < CODECHAL_ENCODE_VDENC_BRC_CONST_BUFFER_NUM; i++)
130 {
131 allocatedbuffer = m_allocator->AllocateResource(allocParamsForBufferLinear, true);
132 ENCODE_CHK_NULL_RETURN(allocatedbuffer);
133 m_vdencBrcConstDataBuffer[i] = allocatedbuffer;
134 }
135
136 for (uint32_t k = 0; k < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; k++)
137 {
138 // VDENC IMG STATE read buffer
139 allocParamsForBufferLinear.dwBytes = m_brcFeature->GetVdencBRCImgStateBufferSize();
140 allocParamsForBufferLinear.pBufName = "VDENC BRC IMG State Read Buffer";
141 allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ_WRITE_CACHE;
142 allocatedbuffer = m_allocator->AllocateResource(allocParamsForBufferLinear, true);
143 ENCODE_CHK_NULL_RETURN(allocatedbuffer);
144 m_vdencBrcImageStatesReadBuffer[k] = allocatedbuffer;
145
146 for (auto i = 0; i < VDENC_BRC_NUM_OF_PASSES; i++)
147 {
148 // BRC update DMEM
149 allocParamsForBufferLinear.dwBytes = MOS_ALIGN_CEIL(m_vdencBrcUpdateDmemBufferSize, CODECHAL_CACHELINE_SIZE);
150 allocParamsForBufferLinear.pBufName = "VDENC BrcUpdate DmemBuffer";
151 allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_WRITE;
152 allocatedbuffer = m_allocator->AllocateResource(allocParamsForBufferLinear, true);
153 ENCODE_CHK_NULL_RETURN(allocatedbuffer);
154 m_vdencBrcUpdateDmemBuffer[k][i] = allocatedbuffer;
155 }
156 }
157
158 // PAK statistics output buffer
159 allocParamsForBufferLinear.dwBytes = CODECHAL_PAGE_SIZE;
160 allocParamsForBufferLinear.pBufName = "VDENC PAK Statistics MMIO Registers Output Buffer";
161 allocatedbuffer = m_allocator->AllocateResource(allocParamsForBufferLinear, true);
162 ENCODE_CHK_NULL_RETURN(allocatedbuffer);
163 m_resPakOutputViaMmioBuffer = allocatedbuffer;
164
165 return MOS_STATUS_SUCCESS;
166 }
167
SetConstDataHuCBrcUpdate() const168 MOS_STATUS AvcHucBrcUpdatePkt::SetConstDataHuCBrcUpdate()const
169 {
170 ENCODE_FUNC_CALL();
171
172 // Set VDENC BRC constant buffer, data remains the same till BRC Init is called
173 if (m_brcFeature->IsBRCInit())
174 {
175 for (uint8_t picType = 0; picType < CODECHAL_ENCODE_VDENC_BRC_CONST_BUFFER_NUM; picType++)
176 {
177 auto hucConstData = (uint8_t *)m_allocator->LockResourceForWrite(m_vdencBrcConstDataBuffer[picType]);
178 ENCODE_CHK_NULL_RETURN(hucConstData);
179
180 RUN_FEATURE_INTERFACE_RETURN(AvcEncodeBRC, AvcFeatureIDs::avcBrcFeature, FillHucConstData, hucConstData, picType);
181
182 m_allocator->UnLock(m_vdencBrcConstDataBuffer[picType]);
183 }
184 }
185
186 if (m_vdencStaticFrame)
187 {
188 auto hucConstData = (VdencAvcHucBrcConstantData *)m_allocator->LockResourceForWrite(m_vdencBrcConstDataBuffer[GetCurrConstDataBufIdx()]);
189 ENCODE_CHK_NULL_RETURN(hucConstData);
190
191 auto settings = static_cast<AvcVdencFeatureSettings *>(m_featureManager->GetFeatureSettings()->GetConstSettings());
192 ENCODE_CHK_NULL_RETURN(settings);
193
194 const auto &constTable4 = settings->vdencCMD3Table->AvcVdencCMD3ConstSettings_4;
195
196 for (int j = 0; j < 42; j++)
197 {
198 hucConstData->UPD_P_Intra16x16[j] = constTable4[10 + j];
199 }
200
201 m_allocator->UnLock(m_vdencBrcConstDataBuffer[GetCurrConstDataBufIdx()]);
202 }
203
204 return MOS_STATUS_SUCCESS;
205 }
206
Execute(PMOS_COMMAND_BUFFER cmdBuffer,bool storeHucStatus2Needed,bool prologNeeded,HuCFunction function)207 MOS_STATUS AvcHucBrcUpdatePkt::Execute(PMOS_COMMAND_BUFFER cmdBuffer, bool storeHucStatus2Needed, bool prologNeeded, HuCFunction function)
208 {
209 HUC_CHK_NULL_RETURN(cmdBuffer);
210
211 #if _SW_BRC
212 HUC_CHK_STATUS_RETURN(InitSwBrc(function));
213 if (m_swBrc && m_swBrc->SwBrcEnabled())
214 {
215 m_brcFeature->m_swBrc = m_swBrc;
216 SETPAR(HUC_DMEM_STATE, m_hucItf);
217 SETPAR(HUC_VIRTUAL_ADDR_STATE, m_hucItf);
218
219 auto virtualAddrParams = m_hucItf->MHW_GETPAR_F(HUC_VIRTUAL_ADDR_STATE)();
220 auto dmemParams = m_hucItf->MHW_GETPAR_F(HUC_DMEM_STATE)();
221
222 EncodeBasicFeature* basicFeature = dynamic_cast<EncodeBasicFeature*>(m_featureManager->GetFeature(FeatureIDs::basicFeature));
223 HUC_CHK_NULL_RETURN(basicFeature);
224 return m_swBrc->SwBrcImpl(
225 function,
226 virtualAddrParams,
227 dmemParams,
228 basicFeature->m_recycleBuf->GetBuffer(VdencBrcPakMmioBuffer, 0));
229 }
230 #endif // !_SW_BRC
231
232 if (prologNeeded)
233 {
234 SETPAR_AND_ADDCMD(MI_FORCE_WAKEUP, m_miItf, cmdBuffer);
235 ENCODE_CHK_STATUS_RETURN(SendPrologCmds(*cmdBuffer));
236 }
237
238 if (m_brcFeature->IsBRCInitRequired())
239 {
240 m_resHucStatus2Buffer = m_brcFeature->GetHucStatus2Buffer();
241
242 // Insert conditional batch buffer end for HuC valid IMEM loaded check
243 auto &miConditionalBatchBufferEndParams = m_miItf->MHW_GETPAR_F(MI_CONDITIONAL_BATCH_BUFFER_END)();
244 miConditionalBatchBufferEndParams = {};
245 miConditionalBatchBufferEndParams.presSemaphoreBuffer = m_resHucStatus2Buffer;
246 ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_CONDITIONAL_BATCH_BUFFER_END)(cmdBuffer));
247 }
248
249 SetPerfTag(m_pipeline->IsFirstPass() ? CODECHAL_ENCODE_PERFTAG_CALL_BRC_UPDATE : CODECHAL_ENCODE_PERFTAG_CALL_BRC_UPDATE_SECOND_PASS,
250 (uint16_t)m_basicFeature->m_mode,
251 m_basicFeature->m_pictureCodingType);
252 ENCODE_CHK_STATUS_RETURN(StartPerfCollect(*cmdBuffer));
253 if (m_pipeline->IsSingleTaskPhaseSupported())
254 {
255 auto &miCpyMemMemParams = m_miItf->MHW_GETPAR_F(MI_COPY_MEM_MEM)();
256 miCpyMemMemParams = {};
257 miCpyMemMemParams.presSrc = m_resPakOutputViaMmioBuffer;
258 miCpyMemMemParams.presDst = (m_vdencBrcUpdateDmemBuffer[m_pipeline->m_currRecycledBufIdx][m_pipeline->GetCurrentPass()]);
259 miCpyMemMemParams.dwSrcOffset = miCpyMemMemParams.dwDstOffset = CODECHAL_OFFSETOF(VdencAvcHucBrcUpdateDmem, FrameByteCount);
260 ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_COPY_MEM_MEM)(cmdBuffer));
261
262 miCpyMemMemParams.dwSrcOffset = miCpyMemMemParams.dwDstOffset = CODECHAL_OFFSETOF(VdencAvcHucBrcUpdateDmem, ImgStatusCtrl);
263 ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_COPY_MEM_MEM)(cmdBuffer));
264
265 miCpyMemMemParams.dwSrcOffset = miCpyMemMemParams.dwDstOffset = CODECHAL_OFFSETOF(VdencAvcHucBrcUpdateDmem, NumOfSlice);
266 ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_COPY_MEM_MEM)(cmdBuffer));
267 }
268
269 // load kernel from WOPCM into L2 storage RAM
270 AddAllCmds_HUC_IMEM_STATE(cmdBuffer);
271
272 // pipe mode select
273 AddAllCmds_HUC_PIPE_MODE_SELECT(cmdBuffer);
274
275 // set HuC DMEM param
276 SETPAR_AND_ADDCMD(HUC_DMEM_STATE, m_hucItf, cmdBuffer);
277
278 // Copy data from BrcPakStatisticBufferFull to BrcPakStatisticBuffer if m_perMBStreamOutEnable is true
279 if (m_basicFeature->m_perMBStreamOutEnable)
280 {
281 CodechalHucStreamoutParams hucStreamOutParams;
282 MOS_ZeroMemory(&hucStreamOutParams, sizeof(hucStreamOutParams));
283
284 auto setting = static_cast<AvcVdencFeatureSettings *>(m_featureManager->GetFeatureSettings()->GetConstSettings());
285 ENCODE_CHK_NULL_RETURN(setting);
286
287 PMOS_RESOURCE sourceSurface = m_basicFeature->m_recycleBuf->GetBuffer(BrcPakStatisticBufferFull, m_basicFeature->m_frameNum);
288 PMOS_RESOURCE destSurface = m_basicFeature->m_recycleBuf->GetBuffer(BrcPakStatisticBuffer, 0);
289 uint32_t copySize = setting->brcSettings.vdencBrcPakStatsBufferSize;
290 uint32_t sourceOffset = m_basicFeature->m_picWidthInMb * m_basicFeature->m_picHeightInMb * 64;
291 uint32_t destOffset = 0;
292
293 // Ind Obj Addr command
294 hucStreamOutParams.dataBuffer = sourceSurface;
295 hucStreamOutParams.dataSize = copySize + sourceOffset;
296 hucStreamOutParams.dataOffset = MOS_ALIGN_FLOOR(sourceOffset, CODECHAL_PAGE_SIZE);
297 hucStreamOutParams.streamOutObjectBuffer = destSurface;
298 hucStreamOutParams.streamOutObjectSize = copySize + destOffset;
299 hucStreamOutParams.streamOutObjectOffset = MOS_ALIGN_FLOOR(destOffset, CODECHAL_PAGE_SIZE);
300
301 // Stream object params
302 hucStreamOutParams.indStreamInLength = copySize;
303 hucStreamOutParams.inputRelativeOffset = sourceOffset - hucStreamOutParams.dataOffset;
304 hucStreamOutParams.outputRelativeOffset = destOffset - hucStreamOutParams.streamOutObjectOffset;
305
306 ENCODE_CHK_STATUS_RETURN(m_hwInterface->PerformHucStreamOut(
307 &hucStreamOutParams,
308 cmdBuffer));
309 }
310
311 SETPAR_AND_ADDCMD(HUC_VIRTUAL_ADDR_STATE, m_hucItf, cmdBuffer);
312
313 HUC_CHK_STATUS_RETURN(StoreHuCStatus2Register(cmdBuffer, storeHucStatus2Needed));
314
315 SETPAR_AND_ADDCMD(HUC_START, m_hucItf, cmdBuffer);
316
317 CODECHAL_DEBUG_TOOL(
318 ENCODE_CHK_STATUS_RETURN(DumpInput()))
319
320 //TODO: double confirm why need Vdenc pipe flush
321 SETPAR_AND_ADDCMD(VD_PIPELINE_FLUSH, m_vdencItf, cmdBuffer);
322
323 // Flush the engine to ensure memory written out
324 auto &flushDwParams = m_miItf->MHW_GETPAR_F(MI_FLUSH_DW)();
325 flushDwParams = {};
326 flushDwParams.bVideoPipelineCacheInvalidate = true;
327 ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_FLUSH_DW)(cmdBuffer));
328
329 ENCODE_CHK_STATUS_RETURN(EndPerfCollect(*cmdBuffer));
330
331 return MOS_STATUS_SUCCESS;
332 }
333
Submit(MOS_COMMAND_BUFFER * commandBuffer,uint8_t packetPhase)334 MOS_STATUS AvcHucBrcUpdatePkt::Submit(MOS_COMMAND_BUFFER *commandBuffer, uint8_t packetPhase)
335 {
336 ENCODE_FUNC_CALL();
337
338 ENCODE_CHK_STATUS_RETURN(ConstructImageStateReadBuffer(m_vdencBrcImageStatesReadBuffer[m_pipeline->m_currRecycledBufIdx]));
339
340 bool firstTaskInPhase = packetPhase & firstPacket;
341 bool requestProlog = false;
342
343 if (!m_pipeline->IsSingleTaskPhaseSupported() || firstTaskInPhase)
344 {
345 // Send command buffer header at the beginning (OS dependent)
346 requestProlog = true;
347 }
348
349 ENCODE_CHK_STATUS_RETURN(Execute(commandBuffer, true, requestProlog, BRC_UPDATE));
350
351 ENCODE_CHK_COND_RETURN((m_vdboxIndex > m_mfxItf->GetMaxVdboxIndex()),
352 "ERROR - vdbox index exceed the maximum");
353 auto mmioRegisters = m_hucItf->GetMmioRegisters(m_vdboxIndex);
354
355 #if _SW_BRC
356 if (!m_swBrc->SwBrcEnabled())
357 #endif
358 {
359 // Write HUC_STATUS mask
360 auto &storeDataParams = m_miItf->MHW_GETPAR_F(MI_STORE_DATA_IMM)();
361 storeDataParams = {};
362 storeDataParams.pOsResource = m_basicFeature->m_recycleBuf->GetBuffer(VdencBrcPakMmioBuffer, 0);
363 storeDataParams.dwResourceOffset = sizeof(uint32_t);
364 storeDataParams.dwValue = VDENC_AVC_BRC_HUC_STATUS_REENCODE_MASK;
365 ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_STORE_DATA_IMM)(commandBuffer));
366
367 // store HUC_STATUS register
368 auto &storeRegMemParams = m_miItf->MHW_GETPAR_F(MI_STORE_REGISTER_MEM)();
369 storeRegMemParams = {};
370 storeRegMemParams.presStoreBuffer = m_basicFeature->m_recycleBuf->GetBuffer(VdencBrcPakMmioBuffer, 0);
371 storeRegMemParams.dwOffset = 0;
372 storeRegMemParams.dwRegister = mmioRegisters->hucStatusRegOffset;
373 ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_STORE_REGISTER_MEM)(commandBuffer));
374 }
375
376 CODECHAL_DEBUG_TOOL(
377 ENCODE_CHK_STATUS_RETURN(DumpHucBrcUpdate(true));)
378
379 // Set HuC DMEM buffers which need to be updated.
380 // They are first pass of next frame and next pass of current frame, as the 2nd VDEnc+PAK pass may not be triggered.
381 uint32_t nextRecycledBufIdx = (m_pipeline->m_currRecycledBufIdx + 1) % CODECHAL_ENCODE_RECYCLED_BUFFER_NUM;
382 uint32_t nextPass = (m_pipeline->GetCurrentPass() + 1) % CODECHAL_VDENC_BRC_NUM_OF_PASSES;
383
384 PMOS_RESOURCE vdencBrcUpdateDmemBuffer0 = m_vdencBrcUpdateDmemBuffer[nextRecycledBufIdx][0];
385 PMOS_RESOURCE vdencBrcUpdateDmemBuffer1 = m_pipeline->IsLastPass() ? nullptr : m_vdencBrcUpdateDmemBuffer[m_pipeline->m_currRecycledBufIdx][nextPass];
386
387 #if _SW_BRC
388 if (!m_swBrc->SwBrcEnabled())
389 #endif
390 {
391 if (m_pipeline->IsSingleTaskPhaseSupported())
392 {
393 vdencBrcUpdateDmemBuffer0 = m_resPakOutputViaMmioBuffer;
394 vdencBrcUpdateDmemBuffer1 = nullptr;
395 }
396 }
397
398 RUN_FEATURE_INTERFACE_NO_RETURN(AvcEncodeBRC, AvcFeatureIDs::avcBrcFeature, SaveBrcUpdateDmemBufferPtr, vdencBrcUpdateDmemBuffer0, vdencBrcUpdateDmemBuffer1);
399
400 // Disable Brc Init/reset here after init cmd executed, APP will re-trigger the reset by DDI params m_seqParam->bResetBRC
401 RUN_FEATURE_INTERFACE_NO_RETURN(AvcEncodeBRC, AvcFeatureIDs::avcBrcFeature, DisableBrcInitReset);
402
403 return MOS_STATUS_SUCCESS;
404 }
405
ConstructImageStateReadBuffer(PMOS_RESOURCE imageStateBuffer)406 MOS_STATUS AvcHucBrcUpdatePkt::ConstructImageStateReadBuffer(PMOS_RESOURCE imageStateBuffer)
407 {
408 ENCODE_FUNC_CALL();
409
410 ENCODE_CHK_NULL_RETURN(m_mfxItf);
411 ENCODE_CHK_NULL_RETURN(m_vdencItf);
412
413 uint32_t mfxAvcImgStateSize = m_mfxItf->MHW_GETSIZE_F(MFX_AVC_IMG_STATE)();
414 uint32_t vdencAvcCostStateSize = m_vdencItf->MHW_GETSIZE_F(VDENC_CMD3)();
415 uint32_t vdencAvcImgStateSize = m_vdencItf->MHW_GETSIZE_F(VDENC_AVC_IMG_STATE)();
416 uint32_t miBatchBufferEndSize = m_miItf->MHW_GETSIZE_F(MI_BATCH_BUFFER_END)();
417
418 uint8_t *data = (uint8_t*)m_allocator->LockResourceForWrite(imageStateBuffer);
419
420 MOS_COMMAND_BUFFER constructedCmdBuf;
421 MOS_ZeroMemory(&constructedCmdBuf, sizeof(MOS_COMMAND_BUFFER));
422 constructedCmdBuf.pCmdBase = constructedCmdBuf.pCmdPtr = (uint32_t *) data;
423 constructedCmdBuf.iRemaining = m_brcFeature->GetVdencBRCImgStateBufferSize();
424
425 // Set MFX_AVC_IMG_STATE command
426 SETPAR_AND_ADDCMD(MFX_AVC_IMG_STATE, m_mfxItf, &constructedCmdBuf);
427
428 // Set VDENC_CMD3 command
429 SETPAR_AND_ADDCMD(VDENC_CMD3, m_vdencItf, &constructedCmdBuf);
430
431 // Set VDENC_AVC_IMG_STATE command
432 SETPAR_AND_ADDCMD(VDENC_AVC_IMG_STATE, m_vdencItf, &constructedCmdBuf);
433
434 // Add batch buffer end insertion flag
435 ENCODE_CHK_STATUS_RETURN(m_miItf->AddBatchBufferEndInsertionFlag(constructedCmdBuf));
436
437 // AddBatchBufferEndInsertionFlag doesn't modify pCmdPtr + iOffset
438 constructedCmdBuf.pCmdPtr += miBatchBufferEndSize / sizeof(uint32_t);
439 constructedCmdBuf.iOffset += miBatchBufferEndSize;
440 constructedCmdBuf.iRemaining -= miBatchBufferEndSize;
441
442 // Add MI_NOOPs to align to CODECHAL_CACHELINE_SIZE
443 uint32_t size = (MOS_ALIGN_CEIL(constructedCmdBuf.iOffset, CODECHAL_CACHELINE_SIZE) - constructedCmdBuf.iOffset) / sizeof(uint32_t);
444 for (uint32_t i = 0; i < size; i++)
445 ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_NOOP)(&constructedCmdBuf));
446
447 for (uint16_t slcCount = 0; slcCount < m_basicFeature->m_numSlices; slcCount++)
448 {
449 size = constructedCmdBuf.iOffset;
450
451 // Set MFX_AVC_SLICE_STATE command
452 SETPAR_AND_ADDCMD(MFX_AVC_SLICE_STATE, m_mfxItf, &constructedCmdBuf);
453
454 // Set VDENC_AVC_SLICE_STATE command
455 SETPAR_AND_ADDCMD(VDENC_AVC_SLICE_STATE, m_vdencItf, &constructedCmdBuf);
456
457 m_miItf->AddBatchBufferEndInsertionFlag(constructedCmdBuf);
458 constructedCmdBuf.pCmdPtr += miBatchBufferEndSize / sizeof(uint32_t);
459 constructedCmdBuf.iOffset += miBatchBufferEndSize;
460 constructedCmdBuf.iRemaining -= miBatchBufferEndSize;
461
462 ENCODE_ASSERT(constructedCmdBuf.iOffset - size % CODECHAL_CACHELINE_SIZE != 0);
463 }
464
465 if (data)
466 {
467 m_allocator->UnLock(imageStateBuffer);
468 }
469
470 CODECHAL_DEBUG_TOOL(
471 ENCODE_CHK_STATUS_RETURN(PopulatePakParam(
472 nullptr,
473 nullptr));
474
475 ENCODE_CHK_STATUS_RETURN(PopulateEncParam(
476 0,
477 nullptr));)
478
479 return MOS_STATUS_SUCCESS;
480 }
481
GetCurrConstDataBufIdx() const482 uint32_t AvcHucBrcUpdatePkt::GetCurrConstDataBufIdx() const
483 {
484 return m_basicFeature->m_picParam->CodingType == B_TYPE && m_basicFeature->m_picParam->RefPicFlag ? m_basicFeature->m_picParam->CodingType // refB
485 : m_basicFeature->m_picParam->CodingType - 1;
486 }
487
MHW_SETPAR_DECL_SRC(MFX_AVC_IMG_STATE,AvcHucBrcUpdatePkt)488 MHW_SETPAR_DECL_SRC(MFX_AVC_IMG_STATE, AvcHucBrcUpdatePkt)
489 {
490 bool bIPCMPass = m_pipeline->GetCurrentPass() && m_pipeline->IsLastPass() && (!m_brcFeature->IsVdencBrcEnabled());
491 params.mbstatenabled = bIPCMPass ? true : false; // Disable for the first pass
492
493 return MOS_STATUS_SUCCESS;
494 }
495
MHW_SETPAR_DECL_SRC(HUC_IMEM_STATE,AvcHucBrcUpdatePkt)496 MHW_SETPAR_DECL_SRC(HUC_IMEM_STATE, AvcHucBrcUpdatePkt)
497 {
498 auto setting = static_cast<AvcVdencFeatureSettings *>(m_featureManager->GetFeatureSettings()->GetConstSettings());
499 ENCODE_CHK_NULL_RETURN(setting);
500
501 params.kernelDescriptor = setting->brcSettings.vdboxHucVdencBrcUpdateKernelDescriptor;
502
503 return MOS_STATUS_SUCCESS;
504 }
505
MHW_SETPAR_DECL_SRC(HUC_DMEM_STATE,AvcHucBrcUpdatePkt)506 MHW_SETPAR_DECL_SRC(HUC_DMEM_STATE, AvcHucBrcUpdatePkt)
507 {
508 ENCODE_CHK_STATUS_RETURN(SetDmemBuffer());
509
510 params.function = BRC_UPDATE;
511 params.hucDataSource = m_vdencBrcUpdateDmemBuffer[m_pipeline->m_currRecycledBufIdx][m_pipeline->GetCurrentPass()];
512 params.dataLength = MOS_ALIGN_CEIL(m_vdencBrcUpdateDmemBufferSize, CODECHAL_CACHELINE_SIZE);
513 params.dmemOffset = HUC_DMEM_OFFSET_RTOS_GEMS;
514
515 return MOS_STATUS_SUCCESS;
516 }
517
MHW_SETPAR_DECL_SRC(HUC_VIRTUAL_ADDR_STATE,AvcHucBrcUpdatePkt)518 MHW_SETPAR_DECL_SRC(HUC_VIRTUAL_ADDR_STATE, AvcHucBrcUpdatePkt)
519 {
520 params.function = BRC_UPDATE;
521
522 // Set Const Data buffer
523 ENCODE_CHK_STATUS_RETURN(SetConstDataHuCBrcUpdate());
524
525 // Input regions
526 params.regionParams[1].presRegion = m_basicFeature->m_recycleBuf->GetBuffer(VdencStatsBuffer, 0);
527 params.regionParams[2].presRegion = m_basicFeature->m_recycleBuf->GetBuffer(BrcPakStatisticBuffer, 0);
528 params.regionParams[3].presRegion = m_vdencBrcImageStatesReadBuffer[m_pipeline->m_currRecycledBufIdx];
529 params.regionParams[5].presRegion = m_vdencBrcConstDataBuffer[GetCurrConstDataBufIdx()];
530 params.regionParams[7].presRegion = m_basicFeature->m_recycleBuf->GetBuffer(PakSliceSizeStreamOutBuffer, m_pipeline->GetCurrentPass() ?
531 m_basicFeature->m_frameNum : m_basicFeature->m_frameNum ? m_basicFeature->m_frameNum-1 : 0); // use stats from previous frame for pass 0
532 // use stats from pass 0 for pass 1
533
534 if (m_basicFeature->m_picParam->NumROI && !m_basicFeature->m_picParam->bNativeROI) // Only for BRC non-native ROI
535 {
536 if (m_hwInterface->GetOsInterface()->osCpInterface != nullptr &&
537 m_hwInterface->GetOsInterface()->osCpInterface->IsCpEnabled())
538 {
539 ENCODE_ASSERTMESSAGE("Non-native BRC ROI doesn't supports in CP case");
540 return MOS_STATUS_UNIMPLEMENTED;
541 }
542 params.regionParams[8].presRegion = m_basicFeature->m_recycleBuf->GetBuffer(RecycleResId::HucRoiMapBuffer, m_basicFeature->m_frameNum);
543 }
544
545 return MOS_STATUS_SUCCESS;
546 }
547
548 #if USE_CODECHAL_DEBUG_TOOL
DumpHucBrcUpdate(bool isInput)549 MOS_STATUS AvcHucBrcUpdatePkt::DumpHucBrcUpdate(bool isInput)
550 {
551 ENCODE_FUNC_CALL();
552
553 CodechalDebugInterface *debugInterface = m_pipeline->GetDebugInterface();
554 ENCODE_CHK_NULL_RETURN(debugInterface);
555
556 auto settings = static_cast<AvcVdencFeatureSettings *>(m_featureManager->GetFeatureSettings()->GetConstSettings());
557 ENCODE_CHK_NULL_RETURN(settings);
558
559 auto brcSettings = settings->brcSettings;
560
561 uint16_t currentPass = m_pipeline->GetCurrentPass();
562
563 auto virtualAddrParams = m_hucItf->MHW_GETPAR_F(HUC_VIRTUAL_ADDR_STATE)();
564
565 if (isInput)
566 {
567 //HUC DMEM dump
568 ENCODE_CHK_STATUS_RETURN(debugInterface->DumpHucDmem(
569 m_vdencBrcUpdateDmemBuffer[m_pipeline->m_currRecycledBufIdx][currentPass],
570 m_vdencBrcUpdateDmemBufferSize,
571 currentPass,
572 hucRegionDumpUpdate));
573
574 // History Buffer dump
575 ENCODE_CHK_STATUS_RETURN(DumpRegion(0, "_History", isInput, hucRegionDumpUpdate, brcSettings.vdencBrcHistoryBufferSize));
576
577 // Constant Data Buffer dump
578 ENCODE_CHK_STATUS_RETURN(DumpRegion(5, "_ConstData", isInput, hucRegionDumpUpdate, m_vdencBrcConstDataBufferSize));
579
580 // VDENC Statistics Buffer dump
581 ENCODE_CHK_STATUS_RETURN(DumpRegion(1, "_VdencStats", isInput, hucRegionDumpUpdate, brcSettings.vdencBrcStatsBufferSize));
582
583 // PAK Statistics Buffer dump
584 ENCODE_CHK_STATUS_RETURN(DumpRegion(2, "_PakStats", isInput, hucRegionDumpUpdate, brcSettings.vdencBrcPakStatsBufferSize));
585
586 // VDENC Img State Read Buffer dump
587 ENCODE_CHK_STATUS_RETURN(DumpRegion(3, "_ImageStateRead", isInput, hucRegionDumpUpdate, m_brcFeature->GetVdencBRCImgStateBufferSize()));
588
589 // Slice size Buffer dump
590 ENCODE_CHK_STATUS_RETURN(DumpRegion(7, "_SliceSizeStreamOut", isInput, hucRegionDumpUpdate, CODECHAL_ENCODE_SLICESIZE_BUF_SIZE));
591
592 // BRC non-native ROI
593 if (m_basicFeature->m_picParam->NumROI && !m_basicFeature->m_picParam->bNativeROI)
594 {
595 ENCODE_CHK_STATUS_RETURN(DumpRegion(8, "_BrcROI_idxs", isInput, hucRegionDumpUpdate, m_basicFeature->m_picWidthInMb * m_basicFeature->m_picHeightInMb));
596 }
597
598 // VDEnc StreamIn
599 if (m_basicFeature->m_picParam->NumROI && !m_basicFeature->m_picParam->bNativeROI)
600 {
601 ENCODE_CHK_STATUS_RETURN(DumpRegion(9, "_VDEnc_StreamIn", isInput, hucRegionDumpUpdate, m_basicFeature->m_picWidthInMb * m_basicFeature->m_picHeightInMb * CODECHAL_CACHELINE_SIZE));
602 }
603 }
604 else
605 {
606 // History Buffer dump
607 ENCODE_CHK_STATUS_RETURN(DumpRegion(0, "_History", isInput, hucRegionDumpUpdate, brcSettings.vdencBrcHistoryBufferSize));
608
609 // VDENC Img State Write Buffer dump
610 ENCODE_CHK_STATUS_RETURN(DumpRegion(6, "_ImageStateWrite", isInput, hucRegionDumpUpdate, m_brcFeature->GetVdencBRCImgStateBufferSize()));
611
612 // VDEnc StreamIn
613 if (m_basicFeature->m_picParam->NumROI && !m_basicFeature->m_picParam->bNativeROI)
614 {
615 ENCODE_CHK_STATUS_RETURN(DumpRegion(10, "_VDEnc_StreamIn", isInput, hucRegionDumpUpdate, m_basicFeature->m_picWidthInMb * m_basicFeature->m_picHeightInMb * CODECHAL_CACHELINE_SIZE));
616 }
617
618 ENCODE_CHK_STATUS_RETURN(DumpRegion(15, "_Debug", isInput, hucRegionDumpUpdate, brcSettings.vdencBrcDbgBufferSize));
619 }
620
621 return MOS_STATUS_SUCCESS;
622 }
623
DumpEncodeImgStats(PMOS_COMMAND_BUFFER cmdbuffer)624 MOS_STATUS AvcHucBrcUpdatePkt::DumpEncodeImgStats(
625 PMOS_COMMAND_BUFFER cmdbuffer)
626 {
627 ENCODE_FUNC_CALL();
628
629 CodechalDebugInterface *debugInterface = m_pipeline->GetDebugInterface();
630 ENCODE_CHK_NULL_RETURN(debugInterface);
631
632 if (!debugInterface->DumpIsEnabled(CodechalDbgAttr::attrImageState))
633 {
634 return MOS_STATUS_SUCCESS;
635 }
636
637 std::string SurfName = "Pak_VDEnc_Pass[" + std::to_string(static_cast<uint32_t>(m_pipeline->GetCurrentPass())) + "]";
638
639 // MFX_AVC_IMG_STATE
640 if (m_brcFeature->IsVdencBrcEnabled())
641 {
642 // BRC case: both MFX_AVC_IMG_STATE and VDENC_IMG_STATE are updated by HuC FW
643 ENCODE_CHK_STATUS_RETURN(debugInterface->DumpBuffer(
644 &(m_brcFeature->GetBatchBufferForVdencImgStat()->OsResource),
645 CodechalDbgAttr::attrImageState,
646 SurfName.c_str(),
647 m_hwInterface->m_vdencBrcImgStateBufferSize,
648 0,
649 CODECHAL_NUM_MEDIA_STATES));
650 }
651
652 return MOS_STATUS_SUCCESS;
653 }
654 #endif
655
656 }
657