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