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