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