1 /*
2 * Copyright (c) 2017-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 codechal_huc_cmd_initializer.cpp
24 //! \brief Defines base class for command initializer encoder.
25 //!
26
27 #include "codec_def_encode_hevc.h"
28 #if defined (_HEVC_ENCODE_VME_SUPPORTED) || defined (_HEVC_ENCODE_VDENC_SUPPORTED)
29 #include "codechal_encode_hevc_base.h"
30 #endif
31 #include "codechal_huc_cmd_initializer.h"
32 #include "codechal_encoder_base.h"
33 #ifdef _VP9_ENCODE_VDENC_SUPPORTED
34 #include "codechal_vdenc_vp9_base.h"
35 #endif
36
37 #define VDBOX_HUC_CMD_INITIALIZER_HEVC_CMD1_STARTOFFSERT 28
38 #define VDBOX_HUC_CMD_INITIALIZER_HEVC_CMD2_STARTOFFSERT 276
39 #define VDBOX_HUC_CMD_INITIALIZER_HEVC_CQP_CMD2_STARTOFFSET 248
40
CodechalCmdInitializer(CodechalEncoderState * encoder)41 CodechalCmdInitializer::CodechalCmdInitializer(
42 CodechalEncoderState *encoder)
43 {
44 m_encoder = encoder;
45 m_cmdCount = 0;
46 m_currentPass = 0;
47 }
48
CmdInitializerAllocateResources(CodechalHwInterface * hwInterface)49 MOS_STATUS CodechalCmdInitializer::CmdInitializerAllocateResources(
50 CodechalHwInterface *hwInterface)
51 {
52 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
53
54 CODECHAL_ENCODE_FUNCTION_ENTER;
55
56 m_hwInterface = hwInterface;
57 m_osInterface = m_hwInterface->GetOsInterface();
58 m_miInterface = m_hwInterface->GetMiInterface();
59 MOS_ALLOC_GFXRES_PARAMS allocParamsForBufferLinear;
60 MOS_ZeroMemory(&allocParamsForBufferLinear, sizeof(MOS_ALLOC_GFXRES_PARAMS));
61 allocParamsForBufferLinear.Type = MOS_GFXRES_BUFFER;
62 allocParamsForBufferLinear.TileType = MOS_TILE_LINEAR;
63 allocParamsForBufferLinear.Format = Format_Buffer;
64
65 //Allocate buffers for every pass.
66 for (int i = 0; i < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; i++)
67 {
68 for(int j = 0; j < 3; j++)
69 {
70 // Cmd Initializer DMEM
71 allocParamsForBufferLinear.dwBytes = MOS_ALIGN_CEIL(sizeof(HucComDmem), CODECHAL_CACHELINE_SIZE);
72 allocParamsForBufferLinear.pBufName = "VDEnc CmdInitializer Dmem Buffer";
73 CODECHAL_ENCODE_CHK_STATUS_RETURN(
74 m_osInterface->pfnAllocateResource(
75 m_osInterface,
76 &allocParamsForBufferLinear,
77 &m_cmdInitializerDmemBuffer[i][j]));
78
79 // Cmd Initializer Data buffer
80 allocParamsForBufferLinear.dwBytes = MOS_ALIGN_CEIL(sizeof(HucComData), CODECHAL_PAGE_SIZE);
81 allocParamsForBufferLinear.pBufName = "VDEnc CmdInitializer Data Buffer";
82 CODECHAL_ENCODE_CHK_STATUS_RETURN(
83 m_osInterface->pfnAllocateResource(
84 m_osInterface,
85 &allocParamsForBufferLinear,
86 &m_cmdInitializerDataBuffer[i][j]));
87
88 MOS_LOCK_PARAMS lockFlagsWriteOnly;
89 MOS_ZeroMemory(&lockFlagsWriteOnly, sizeof(MOS_LOCK_PARAMS));
90 lockFlagsWriteOnly.WriteOnly = 1;
91
92 uint8_t *pData = (uint8_t *)m_osInterface->pfnLockResource(
93 m_osInterface,
94 &m_cmdInitializerDataBuffer[i][j],
95 &lockFlagsWriteOnly);
96 CODECHAL_ENCODE_CHK_NULL_RETURN(pData);
97 MOS_ZeroMemory(pData, allocParamsForBufferLinear.dwBytes);
98 m_osInterface->pfnUnlockResource(m_osInterface, &m_cmdInitializerDataBuffer[i][j]);
99 }
100 }
101
102 //Allocate extra buffers for dynamic scaling
103 // Cmd Initializer DMEM
104 allocParamsForBufferLinear.dwBytes = MOS_ALIGN_CEIL(sizeof(HucComDmem), CODECHAL_CACHELINE_SIZE);
105 allocParamsForBufferLinear.pBufName = "VDEnc Dynamic Sclaing CmdInitializer Dmem Buffer";
106 CODECHAL_ENCODE_CHK_STATUS_RETURN(
107 m_osInterface->pfnAllocateResource(
108 m_osInterface,
109 &allocParamsForBufferLinear,
110 &m_cmdInitializerDysScalingDmemBuffer));
111
112 // Cmd Initializer Data buffer
113 allocParamsForBufferLinear.dwBytes = MOS_ALIGN_CEIL(sizeof(HucComData), CODECHAL_PAGE_SIZE);
114 allocParamsForBufferLinear.pBufName = "VDEnc Dynamic Sclaing CmdInitializer Data Buffer";
115 CODECHAL_ENCODE_CHK_STATUS_RETURN(
116 m_osInterface->pfnAllocateResource(
117 m_osInterface,
118 &allocParamsForBufferLinear,
119 &m_cmdInitializerDysScalingDataBuffer));
120
121 MOS_LOCK_PARAMS lockFlagsWriteOnly;
122 MOS_ZeroMemory(&lockFlagsWriteOnly, sizeof(MOS_LOCK_PARAMS));
123 lockFlagsWriteOnly.WriteOnly = 1;
124
125 uint8_t* pData = (uint8_t*)m_osInterface->pfnLockResource(
126 m_osInterface,
127 &m_cmdInitializerDysScalingDataBuffer,
128 &lockFlagsWriteOnly);
129 CODECHAL_ENCODE_CHK_NULL_RETURN(pData);
130 MOS_ZeroMemory(pData, allocParamsForBufferLinear.dwBytes);
131 m_osInterface->pfnUnlockResource(m_osInterface, &m_cmdInitializerDysScalingDataBuffer);
132
133 return eStatus;
134 }
135
CmdInitializerFreeResources()136 void CodechalCmdInitializer::CmdInitializerFreeResources()
137 {
138 for (int i = 0; i < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; i++)
139 {
140 for(int j = 0; j < 3; j++)
141 {
142 m_osInterface->pfnFreeResource(m_osInterface, &m_cmdInitializerDmemBuffer[i][j]);
143 m_osInterface->pfnFreeResource(m_osInterface, &m_cmdInitializerDataBuffer[i][j]);
144 }
145 }
146 m_osInterface->pfnFreeResource(m_osInterface, &m_cmdInitializerDysScalingDmemBuffer);
147 m_osInterface->pfnFreeResource(m_osInterface, &m_cmdInitializerDysScalingDataBuffer);
148
149 }
150
151 #if defined (_HEVC_ENCODE_VME_SUPPORTED) || defined (_HEVC_ENCODE_VDENC_SUPPORTED)
CmdInitializerSetDmem(bool brcEnabled)152 MOS_STATUS CodechalCmdInitializer::CmdInitializerSetDmem(bool brcEnabled)
153 {
154 HucComDmem* hucCmdInitializerDmem;
155 MOS_LOCK_PARAMS lockFlagsWriteOnly;
156 uint16_t offset = 0;
157 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
158
159 CODECHAL_ENCODE_FUNCTION_ENTER;
160
161 m_osInterface = m_encoder->GetOsInterface();
162
163 MOS_ZeroMemory(&lockFlagsWriteOnly, sizeof(MOS_LOCK_PARAMS));
164 lockFlagsWriteOnly.WriteOnly = 1;
165
166 // Setup CmdInitializer DMEM
167 hucCmdInitializerDmem = (HucComDmem *)m_osInterface->pfnLockResource(
168 m_osInterface, &m_cmdInitializerDmemBuffer[m_encoder->m_currRecycledBufIdx][m_currentPass], &lockFlagsWriteOnly);
169
170 MOS_ZeroMemory(hucCmdInitializerDmem, sizeof(HucComDmem));
171
172 CODECHAL_ENCODE_ASSERT(m_cmdCount == 2);
173 hucCmdInitializerDmem->TotalOutputCommands = 2;
174
175 hucCmdInitializerDmem->TargetUsage = 4;
176 switch (m_encoder->m_standard)
177 {
178 case CODECHAL_HEVC:
179 hucCmdInitializerDmem->Codec = 0;
180 hucCmdInitializerDmem->TargetUsage = (uint8_t)m_encoder->m_targetUsage;
181 break;
182 case CODECHAL_VP9:
183 hucCmdInitializerDmem->Codec = 1;
184 break;
185 default:
186 hucCmdInitializerDmem->Codec = 0;
187 break;
188 }
189 hucCmdInitializerDmem->FrameType = m_encoder->m_pictureCodingType - 1;
190 hucCmdInitializerDmem->OutputCOM[0].ID = 2;
191 hucCmdInitializerDmem->OutputCOM[0].Type = 1;
192 hucCmdInitializerDmem->OutputCOM[0].StartInBytes = GetCmd1StartOffset(brcEnabled);
193
194 offset += CODECHAL_CMDINITIALIZER_MAX_CMD_SIZE;
195
196 // Command ID 1
197 hucCmdInitializerDmem->OutputCOM[1].ID = 1;
198 hucCmdInitializerDmem->OutputCOM[1].Type = 1;
199 hucCmdInitializerDmem->OutputCOM[1].StartInBytes = GetCmd2StartOffset(brcEnabled);
200
201 offset += CODECHAL_CMDINITIALIZER_MAX_CMD_SIZE;
202
203 hucCmdInitializerDmem->OutputSize = offset;
204
205 m_osInterface->pfnUnlockResource(m_osInterface, &m_cmdInitializerDmemBuffer[m_encoder->m_currRecycledBufIdx][m_currentPass]);
206
207 return eStatus;
208 }
209
ConstructHevcHucCmd1ConstData(PCODEC_HEVC_ENCODE_SEQUENCE_PARAMS seqParams,PCODEC_HEVC_ENCODE_PICTURE_PARAMS picParams,PCODEC_HEVC_ENCODE_SLICE_PARAMS sliceParams,struct HucComData * hucConstData)210 MOS_STATUS CodechalCmdInitializer::ConstructHevcHucCmd1ConstData(
211 PCODEC_HEVC_ENCODE_SEQUENCE_PARAMS seqParams,
212 PCODEC_HEVC_ENCODE_PICTURE_PARAMS picParams,
213 PCODEC_HEVC_ENCODE_SLICE_PARAMS sliceParams,
214 struct HucComData * hucConstData)
215 {
216 hucConstData->InputCOM[1].ID = 1;
217 hucConstData->InputCOM[1].SizeOfData = sizeof(HucInputCmd1) / sizeof(uint8_t);
218
219 auto qpPrimeYAC = 10; //This is constant from Arch C Model
220 double qpScale = (picParams->CodingType == I_TYPE) ? 0.60 : 0.65;
221
222 HucInputCmd1 cmd1;
223 MOS_ZeroMemory(&cmd1, sizeof(HucInputCmd1));
224
225 // Shared HEVC/VP9
226 cmd1.FrameWidthInMinCbMinus1 = seqParams->wFrameWidthInMinCbMinus1;
227 cmd1.FrameHeightInMinCbMinus1 = seqParams->wFrameHeightInMinCbMinus1;
228
229 cmd1.log2_min_coding_block_size_minus3 = seqParams->log2_min_coding_block_size_minus3;
230
231 cmd1.VdencStreamInEnabled = (uint8_t)m_streamInEnabled;
232 cmd1.PakOnlyMultipassEnable = m_pakOnlyPass;
233 cmd1.num_ref_idx_l0_active_minus1 = sliceParams->num_ref_idx_l0_active_minus1;
234
235 auto qpPrimeYac = CodecHal_Clip3(0, 51, picParams->QpY + sliceParams->slice_qp_delta);
236 double lambda = sqrt(qpScale * pow(2.0, MOS_MAX(0, qpPrimeYac - 12) / 3.0));
237 cmd1.SADQPLambda = (uint16_t)(lambda * 4 + 0.5);
238 cmd1.RDQPLambda = (uint16_t)(qpScale * pow(2.0, MOS_MAX(0, picParams->QpY - 12) / 3.0) * 4 + 0.5); //U14.2
239
240 cmd1.num_ref_idx_l1_active_minus1 = sliceParams->num_ref_idx_l1_active_minus1;
241 cmd1.ROIStreamInEnabled = (uint8_t)m_roiStreamInEnabled;
242 cmd1.UseDefaultQpDeltas = (m_acqpEnabled && seqParams->QpAdjustment) || (m_brcEnabled && seqParams->MBBRC != mbBrcDisabled);
243 cmd1.TemporalMvpEnableFlag = sliceParams->slice_temporal_mvp_enable_flag;
244 cmd1.PanicEnabled = m_panicEnabled;
245
246 if (m_roiStreamInEnabled)
247 {
248 for (int8_t i = 0; i < ENCODE_VDENC_HEVC_MAX_STREAMINROI_G10; i++)
249 {
250 cmd1.ROIDeltaQp[i] = picParams->ROIDistinctDeltaQp[i];
251 }
252 }
253
254 // default
255 cmd1.FwdPocNumForRefId0inL0 = 0x01;
256 cmd1.FwdPocNumForRefId0inL1 = 0xff;
257 cmd1.FwdPocNumForRefId1inL0 = 0x02;
258 cmd1.FwdPocNumForRefId1inL1 = 0xfe;
259 cmd1.FwdPocNumForRefId2inL0 = 0x03;
260 cmd1.FwdPocNumForRefId2inL1 = 0xfd;
261 cmd1.FwdPocNumForRefId3inL0 = 0x04;
262 cmd1.FwdPocNumForRefId3inL1 = 0xfc;
263
264 if (picParams->CodingType != I_TYPE)
265 {
266 uint8_t refFrameID;
267 char diff_poc;
268
269 refFrameID = sliceParams->RefPicList[0][0].FrameIdx;
270 diff_poc = picParams->RefFramePOCList[refFrameID] - picParams->CurrPicOrderCnt;
271 cmd1.FwdPocNumForRefId0inL0 = -diff_poc;
272 cmd1.FwdPocNumForRefId0inL1 = -diff_poc;
273
274 refFrameID = sliceParams->RefPicList[0][1].FrameIdx;
275 diff_poc = picParams->RefFramePOCList[refFrameID] - picParams->CurrPicOrderCnt;
276 cmd1.FwdPocNumForRefId1inL0 = -diff_poc;
277 cmd1.FwdPocNumForRefId1inL1 = -diff_poc;
278
279 refFrameID = sliceParams->RefPicList[0][2].FrameIdx;
280 diff_poc = picParams->RefFramePOCList[refFrameID] - picParams->CurrPicOrderCnt;
281 cmd1.FwdPocNumForRefId2inL0 = -diff_poc;
282 cmd1.FwdPocNumForRefId2inL1 = -diff_poc;
283 }
284
285 cmd1.EnableRollingIntraRefresh = picParams->bEnableRollingIntraRefresh;
286 cmd1.QpDeltaForInsertedIntra = picParams->QpDeltaForInsertedIntra;
287 cmd1.IntraInsertionSize = picParams->IntraInsertionSize;
288 cmd1.IntraInsertionLocation = picParams->IntraInsertionLocation;
289 cmd1.IntraInsertionReferenceLocation[0] = picParams->RollingIntraReferenceLocation[0];
290 cmd1.IntraInsertionReferenceLocation[1] = picParams->RollingIntraReferenceLocation[1];
291 cmd1.IntraInsertionReferenceLocation[2] = picParams->RollingIntraReferenceLocation[2];
292
293 cmd1.QpY = picParams->QpY + sliceParams->slice_qp_delta;
294 cmd1.RoundingEnabled = (uint8_t)m_roundingEnabled;
295
296 MOS_SecureMemcpy(hucConstData->InputCOM[1].data, sizeof(HucInputCmd1), &cmd1, sizeof(HucInputCmd1));
297
298 return MOS_STATUS_SUCCESS;
299 }
300
ConstructHevcHucCmd2ConstData(PCODEC_HEVC_ENCODE_SEQUENCE_PARAMS seqParams,PCODEC_HEVC_ENCODE_PICTURE_PARAMS picParams,PCODEC_HEVC_ENCODE_SLICE_PARAMS sliceParams,struct HucComData * hucConstData)301 MOS_STATUS CodechalCmdInitializer::ConstructHevcHucCmd2ConstData(
302 PCODEC_HEVC_ENCODE_SEQUENCE_PARAMS seqParams,
303 PCODEC_HEVC_ENCODE_PICTURE_PARAMS picParams,
304 PCODEC_HEVC_ENCODE_SLICE_PARAMS sliceParams,
305 struct HucComData * hucConstData)
306 {
307 hucConstData->InputCOM[0].ID = 2;
308 hucConstData->InputCOM[0].SizeOfData = 2;
309
310 auto qpPrimeYAC = 10; //This is constant from Arch C Model
311
312 double qpScale = (picParams->CodingType == I_TYPE) ? 0.60 : 0.65;
313 double lambdaInputCom = sqrt(qpScale * pow(2.0, MOS_MAX(0, qpPrimeYAC - 12) / 3.0));
314
315 // SADQPLambda
316 hucConstData->InputCOM[0].data[0] = (uint32_t)(lambdaInputCom * 4 + 0.5);
317 hucConstData->InputCOM[0].data[1] = m_roiStreamInEnabled;
318
319 return MOS_STATUS_SUCCESS;
320 }
321
GetCmd1StartOffset(bool brcEnabled)322 uint16_t CodechalCmdInitializer::GetCmd1StartOffset(bool brcEnabled)
323 {
324 return brcEnabled ? VDBOX_HUC_CMD_INITIALIZER_HEVC_CMD1_STARTOFFSERT : 0;
325 }
326
GetCmd2StartOffset(bool brcEnabled)327 uint16_t CodechalCmdInitializer::GetCmd2StartOffset(bool brcEnabled)
328 {
329 return brcEnabled ? VDBOX_HUC_CMD_INITIALIZER_HEVC_CMD2_STARTOFFSERT : VDBOX_HUC_CMD_INITIALIZER_HEVC_CQP_CMD2_STARTOFFSET;
330 }
331
CmdInitializerSetConstData(PMOS_INTERFACE osInterface,MhwMiInterface * miInterface,MhwVdboxVdencInterface * vdencInterface,void * sequenceParams,void * pictureParams,void * slcParams,bool pakOnlyPass,bool acqpEnabled,bool brcEnabled,bool streaminEnabled,bool roiStreamInEnabled,bool roundingEnabled,bool panicEnabled,int32_t currentPass)332 MOS_STATUS CodechalCmdInitializer::CmdInitializerSetConstData(
333 PMOS_INTERFACE osInterface,
334 MhwMiInterface *miInterface,
335 MhwVdboxVdencInterface *vdencInterface,
336 void* sequenceParams,
337 void* pictureParams,
338 void* slcParams,
339 bool pakOnlyPass,
340 bool acqpEnabled,
341 bool brcEnabled,
342 bool streaminEnabled,
343 bool roiStreamInEnabled,
344 bool roundingEnabled,
345 bool panicEnabled,
346 int32_t currentPass
347 )
348 {
349 HucComData* hucConstData;
350 MOS_LOCK_PARAMS lockFlagsWriteOnly;
351 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
352
353 CODECHAL_ENCODE_FUNCTION_ENTER;
354
355 CODECHAL_ENCODE_CHK_NULL_RETURN(osInterface);
356 CODECHAL_ENCODE_CHK_NULL_RETURN(miInterface);
357 CODECHAL_ENCODE_CHK_NULL_RETURN(vdencInterface);
358 CODECHAL_ENCODE_CHK_NULL_RETURN(sequenceParams);
359 CODECHAL_ENCODE_CHK_NULL_RETURN(pictureParams);
360 CODECHAL_ENCODE_CHK_NULL_RETURN(slcParams);
361
362 m_osInterface = osInterface;
363 m_miInterface = miInterface;
364 m_vdencInterface = vdencInterface;
365 m_seqParams = sequenceParams;
366 m_picParams = pictureParams;
367 m_sliceParams = slcParams;
368
369 PCODEC_HEVC_ENCODE_SEQUENCE_PARAMS seqParams = (PCODEC_HEVC_ENCODE_SEQUENCE_PARAMS)sequenceParams;
370 PCODEC_HEVC_ENCODE_PICTURE_PARAMS picParams = (PCODEC_HEVC_ENCODE_PICTURE_PARAMS)pictureParams;
371 PCODEC_HEVC_ENCODE_SLICE_PARAMS sliceParams = (PCODEC_HEVC_ENCODE_SLICE_PARAMS)slcParams;
372
373 m_pakOnlyPass = pakOnlyPass;
374 m_acqpEnabled = acqpEnabled;
375 m_brcEnabled = brcEnabled;
376 m_streamInEnabled = streaminEnabled;
377 m_roundingEnabled = roundingEnabled;
378 m_panicEnabled = panicEnabled;
379 m_roiStreamInEnabled = roiStreamInEnabled;
380 m_currentPass = currentPass;
381
382 MOS_ZeroMemory(&lockFlagsWriteOnly, sizeof(MOS_LOCK_PARAMS));
383 lockFlagsWriteOnly.WriteOnly = 1;
384
385 hucConstData = (HucComData *)m_osInterface->pfnLockResource(m_osInterface, &m_cmdInitializerDataBuffer[m_encoder->m_currRecycledBufIdx][currentPass], &lockFlagsWriteOnly);
386
387 MOS_ZeroMemory(hucConstData, sizeof(HucComData));
388 m_cmdCount = 0;
389
390 // Command ID 2
391 ConstructHevcHucCmd2ConstData(seqParams, picParams, sliceParams, hucConstData);
392 m_cmdCount++;
393
394 // Command ID 1
395 ConstructHevcHucCmd1ConstData(seqParams, picParams, sliceParams, hucConstData);
396 m_cmdCount++;
397
398 hucConstData->TotalCommands = m_cmdCount;
399
400 m_osInterface->pfnUnlockResource(m_osInterface, &m_cmdInitializerDataBuffer[m_encoder->m_currRecycledBufIdx][currentPass]);
401
402 return eStatus;
403 }
404
CmdInitializerExecute(bool brcEnabled,PMOS_RESOURCE secondlevelBB,MOS_COMMAND_BUFFER * cmdBuffer)405 MOS_STATUS CodechalCmdInitializer::CmdInitializerExecute(
406 bool brcEnabled,
407 PMOS_RESOURCE secondlevelBB,
408 MOS_COMMAND_BUFFER* cmdBuffer)
409 {
410 MHW_MI_FLUSH_DW_PARAMS flushDwParams;
411 MHW_VDBOX_PIPE_MODE_SELECT_PARAMS pipeModeSelectParams;
412 MHW_VDBOX_HUC_IMEM_STATE_PARAMS imemParams;
413 MHW_VDBOX_HUC_DMEM_STATE_PARAMS dmemParams;
414 MHW_VDBOX_HUC_VIRTUAL_ADDR_PARAMS virtualAddrParams;
415 MOS_LOCK_PARAMS lockFlagsWriteOnly;
416 MHW_VDBOX_VD_PIPE_FLUSH_PARAMS vdPipeFlushParams;
417 bool requestFrameTracking;
418 uint8_t codec;
419 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
420 bool renderingFlags;
421 CodechalHwInterface *hwInterface;
422 bool externCmdBuffer = (cmdBuffer != nullptr);
423
424 CODECHAL_ENCODE_FUNCTION_ENTER;
425
426 hwInterface = m_encoder->GetHwInterface();
427 m_osInterface = m_encoder->GetOsInterface();
428 m_miInterface = hwInterface->GetMiInterface();
429
430 // for scalability, the cmdbuffer is passed outside
431 // otherwise the cmdbuffer is fetched here
432 if (cmdBuffer == nullptr)
433 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, cmdBuffer, 0));
434
435 if (!m_encoder->m_singleTaskPhaseSupported || m_encoder->m_firstTaskInPhase)
436 {
437 // Send command buffer header at the beginning (OS dependent)
438 requestFrameTracking = m_encoder->m_singleTaskPhaseSupported ? m_encoder->m_firstTaskInPhase : 0;
439 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->SendPrologWithFrameTracking(cmdBuffer, requestFrameTracking));
440 }
441
442 // load kernel from WOPCM into L2 storage RAM
443 MOS_ZeroMemory(&imemParams, sizeof(imemParams));
444 imemParams.dwKernelDescriptor = m_hucCmdInitializerKernelDescriptor;
445
446 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->GetHwInterface()->GetHucInterface()->AddHucImemStateCmd(cmdBuffer, &imemParams));
447
448 // HUC_PIPE_MODE_SELECT
449 pipeModeSelectParams.Mode = m_encoder->m_mode;
450 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->GetHwInterface()->GetHucInterface()->AddHucPipeModeSelectCmd(cmdBuffer, &pipeModeSelectParams));
451
452 CODECHAL_ENCODE_CHK_STATUS_RETURN(CmdInitializerSetDmem(brcEnabled));
453
454 // set HuC DMEM param
455 MOS_ZeroMemory(&dmemParams, sizeof(dmemParams));
456 dmemParams.presHucDataSource = &m_cmdInitializerDmemBuffer[m_encoder->m_currRecycledBufIdx][m_currentPass];
457 dmemParams.dwDataLength = MOS_ALIGN_CEIL(sizeof(HucComDmem), CODECHAL_CACHELINE_SIZE);
458 dmemParams.dwDmemOffset = HUC_DMEM_OFFSET_RTOS_GEMS;
459 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->GetHwInterface()->GetHucInterface()->AddHucDmemStateCmd(cmdBuffer, &dmemParams));
460
461 MOS_ZeroMemory(&virtualAddrParams, sizeof(virtualAddrParams));
462 virtualAddrParams.regionParams[0].presRegion = &m_cmdInitializerDataBuffer[m_encoder->m_currRecycledBufIdx][m_currentPass];
463
464 virtualAddrParams.regionParams[1].presRegion = secondlevelBB;
465
466 virtualAddrParams.regionParams[1].isWritable = true;
467
468 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->GetHwInterface()->GetHucInterface()->AddHucVirtualAddrStateCmd(cmdBuffer, &virtualAddrParams));
469
470 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->GetHwInterface()->GetHucInterface()->AddHucStartCmd(cmdBuffer, true));
471
472 // wait Huc completion (use HEVC bit for now)
473 MOS_ZeroMemory(&vdPipeFlushParams, sizeof(vdPipeFlushParams));
474 vdPipeFlushParams.Flags.bFlushHEVC = 1;
475 vdPipeFlushParams.Flags.bWaitDoneHEVC = 1;
476 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->GetHwInterface()->GetVdencInterface()->AddVdPipelineFlushCmd(cmdBuffer, &vdPipeFlushParams));
477
478 // Flush the engine to ensure memory written out
479 MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
480 flushDwParams.bVideoPipelineCacheInvalidate = true;
481 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(cmdBuffer, &flushDwParams));
482
483 if (!m_encoder->m_singleTaskPhaseSupported && (m_osInterface->bNoParsingAssistanceInKmd))
484 {
485 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(cmdBuffer, &flushDwParams));
486 }
487
488 if ((!m_encoder->m_singleTaskPhaseSupported))
489 {
490 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(cmdBuffer, nullptr));
491 }
492
493 // if the cmdbuffer is passed outside, then we don't need to submit, just return
494 if (externCmdBuffer)
495 return eStatus;
496
497 m_osInterface->pfnReturnCommandBuffer(m_osInterface, cmdBuffer, 0);
498
499 if (!m_encoder->m_singleTaskPhaseSupported)
500 {
501 renderingFlags = m_encoder->m_videoContextUsesNullHw;
502
503 CODECHAL_DEBUG_TOOL(CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->GetDebugInterface()->DumpCmdBuffer(
504 cmdBuffer,
505 CODECHAL_NUM_MEDIA_STATES,
506 "HucCmd")));
507
508 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(m_osInterface, cmdBuffer, renderingFlags));
509 CODECHAL_DEBUG_TOOL(CODECHAL_ENCODE_CHK_STATUS_RETURN(DumpHucCmdInit(secondlevelBB)));
510 }
511
512 return eStatus;
513 }
514 #endif
515
516 #ifdef _VP9_ENCODE_VDENC_SUPPORTED
517 //VP9 Specific functions
518
CommandInitializerSetVp9Params(CodechalVdencVp9State * state)519 MOS_STATUS CodechalCmdInitializer::CommandInitializerSetVp9Params(CodechalVdencVp9State *state)
520 {
521 HucComData * hucConstData;
522 MOS_LOCK_PARAMS lockFlagsWriteOnly;
523 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
524
525 CODECHAL_ENCODE_CHK_NULL_RETURN(state);
526 MOS_ZeroMemory(&m_vp9Params, sizeof(m_vp9Params));
527 m_vp9Params.prevFrameSegEnabled = state->m_prevFrameSegEnabled;
528 m_vp9Params.seqParams = state->m_vp9SeqParams;
529 m_vp9Params.picParams = state->m_vp9PicParams;
530 m_vp9Params.segmentationEnabled = state->m_vp9PicParams->PicFlags.fields.segmentation_enabled;
531 m_vp9Params.segmentMapProvided = state->m_segmentMapProvided;
532 m_vp9Params.prevFrameSegEnabled = state->m_prevFrameSegEnabled;
533 m_vp9Params.numRefFrames = state->m_numRefFrames;
534 m_vp9Params.me16Enabled = state->m_16xMeEnabled;
535 m_vp9Params.dysVdencMultiPassEnabled = state->m_dysVdencMultiPassEnabled;
536 m_vp9Params.vdencPakOnlyMultipassEnabled = state->m_vdencPakonlyMultipassEnabled;
537 m_vp9Params.pictureCodingType = state->m_pictureCodingType;
538 m_vp9Params.currentPass = state->GetCurrentPass();
539 m_currentPass = m_vp9Params.currentPass;
540 m_vp9Params.singleTaskPhaseSupported = state->m_singleTaskPhaseSupported;
541 m_vp9Params.lastTaskInPhase = state->m_lastTaskInPhase;
542 m_vp9Params.firstTaskInPhase = state->m_firstTaskInPhase;
543 m_vp9Params.mode = state->m_mode;
544 m_vdencInterface = state->m_vdencInterface;
545 m_vp9Params.videoContextUsesNullHw = state->m_videoContextUsesNullHw;
546 m_vp9Params.debugInterface = state->GetDebugInterface();
547 m_vp9Params.dynamicScalingEnabled = (state->m_dysRefFrameFlags != DYS_REF_NONE) ? true : false;
548 m_vp9Params.segmentParams = state->m_vp9SegmentParams;
549 m_vp9Params.bPrevFrameKey = state->m_prevFrameInfo.KeyFrame;
550 return eStatus;
551 }
552
CmdInitializerVp9Execute(PMOS_COMMAND_BUFFER cmdBuffer,PMOS_RESOURCE picStateBuffer)553 MOS_STATUS CodechalCmdInitializer::CmdInitializerVp9Execute(PMOS_COMMAND_BUFFER cmdBuffer, PMOS_RESOURCE picStateBuffer)
554 {
555 MHW_VDBOX_PIPE_MODE_SELECT_PARAMS pipeModeSelectParams;
556 MHW_VDBOX_HUC_IMEM_STATE_PARAMS imemParams;
557 MHW_VDBOX_HUC_DMEM_STATE_PARAMS dmemParams;
558 MHW_VDBOX_HUC_VIRTUAL_ADDR_PARAMS virtualAddrParams;
559 MOS_LOCK_PARAMS lockFlagsWriteOnly;
560 bool requestFrameTracking;
561 uint8_t codec;
562 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
563 bool renderingFlags;
564
565 CODECHAL_ENCODE_FUNCTION_ENTER;
566 CODECHAL_ENCODE_CHK_NULL_RETURN(m_encoder);
567 CODECHAL_ENCODE_CHK_NULL_RETURN(cmdBuffer);
568
569 // load kernel from WOPCM into L2 storage RAM
570 MOS_ZeroMemory(&imemParams, sizeof(imemParams));
571 imemParams.dwKernelDescriptor = m_hucCmdInitializerKernelDescriptor;
572
573 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->GetHucInterface()->AddHucImemStateCmd(cmdBuffer, &imemParams));
574
575 // HUC_PIPE_MODE_SELECT
576 pipeModeSelectParams.Mode = m_vp9Params.mode;
577 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->GetHucInterface()->AddHucPipeModeSelectCmd(cmdBuffer, &pipeModeSelectParams));
578
579 CODECHAL_ENCODE_CHK_STATUS_RETURN(CmdInitializerVp9SetDmem());
580
581 // set HuC DMEM param
582 MOS_ZeroMemory(&dmemParams, sizeof(dmemParams));
583 if (m_vp9Params.dynamicScalingEnabled)
584 {
585 dmemParams.presHucDataSource = &m_cmdInitializerDysScalingDmemBuffer;
586 }
587 else
588 {
589 dmemParams.presHucDataSource = &m_cmdInitializerDmemBuffer[m_encoder->m_currRecycledBufIdx][m_vp9Params.currentPass];
590 }
591 dmemParams.dwDataLength = MOS_ALIGN_CEIL(sizeof(HucComDmem), CODECHAL_CACHELINE_SIZE);
592 dmemParams.dwDmemOffset = HUC_DMEM_OFFSET_RTOS_GEMS;
593 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->GetHucInterface()->AddHucDmemStateCmd(cmdBuffer, &dmemParams));
594
595 MOS_ZeroMemory(&virtualAddrParams, sizeof(virtualAddrParams));
596 if (m_vp9Params.dynamicScalingEnabled)
597 {
598 virtualAddrParams.regionParams[0].presRegion = &m_cmdInitializerDysScalingDataBuffer;
599 virtualAddrParams.regionParams[1].presRegion = picStateBuffer; // Region 1 Output SLB Buffer Pass 1 (Output)
600 }
601 else
602 {
603 virtualAddrParams.regionParams[0].presRegion = &m_cmdInitializerDataBuffer[m_encoder->m_currRecycledBufIdx][m_vp9Params.currentPass];
604 virtualAddrParams.regionParams[1].presRegion = picStateBuffer; // Region 1 Output SLB Buffer Pass 1 (Output)
605 }
606
607 virtualAddrParams.regionParams[1].isWritable = true;
608
609 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->GetHucInterface()->AddHucVirtualAddrStateCmd(cmdBuffer, &virtualAddrParams));
610
611 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->GetHucInterface()->AddHucStartCmd(cmdBuffer, true));
612
613 // wait Huc completion (use HEVC bit for now)
614 MHW_VDBOX_VD_PIPE_FLUSH_PARAMS vdPipeFlushParams;
615 MOS_ZeroMemory(&vdPipeFlushParams, sizeof(vdPipeFlushParams));
616 vdPipeFlushParams.Flags.bFlushHEVC = 1;
617 vdPipeFlushParams.Flags.bWaitDoneHEVC = 1;
618 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->GetVdencInterface()->AddVdPipelineFlushCmd(cmdBuffer, &vdPipeFlushParams));
619
620 // Flush the engine to ensure memory written out
621 MHW_MI_FLUSH_DW_PARAMS flushDwParams;
622 MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
623 flushDwParams.bVideoPipelineCacheInvalidate = true;
624 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(cmdBuffer, &flushDwParams));
625
626 if (!m_vp9Params.singleTaskPhaseSupported)
627 {
628 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(cmdBuffer, nullptr));
629 }
630
631 m_osInterface->pfnReturnCommandBuffer(m_osInterface, cmdBuffer, 0);
632
633 if (!m_vp9Params.singleTaskPhaseSupported)
634 {
635 bool renderFlags = m_vp9Params.videoContextUsesNullHw;
636 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(m_osInterface, cmdBuffer, renderFlags));
637 }
638
639 return eStatus;
640 }
641
CmdInitializerVp9SetDmem()642 MOS_STATUS CodechalCmdInitializer::CmdInitializerVp9SetDmem()
643 {
644 HucComDmem * hucCmdInitializerDmem;
645 MOS_LOCK_PARAMS lockFlagsWriteOnly;
646 uint16_t offset = 0;
647 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
648
649 CODECHAL_ENCODE_FUNCTION_ENTER;
650 CODECHAL_ENCODE_CHK_NULL_RETURN(m_encoder);
651
652 MOS_ZeroMemory(&lockFlagsWriteOnly, sizeof(MOS_LOCK_PARAMS));
653 lockFlagsWriteOnly.WriteOnly = 1;
654
655 HucComData *hucConstData;
656 if (m_vp9Params.dynamicScalingEnabled)
657 {
658 hucConstData = (HucComData *)m_osInterface->pfnLockResource(m_osInterface, &m_cmdInitializerDysScalingDataBuffer, &lockFlagsWriteOnly);
659 }
660 else
661 {
662 hucConstData = (HucComData *)m_osInterface->pfnLockResource(m_osInterface, &m_cmdInitializerDataBuffer[m_encoder->m_currRecycledBufIdx][m_vp9Params.currentPass], &lockFlagsWriteOnly);
663 }
664
665 MOS_ZeroMemory(hucConstData, sizeof(HucComData));
666
667 hucConstData->TotalCommands = 2;
668
669 // Command ID 2
670 hucConstData->InputCOM[0].ID = 2;
671 hucConstData->InputCOM[0].SizeOfData = 2;
672
673 double qpScale = (m_vp9Params.pictureCodingType == I_TYPE) ? 0.31 : 0.33;
674 uint8_t qp = m_vp9Params.picParams->LumaACQIndex;
675 double lambda = qpScale * CODECHAL_VP9_QUANT_AC[qp] / 8;
676
677 // SADQPLambda
678 hucConstData->InputCOM[0].data[0] = (uint32_t)(lambda * 4 + 0.5);
679
680 // Command ID 1
681 hucConstData->InputCOM[1].ID = 1;
682 hucConstData->InputCOM[1].SizeOfData = 0x17;
683
684 HucInputCmd1 hucInputCmd1;
685 MOS_ZeroMemory(&hucInputCmd1, sizeof(hucInputCmd1));
686 hucInputCmd1.VdencStreamInEnabled = m_vp9Params.segmentMapProvided || m_vp9Params.me16Enabled;
687 hucInputCmd1.SegMapStreamInEnabled = m_vp9Params.segmentMapProvided || m_vp9Params.me16Enabled;
688 hucInputCmd1.PakOnlyMultipassEnable = m_vp9Params.vdencPakOnlyMultipassEnabled;
689 hucInputCmd1.num_ref_idx_l0_active_minus1 = (m_vp9Params.picParams->PicFlags.fields.frame_type) ? m_vp9Params.numRefFrames - 1 : 0;
690
691 hucInputCmd1.SADQPLambda = (uint16_t)(lambda * 4 + 0.5);
692 hucInputCmd1.RDQPLambda = (uint16_t)(lambda * lambda * 4 + 0.5); //U14.2
693
694 hucInputCmd1.SrcFrameHeightMinus1 = m_vp9Params.picParams->SrcFrameHeightMinus1;
695 hucInputCmd1.SrcFrameWidthMinus1 = m_vp9Params.picParams->SrcFrameWidthMinus1;
696 hucInputCmd1.SegmentationEnabled = m_vp9Params.segmentationEnabled;
697 hucInputCmd1.PrevFrameSegEnabled = m_vp9Params.prevFrameSegEnabled;
698 hucInputCmd1.LumaACQIndex = m_vp9Params.picParams->LumaACQIndex;
699 hucInputCmd1.LumaDCQIndexDelta = m_vp9Params.picParams->LumaDCQIndexDelta;
700
701 if (m_vp9Params.segmentationEnabled)
702 {
703 for (int i = 0; i < 8; i++)
704 {
705 hucInputCmd1.SegmentQIndexDelta[i] = m_vp9Params.segmentParams->SegData[i].SegmentQIndexDelta;
706 }
707 }
708
709 MOS_SecureMemcpy(hucConstData->InputCOM[1].data, sizeof(HucInputCmd1), &hucInputCmd1, sizeof(HucInputCmd1));
710 if (m_vp9Params.dynamicScalingEnabled)
711 {
712 m_osInterface->pfnUnlockResource(m_osInterface, &m_cmdInitializerDysScalingDataBuffer);
713 }
714 else
715 {
716 m_osInterface->pfnUnlockResource(m_osInterface, &m_cmdInitializerDataBuffer[m_encoder->m_currRecycledBufIdx][m_vp9Params.currentPass]);
717 }
718 MOS_ZeroMemory(&lockFlagsWriteOnly, sizeof(MOS_LOCK_PARAMS));
719 lockFlagsWriteOnly.WriteOnly = 1;
720
721 // Setup CmdInitializer DMEM
722 if (m_vp9Params.dynamicScalingEnabled)
723 {
724 hucCmdInitializerDmem = (HucComDmem *)m_osInterface->pfnLockResource(
725 m_osInterface, &m_cmdInitializerDysScalingDmemBuffer, &lockFlagsWriteOnly);
726 }
727 else
728 {
729 hucCmdInitializerDmem = (HucComDmem *)m_osInterface->pfnLockResource(
730 m_osInterface, &m_cmdInitializerDmemBuffer[m_encoder->m_currRecycledBufIdx][m_vp9Params.currentPass], &lockFlagsWriteOnly);
731 }
732 MOS_ZeroMemory(hucCmdInitializerDmem, sizeof(HucComDmem));
733
734 hucCmdInitializerDmem->TotalOutputCommands = 2;
735
736 hucCmdInitializerDmem->TargetUsage = 4;
737
738 hucCmdInitializerDmem->Codec = 1;
739 hucCmdInitializerDmem->TargetUsage = (uint8_t)m_vp9Params.seqParams->TargetUsage;
740 hucCmdInitializerDmem->FrameType = (uint8_t)m_vp9Params.picParams->PicFlags.fields.frame_type;
741 hucCmdInitializerDmem->OutputCOM[0].ID = 2;
742 hucCmdInitializerDmem->OutputCOM[0].Type = 1;
743 hucCmdInitializerDmem->OutputCOM[0].StartInBytes = 0;
744
745 // Command ID 1
746 hucCmdInitializerDmem->OutputCOM[1].ID = 1;
747 hucCmdInitializerDmem->OutputCOM[1].Type = 1;
748 hucCmdInitializerDmem->OutputCOM[1].StartInBytes = 544;
749
750 hucCmdInitializerDmem->OutputSize = 544 + CODECHAL_CMD2_SIZE;
751 if (m_vp9Params.dynamicScalingEnabled)
752 {
753 m_osInterface->pfnUnlockResource(m_osInterface, &m_cmdInitializerDysScalingDmemBuffer);
754 }
755 else
756 {
757 m_osInterface->pfnUnlockResource(m_osInterface, &m_cmdInitializerDmemBuffer[m_encoder->m_currRecycledBufIdx][m_vp9Params.currentPass]);
758 }
759
760 return eStatus;
761 }
762 #if USE_CODECHAL_DEBUG_TOOL
DumpHucCmdInit(PMOS_RESOURCE secondlevelBB)763 MOS_STATUS CodechalCmdInitializer::DumpHucCmdInit(PMOS_RESOURCE secondlevelBB)
764 {
765 CODECHAL_ENCODE_FUNCTION_ENTER;
766 int idx = (m_encoder == nullptr) ? 0 : m_encoder->m_currRecycledBufIdx;
767 // Dump DMEM
768 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->GetDebugInterface()->DumpHucDmem(
769 &m_cmdInitializerDmemBuffer[idx][m_currentPass],
770 sizeof(HucComDmem),
771 m_currentPass,
772 hucRegionDumpCmdInitializer));
773
774 // Region 0 - input data buffer
775 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->GetDebugInterface()->DumpHucRegion(
776 &m_cmdInitializerDataBuffer[idx][m_currentPass],
777 0,
778 sizeof(HucComData),
779 0,
780 "",
781 true,
782 m_currentPass,
783 hucRegionDumpCmdInitializer));
784
785 // Region 1 - output cmd
786 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->GetDebugInterface()->DumpHucRegion(
787 secondlevelBB,
788 0,
789 m_hwInterface->m_vdencReadBatchBufferSize,
790 1,
791 "",
792 false,
793 m_currentPass,
794 hucRegionDumpCmdInitializer));
795
796 return MOS_STATUS_SUCCESS;
797 }
798 #endif
799 #endif
800