xref: /aosp_15_r20/external/intel-media-driver/media_driver/agnostic/gen9/hw/mhw_sfc_g9_X.cpp (revision ba62d9d3abf0e404f2022b4cd7a85e107f48596f)
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