1 /*
2 * Copyright (c) 2019-2022, 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 vphal_render_vebox_memdecomp_g12.cpp
24 //! \brief Defines data structures and interfaces for media memory decompression.
25 //! \details
26 //!
27
28 #include "vphal_render_vebox_memdecomp_g12.h"
29 #include "mhw_vebox_hwcmd_g12_X.h"
30 #include "mhw_vebox_g12_X.h"
31 #include "hal_oca_interface.h"
32 #include "mos_os_cp_interface_specific.h"
33 #include "vp_utils.h"
34
MediaVeboxDecompStateG12()35 MediaVeboxDecompStateG12::MediaVeboxDecompStateG12() :
36 MediaVeboxDecompState()
37 {
38 }
39
RenderDecompCMD(PMOS_SURFACE surface)40 MOS_STATUS MediaVeboxDecompStateG12::RenderDecompCMD(PMOS_SURFACE surface)
41 {
42 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
43 MHW_VEBOX_STATE_CMD_PARAMS veboxStateCmdParams;
44 MOS_COMMAND_BUFFER cmdBuffer;
45 PMHW_VEBOX_INTERFACE veboxInterface;
46 MHW_VEBOX_SURFACE_STATE_CMD_PARAMS mhwVeboxSurfaceStateCmdParams;
47 MHW_MI_FLUSH_DW_PARAMS flushDwParams;
48 uint32_t streamID = 0;
49 const MHW_VEBOX_HEAP *veboxHeap = nullptr;
50 MOS_CONTEXT * pOsContext = nullptr;
51 PMHW_MI_MMIOREGISTERS pMmioRegisters = nullptr;
52
53 VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(surface);
54 VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(m_osInterface);
55 VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(pOsContext = m_osInterface->pOsContext);
56 VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(m_mhwMiInterface);
57 VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(pMmioRegisters = m_mhwMiInterface->GetMmioRegisters());
58
59 if (surface->CompressionMode != MOS_MMC_MC &&
60 surface->CompressionMode != MOS_MMC_RC)
61 {
62 VPHAL_MEMORY_DECOMP_NORMALMESSAGE("Input surface is uncompressed, In_Place resolve is not needed");
63 return eStatus;
64 }
65
66 if (!IsFormatSupported(surface))
67 {
68 VPHAL_MEMORY_DECOMP_NORMALMESSAGE("Input surface is not supported by Vebox, In_Place resolve can't be done");
69 return eStatus;
70 }
71
72 veboxInterface = m_veboxInterface;
73
74 m_osInterface->pfnSetGpuContext(m_osInterface, MOS_GPU_CONTEXT_VEBOX);
75 if (m_syncResource)
76 {
77 VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(m_osInterface->pfnRegisterResource(m_osInterface, m_syncResource, true, true));
78 }
79
80 // Reset allocation list and house keeping
81 m_osInterface->pfnResetOsStates(m_osInterface);
82
83 VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(veboxInterface->GetVeboxHeapInfo(&veboxHeap));
84 VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(&surface->OsResource);
85 VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(m_osInterface->osCpInterface);
86
87 // Check whether surface is ready for write
88 m_osInterface->pfnSyncOnResource(
89 m_osInterface,
90 &surface->OsResource,
91 MOS_GPU_CONTEXT_VEBOX,
92 true);
93
94 // preprocess in cp first
95 m_osInterface->osCpInterface->PrepareResources((void **)&surface, 1, nullptr, 0);
96
97 // initialize the command buffer struct
98 MOS_ZeroMemory(&cmdBuffer, sizeof(MOS_COMMAND_BUFFER));
99
100 VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
101
102 HalOcaInterface::On1stLevelBBStart(cmdBuffer, *pOsContext, m_osInterface->CurrentGpuContextHandle, *m_mhwMiInterface, *pMmioRegisters);
103
104 VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(InitCommandBuffer(&cmdBuffer));
105
106 // Prepare Vebox_Surface_State, surface input/and output are the same but the compressed status.
107 VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(SetupVeboxSurfaceState(&mhwVeboxSurfaceStateCmdParams, surface, nullptr));
108
109 //---------------------------------
110 // Send Pvt MMCD CMD
111 //---------------------------------
112 MhwVeboxInterfaceG12 *pVeboxInterfaceExt12;
113 pVeboxInterfaceExt12 = (MhwVeboxInterfaceG12 *)veboxInterface;
114
115 VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(pVeboxInterfaceExt12->setVeboxPrologCmd(
116 m_mhwMiInterface,
117 &cmdBuffer));
118
119 //---------------------------------
120 // Send CMD: Vebox_Surface_State
121 //---------------------------------
122 VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(veboxInterface->AddVeboxSurfaces(
123 &cmdBuffer,
124 &mhwVeboxSurfaceStateCmdParams));
125
126 HalOcaInterface::OnDispatch(cmdBuffer, *m_osInterface, *m_mhwMiInterface, *pMmioRegisters);
127
128 //---------------------------------
129 // Send CMD: Vebox_Tiling_Convert
130 //---------------------------------
131 VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(VeboxSendVeboxTileConvertCMD(&cmdBuffer, surface, nullptr, streamID));
132
133 MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
134
135 VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(m_mhwMiInterface->AddMiFlushDwCmd(
136 &cmdBuffer,
137 &flushDwParams));
138
139 if (!m_osInterface->bEnableKmdMediaFrameTracking && veboxHeap)
140 {
141 MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
142 flushDwParams.pOsResource = (PMOS_RESOURCE)&veboxHeap->DriverResource;
143 flushDwParams.dwResourceOffset = veboxHeap->uiOffsetSync;
144 flushDwParams.dwDataDW1 = veboxHeap->dwNextTag;
145 VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(m_mhwMiInterface->AddMiFlushDwCmd(
146 &cmdBuffer,
147 &flushDwParams));
148 }
149
150 HalOcaInterface::On1stLevelBBEnd(cmdBuffer, *m_osInterface);
151
152 VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(m_mhwMiInterface->AddMiBatchBufferEnd(
153 &cmdBuffer,
154 nullptr));
155
156 // Return unused command buffer space to OS
157 m_osInterface->pfnReturnCommandBuffer(
158 m_osInterface,
159 &cmdBuffer,
160 0);
161
162 // Flush the command buffer
163 VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(
164 m_osInterface,
165 &cmdBuffer,
166 false));
167
168 veboxInterface->UpdateVeboxSync();
169
170 return eStatus;
171 }
172
IsVeboxDecompressionEnabled()173 MOS_STATUS MediaVeboxDecompStateG12::IsVeboxDecompressionEnabled()
174 {
175 bool customValue = true;
176 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
177
178 ReadUserSetting(
179 m_userSettingPtr,
180 m_veboxMMCResolveEnabled,
181 __VPHAL_ENABLE_VEBOX_MMC_DECOMPRESS,
182 MediaUserSetting::Group::Device,
183 customValue,
184 true);
185
186 return eStatus;
187 }
188
RenderDoubleBufferDecompCMD(PMOS_SURFACE inputSurface,PMOS_SURFACE outputSurface)189 MOS_STATUS MediaVeboxDecompStateG12::RenderDoubleBufferDecompCMD(
190 PMOS_SURFACE inputSurface,
191 PMOS_SURFACE outputSurface)
192 {
193 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
194 MHW_VEBOX_STATE_CMD_PARAMS veboxStateCmdParams;
195 MOS_COMMAND_BUFFER cmdBuffer;
196 PMHW_VEBOX_INTERFACE veboxInterface;
197 MHW_VEBOX_SURFACE_STATE_CMD_PARAMS mhwVeboxSurfaceStateCmdParams;
198 MHW_MI_FLUSH_DW_PARAMS flushDwParams;
199 uint32_t streamID = 0;
200 const MHW_VEBOX_HEAP *veboxHeap = nullptr;
201
202 VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(inputSurface);
203 VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(outputSurface);
204
205 if (!IsFormatSupported(inputSurface) || !IsFormatSupported(outputSurface))
206 {
207 VPHAL_MEMORY_DECOMP_NORMALMESSAGE("Input surface is not supported by Vebox, In_Place resolve can't be done");
208 return eStatus;
209 }
210
211 veboxInterface = m_veboxInterface;
212
213 m_osInterface->pfnSetGpuContext(m_osInterface, MOS_GPU_CONTEXT_VEBOX);
214
215 // Reset allocation list and house keeping
216 m_osInterface->pfnResetOsStates(m_osInterface);
217
218 VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(veboxInterface->GetVeboxHeapInfo(&veboxHeap));
219 VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(&inputSurface->OsResource);
220 VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(&outputSurface->OsResource);
221 VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(m_osInterface->osCpInterface);
222
223 //there is a new usage that input surface is clear and output surface is secure.
224 //replace Huc Copy by DoubleBuffer resolve to update ccs data.
225 //So need consolidate both input/output surface information to decide cp context.
226 PMOS_SURFACE surfaceArray[2];
227 surfaceArray[0] = inputSurface;
228 surfaceArray[1] = outputSurface;
229
230 // preprocess in cp first
231 m_osInterface->osCpInterface->PrepareResources((void **)&surfaceArray, sizeof(surfaceArray) / sizeof(PMOS_SURFACE), nullptr, 0);
232
233 // initialize the command buffer struct
234 MOS_ZeroMemory(&cmdBuffer, sizeof(MOS_COMMAND_BUFFER));
235
236 VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
237 VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(InitCommandBuffer(&cmdBuffer));
238
239 // Prepare Vebox_Surface_State, surface input/and output are the same but the compressed status.
240 VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(SetupVeboxSurfaceState(&mhwVeboxSurfaceStateCmdParams, inputSurface, outputSurface));
241
242 MhwVeboxInterfaceG12 *pVeboxInterfaceExt12;
243 pVeboxInterfaceExt12 = (MhwVeboxInterfaceG12 *)veboxInterface;
244
245 VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(pVeboxInterfaceExt12->setVeboxPrologCmd(
246 m_mhwMiInterface,
247 &cmdBuffer));
248
249 //---------------------------------
250 // Send CMD: Vebox_Surface_State
251 //---------------------------------
252 VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(veboxInterface->AddVeboxSurfaces(
253 &cmdBuffer,
254 &mhwVeboxSurfaceStateCmdParams));
255
256 //---------------------------------
257 // Send CMD: Vebox_Tiling_Convert
258 //---------------------------------
259 VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(VeboxSendVeboxTileConvertCMD(&cmdBuffer, inputSurface, outputSurface, streamID));
260
261 MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
262
263 VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(m_mhwMiInterface->AddMiFlushDwCmd(
264 &cmdBuffer,
265 &flushDwParams));
266
267 if (!m_osInterface->bEnableKmdMediaFrameTracking && veboxHeap)
268 {
269 MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
270 flushDwParams.pOsResource = (PMOS_RESOURCE)&veboxHeap->DriverResource;
271 flushDwParams.dwResourceOffset = veboxHeap->uiOffsetSync;
272 flushDwParams.dwDataDW1 = veboxHeap->dwNextTag;
273 VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(m_mhwMiInterface->AddMiFlushDwCmd(
274 &cmdBuffer,
275 &flushDwParams));
276 }
277
278 VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(m_mhwMiInterface->AddMiBatchBufferEnd(
279 &cmdBuffer,
280 nullptr));
281
282 // Return unused command buffer space to OS
283 m_osInterface->pfnReturnCommandBuffer(
284 m_osInterface,
285 &cmdBuffer,
286 0);
287
288 // Flush the command buffer
289 VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(
290 m_osInterface,
291 &cmdBuffer,
292 false));
293
294 veboxInterface->UpdateVeboxSync();
295
296 return eStatus;
297 }
298
VeboxSendVeboxTileConvertCMD(PMOS_COMMAND_BUFFER cmdBuffer,PMOS_SURFACE inputSurface,PMOS_SURFACE outputSurface,uint32_t streamID)299 MOS_STATUS MediaVeboxDecompStateG12::VeboxSendVeboxTileConvertCMD(
300 PMOS_COMMAND_BUFFER cmdBuffer,
301 PMOS_SURFACE inputSurface,
302 PMOS_SURFACE outputSurface,
303 uint32_t streamID)
304 {
305 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
306 PMOS_SURFACE surface = nullptr;
307 mhw_vebox_g12_X::VEB_DI_IECP_COMMAND_SURFACE_CONTROL_BITS_CMD veboxInputSurfCtrlBits, veboxOutputSurfCtrlBits;
308
309 mhw_vebox_g12_X::VEBOX_TILING_CONVERT_CMD cmd;
310 MHW_RESOURCE_PARAMS ResourceParams = {0};
311
312 MOS_UNUSED(streamID);
313 VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(cmdBuffer);
314 VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(inputSurface);
315 VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(m_osInterface);
316 VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(m_veboxInterface);
317 VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(m_veboxInterface->pfnAddResourceToCmd);
318
319 // Set up VEB_DI_IECP_COMMAND_SURFACE_CONTROL_BITS
320 MOS_ZeroMemory(&veboxInputSurfCtrlBits, sizeof(veboxInputSurfCtrlBits));
321 MOS_ZeroMemory(&veboxOutputSurfCtrlBits, sizeof(veboxOutputSurfCtrlBits));
322
323 veboxInputSurfCtrlBits.DW0.IndexToMemoryObjectControlStateMocsTables =
324 veboxOutputSurfCtrlBits.DW0.IndexToMemoryObjectControlStateMocsTables =
325 (m_osInterface->pfnCachePolicyGetMemoryObject(
326 MOS_MP_RESOURCE_USAGE_DEFAULT,
327 m_osInterface->pfnGetGmmClientContext(m_osInterface))).Gen12.Index;
328
329 // Set Input surface compression status
330 if (inputSurface->CompressionMode != MOS_MMC_DISABLED)
331 {
332 veboxInputSurfCtrlBits.DW0.MemoryCompressionEnable = true;
333
334 if (inputSurface->CompressionMode == MOS_MMC_RC)
335 {
336 veboxInputSurfCtrlBits.DW0.CompressionType = 1;
337 }
338 else
339 {
340 veboxInputSurfCtrlBits.DW0.CompressionType = 0;
341 }
342 }
343
344 switch (inputSurface->TileType)
345 {
346 case MOS_TILE_YF:
347 veboxInputSurfCtrlBits.DW0.TiledResourceModeForOutputFrameSurfaceBaseAddress = TRMODE_TILEYF;
348 break;
349 case MOS_TILE_YS:
350 veboxInputSurfCtrlBits.DW0.TiledResourceModeForOutputFrameSurfaceBaseAddress = TRMODE_TILEYS;
351 break;
352 default:
353 veboxInputSurfCtrlBits.DW0.TiledResourceModeForOutputFrameSurfaceBaseAddress = TRMODE_NONE;
354 break;
355 }
356
357 // Set Output surface compression status
358 if (outputSurface)
359 {
360 // Double Buffer copy
361 surface = outputSurface;
362
363 if (outputSurface->CompressionMode == MOS_MMC_MC)
364 {
365 veboxOutputSurfCtrlBits.DW0.MemoryCompressionEnable = true;
366 veboxOutputSurfCtrlBits.DW0.CompressionType = 0;
367 }
368 else if (outputSurface->CompressionMode == MOS_MMC_RC)
369 {
370 veboxOutputSurfCtrlBits.DW0.MemoryCompressionEnable = true;
371 veboxOutputSurfCtrlBits.DW0.CompressionType = 1;
372 }
373 else
374 {
375 veboxOutputSurfCtrlBits.DW0.MemoryCompressionEnable = false;
376 veboxOutputSurfCtrlBits.DW0.CompressionType = 0;
377 }
378
379 }
380 else
381 {
382 // In-Place Resolve
383 surface = inputSurface;
384 veboxOutputSurfCtrlBits.DW0.MemoryCompressionEnable = true;
385 veboxOutputSurfCtrlBits.DW0.CompressionType = 1;
386 }
387
388 switch (surface->TileType)
389 {
390 case MOS_TILE_YF:
391 veboxOutputSurfCtrlBits.DW0.TiledResourceModeForOutputFrameSurfaceBaseAddress = TRMODE_TILEYF;
392 break;
393 case MOS_TILE_YS:
394 veboxOutputSurfCtrlBits.DW0.TiledResourceModeForOutputFrameSurfaceBaseAddress = TRMODE_TILEYS;
395 break;
396 default:
397 veboxOutputSurfCtrlBits.DW0.TiledResourceModeForOutputFrameSurfaceBaseAddress = TRMODE_NONE;
398 break;
399 }
400
401 InitMocsParams(ResourceParams, &cmd.DW1_2.Value[0], 1, 6);
402
403 ResourceParams.presResource = &inputSurface->OsResource;
404 ResourceParams.HwCommandType = MOS_VEBOX_TILING_CONVERT;
405
406 // set up DW[2:1], input graphics address
407 ResourceParams.dwLocationInCmd = 1;
408 ResourceParams.pdwCmd = &(cmd.DW1_2.Value[0]);
409 ResourceParams.bIsWritable = false;
410 ResourceParams.dwOffset = inputSurface->dwOffset + veboxInputSurfCtrlBits.DW0.Value;
411 VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(m_veboxInterface->pfnAddResourceToCmd(m_osInterface, cmdBuffer, &ResourceParams));
412
413 MOS_ZeroMemory(&ResourceParams, sizeof(MHW_RESOURCE_PARAMS));
414 InitMocsParams(ResourceParams, &cmd.DW3_4.Value[0], 1, 6);
415
416 if (outputSurface)
417 {
418 ResourceParams.presResource = &outputSurface->OsResource;
419 }
420 else
421 {
422 ResourceParams.presResource = &inputSurface->OsResource;
423 }
424
425 ResourceParams.HwCommandType = MOS_VEBOX_TILING_CONVERT;
426
427 // set up DW[4:3], output graphics address
428 ResourceParams.dwLocationInCmd = 3;
429 ResourceParams.pdwCmd = &(cmd.DW3_4.Value[0]);
430 ResourceParams.bIsWritable = true;
431 ResourceParams.dwOffset =
432 (outputSurface != nullptr ? outputSurface->dwOffset : inputSurface->dwOffset) + veboxOutputSurfCtrlBits.DW0.Value;
433 VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(m_veboxInterface->pfnAddResourceToCmd(m_osInterface, cmdBuffer, &ResourceParams));
434
435 m_osInterface->pfnAddCommand(cmdBuffer, &cmd, cmd.byteSize);
436
437 return eStatus;
438 }
439