1 /*
2 * Copyright (c) 2014-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_sfc_g9_X.cpp
24 //! \brief Constructs sfc commands on Gen9-based platforms
25 //! \details Each client facing function both creates a HW command and adds
26 //! that command to a command or batch buffer.
27 //!
28
29 #include "mhw_sfc.h"
30 #include "mhw_sfc_g9_X.h"
31 #include "mos_os_cp_interface_specific.h"
32
AddSfcState(PMOS_COMMAND_BUFFER pCmdBuffer,PMHW_SFC_STATE_PARAMS pSfcStateParams,PMHW_SFC_OUT_SURFACE_PARAMS pOutSurface)33 MOS_STATUS MhwSfcInterfaceG9::AddSfcState(
34 PMOS_COMMAND_BUFFER pCmdBuffer,
35 PMHW_SFC_STATE_PARAMS pSfcStateParams,
36 PMHW_SFC_OUT_SURFACE_PARAMS pOutSurface)
37 {
38 PMOS_INTERFACE pOsInterface;
39 bool bHalfPitchForChroma;
40 bool bInterleaveChroma;
41 uint16_t wUXOffset;
42 uint16_t wUYOffset;
43 uint16_t wVXOffset;
44 uint16_t wVYOffset;
45 MHW_RESOURCE_PARAMS ResourceParams;
46 MEDIA_WA_TABLE *pWaTable = nullptr;
47 mhw_sfc_g9_X::SFC_STATE_CMD cmd;
48 MHW_MEMORY_OBJECT_CONTROL_PARAMS outputSurfCtrl;
49
50 MHW_CHK_NULL_RETURN(pCmdBuffer);
51 MHW_CHK_NULL_RETURN(pSfcStateParams);
52 MHW_CHK_NULL_RETURN(pOutSurface);
53
54 pOsInterface = m_osInterface;
55
56 MHW_CHK_NULL_RETURN(pOsInterface);
57 pWaTable = pOsInterface->pfnGetWaTable(pOsInterface);
58 MHW_CHK_NULL_RETURN(pWaTable);
59
60 bHalfPitchForChroma = false;
61 bInterleaveChroma = false;
62 wUXOffset = 0;
63 wUYOffset = 0;
64 wVXOffset = 0;
65 wVYOffset = 0;
66
67 outputSurfCtrl.Value = m_outputSurfCtrl.Value;
68 if (pOsInterface->osCpInterface && pOsInterface->osCpInterface->IsHMEnabled())
69 {
70 outputSurfCtrl.Value = pOsInterface->pfnCachePolicyGetMemoryObject(
71 MOS_MHW_RESOURCE_USAGE_Sfc_CurrentOutputSurface_PartialEncSurface,
72 pOsInterface->pfnGetGmmClientContext(pOsInterface)).DwordValue;
73 }
74
75 // Check input/output size
76 MHW_ASSERT(pSfcStateParams->dwInputFrameWidth >= MHW_SFC_MIN_WIDTH);
77 MHW_ASSERT(pSfcStateParams->dwInputFrameHeight >= MHW_SFC_MIN_HEIGHT);
78 MHW_ASSERT(pSfcStateParams->dwOutputFrameWidth <= MHW_SFC_MAX_WIDTH);
79 MHW_ASSERT(pSfcStateParams->dwOutputFrameHeight <= MHW_SFC_MAX_HEIGHT);
80
81 cmd.DW1.SfcPipeMode = pSfcStateParams->sfcPipeMode;
82 cmd.DW1.SfcInputChromaSubSampling = pSfcStateParams->dwInputChromaSubSampling;
83 cmd.DW1.VdVeInputOrderingMode = pSfcStateParams->dwVDVEInputOrderingMode;
84
85 // Set DW2
86 cmd.DW2.InputFrameResolutionWidth = pSfcStateParams->dwInputFrameWidth - 1;
87 cmd.DW2.InputFrameResolutionHeight = pSfcStateParams->dwInputFrameHeight - 1;
88
89 switch (pSfcStateParams->OutputFrameFormat)
90 {
91 case Format_AYUV: //AYUV 4:4:4 (8:8:8:8 MSB-A:Y:U:V)
92 cmd.DW3.OutputSurfaceFormatType = cmd.OUTPUT_SURFACE_FORMAT_TYPE_AYUV;
93 break;
94 case Format_X8R8G8B8:
95 case Format_A8R8G8B8:
96 case Format_X8B8G8R8:
97 case Format_A8B8G8R8:
98 cmd.DW3.OutputSurfaceFormatType = cmd.OUTPUT_SURFACE_FORMAT_TYPE_A8B8G8R8;
99 break;
100 case Format_R10G10B10A2:
101 case Format_B10G10R10A2:
102 cmd.DW3.OutputSurfaceFormatType = cmd.OUTPUT_SURFACE_FORMAT_TYPE_A2R10G10B10;
103 break;
104 case Format_R5G6B5:
105 cmd.DW3.OutputSurfaceFormatType = cmd.OUTPUT_SURFACE_FORMAT_TYPE_R5G6B5;
106 break;
107 case Format_NV12:
108 cmd.DW3.OutputSurfaceFormatType = cmd.OUTPUT_SURFACE_FORMAT_TYPE_NV12;
109 bInterleaveChroma = true;
110 wUYOffset = (uint16_t)pOutSurface->dwUYoffset;
111 break;
112 case Format_YUY2:
113 cmd.DW3.OutputSurfaceFormatType = cmd.OUTPUT_SURFACE_FORMAT_TYPE_YUYV;
114 break;
115 case Format_UYVY:
116 cmd.DW3.OutputSurfaceFormatType = cmd.OUTPUT_SURFACE_FORMAT_TYPE_UYVY;
117 break;
118 default:
119 MHW_ASSERTMESSAGE("Unknown Output Format.");
120 return MOS_STATUS_UNKNOWN;
121 }
122
123 // RGBASwapEnable is true when the OutputSurfaceFormatType is set as A8B8G8R8 for X8R8G8B8 and A8R8G8B8 output,
124 // the OutputSurfaceFormatType is set as A2R10G10B10 for R10G10B10A2 output,
125 cmd.DW3.RgbaChannelSwapEnable = pSfcStateParams->bRGBASwapEnable;
126
127 cmd.DW3.PreAvsChromaDownsamplingEnable = pSfcStateParams->dwChromaDownSamplingMode;
128 cmd.DW3.PreAvsChromaDownsamplingCoSitingPositionVerticalDirection = pSfcStateParams->dwChromaDownSamplingVerticalCoef;
129 cmd.DW3.PreAvsChromaDownsamplingCoSitingPositionHorizontalDirection = pSfcStateParams->dwChromaDownSamplingHorizontalCoef;
130
131 // Set DW4
132 cmd.DW4.IefEnable = pSfcStateParams->bIEFEnable;
133 cmd.DW4.SkinToneTunedIefEnable = pSfcStateParams->bSkinToneTunedIEFEnable;
134 cmd.DW4.AvsFilterMode = pSfcStateParams->dwAVSFilterMode;
135 cmd.DW4.AdaptiveFilterForAllChannels = (pSfcStateParams->dwAVSFilterMode == cmd.AVS_FILTER_MODE_8X8POLY_PHASEFILTERBILINEAR_ADAPTIVE) ?
136 true : false;
137 cmd.DW4.AvsScalingEnable = ((pSfcStateParams->fAVSXScalingRatio == 1.0F) &&
138 (pSfcStateParams->fAVSYScalingRatio == 1.0F)) ? false : true;
139 cmd.DW4.BypassYAdaptiveFiltering = pSfcStateParams->bBypassYAdaptiveFilter;
140 cmd.DW4.BypassXAdaptiveFiltering = pSfcStateParams->bBypassXAdaptiveFilter;
141 cmd.DW4.ChromaUpsamplingEnable = pSfcStateParams->bAVSChromaUpsamplingEnable;
142 cmd.DW4.RotationMode = pSfcStateParams->RotationMode;
143 cmd.DW4.ColorFillEnable = pSfcStateParams->bColorFillEnable;
144 cmd.DW4.CscEnable = pSfcStateParams->bCSCEnable;
145
146 // Set DW5, DW6, DW7, DW8, DW9
147 cmd.DW5.SourceRegionWidth = pSfcStateParams->dwSourceRegionWidth - 1;
148 cmd.DW5.SourceRegionHeight = pSfcStateParams->dwSourceRegionHeight - 1;
149 cmd.DW6.SourceRegionHorizontalOffset = pSfcStateParams->dwSourceRegionHorizontalOffset;
150 cmd.DW6.SourceRegionVerticalOffset = pSfcStateParams->dwSourceRegionVerticalOffset;
151 cmd.DW7.OutputFrameWidth = pSfcStateParams->dwOutputFrameWidth + pOutSurface->dwSurfaceXOffset - 1;
152 cmd.DW7.OutputFrameHeight = pSfcStateParams->dwOutputFrameHeight + pOutSurface->dwSurfaceYOffset - 1;
153 cmd.DW8.ScaledRegionSizeWidth = pSfcStateParams->dwScaledRegionWidth - 1;
154 cmd.DW8.ScaledRegionSizeHeight = pSfcStateParams->dwScaledRegionHeight - 1;
155 cmd.DW9.ScaledRegionHorizontalOffset = pSfcStateParams->dwScaledRegionHorizontalOffset + pOutSurface->dwSurfaceXOffset;
156 cmd.DW9.ScaledRegionVerticalOffset = pSfcStateParams->dwScaledRegionVerticalOffset + pOutSurface->dwSurfaceYOffset;
157
158 // Vertical line issue for SFC 270 degree rotation & NV12 output
159 // HW requires Scaled Region Size Width < Output Frame Width && Scaled Region Size Height < Output Frame Height.
160 // HW Design team recommends to program both Output Frame Width/Height to the maximum value of both for the new SW WA.
161 if (MEDIA_IS_WA(pWaTable, WaSFC270DegreeRotation) &&
162 cmd.DW4.RotationMode == MHW_ROTATION_270 &&
163 cmd.DW3.OutputSurfaceFormatType == cmd.OUTPUT_SURFACE_FORMAT_TYPE_NV12)
164 {
165 MHW_NORMALMESSAGE("SW WA vertical line issue for SFC 270 degree rotation & NV12 output.");
166 MHW_NORMALMESSAGE("SFC_STATE before SW WA: OutputFrameWidth = %d, OutputFrameHeight = %d, ScaledRegionSizeWidth = %d, ScaledRegionSizeHeight = %d.",
167 cmd.DW7.OutputFrameWidth, cmd.DW7.OutputFrameHeight,
168 cmd.DW8.ScaledRegionSizeWidth, cmd.DW8.ScaledRegionSizeHeight);
169 if (cmd.DW7.OutputFrameWidth > cmd.DW7.OutputFrameHeight)
170 {
171 cmd.DW7.OutputFrameHeight = cmd.DW7.OutputFrameWidth;
172 }
173 else
174 {
175 cmd.DW7.OutputFrameWidth = cmd.DW7.OutputFrameHeight;
176 }
177 MHW_NORMALMESSAGE("SFC_STATE after SW WA: OutputFrameWidth = %d, OutputFrameHeight = %d, ScaledRegionSizeWidth = %d, ScaledRegionSizeHeight = %d.",
178 cmd.DW7.OutputFrameWidth, cmd.DW7.OutputFrameHeight,
179 cmd.DW8.ScaledRegionSizeWidth, cmd.DW8.ScaledRegionSizeHeight);
180 }
181
182 // Set DW10
183 cmd.DW10.GrayBarPixelUG = MOS_CLAMP_MIN_MAX(MOS_F_ROUND(pSfcStateParams->fColorFillUGPixel * 1024.0F), 0, 1023); // U10
184 cmd.DW10.GrayBarPixelYR = MOS_CLAMP_MIN_MAX(MOS_F_ROUND(pSfcStateParams->fColorFillYRPixel * 1024.0F), 0, 1023); // U10
185
186 // Set DW11
187 cmd.DW11.GrayBarPixelA = MOS_CLAMP_MIN_MAX(MOS_F_ROUND(pSfcStateParams->fColorFillAPixel * 1024.0F), 0, 1023); // U10
188 cmd.DW11.GrayBarPixelVB = MOS_CLAMP_MIN_MAX(MOS_F_ROUND(pSfcStateParams->fColorFillVBPixel * 1024.0F), 0, 1023); // U10
189
190 // Set DW13
191 cmd.DW13.AlphaDefaultValue = MOS_CLAMP_MIN_MAX(MOS_F_ROUND(pSfcStateParams->fAlphaPixel * 1024.0F), 0, 1023); // U10
192
193 // Set DW14
194 cmd.DW14.ScalingFactorHeight = MOS_UF_ROUND((1.0F / pSfcStateParams->fAVSYScalingRatio) * 131072.0F); // U4.17
195
196 // Set DW15
197 cmd.DW15.ScalingFactorWidth = MOS_UF_ROUND((1.0F / pSfcStateParams->fAVSXScalingRatio) * 131072.0f); // U4.17
198
199 // Set DW19
200 cmd.DW19.OutputFrameSurfaceBaseAddressMemoryCompressionEnable = pSfcStateParams->bMMCEnable;
201 cmd.DW19.OutputFrameSurfaceBaseAddressIndexToMemoryObjectControlStateMocsTables = outputSurfCtrl.Gen9.Index;
202
203 if (pSfcStateParams->MMCMode == MOS_MMC_VERTICAL)
204 {
205 cmd.DW19.OutputFrameSurfaceBaseAddressMemoryCompressionMode = 1;
206 }
207
208 // Set DW22
209 cmd.DW22.AvsLineBufferBaseAddressIndexToMemoryObjectControlStateMocsTables
210 = (uint32_t)m_avsLineBufferCtrl.Gen9.Index;
211 // Set DW25
212 cmd.DW25.IefLineBufferBaseAddressIndexToMemoryObjectControlStateMocsTables
213 = m_iefLineBufferCtrl.Gen9.Index;
214
215 // Set DW29
216 cmd.DW29.OutputSurfaceTileWalk = (pOutSurface->TileType == MOS_TILE_Y) ?
217 true : false;
218 cmd.DW29.OutputSurfaceTiled = (pOutSurface->TileType != MOS_TILE_LINEAR) ?
219 true : false;
220 cmd.DW29.OutputSurfaceHalfPitchForChroma
221 = bHalfPitchForChroma;
222 cmd.DW29.OutputSurfacePitch = pOutSurface->dwPitch - 1;
223 cmd.DW29.OutputSurfaceInterleaveChromaEnable
224 = bInterleaveChroma;
225 cmd.DW29.OutputSurfaceFormat = cmd.DW3.OutputSurfaceFormatType;
226
227 // Set DW30, DW31
228 cmd.DW30.OutputSurfaceYOffsetForU = wUYOffset;
229 cmd.DW30.OutputSurfaceXOffsetForU = wUXOffset;
230 cmd.DW31.OutputSurfaceYOffsetForV = wVYOffset;
231 cmd.DW31.OutputSurfaceXOffsetForV = wVXOffset;
232
233 if (pSfcStateParams->pOsResOutputSurface)
234 {
235 MOS_ZeroMemory(&ResourceParams, sizeof(ResourceParams));
236 ResourceParams.presResource = pSfcStateParams->pOsResOutputSurface;
237 ResourceParams.pdwCmd = &(cmd.DW17.Value);
238 ResourceParams.dwLocationInCmd = 17;
239 ResourceParams.HwCommandType = MOS_SFC_STATE;
240 ResourceParams.bIsWritable = true;
241 ResourceParams.dwOffset = pSfcStateParams->dwOutputSurfaceOffset;
242
243 MHW_CHK_STATUS_RETURN(pfnAddResourceToCmd(
244 pOsInterface,
245 pCmdBuffer,
246 &ResourceParams));
247 }
248
249 if (pSfcStateParams->pOsResAVSLineBuffer)
250 {
251 MOS_ZeroMemory(&ResourceParams, sizeof(ResourceParams));
252 ResourceParams.presResource = pSfcStateParams->pOsResAVSLineBuffer;
253 ResourceParams.pdwCmd = &(cmd.DW20.Value);
254 ResourceParams.dwLocationInCmd = 20;
255 ResourceParams.HwCommandType = MOS_SFC_STATE;
256 ResourceParams.bIsWritable = true;
257
258 MHW_CHK_STATUS_RETURN(pfnAddResourceToCmd(
259 pOsInterface,
260 pCmdBuffer,
261 &ResourceParams));
262 }
263
264 if (pSfcStateParams->pOsResIEFLineBuffer)
265 {
266 MOS_ZeroMemory(&ResourceParams, sizeof(ResourceParams));
267 ResourceParams.presResource = pSfcStateParams->pOsResIEFLineBuffer;
268 ResourceParams.pdwCmd = &(cmd.DW23.Value);
269 ResourceParams.dwLocationInCmd = 23;
270 ResourceParams.HwCommandType = MOS_SFC_STATE;
271 ResourceParams.bIsWritable = true;
272
273 MHW_CHK_STATUS_RETURN(pfnAddResourceToCmd(
274 pOsInterface,
275 pCmdBuffer,
276 &ResourceParams));
277 }
278
279 MHW_CHK_STATUS_RETURN(pOsInterface->pfnAddCommand(pCmdBuffer, &cmd, cmd.byteSize));
280
281 return MOS_STATUS_SUCCESS;
282 }
283
MhwSfcInterfaceG9(PMOS_INTERFACE pOsInterface)284 MhwSfcInterfaceG9::MhwSfcInterfaceG9(PMOS_INTERFACE pOsInterface)
285 : MhwSfcInterfaceGeneric(pOsInterface)
286 {
287 // Get Memory control object directly from MOS.
288 // If any override is needed, something like pfnOverrideMemoryObjectCtrl() / pfnComposeSurfaceCacheabilityControl()
289 // will need to be implemented.
290 // Caching policy if any of below modes are true
291 if (m_osInterface == nullptr)
292 {
293 MHW_ASSERTMESSAGE("Invalid Input Parameter: m_osInterface is nullptr");
294 return;
295 }
296
297 m_outputSurfCtrl.Value = m_osInterface->pfnCachePolicyGetMemoryObject(
298 MOS_MHW_RESOURCE_USAGE_Sfc_CurrentOutputSurface,
299 m_osInterface->pfnGetGmmClientContext(m_osInterface)).DwordValue;
300
301 m_avsLineBufferCtrl.Value = m_osInterface->pfnCachePolicyGetMemoryObject(
302 MOS_MHW_RESOURCE_USAGE_Sfc_AvsLineBufferSurface,
303 m_osInterface->pfnGetGmmClientContext(m_osInterface)).DwordValue;
304 m_iefLineBufferCtrl.Value = m_osInterface->pfnCachePolicyGetMemoryObject(
305 MOS_MHW_RESOURCE_USAGE_Sfc_IefLineBufferSurface,
306 m_osInterface->pfnGetGmmClientContext(m_osInterface)).DwordValue;
307 }
308