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