1 /*
2 * Copyright (c) 2020-2024, 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 vp_render_sfc_m12.cpp
24 //! \brief SFC rendering component
25 //! \details The SFC renderer supports Scaling, IEF, CSC/ColorFill and Rotation.
26 //! It's responsible for setting up HW states and generating the SFC
27 //! commands.
28 //!
29
30 #include "vp_render_sfc_m12.h"
31 #include "vp_hal_ddi_utils.h"
32 #include "mhw_sfc_g12_X.h"
33 #include "mos_defs.h"
34
35 using namespace vp;
36
SfcRenderM12(VP_MHWINTERFACE & vpMhwinterface,PVpAllocator & allocator,bool disbaleSfcDithering)37 SfcRenderM12::SfcRenderM12(
38 VP_MHWINTERFACE &vpMhwinterface,
39 PVpAllocator &allocator,
40 bool disbaleSfcDithering) :
41 SfcRenderBaseLegacy(vpMhwinterface, allocator, disbaleSfcDithering)
42 {
43 }
44
~SfcRenderM12()45 SfcRenderM12::~SfcRenderM12()
46 {
47 }
48
SetupSfcState(PVP_SURFACE targetSurface)49 MOS_STATUS SfcRenderM12::SetupSfcState(
50 PVP_SURFACE targetSurface)
51 {
52 VP_FUNC_CALL();
53
54 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
55 PMHW_SFC_STATE_PARAMS_G12 sfcStateParamsM12 = nullptr;
56
57 VP_RENDER_CHK_STATUS_RETURN(SfcRenderBaseLegacy::SetupSfcState(targetSurface));
58
59 //Set SFD Line Buffer
60 VP_RENDER_CHK_NULL_RETURN(m_renderDataLegacy.sfcStateParams);
61 sfcStateParamsM12 = static_cast<PMHW_SFC_STATE_PARAMS_G12>(m_renderDataLegacy.sfcStateParams);
62 VP_RENDER_CHK_NULL_RETURN(sfcStateParamsM12);
63
64 if (m_renderData.b1stPassOfSfc2PassScaling)
65 {
66 VP_RENDER_CHK_STATUS_RETURN(SetLineBuffer(sfcStateParamsM12->resAvsLineBuffer, m_AVSLineBufferSurfaceArrayfor1stPassofSfc2Pass[m_scalabilityParams.curPipe]));
67 VP_RENDER_CHK_STATUS_RETURN(SetLineBuffer(sfcStateParamsM12->resIefLineBuffer, m_IEFLineBufferSurfaceArrayfor1stPassofSfc2Pass[m_scalabilityParams.curPipe]));
68 VP_RENDER_CHK_STATUS_RETURN(SetLineBuffer(sfcStateParamsM12->resSfdLineBuffer, m_SFDLineBufferSurfaceArrayfor1stPassofSfc2Pass[m_scalabilityParams.curPipe]));
69 }
70 else
71 {
72 VP_RENDER_CHK_STATUS_RETURN(SetLineBuffer(sfcStateParamsM12->resAvsLineBuffer, m_AVSLineBufferSurfaceArray[m_scalabilityParams.curPipe]));
73 VP_RENDER_CHK_STATUS_RETURN(SetLineBuffer(sfcStateParamsM12->resIefLineBuffer, m_IEFLineBufferSurfaceArray[m_scalabilityParams.curPipe]));
74 VP_RENDER_CHK_STATUS_RETURN(SetLineBuffer(sfcStateParamsM12->resSfdLineBuffer, m_SFDLineBufferSurfaceArray[m_scalabilityParams.curPipe]));
75 }
76
77 VP_RENDER_CHK_STATUS_RETURN(SetLineBuffer(sfcStateParamsM12->resAvsLineTileBuffer, m_AVSLineTileBufferSurface));
78 VP_RENDER_CHK_STATUS_RETURN(SetLineBuffer(sfcStateParamsM12->resIefLineTileBuffer, m_IEFLineTileBufferSurface));
79 VP_RENDER_CHK_STATUS_RETURN(SetLineBuffer(sfcStateParamsM12->resSfdLineTileBuffer, m_SFDLineTileBufferSurface));
80
81 sfcStateParamsM12->histogramSurface = &m_histogramSurf;
82
83 return eStatus;
84 }
85
InitSfcStateParams()86 MOS_STATUS SfcRenderM12::InitSfcStateParams()
87 {
88 VP_FUNC_CALL();
89
90 if (nullptr == m_sfcStateParamsLegacy)
91 {
92 m_sfcStateParamsLegacy = (MHW_SFC_STATE_PARAMS_G12*)MOS_AllocAndZeroMemory(sizeof(MHW_SFC_STATE_PARAMS_G12));
93 }
94 else
95 {
96 MOS_ZeroMemory(m_sfcStateParamsLegacy, sizeof(MHW_SFC_STATE_PARAMS_G12));
97 }
98
99 VP_PUBLIC_CHK_NULL_RETURN(m_sfcStateParamsLegacy);
100
101 m_renderDataLegacy.sfcStateParams = m_sfcStateParamsLegacy;
102
103 return MOS_STATUS_SUCCESS;
104 }
105
SetCodecPipeMode(CODECHAL_STANDARD codecStandard)106 MOS_STATUS SfcRenderM12::SetCodecPipeMode(CODECHAL_STANDARD codecStandard)
107 {
108 VP_FUNC_CALL();
109
110 if (CODECHAL_HEVC == codecStandard ||
111 CODECHAL_VP9 == codecStandard)
112 {
113 m_pipeMode = MhwSfcInterfaceG12::SFC_PIPE_MODE_HCP;
114 }
115 else
116 {
117 return SfcRenderBase::SetCodecPipeMode(codecStandard);
118 }
119 return MOS_STATUS_SUCCESS;
120 }
121
SetSfcStateInputOrderingModeHcp(PMHW_SFC_STATE_PARAMS sfcStateParams)122 MOS_STATUS SfcRenderM12::SetSfcStateInputOrderingModeHcp(
123 PMHW_SFC_STATE_PARAMS sfcStateParams)
124 {
125 VP_FUNC_CALL();
126
127 if (CODECHAL_HEVC != m_videoConfig.codecStandard &&
128 CODECHAL_VP9 != m_videoConfig.codecStandard)
129 {
130 return MOS_STATUS_INVALID_PARAMETER;
131 }
132 if (CODECHAL_HEVC == m_videoConfig.codecStandard)
133 {
134 sfcStateParams->dwVDVEInputOrderingMode = (16 == m_videoConfig.hevc.lcuSize) ? MhwSfcInterfaceG12::LCU_16_16_HEVC :
135 (32 == m_videoConfig.hevc.lcuSize) ? MhwSfcInterfaceG12::LCU_32_32_HEVC : MhwSfcInterfaceG12::LCU_64_64_HEVC;
136 }
137 else if (CODECHAL_VP9 == m_videoConfig.codecStandard)
138 {
139 VPHAL_COLORPACK colorPack = VpHalDDIUtils::GetSurfaceColorPack(m_renderDataLegacy.SfcInputFormat);
140
141 if ((VPHAL_COLORPACK_420 == colorPack)
142 || (VPHAL_COLORPACK_444 == colorPack))
143 {
144 sfcStateParams->dwVDVEInputOrderingMode = MhwSfcInterfaceG12::LCU_64_64_VP9;
145 }
146 else
147 {
148 return MOS_STATUS_INVALID_PARAMETER;
149 }
150 }
151 return MOS_STATUS_SUCCESS;
152 }
153
AddSfcLock(PMOS_COMMAND_BUFFER pCmdBuffer,PMHW_SFC_LOCK_PARAMS pSfcLockParams)154 MOS_STATUS SfcRenderM12::AddSfcLock(
155 PMOS_COMMAND_BUFFER pCmdBuffer,
156 PMHW_SFC_LOCK_PARAMS pSfcLockParams)
157 {
158 VP_FUNC_CALL();
159
160 VP_RENDER_CHK_NULL_RETURN(m_miInterface);
161
162 // Send SFC_LOCK command to acquire SFC pipe for Vebox
163 VP_RENDER_CHK_STATUS_RETURN(SfcRenderBaseLegacy::AddSfcLock(
164 pCmdBuffer,
165 pSfcLockParams));
166
167 //insert 2 dummy VD_CONTROL_STATE packets with data=0 after every HCP_SFC_LOCK
168 if (MhwSfcInterfaceG12::SFC_PIPE_MODE_HCP == m_pipeMode && MEDIA_IS_WA(m_waTable, Wa_14010222001))
169 {
170 MHW_MI_VD_CONTROL_STATE_PARAMS vdCtrlParam;
171 MOS_ZeroMemory(&vdCtrlParam, sizeof(MHW_MI_VD_CONTROL_STATE_PARAMS));
172 for (int i = 0; i < 2; i++)
173 {
174 VP_RENDER_CHK_STATUS_RETURN(static_cast<MhwMiInterfaceG12 *>(m_miInterface)->AddMiVdControlStateCmd(pCmdBuffer, &vdCtrlParam));
175 }
176 }
177 return MOS_STATUS_SUCCESS;
178 }
179
SetupScalabilityParams()180 MOS_STATUS SfcRenderM12::SetupScalabilityParams()
181 {
182
183 VP_FUNC_CALL();
184
185 VP_RENDER_CHK_NULL_RETURN(m_renderDataLegacy.sfcStateParams);
186 PMHW_SFC_STATE_PARAMS_G12 sfcStateParams = static_cast<PMHW_SFC_STATE_PARAMS_G12>(m_renderDataLegacy.sfcStateParams);
187
188 if (MhwSfcInterfaceG12::SFC_PIPE_MODE_HCP != m_pipeMode &&
189 MhwSfcInterface::SFC_PIPE_MODE_VEBOX!= m_pipeMode)
190 {
191 VP_RENDER_NORMALMESSAGE("No scalability params need be applied for pipeMode(%d)", m_pipeMode);
192 return MOS_STATUS_SUCCESS;
193 }
194
195 if (1 == m_scalabilityParams.numPipe)
196 {
197 VP_RENDER_NORMALMESSAGE("Scalability is disabled.");
198 return MOS_STATUS_SUCCESS;
199 }
200
201 // Check whether engine mode being valid.
202 uint32_t engineMode = (0 == m_scalabilityParams.curPipe) ? 1 :
203 (m_scalabilityParams.numPipe - 1 == m_scalabilityParams.curPipe) ? 2 : 3;
204 if (engineMode != m_scalabilityParams.engineMode)
205 {
206 VP_RENDER_ASSERTMESSAGE("engineMode (%d) may not be expected according to curPipe(%d) and numPipe(%d).",
207 m_scalabilityParams.engineMode, m_scalabilityParams.curPipe, m_scalabilityParams.numPipe);
208 }
209
210 sfcStateParams->engineMode = m_scalabilityParams.engineMode;
211
212 if (MhwSfcInterfaceG12::SFC_PIPE_MODE_HCP == m_pipeMode)
213 {
214 VPHAL_COLORPACK colorPack = VpHalDDIUtils::GetSurfaceColorPack(m_renderDataLegacy.SfcInputFormat);
215
216 if ((VPHAL_COLORPACK_420 == colorPack || VPHAL_COLORPACK_422 == colorPack) &&
217 (!MOS_IS_ALIGNED(m_scalabilityParams.srcStartX, 2) || MOS_IS_ALIGNED(m_scalabilityParams.srcEndX, 2)))
218 {
219 VP_PUBLIC_ASSERTMESSAGE("srcStartX(%d) is not even or srcEndX(%d) is not odd with input format(%d).",
220 m_scalabilityParams.srcStartX, m_scalabilityParams.srcEndX, m_renderDataLegacy.SfcInputFormat);
221 }
222 sfcStateParams->tileType = m_scalabilityParams.tileType;
223 sfcStateParams->srcStartX = m_scalabilityParams.srcStartX;
224 sfcStateParams->srcEndX = m_scalabilityParams.srcEndX;
225 sfcStateParams->dstStartX = m_scalabilityParams.dstStartX;
226 sfcStateParams->dstEndX = m_scalabilityParams.dstEndX;
227 }
228
229 return MOS_STATUS_SUCCESS;
230 }
231
232 //!
233 //! \brief Set sfc pipe selected with vebox
234 //! \details Set sfc pipe selected with vebox
235 //! \param [in] dwSfcPipe
236 //! Sfc pipe selected with vebox
237 //! \param [in] dwSfcNum
238 //! Sfc pipe num in total
239 //! \return MOS_STATUS
240 //! MOS_STATUS_SUCCESS if success, else fail reason
SetSfcPipe(uint32_t dwSfcPipe,uint32_t dwSfcNum)241 MOS_STATUS SfcRenderM12::SetSfcPipe(
242 uint32_t dwSfcPipe,
243 uint32_t dwSfcNum)
244 {
245 VP_FUNC_CALL();
246
247 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
248
249 VP_PUBLIC_CHK_NULL_RETURN(m_sfcInterface);
250 PMHW_SFC_INTERFACE pSfcInterface = static_cast<PMHW_SFC_INTERFACE>(m_sfcInterface);
251
252 if (dwSfcPipe >= dwSfcNum)
253 {
254 VP_PUBLIC_ASSERTMESSAGE("Scalability sfc pipe set by vebox, dwSfcPipe %d, dwSfcNum %d", dwSfcPipe, dwSfcNum);
255 return MOS_STATUS_INVALID_PARAMETER;
256 }
257
258 m_scalabilityParams.curPipe = dwSfcPipe;
259 m_scalabilityParams.numPipe = dwSfcNum;
260 m_scalabilityParams.engineMode = (0 == m_scalabilityParams.curPipe) ? 1 : (m_scalabilityParams.numPipe - 1 == m_scalabilityParams.curPipe) ? 2 : 3;
261
262 pSfcInterface = m_sfcInterface;
263
264 pSfcInterface->SetSfcIndex(dwSfcPipe, dwSfcNum);
265
266 return eStatus;
267 }
268
IsOutputChannelSwapNeeded(MOS_FORMAT outputFormat)269 bool SfcRenderM12::IsOutputChannelSwapNeeded(MOS_FORMAT outputFormat)
270 {
271 VP_FUNC_CALL();
272
273 // ARGB8,ABGR10, output format need to enable swap
274 // Only be used with RGB output formats and CSC conversion is turned on.
275 if (outputFormat == Format_X8R8G8B8 ||
276 outputFormat == Format_A8R8G8B8 ||
277 outputFormat == Format_R10G10B10A2)
278 {
279 return true;
280 }
281 else
282 {
283 return false;
284 }
285 }
286
IsCscNeeded(SFC_CSC_PARAMS & cscParams)287 bool SfcRenderM12::IsCscNeeded(SFC_CSC_PARAMS &cscParams)
288 {
289 VP_FUNC_CALL();
290
291 return cscParams.bCSCEnabled ||
292 IsInputChannelSwapNeeded(cscParams.inputFormat) ||
293 IsOutputChannelSwapNeeded(cscParams.outputFormat);
294 }
295