1 /*
2 * Copyright (c) 2017-2019, 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 mhw_vdbox_vdenc_g9_skl.cpp
24 //! \brief Defines functions for constructing Vdbox Vdenc commands on G9 SKL
25 //!
26
27 #include "mhw_vdbox_vdenc_g9_skl.h"
28
AddVdencSrcSurfaceStateCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_VDBOX_SURFACE_PARAMS params)29 MOS_STATUS MhwVdboxVdencInterfaceG9Skl::AddVdencSrcSurfaceStateCmd(
30 PMOS_COMMAND_BUFFER cmdBuffer,
31 PMHW_VDBOX_SURFACE_PARAMS params)
32 {
33 MHW_FUNCTION_ENTER;
34
35 MHW_MI_CHK_NULL(cmdBuffer);
36 MHW_MI_CHK_NULL(params);
37 MHW_MI_CHK_NULL(params->psSurface);
38
39 mhw_vdbox_vdenc_g9_skl::VDENC_SRC_SURFACE_STATE_CMD cmd;
40
41 cmd.Dwords25.DW0.Width = params->psSurface->dwWidth - 1;
42 cmd.Dwords25.DW0.Height = params->psSurface->dwHeight - 1;
43 cmd.Dwords25.DW0.CrVCbUPixelOffsetVDirection = params->ucVDirection;
44 cmd.Dwords25.DW1.TiledSurface = IS_TILE_FORMAT(params->psSurface->TileType) ? 1 : 0;
45
46 if (cmd.Dwords25.DW1.TiledSurface)
47 {
48 cmd.Dwords25.DW1.TileWalk = (params->psSurface->TileType);
49 }
50 cmd.Dwords25.DW1.SurfaceFormat = MosToMediaStateFormat(params->psSurface->Format); //dwSurfaceFormat; should be 4
51 cmd.Dwords25.DW1.InterleaveChroma = 1;
52 cmd.Dwords25.DW1.SurfacePitch = params->psSurface->dwPitch - 1;
53 cmd.Dwords25.DW2.YOffsetForUCb = cmd.Dwords25.DW3.YOffsetForVCr =
54 MOS_ALIGN_CEIL(params->psSurface->UPlaneOffset.iYOffset, MHW_VDBOX_MFX_RAW_UV_PLANE_ALIGNMENT_GEN9);
55
56 MHW_MI_CHK_STATUS(Mos_AddCommand(cmdBuffer, &cmd, sizeof(cmd)));
57
58 return MOS_STATUS_SUCCESS;
59 }
60
AddVdencImgStateCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_BATCH_BUFFER batchBuffer,PMHW_VDBOX_AVC_IMG_PARAMS params)61 MOS_STATUS MhwVdboxVdencInterfaceG9Skl::AddVdencImgStateCmd(
62 PMOS_COMMAND_BUFFER cmdBuffer,
63 PMHW_BATCH_BUFFER batchBuffer,
64 PMHW_VDBOX_AVC_IMG_PARAMS params)
65 {
66 MHW_FUNCTION_ENTER;
67
68 MHW_MI_CHK_NULL(params);
69 MHW_MI_CHK_NULL(params->pEncodeAvcSeqParams);
70 MHW_MI_CHK_NULL(params->pEncodeAvcPicParams);
71
72 mhw_vdbox_vdenc_g9_skl::VDENC_IMG_STATE_CMD cmd;
73
74 auto avcSeqParams = params->pEncodeAvcSeqParams;
75 auto avcPicParams = params->pEncodeAvcPicParams;
76 auto avcSliceParams = params->pEncodeAvcSliceParams;
77
78 // initialize
79 cmd.DW2.UnidirectionalMixDisable = false;
80 cmd.DW4.IntraSadMeasureAdjustment = 2;
81 cmd.DW4.SubMacroblockSubPartitionMask = 0x70;
82 cmd.DW8.BilinearFilterEnable = false;
83 cmd.DW9.Mode0Cost = 10;
84 cmd.DW9.Mode1Cost = 0;
85 cmd.DW9.Mode2Cost = 3;
86 cmd.DW9.Mode3Cost = 30;
87 cmd.DW20.PenaltyForIntra16X16NondcPrediction = 36;
88 cmd.DW20.PenaltyForIntra8X8NondcPrediction = 12;
89 cmd.DW20.PenaltyForIntra4X4NondcPrediction = 4;
90 cmd.DW22.Smallmbsizeinword = 0xff;
91 cmd.DW22.Largembsizeinword = 0xff;
92 cmd.DW27.MaxHmvR = 0x2000;
93 cmd.DW27.MaxVmvR = 0x200;
94 cmd.DW33.Maxdeltaqp = 0x0f;
95
96 // initialize for P frame
97 if (avcPicParams->CodingType != I_TYPE)
98 {
99 cmd.DW2.BidirectionalWeight = 0x20;
100 cmd.DW4.SubPelMode = 3;
101 cmd.DW4.BmeDisableForFbrMessage = 1;
102 cmd.DW4.InterSadMeasureAdjustment = 2;
103 cmd.DW5.CrePrefetchEnable = 1;
104 cmd.DW8.NonSkipZeroMvCostAdded = 1;
105 cmd.DW8.NonSkipMbModeCostAdded = 1;
106 cmd.DW9.Mode0Cost = 7;
107 cmd.DW9.Mode1Cost = 26;
108 cmd.DW9.Mode2Cost = 30;
109 cmd.DW9.Mode3Cost = 57;
110 cmd.DW10.Mode4Cost = 8;
111 cmd.DW10.Mode5Cost = 2;
112 cmd.DW10.Mode6Cost = 4;
113 cmd.DW10.Mode7Cost = 6;
114 cmd.DW11.Mode8Cost = 5;
115 cmd.DW11.Mode9Cost = 0;
116 cmd.DW11.RefIdCost = 4;
117 cmd.DW12.MvCost0 = 0;
118 cmd.DW12.MvCost1 = 6;
119 cmd.DW12.MvCost2 = 6;
120 cmd.DW12.MvCost3 = 9;
121 cmd.DW13.MvCost4 = 10;
122 cmd.DW13.MvCost5 = 13;
123 cmd.DW13.MvCost6 = 14;
124 cmd.DW13.MvCost7 = 24;
125 cmd.DW31.SadHaarThreshold0 = 800;
126 cmd.DW32.SadHaarThreshold1 = 1600;
127 cmd.DW32.SadHaarThreshold2 = 2400;
128 cmd.DW34.MidpointSadHaar = 0x640;
129 }
130
131 cmd.DW1.Transform8X8Flag = avcPicParams->transform_8x8_mode_flag;
132
133 cmd.DW3.PictureWidth = params->wPicWidthInMb;
134 cmd.DW4.ForwardTransformSkipCheckEnable = m_vdencFTQEnabled[avcSeqParams->TargetUsage];
135 cmd.DW4.BlockBasedSkipEnabled = m_vdencBlockBasedSkipEnabled[avcSeqParams->TargetUsage];
136 cmd.DW5.CrePrefetchEnable = params->bCrePrefetchEnable;
137 cmd.DW5.PictureHeightMinusOne = params->wPicHeightInMb - 1;
138 cmd.DW5.PictureType = avcPicParams->CodingType - 1;
139 cmd.DW5.ConstrainedIntraPredictionFlag = avcPicParams->constrained_intra_pred_flag;
140
141 if (avcPicParams->CodingType != I_TYPE)
142 {
143 cmd.DW5.HmeRef1Disable = params->pEncodeAvcSliceParams->num_ref_idx_l0_active_minus1 ? 0 : 1;
144 }
145
146 if (avcSeqParams->EnableSliceLevelRateCtrl)
147 {
148 cmd.DW5.MbSliceThresholdValue = params->dwMbSlcThresholdValue;
149 }
150
151 cmd.DW6.SliceMacroblockHeightMinusOne = params->wSlcHeightInMb - 1;
152 cmd.DW8.LumaIntraPartitionMask = avcPicParams->transform_8x8_mode_flag ? 0 : mhw_vdbox_vdenc_g9_skl::VDENC_IMG_STATE_CMD::LUMA_INTRA_PARTITION_MASK_UNNAMED2;
153 cmd.DW14.QpPrimeY = avcPicParams->QpY + avcSliceParams->slice_qp_delta;
154
155 if (params->pVDEncModeCost)
156 {
157 cmd.DW9.Mode0Cost = *(params->pVDEncModeCost);
158 cmd.DW9.Mode1Cost = *(params->pVDEncModeCost + 1);
159 cmd.DW9.Mode2Cost = *(params->pVDEncModeCost + 2);
160 cmd.DW9.Mode3Cost = *(params->pVDEncModeCost + 3);
161
162 cmd.DW10.Mode4Cost = *(params->pVDEncModeCost + 4);
163 cmd.DW10.Mode5Cost = *(params->pVDEncModeCost + 5);
164 cmd.DW10.Mode6Cost = *(params->pVDEncModeCost + 6);
165 cmd.DW10.Mode7Cost = *(params->pVDEncModeCost + 7);
166
167 cmd.DW11.Mode8Cost = *(params->pVDEncModeCost + 8);
168 cmd.DW11.RefIdCost = *(params->pVDEncModeCost + 10);
169 }
170 if (params->pVDEncMvCost)
171 {
172 cmd.DW12.MvCost0 = *(params->pVDEncMvCost);
173 cmd.DW12.MvCost1 = *(params->pVDEncMvCost + 1);
174 cmd.DW12.MvCost2 = *(params->pVDEncMvCost + 2);
175 cmd.DW12.MvCost3 = *(params->pVDEncMvCost + 3);
176 cmd.DW13.MvCost4 = *(params->pVDEncMvCost + 4);
177 cmd.DW13.MvCost5 = *(params->pVDEncMvCost + 5);
178 cmd.DW13.MvCost6 = *(params->pVDEncMvCost + 6);
179 cmd.DW13.MvCost7 = *(params->pVDEncMvCost + 7);
180 }
181
182 cmd.DW27.MaxVmvR = params->dwMaxVmvR;
183
184 if (params->pVDEncHmeMvCost)
185 {
186 cmd.DW28.HmeMvCost0 = *(params->pVDEncHmeMvCost);
187 cmd.DW28.HmeMvCost1 = *(params->pVDEncHmeMvCost + 1);
188 cmd.DW28.HmeMvCost2 = *(params->pVDEncHmeMvCost + 2);
189 cmd.DW28.HmeMvCost3 = *(params->pVDEncHmeMvCost + 3);
190 cmd.DW29.HmeMvCost4 = *(params->pVDEncHmeMvCost + 4);
191 cmd.DW29.HmeMvCost5 = *(params->pVDEncHmeMvCost + 5);
192 cmd.DW29.HmeMvCost6 = *(params->pVDEncHmeMvCost + 6);
193 cmd.DW29.HmeMvCost7 = *(params->pVDEncHmeMvCost + 7);
194 }
195
196 cmd.DW34.ImageStateQpOverride = avcSeqParams->RateControlMethod == RATECONTROL_CQP ? 1 : 0;
197
198 // Rolling-I settings
199 if ((avcPicParams->CodingType != I_TYPE) && (avcPicParams->EnableRollingIntraRefresh != ROLLING_I_DISABLED))
200 {
201 cmd.DW1.VdencExtendedPakObjCmdEnable = 1;
202 cmd.DW21.IntraRefreshEnableRollingIEnable = avcPicParams->EnableRollingIntraRefresh != ROLLING_I_DISABLED ? 1 : 0; // 0->Row based ; 1->Column based
203 cmd.DW21.IntraRefreshMode = avcPicParams->EnableRollingIntraRefresh == ROLLING_I_ROW ? 0 : 1;
204 cmd.DW21.IntraRefreshMBPos = avcPicParams->IntraRefreshMBNum;
205 cmd.DW21.IntraRefreshMBSizeMinusOne = avcPicParams->IntraRefreshUnitinMB;
206 cmd.DW21.QpAdjustmentForRollingI = avcPicParams->IntraRefreshQPDelta;
207 }
208
209 // Setting MinMaxQP values if they are presented
210 if (avcPicParams->ucMaximumQP && avcPicParams->ucMinimumQP)
211 {
212 cmd.DW33.MaxQp = avcPicParams->ucMaximumQP;
213 cmd.DW33.MinQp = avcPicParams->ucMinimumQP;
214 }
215 else
216 {
217 // Set default values
218 cmd.DW33.MaxQp = 0x33;
219 cmd.DW33.MinQp = 0x0a;
220 }
221
222 // VDEnc CQP case ROI settings, BRC ROI will be handled in HuC FW
223 if (!params->bVdencBRCEnabled && avcPicParams->NumROI)
224 {
225 MHW_ASSERT(avcPicParams->NumROI < 4);
226
227 int8_t priorityLevelOrDQp[ENCODE_VDENC_AVC_MAX_ROI_NUMBER_G9] = { 0 };
228
229 for (uint8_t i = 0; i < avcPicParams->NumROI; i++)
230 {
231 int8_t dQpRoi = avcPicParams->ROI[i].PriorityLevelOrDQp;
232
233 // clip delta qp roi to VDEnc supported range
234 priorityLevelOrDQp[i] = (char)CodecHal_Clip3(ENCODE_VDENC_AVC_MIN_ROI_DELTA_QP_G9, ENCODE_VDENC_AVC_MAX_ROI_DELTA_QP_G9, dQpRoi);
235 }
236
237 cmd.DW34.RoiEnable = true;
238
239 // Zone0 is reserved for non-ROI region
240 cmd.DW30.RoiQpAdjustmentForZone1 = priorityLevelOrDQp[0];
241 cmd.DW30.RoiQpAdjustmentForZone2 = priorityLevelOrDQp[1];
242 cmd.DW30.RoiQpAdjustmentForZone3 = priorityLevelOrDQp[2];
243 }
244
245 if (params->bVdencBRCEnabled && avcPicParams->NumDirtyROI && params->bVdencStreamInEnabled)
246 {
247 cmd.DW34.RoiEnable = true;
248 }
249
250 if (params->bVdencStreamInEnabled)
251 {
252 cmd.DW34.FwdPredictor0MvEnable = 1;
253 cmd.DW34.PpmvDisable = 1;
254 }
255
256 if (cmdBuffer == nullptr && batchBuffer == nullptr)
257 {
258 MHW_ASSERTMESSAGE("There was no valid buffer to add the HW command to.");
259 return MOS_STATUS_NULL_POINTER;
260 }
261
262 MHW_MI_CHK_STATUS(Mhw_AddCommandCmdOrBB(cmdBuffer, batchBuffer, &cmd, sizeof(cmd)));
263
264 return MOS_STATUS_SUCCESS;
265 }
266
AddVdencWalkerStateCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_VDBOX_VDENC_WALKER_STATE_PARAMS params)267 MOS_STATUS MhwVdboxVdencInterfaceG9Skl::AddVdencWalkerStateCmd(
268 PMOS_COMMAND_BUFFER cmdBuffer,
269 PMHW_VDBOX_VDENC_WALKER_STATE_PARAMS params)
270 {
271 MHW_FUNCTION_ENTER;
272
273 MHW_MI_CHK_NULL(cmdBuffer);
274 MHW_MI_CHK_NULL(params);
275
276 mhw_vdbox_vdenc_g9_skl::VDENC_WALKER_STATE_CMD cmd;
277
278 // MB start X/Y posistion set to 0
279 cmd.DW1.MbLcuStartXPosition = 0;
280 cmd.DW1.MbLcuStartYPosition = 0;
281
282 MHW_MI_CHK_STATUS(Mos_AddCommand(cmdBuffer, &cmd, sizeof(cmd)));
283
284 return MOS_STATUS_SUCCESS;
285 }
286