1 /*
2 * Copyright (c) 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_g11.cpp
24 //! \brief Defines class for g11 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_g11.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_G11 36
38 #define VDBOX_HUC_CMD_INITIALIZER_HEVC_CMD2_STARTOFFSERT_G11 308
39 #define VDBOX_HUC_CMD_INITIALIZER_HEVC_CQP_CMD2_STARTOFFSET_G11 272
40 #define VDBOX_HUC_CMD_INITIALIZER_HEVC_CMD5_BRC_STARTOFFSET_G11 156
41 #define VDBOX_HUC_CMD_INITIALIZER_HEVC_CMD5_CQP_STARTOFFSET_G11 120
42
43 #define CMD_LIST_MODE 1
44 #define BATCH_BUFFER_END 0x05000000
45
CodechalCmdInitializerG11(CodechalEncoderState * encoder)46 CodechalCmdInitializerG11::CodechalCmdInitializerG11(
47 CodechalEncoderState *encoder)
48 : CodechalCmdInitializer(encoder)
49 {
50 }
51
52 #if defined (_HEVC_ENCODE_VME_SUPPORTED) || defined (_HEVC_ENCODE_VDENC_SUPPORTED)
53
ConstructHevcHucCmd1ConstData(PCODEC_HEVC_ENCODE_SEQUENCE_PARAMS seqParams,PCODEC_HEVC_ENCODE_PICTURE_PARAMS picParams,PCODEC_HEVC_ENCODE_SLICE_PARAMS sliceParams,struct HucComData * hucConstData)54 MOS_STATUS CodechalCmdInitializerG11::ConstructHevcHucCmd1ConstData(
55 PCODEC_HEVC_ENCODE_SEQUENCE_PARAMS seqParams,
56 PCODEC_HEVC_ENCODE_PICTURE_PARAMS picParams,
57 PCODEC_HEVC_ENCODE_SLICE_PARAMS sliceParams,
58 struct HucComData * hucConstData)
59 {
60 hucConstData->InputCOM[1].ID = 1;
61 hucConstData->InputCOM[1].SizeOfData = sizeof(HucInputCmd1G11) / sizeof(uint32_t);
62
63 auto qpPrimeYAC = 10; //This is constant from Arch C Model
64 double qpScale = (picParams->CodingType == I_TYPE) ? 0.60 : 0.65;
65
66 HucInputCmd1G11 cmd1;
67 MOS_ZeroMemory(&cmd1, sizeof(HucInputCmd1G11));
68
69 // Shared HEVC/VP9
70 cmd1.FrameWidthInMinCbMinus1 = seqParams->wFrameWidthInMinCbMinus1;
71 cmd1.FrameHeightInMinCbMinus1 = seqParams->wFrameHeightInMinCbMinus1;
72 cmd1.TransformSkip = picParams->transform_skip_enabled_flag;
73
74 cmd1.log2_min_coding_block_size_minus3 = seqParams->log2_min_coding_block_size_minus3;
75
76 cmd1.tiles_enabled_flag = picParams->tiles_enabled_flag;
77 cmd1.VdencStreamInEnabled = (uint8_t)m_streamInEnabled;
78 cmd1.PakOnlyMultipassEnable = m_pakOnlyPass;
79 cmd1.num_ref_idx_l0_active_minus1 = sliceParams->num_ref_idx_l0_active_minus1;
80
81 auto qpPrimeYac = CodecHal_Clip3(10, 51, picParams->QpY + sliceParams->slice_qp_delta);
82 double lambda = sqrt(qpScale * pow(2.0, MOS_MAX(0, qpPrimeYac - 12) / 3.0));
83 cmd1.SADQPLambda = (uint16_t)(lambda * 4 + 0.5);
84 cmd1.RDQPLambda = (uint16_t)(qpScale * pow(2.0, MOS_MAX(0, picParams->QpY - 12) / 3.0) * 4 + 0.5); //U14.2
85
86 if (m_hevcVisualQualityImprovement)
87 {
88 if (qpPrimeYac >= 22 && qpPrimeYac <= 51 && sliceParams->slice_type == SLICE_I)
89 {
90 double ScalingFactor = 1.0 + 0.025 * (qpPrimeYac - 22);
91 ScalingFactor = (ScalingFactor >= 1.5 ? 1.5 : ScalingFactor);
92 cmd1.SADQPLambda = (uint16_t)(ScalingFactor * lambda * 4 + 0.5); //U8.2
93 }
94
95 if (picParams->QpY >= 22 && picParams->QpY <= 51)
96 {
97 cmd1.Intra32X32ModeMask = 507;
98 }
99 }
100
101 cmd1.num_ref_idx_l1_active_minus1 = sliceParams->num_ref_idx_l1_active_minus1;
102 cmd1.ROIStreamInEnabled = (uint8_t)m_roiStreamInEnabled;
103 cmd1.UseDefaultQpDeltas = (m_acqpEnabled && seqParams->QpAdjustment) || (m_brcEnabled && seqParams->MBBRC != mbBrcDisabled);
104 cmd1.TemporalMvpEnableFlag = sliceParams->slice_temporal_mvp_enable_flag;
105 cmd1.PanicEnabled = m_panicEnabled;
106
107 if (m_roiStreamInEnabled)
108 {
109 for (int8_t i = 0; i < ENCODE_VDENC_HEVC_MAX_STREAMINROI_G10; i++)
110 {
111 cmd1.ROIDeltaQp[i] = picParams->ROIDistinctDeltaQp[i];
112 }
113 }
114
115 // For TCBRC adaptive region boost
116 if(m_brcAdaptiveRegionBoostEnabled)
117 {
118 cmd1.ROIStreamInEnabled = 1;
119 }
120
121 // default
122 cmd1.FwdPocNumForRefId0inL0 = 0x01;
123 cmd1.FwdPocNumForRefId0inL1 = 0xff;
124 cmd1.FwdPocNumForRefId1inL0 = 0x02;
125 cmd1.FwdPocNumForRefId1inL1 = 0xfe;
126 cmd1.FwdPocNumForRefId2inL0 = 0x03;
127 cmd1.FwdPocNumForRefId2inL1 = 0xfd;
128 cmd1.FwdPocNumForRefId3inL0 = 0x04;
129 cmd1.FwdPocNumForRefId3inL1 = 0xfc;
130
131 if (picParams->CodingType != I_TYPE)
132 {
133 uint8_t refFrameID;
134 char diff_poc;
135
136 refFrameID = sliceParams->RefPicList[0][0].FrameIdx;
137 diff_poc = picParams->RefFramePOCList[refFrameID] - picParams->CurrPicOrderCnt;
138 cmd1.FwdPocNumForRefId0inL0 = -diff_poc;
139 cmd1.FwdPocNumForRefId0inL1 = -diff_poc;
140
141 refFrameID = sliceParams->RefPicList[0][1].FrameIdx;
142 diff_poc = picParams->RefFramePOCList[refFrameID] - picParams->CurrPicOrderCnt;
143 cmd1.FwdPocNumForRefId1inL0 = -diff_poc;
144 cmd1.FwdPocNumForRefId1inL1 = -diff_poc;
145
146 refFrameID = sliceParams->RefPicList[0][2].FrameIdx;
147 diff_poc = picParams->RefFramePOCList[refFrameID] - picParams->CurrPicOrderCnt;
148 cmd1.FwdPocNumForRefId2inL0 = -diff_poc;
149 cmd1.FwdPocNumForRefId2inL1 = -diff_poc;
150 }
151
152 cmd1.EnableRollingIntraRefresh = picParams->bEnableRollingIntraRefresh;
153 cmd1.QpDeltaForInsertedIntra = picParams->QpDeltaForInsertedIntra;
154 cmd1.IntraInsertionSize = picParams->IntraInsertionSize;
155 cmd1.IntraInsertionLocation = picParams->IntraInsertionLocation;
156 cmd1.IntraInsertionReferenceLocation[0] = picParams->RollingIntraReferenceLocation[0];
157 cmd1.IntraInsertionReferenceLocation[1] = picParams->RollingIntraReferenceLocation[1];
158 cmd1.IntraInsertionReferenceLocation[2] = picParams->RollingIntraReferenceLocation[2];
159
160 cmd1.QpY = picParams->QpY + sliceParams->slice_qp_delta;
161 cmd1.RoundingEnabled = (uint8_t)m_roundingEnabled;
162
163 cmd1.BRCMinQp = picParams->BRCMinQp < 0x0a ? 0x0a : picParams->BRCMinQp; // Setting values from arch spec
164 cmd1.BRCMaxQp = picParams->BRCMaxQp < 0x0a ? 0x33 : (picParams->BRCMaxQp > 0x33 ? 0x33 : picParams->BRCMaxQp); // Setting values from arch spec
165
166 MOS_SecureMemcpy(hucConstData->InputCOM[1].data, sizeof(HucInputCmd1G11), &cmd1, sizeof(HucInputCmd1G11));
167
168 return MOS_STATUS_SUCCESS;
169 }
170
ConstructHevcHucCmd2ConstData(PCODEC_HEVC_ENCODE_SEQUENCE_PARAMS seqParams,PCODEC_HEVC_ENCODE_PICTURE_PARAMS picParams,PCODEC_HEVC_ENCODE_SLICE_PARAMS sliceParams,struct HucComData * hucConstData)171 MOS_STATUS CodechalCmdInitializerG11::ConstructHevcHucCmd2ConstData(
172 PCODEC_HEVC_ENCODE_SEQUENCE_PARAMS seqParams,
173 PCODEC_HEVC_ENCODE_PICTURE_PARAMS picParams,
174 PCODEC_HEVC_ENCODE_SLICE_PARAMS sliceParams,
175 struct HucComData * hucConstData)
176 {
177 hucConstData->InputCOM[0].ID = 2;
178 hucConstData->InputCOM[0].SizeOfData = 2;
179
180 auto qpPrimeYAC = 10; //This is constant from Arch C Model
181
182 double qpScale = (picParams->CodingType == I_TYPE) ? 0.60 : 0.65;
183 double lambdaInputCom = sqrt(qpScale * pow(2.0, MOS_MAX(0, qpPrimeYAC - 12) / 3.0));
184
185 uint8_t SadPenaltyforIntraNonDC32X32PredMode = (uint8_t)(0.00 * 4 + 0.5);
186 if (m_hevcVisualQualityImprovement)
187 {
188 auto qpPrimeYac = CodecHal_Clip3(10, 51, picParams->QpY + sliceParams->slice_qp_delta);
189 if (qpPrimeYac >= 22 && qpPrimeYac <= 51)
190 {
191 uint8_t penaltyForIntraNonDC32x32Predmode = (uint8_t)((0.1 * 63) * (qpPrimeYac - 22));
192 penaltyForIntraNonDC32x32Predmode = (penaltyForIntraNonDC32x32Predmode >= 63) ? 63 : penaltyForIntraNonDC32x32Predmode;
193 SadPenaltyforIntraNonDC32X32PredMode = penaltyForIntraNonDC32x32Predmode;
194 }
195 }
196
197 hucConstData->InputCOM[0].data[0] = (uint32_t)(lambdaInputCom * 4 + 0.5);
198 hucConstData->InputCOM[0].data[1] = (SadPenaltyforIntraNonDC32X32PredMode << 8) | (uint8_t)m_roiStreamInEnabled;
199
200 return MOS_STATUS_SUCCESS;
201 }
202
AddCmdConstData(uint16_t cmdId,uint32_t * data,uint16_t size,uint32_t startOffset)203 MOS_STATUS CodechalCmdInitializerG11::AddCmdConstData(
204 uint16_t cmdId,
205 uint32_t* data,
206 uint16_t size,
207 uint32_t startOffset
208 )
209 {
210 MOS_LOCK_PARAMS lockFlagsWriteOnly;
211 HucComData* hucConstData;
212 int idx = m_cmdCount++;
213
214 MOS_ZeroMemory(&lockFlagsWriteOnly, sizeof(MOS_LOCK_PARAMS));
215 lockFlagsWriteOnly.WriteOnly = 1;
216
217 hucConstData = (HucComData *)m_osInterface->pfnLockResource(m_osInterface, &m_cmdInitializerDataBuffer[m_encoder->m_currRecycledBufIdx][m_currentPass], &lockFlagsWriteOnly);
218 CODECHAL_ENCODE_CHK_NULL_RETURN(hucConstData);
219
220 hucConstData->TotalCommands = m_cmdCount;
221
222 hucConstData->InputCOM[idx].ID = cmdId;
223 hucConstData->InputCOM[idx].SizeOfData = size;
224
225 MOS_SecureMemcpy(hucConstData->InputCOM[idx].data, size, data, size);
226
227 m_osInterface->pfnUnlockResource(m_osInterface, &m_cmdInitializerDataBuffer[m_encoder->m_currRecycledBufIdx][m_currentPass]);
228 return MOS_STATUS_SUCCESS;
229 }
230
CmdInitializerSetDmem(bool brcEnabled)231 MOS_STATUS CodechalCmdInitializerG11::CmdInitializerSetDmem(bool brcEnabled)
232 {
233 HucComDmem* hucCmdInitializerDmem;
234 MOS_LOCK_PARAMS lockFlagsWriteOnly;
235 uint16_t offset = 0;
236 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
237
238 CODECHAL_ENCODE_FUNCTION_ENTER;
239
240 m_osInterface = m_encoder->GetOsInterface();
241
242 MOS_ZeroMemory(&lockFlagsWriteOnly, sizeof(MOS_LOCK_PARAMS));
243 lockFlagsWriteOnly.WriteOnly = 1;
244
245 // Setup CmdInitializer DMEM
246 hucCmdInitializerDmem = (HucComDmem *)m_osInterface->pfnLockResource(
247 m_osInterface, &m_cmdInitializerDmemBuffer[m_encoder->m_currRecycledBufIdx][m_currentPass], &lockFlagsWriteOnly);
248 CODECHAL_ENCODE_CHK_NULL_RETURN(hucCmdInitializerDmem);
249
250 MOS_ZeroMemory(hucCmdInitializerDmem, sizeof(HucComDmem));
251
252 CODECHAL_ENCODE_ASSERT(m_cmdCount == 3);
253 hucCmdInitializerDmem->TotalOutputCommands = 3;
254
255 hucCmdInitializerDmem->TargetUsage = 4;
256 switch (m_encoder->m_standard)
257 {
258 case CODECHAL_HEVC:
259 hucCmdInitializerDmem->Codec = 0;
260 hucCmdInitializerDmem->TargetUsage = (uint8_t)m_encoder->m_targetUsage;
261 break;
262 case CODECHAL_VP9:
263 hucCmdInitializerDmem->Codec = 1;
264 break;
265 default:
266 hucCmdInitializerDmem->Codec = 0;
267 break;
268 }
269
270 hucCmdInitializerDmem->FrameType = m_encoder->m_pictureCodingType - 1;
271 hucCmdInitializerDmem->OutputCOM[0].ID = 2;
272 hucCmdInitializerDmem->OutputCOM[0].Type = 1;
273 hucCmdInitializerDmem->OutputCOM[0].StartInBytes = GetCmd1StartOffset(brcEnabled);
274
275 offset += CODECHAL_CMDINITIALIZER_MAX_CMD_SIZE;
276
277 // Command ID 1
278 hucCmdInitializerDmem->OutputCOM[1].ID = 1;
279 hucCmdInitializerDmem->OutputCOM[1].Type = 1;
280 hucCmdInitializerDmem->OutputCOM[1].StartInBytes = GetCmd2StartOffset(brcEnabled);
281 hucCmdInitializerDmem->OutputCOM[1].BBEnd = BATCH_BUFFER_END;
282
283 offset += CODECHAL_CMDINITIALIZER_MAX_CMD_SIZE;
284
285 // Command ID 5
286 hucCmdInitializerDmem->OutputCOM[2].ID = 5;
287 hucCmdInitializerDmem->OutputCOM[2].Type = 1;
288 hucCmdInitializerDmem->OutputCOM[2].StartInBytes = GetCmd5StartOffset(brcEnabled);
289
290 offset += CODECHAL_CMDINITIALIZER_MAX_CMD_SIZE;
291
292 hucCmdInitializerDmem->OutputSize = offset;
293
294 m_osInterface->pfnUnlockResource(m_osInterface, &m_cmdInitializerDmemBuffer[m_encoder->m_currRecycledBufIdx][m_currentPass]);
295
296 return eStatus;
297 }
298
GetCmd2StartOffset(bool brcEnabled)299 uint16_t CodechalCmdInitializerG11::GetCmd2StartOffset(bool brcEnabled)
300 {
301 return brcEnabled ? VDBOX_HUC_CMD_INITIALIZER_HEVC_CMD2_STARTOFFSERT_G11 : VDBOX_HUC_CMD_INITIALIZER_HEVC_CQP_CMD2_STARTOFFSET_G11;
302 }
303
GetCmd1StartOffset(bool brcEnabled)304 uint16_t CodechalCmdInitializerG11::GetCmd1StartOffset(bool brcEnabled)
305 {
306 return brcEnabled ? VDBOX_HUC_CMD_INITIALIZER_HEVC_CMD1_STARTOFFSERT_G11 : 0;
307 }
308
GetCmd5StartOffset(bool brcEnabled)309 uint16_t CodechalCmdInitializerG11::GetCmd5StartOffset(bool brcEnabled)
310 {
311 return brcEnabled ? VDBOX_HUC_CMD_INITIALIZER_HEVC_CMD5_BRC_STARTOFFSET_G11 : VDBOX_HUC_CMD_INITIALIZER_HEVC_CMD5_CQP_STARTOFFSET_G11;
312 }
313
314
315 #endif
316
317 #ifdef _VP9_ENCODE_VDENC_SUPPORTED
318 //VP9 Specific functions
CmdInitializerVp9Execute(PMOS_COMMAND_BUFFER cmdBuffer,PMOS_RESOURCE picStateBuffer)319 MOS_STATUS CodechalCmdInitializerG11::CmdInitializerVp9Execute(PMOS_COMMAND_BUFFER cmdBuffer, PMOS_RESOURCE picStateBuffer)
320 {
321 MHW_VDBOX_PIPE_MODE_SELECT_PARAMS pipeModeSelectParams;
322 MHW_VDBOX_HUC_IMEM_STATE_PARAMS imemParams;
323 MHW_VDBOX_HUC_DMEM_STATE_PARAMS dmemParams;
324 MHW_VDBOX_HUC_VIRTUAL_ADDR_PARAMS virtualAddrParams;
325 MOS_LOCK_PARAMS lockFlagsWriteOnly;
326 bool requestFrameTracking;
327 uint8_t codec;
328 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
329 bool renderingFlags;
330
331 CODECHAL_ENCODE_FUNCTION_ENTER;
332 CODECHAL_ENCODE_CHK_NULL_RETURN(m_encoder);
333 CODECHAL_ENCODE_CHK_NULL_RETURN(cmdBuffer);
334
335 // load kernel from WOPCM into L2 storage RAM
336 MOS_ZeroMemory(&imemParams, sizeof(imemParams));
337 imemParams.dwKernelDescriptor = m_hucCmdInitializerKernelDescriptor;
338
339 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->GetHucInterface()->AddHucImemStateCmd(cmdBuffer, &imemParams));
340
341 // HUC_PIPE_MODE_SELECT
342 pipeModeSelectParams.Mode = m_vp9Params.mode;
343 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->GetHucInterface()->AddHucPipeModeSelectCmd(cmdBuffer, &pipeModeSelectParams));
344
345 CODECHAL_ENCODE_CHK_STATUS_RETURN(CmdInitializerVp9SetDmem());
346
347 // set HuC DMEM param
348 MOS_ZeroMemory(&dmemParams, sizeof(dmemParams));
349 if (m_vp9Params.dynamicScalingEnabled)
350 {
351 dmemParams.presHucDataSource = &m_cmdInitializerDysScalingDmemBuffer;
352 }
353 else
354 {
355 dmemParams.presHucDataSource = &m_cmdInitializerDmemBuffer[m_encoder->m_currRecycledBufIdx][m_vp9Params.currentPass];
356 }
357 dmemParams.dwDataLength = MOS_ALIGN_CEIL(sizeof(HucComDmem), CODECHAL_CACHELINE_SIZE);
358 dmemParams.dwDmemOffset = HUC_DMEM_OFFSET_RTOS_GEMS;
359 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->GetHucInterface()->AddHucDmemStateCmd(cmdBuffer, &dmemParams));
360
361 MOS_ZeroMemory(&virtualAddrParams, sizeof(virtualAddrParams));
362 if (m_vp9Params.dynamicScalingEnabled)
363 {
364 virtualAddrParams.regionParams[0].presRegion = &m_cmdInitializerDysScalingDataBuffer;
365 virtualAddrParams.regionParams[1].presRegion = picStateBuffer; // Region 1 Output SLB Buffer Pass 1 (Output)
366 }
367 else
368 {
369 virtualAddrParams.regionParams[0].presRegion = &m_cmdInitializerDataBuffer[m_encoder->m_currRecycledBufIdx][m_vp9Params.currentPass];
370 virtualAddrParams.regionParams[1].presRegion = picStateBuffer; // Region 1 Output SLB Buffer Pass 1 (Output)
371 }
372
373 virtualAddrParams.regionParams[1].isWritable = true;
374
375 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->GetHucInterface()->AddHucVirtualAddrStateCmd(cmdBuffer, &virtualAddrParams));
376
377 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->GetHucInterface()->AddHucStartCmd(cmdBuffer, true));
378
379 // wait Huc completion (use HEVC bit for now)
380 MHW_VDBOX_VD_PIPE_FLUSH_PARAMS vdPipeFlushParams;
381 MOS_ZeroMemory(&vdPipeFlushParams, sizeof(vdPipeFlushParams));
382 vdPipeFlushParams.Flags.bFlushHEVC = 1;
383 vdPipeFlushParams.Flags.bWaitDoneHEVC = 1;
384 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->GetVdencInterface()->AddVdPipelineFlushCmd(cmdBuffer, &vdPipeFlushParams));
385
386 // Flush the engine to ensure memory written out
387 MHW_MI_FLUSH_DW_PARAMS flushDwParams;
388 MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
389 flushDwParams.bVideoPipelineCacheInvalidate = true;
390 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(cmdBuffer, &flushDwParams));
391
392 return eStatus;
393 }
394
CmdInitializerVp9SetDmem()395 MOS_STATUS CodechalCmdInitializerG11::CmdInitializerVp9SetDmem()
396 {
397 HucComDmem* hucCmdInitializerDmem;
398 MOS_LOCK_PARAMS lockFlagsWriteOnly;
399 uint16_t offset = 0;
400 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
401
402 CODECHAL_ENCODE_FUNCTION_ENTER;
403 CODECHAL_ENCODE_CHK_NULL_RETURN(m_encoder);
404
405 MOS_ZeroMemory(&lockFlagsWriteOnly, sizeof(MOS_LOCK_PARAMS));
406 lockFlagsWriteOnly.WriteOnly = 1;
407
408 HucComData* hucConstData;
409 if (m_vp9Params.dynamicScalingEnabled)
410 {
411 hucConstData = (HucComData*)m_osInterface->pfnLockResource(m_osInterface, &m_cmdInitializerDysScalingDataBuffer, &lockFlagsWriteOnly);
412 }
413 else
414 {
415
416 hucConstData = (HucComData*)m_osInterface->pfnLockResource(m_osInterface, &m_cmdInitializerDataBuffer[m_encoder->m_currRecycledBufIdx][m_vp9Params.currentPass], &lockFlagsWriteOnly);
417 }
418 CODECHAL_ENCODE_CHK_NULL_RETURN(hucConstData);
419
420 MOS_ZeroMemory(hucConstData, sizeof(HucComData));
421
422 hucConstData->TotalCommands = 2;
423
424 // Command ID 2
425 hucConstData->InputCOM[0].ID = 2;
426 hucConstData->InputCOM[0].SizeOfData = 2;
427
428 double qpScale = (m_vp9Params.pictureCodingType == I_TYPE) ? 0.31 : 0.33;
429 uint8_t qp = m_vp9Params.picParams->LumaACQIndex;
430 double lambda = qpScale * CODECHAL_VP9_QUANT_AC[qp] / 8;
431
432 // SADQPLambda
433 hucConstData->InputCOM[0].data[0] = (uint32_t)(lambda * 4 + 0.5);
434
435 // Command ID 1
436 hucConstData->InputCOM[1].ID = 1;
437 hucConstData->InputCOM[1].SizeOfData = sizeof(HucInputCmd1G11) / sizeof(uint32_t);
438
439 HucInputCmd1G11 hucInputCmd1;
440 MOS_ZeroMemory(&hucInputCmd1, sizeof(hucInputCmd1));
441 hucInputCmd1.VdencStreamInEnabled = m_vp9Params.segmentMapProvided || m_vp9Params.me16Enabled;
442 hucInputCmd1.SegMapStreamInEnabled = m_vp9Params.segmentMapProvided || m_vp9Params.me16Enabled;
443 hucInputCmd1.PakOnlyMultipassEnable = m_vp9Params.vdencPakOnlyMultipassEnabled;
444 hucInputCmd1.num_ref_idx_l0_active_minus1 = (m_vp9Params.picParams->PicFlags.fields.frame_type) ? m_vp9Params.numRefFrames - 1 : 0;
445
446 hucInputCmd1.SADQPLambda = (uint16_t)(lambda * 4 + 0.5);
447 hucInputCmd1.RDQPLambda = (uint16_t)(lambda * lambda * 4 + 0.5); //U14.2
448
449 hucInputCmd1.SrcFrameHeight = m_vp9Params.picParams->SrcFrameHeightMinus1 + 1;
450 hucInputCmd1.SrcFrameWidth = m_vp9Params.picParams->SrcFrameWidthMinus1 + 1;
451 hucInputCmd1.SegmentationEnabled = m_vp9Params.segmentationEnabled;
452 hucInputCmd1.PrevFrameSegEnabled = m_vp9Params.prevFrameSegEnabled;
453 hucInputCmd1.LumaACQIndex = m_vp9Params.picParams->LumaACQIndex;
454 hucInputCmd1.LumaDCQIndexDelta = m_vp9Params.picParams->LumaDCQIndexDelta;
455 hucInputCmd1.log2_tile_columns = m_vp9Params.picParams->log2_tile_columns;
456 hucInputCmd1.log2_tile_rows = m_vp9Params.picParams->log2_tile_rows;
457 hucInputCmd1.DynamicScalingEnabled = m_vp9Params.dynamicScalingEnabled;
458 hucInputCmd1.dysVdencMultiPassEnabled = m_vp9Params.dysVdencMultiPassEnabled;
459
460 if (m_vp9Params.segmentationEnabled)
461 {
462 for (int i = 0; i < 8; i++)
463 {
464 hucInputCmd1.SegmentQIndexDelta[i] = m_vp9Params.segmentParams->SegData[i].SegmentQIndexDelta;
465 }
466 }
467
468 MOS_SecureMemcpy(hucConstData->InputCOM[1].data, sizeof(HucInputCmd1G11), &hucInputCmd1, sizeof(HucInputCmd1G11));
469 if (m_vp9Params.dynamicScalingEnabled)
470 {
471 m_osInterface->pfnUnlockResource(m_osInterface, &m_cmdInitializerDysScalingDataBuffer);
472 }
473 else
474 {
475 m_osInterface->pfnUnlockResource(m_osInterface, &m_cmdInitializerDataBuffer[m_encoder->m_currRecycledBufIdx][m_vp9Params.currentPass]);
476 }
477 MOS_ZeroMemory(&lockFlagsWriteOnly, sizeof(MOS_LOCK_PARAMS));
478 lockFlagsWriteOnly.WriteOnly = 1;
479
480 // Setup CmdInitializer DMEM
481 if (m_vp9Params.dynamicScalingEnabled)
482 {
483 hucCmdInitializerDmem = (HucComDmem*)m_osInterface->pfnLockResource(
484 m_osInterface, &m_cmdInitializerDysScalingDmemBuffer, &lockFlagsWriteOnly);
485 }
486 else
487 {
488 hucCmdInitializerDmem = (HucComDmem*)m_osInterface->pfnLockResource(
489 m_osInterface, &m_cmdInitializerDmemBuffer[m_encoder->m_currRecycledBufIdx][m_vp9Params.currentPass], &lockFlagsWriteOnly);
490 }
491 CODECHAL_ENCODE_CHK_NULL_RETURN(hucCmdInitializerDmem);
492
493 MOS_ZeroMemory(hucCmdInitializerDmem, sizeof(HucComDmem));
494
495 hucCmdInitializerDmem->TotalOutputCommands = 2;
496
497 hucCmdInitializerDmem->Codec = 1;
498 hucCmdInitializerDmem->TargetUsage = (uint8_t)m_vp9Params.seqParams->TargetUsage;
499 hucCmdInitializerDmem->FrameType = (uint8_t)m_vp9Params.picParams->PicFlags.fields.frame_type;
500
501 // Command ID 2
502 hucCmdInitializerDmem->OutputCOM[0].ID = 2;
503 hucCmdInitializerDmem->OutputCOM[0].Type = 1;
504 hucCmdInitializerDmem->OutputCOM[0].StartInBytes = 0;
505
506 // Command ID 1
507 hucCmdInitializerDmem->OutputCOM[1].ID = 1;
508 hucCmdInitializerDmem->OutputCOM[1].Type = 1;
509 hucCmdInitializerDmem->OutputCOM[1].StartInBytes = 544;
510
511 hucCmdInitializerDmem->OutputSize = 544 + CODECHAL_CMD2_SIZE;
512 if (m_vp9Params.dynamicScalingEnabled)
513 {
514 m_osInterface->pfnUnlockResource(m_osInterface, &m_cmdInitializerDysScalingDmemBuffer);
515 }
516 else
517 {
518 m_osInterface->pfnUnlockResource(m_osInterface, &m_cmdInitializerDmemBuffer[m_encoder->m_currRecycledBufIdx][m_vp9Params.currentPass]);
519 }
520
521 return eStatus;
522 }
523 #endif
524
CmdInitializerAllocateResources(CodechalHwInterface * hwInterface)525 MOS_STATUS CodechalCmdInitializerG11::CmdInitializerAllocateResources(CodechalHwInterface* hwInterface)
526 {
527 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
528
529 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodechalCmdInitializer::CmdInitializerAllocateResources(hwInterface));
530
531 MOS_ALLOC_GFXRES_PARAMS allocParamsForBufferLinear;
532 MOS_ZeroMemory(&allocParamsForBufferLinear, sizeof(MOS_ALLOC_GFXRES_PARAMS));
533 allocParamsForBufferLinear.Type = MOS_GFXRES_BUFFER;
534 allocParamsForBufferLinear.TileType = MOS_TILE_LINEAR;
535 allocParamsForBufferLinear.Format = Format_Buffer;
536
537 for (int i = 0; i < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; i++)
538 {
539 for (int j = 0; j < CODECHAL_VDENC_BRC_NUM_OF_PASSES; j++)
540 {
541 // Cmd Initializer Copy DMEM
542 allocParamsForBufferLinear.dwBytes = MOS_ALIGN_CEIL(sizeof(HucComDmem), CODECHAL_CACHELINE_SIZE);
543 allocParamsForBufferLinear.pBufName = "VDEnc CmdInitializer Copy Dmem Buffer";
544 CODECHAL_ENCODE_CHK_STATUS_RETURN(
545 m_osInterface->pfnAllocateResource(
546 m_osInterface,
547 &allocParamsForBufferLinear,
548 &m_cmdInitializerCopyDmemBuffer[i][j]));
549
550 // Cmd Initializer Copy Data buffer
551 allocParamsForBufferLinear.dwBytes = MOS_ALIGN_CEIL(sizeof(HucComData), CODECHAL_PAGE_SIZE);
552 allocParamsForBufferLinear.pBufName = "VDEnc CmdInitializer Copy Data Buffer";
553 CODECHAL_ENCODE_CHK_STATUS_RETURN(
554 m_osInterface->pfnAllocateResource(
555 m_osInterface,
556 &allocParamsForBufferLinear,
557 &m_cmdInitializerCopyDataBuffer[i][j]));
558
559 MOS_LOCK_PARAMS lockFlagsWriteOnly;
560 MOS_ZeroMemory(&lockFlagsWriteOnly, sizeof(MOS_LOCK_PARAMS));
561 lockFlagsWriteOnly.WriteOnly = 1;
562
563 uint8_t* pData = (uint8_t*)m_osInterface->pfnLockResource(
564 m_osInterface,
565 &m_cmdInitializerCopyDataBuffer[i][j],
566 &lockFlagsWriteOnly);
567 CODECHAL_ENCODE_CHK_NULL_RETURN(pData);
568 MOS_ZeroMemory(pData, allocParamsForBufferLinear.dwBytes);
569 m_osInterface->pfnUnlockResource(m_osInterface, &m_cmdInitializerCopyDataBuffer[i][j]);
570 }
571 }
572
573 MOS_ZeroMemory(&m_vdencCopyBatchBuffer, sizeof(m_vdencCopyBatchBuffer));
574 m_vdencCopyBatchBuffer.bSecondLevel = true;
575 CODECHAL_ENCODE_CHK_STATUS_RETURN(Mhw_AllocateBb(
576 m_osInterface,
577 &m_vdencCopyBatchBuffer,
578 nullptr,
579 m_hwInterface->m_vdencCopyBatchBufferSize));
580
581 MOS_USER_FEATURE_VALUE_DATA userFeatureData;
582 MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
583 MOS_UserFeature_ReadValue_ID(
584 nullptr,
585 __MEDIA_USER_FEATURE_VALUE_HEVC_VDENC_VQI_ENABLE_ID,
586 &userFeatureData,
587 m_osInterface->pOsContext);
588 m_hevcVisualQualityImprovement = userFeatureData.i32Data ? true : false;
589
590 return eStatus;
591 }
592
CmdInitializerFreeResources()593 void CodechalCmdInitializerG11::CmdInitializerFreeResources()
594 {
595 CodechalCmdInitializer::CmdInitializerFreeResources();
596
597 for (int i = 0; i < CODECHAL_VDENC_BRC_NUM_OF_PASSES; i++)
598 {
599 for (int j = 0; j < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; j++)
600 {
601 m_osInterface->pfnFreeResource(m_osInterface, &m_cmdInitializerCopyDmemBuffer[j][i]);
602 m_osInterface->pfnFreeResource(m_osInterface, &m_cmdInitializerCopyDataBuffer[j][i]);
603 }
604 }
605
606 Mhw_FreeBb(m_osInterface, &m_vdencCopyBatchBuffer, nullptr);
607 }
608
AddCopyCmds(PMOS_COMMAND_BUFFER cmdBuffer,HucCopyParams * params)609 MOS_STATUS CodechalCmdInitializerG11::AddCopyCmds(
610 PMOS_COMMAND_BUFFER cmdBuffer,
611 HucCopyParams* params)
612 {
613 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
614
615 // load kernel from WOPCM into L2 storage RAM
616 MHW_VDBOX_HUC_IMEM_STATE_PARAMS imemParams;
617 MOS_ZeroMemory(&imemParams, sizeof(imemParams));
618 imemParams.dwKernelDescriptor = m_hucCmdInitializerKernelDescriptor;
619
620 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->GetHucInterface()->AddHucImemStateCmd(cmdBuffer, &imemParams));
621
622 CODECHAL_ENCODE_CHK_STATUS_RETURN(SetCopyDmem());
623
624 CODECHAL_ENCODE_CHK_STATUS_RETURN(SetCopyData(params));
625
626 // pipe mode select
627 MHW_VDBOX_PIPE_MODE_SELECT_PARAMS pipeModeSelectParams;
628 CODECHAL_ENCODE_CHK_NULL_RETURN(m_encoder);
629 pipeModeSelectParams.Mode = m_encoder->m_mode;
630 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->GetHucInterface()->AddHucPipeModeSelectCmd(cmdBuffer, &pipeModeSelectParams));
631
632 // set HuC DMEM param
633 MHW_VDBOX_HUC_DMEM_STATE_PARAMS dmemParams;
634 MOS_ZeroMemory(&dmemParams, sizeof(dmemParams));
635 dmemParams.presHucDataSource = &m_cmdInitializerCopyDmemBuffer[m_encoder->m_currRecycledBufIdx][m_currentPass];
636 dmemParams.dwDataLength = MOS_ALIGN_CEIL(sizeof(HucComDmem), CODECHAL_CACHELINE_SIZE);
637 dmemParams.dwDmemOffset = HUC_DMEM_OFFSET_RTOS_GEMS;
638 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->GetHucInterface()->AddHucDmemStateCmd(cmdBuffer, &dmemParams));
639
640 MHW_VDBOX_HUC_VIRTUAL_ADDR_PARAMS virtualAddrParams;
641 MOS_ZeroMemory(&virtualAddrParams, sizeof(virtualAddrParams));
642 virtualAddrParams.regionParams[0].presRegion = &m_cmdInitializerCopyDataBuffer[m_encoder->m_currRecycledBufIdx][m_currentPass];
643 virtualAddrParams.regionParams[1].presRegion = &m_vdencCopyBatchBuffer.OsResource;
644 virtualAddrParams.regionParams[1].isWritable = true;
645 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->GetHucInterface()->AddHucVirtualAddrStateCmd(cmdBuffer, &virtualAddrParams));
646
647 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->GetHucInterface()->AddHucStartCmd(cmdBuffer, true));
648
649 // wait Huc completion (use HEVC bit for now)
650 MHW_VDBOX_VD_PIPE_FLUSH_PARAMS vdPipeFlushParams;
651 MOS_ZeroMemory(&vdPipeFlushParams, sizeof(vdPipeFlushParams));
652 vdPipeFlushParams.Flags.bFlushHEVC = 1;
653 vdPipeFlushParams.Flags.bWaitDoneHEVC = 1;
654 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->GetVdencInterface()->AddVdPipelineFlushCmd(cmdBuffer, &vdPipeFlushParams));
655
656 // Flush the engine to ensure memory written out
657 MHW_MI_FLUSH_DW_PARAMS flushDwParams;
658 MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
659 flushDwParams.bVideoPipelineCacheInvalidate = true;
660 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(cmdBuffer, &flushDwParams));
661
662 // current location to add cmds in 2nd level batch buffer
663 m_vdencCopyBatchBuffer.iCurrent = 0;
664 // reset starting location (offset) executing 2nd level batch buffer for each frame & each pass
665 m_vdencCopyBatchBuffer.dwOffset = 0;
666
667 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferStartCmd(cmdBuffer, &m_vdencCopyBatchBuffer));
668
669 // This wait cmd is needed to make sure copy command is done as suggested by HW folk in encode cases
670 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMfxWaitCmd(cmdBuffer, nullptr, m_osInterface->osCpInterface->IsCpEnabled() ? true : false));
671
672 return eStatus;
673 }
674
SetCopyDmem()675 MOS_STATUS CodechalCmdInitializerG11::SetCopyDmem()
676 {
677 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
678
679 HucComDmem* hucCmdCopyDmem;
680 MOS_LOCK_PARAMS lockFlagsWriteOnly;
681
682 MOS_ZeroMemory(&lockFlagsWriteOnly, sizeof(MOS_LOCK_PARAMS));
683 lockFlagsWriteOnly.WriteOnly = 1;
684
685 hucCmdCopyDmem = (HucComDmem*)m_osInterface->pfnLockResource(
686 m_osInterface, &m_cmdInitializerCopyDmemBuffer[m_encoder->m_currRecycledBufIdx][m_currentPass], &lockFlagsWriteOnly);
687 CODECHAL_ENCODE_CHK_NULL_RETURN(hucCmdCopyDmem);
688
689 MOS_ZeroMemory(hucCmdCopyDmem, sizeof(HucComDmem));
690
691 hucCmdCopyDmem->TotalOutputCommands = 1;
692
693 hucCmdCopyDmem->FrameType = m_encoder->m_pictureCodingType - 1;
694 hucCmdCopyDmem->OutputCOM[0].ID = 3;
695 hucCmdCopyDmem->OutputCOM[0].Type = 1;
696 hucCmdCopyDmem->OutputCOM[0].StartInBytes = 0;
697 hucCmdCopyDmem->OutputCOM[0].BBEnd = BATCH_BUFFER_END;
698
699 hucCmdCopyDmem->OutputSize = m_hwInterface->m_vdencCopyBatchBufferSize;
700
701 m_osInterface->pfnUnlockResource(m_osInterface, &m_cmdInitializerCopyDmemBuffer[m_encoder->m_currRecycledBufIdx][m_currentPass]);
702
703 return eStatus;
704 }
705
SetCopyData(HucCopyParams * params)706 MOS_STATUS CodechalCmdInitializerG11::SetCopyData(
707 HucCopyParams* params)
708 {
709 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
710
711 MOS_LOCK_PARAMS lockFlagsWriteOnly;
712 MOS_ZeroMemory(&lockFlagsWriteOnly, sizeof(MOS_LOCK_PARAMS));
713 lockFlagsWriteOnly.WriteOnly = 1;
714
715 auto hucConstData = (HucComData*)m_osInterface->pfnLockResource(m_osInterface, &m_cmdInitializerCopyDataBuffer[m_encoder->m_currRecycledBufIdx][m_currentPass], &lockFlagsWriteOnly);
716 CODECHAL_ENCODE_CHK_NULL_RETURN(hucConstData);
717
718 MOS_ZeroMemory(hucConstData, sizeof(HucComData));
719 hucConstData->TotalCommands = 1;
720
721 hucConstData->InputCOM[0].ID = CODECHAL_CMD3;
722 hucConstData->InputCOM[0].SizeOfData = 0xF;
723
724 HucInputCmd3G11 hucInputCmd3;
725 MOS_ZeroMemory(&hucInputCmd3, sizeof(HucInputCmd3G11));
726
727 hucInputCmd3.SelectionForIndData = m_osInterface->osCpInterface->IsCpEnabled() ? 4 : 0;
728 hucInputCmd3.CmdMode = CMD_LIST_MODE;
729 hucInputCmd3.LengthOfTable = params->lengthOfTable;
730 hucInputCmd3.CopySize = params->size;
731
732 uint64_t srcAddr = m_osInterface->pfnGetResourceGfxAddress(m_osInterface, params->presSrc);
733 uint64_t destAddr = m_osInterface->pfnGetResourceGfxAddress(m_osInterface, params->presDst);
734 hucInputCmd3.SrcAddrBottom = (uint32_t)(srcAddr & 0x00000000FFFFFFFF);
735 hucInputCmd3.SrcAddrTop = (uint32_t)((srcAddr & 0xFFFFFFFF00000000) >> 32);
736
737 hucInputCmd3.DestAddrBottom = (uint32_t)(destAddr & 0x00000000FFFFFFFF);
738 hucInputCmd3.DestAddrTop = (uint32_t)((destAddr & 0xFFFFFFFF00000000) >> 32);
739
740 MOS_SecureMemcpy(hucConstData->InputCOM[0].data, sizeof(HucInputCmd3G11), &hucInputCmd3, sizeof(HucInputCmd3G11));
741
742 m_osInterface->pfnUnlockResource(m_osInterface, &m_cmdInitializerCopyDataBuffer[m_encoder->m_currRecycledBufIdx][m_currentPass]);
743
744 return eStatus;
745 }
746