1 /*
2 * Copyright (c) 2022-2023, 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     media_mem_decompress_xe_lpm_plus_base.cpp
24 //! \brief    Common interface used in media decompression
25 //! \details  Common interface used in media decompression which are platform independent
26 //!
27 
28 #include "media_mem_decompress_xe_lpm_plus_base.h"
29 #include "hal_oca_interface_next.h"
30 #include "vp_common.h"
31 #include "mhw_vebox_hwcmd_xe_lpm_plus_next.h"
32 #include "mos_interface.h"
33 #include "mos_os_cp_interface_specific.h"
34 
MediaMemDeCompNext_Xe_Lpm_Plus_Base()35 MediaMemDeCompNext_Xe_Lpm_Plus_Base::MediaMemDeCompNext_Xe_Lpm_Plus_Base() :
36     MediaMemDeCompNext()
37 {
38 }
39 
RenderDecompCMD(PMOS_SURFACE surface)40 MOS_STATUS MediaMemDeCompNext_Xe_Lpm_Plus_Base::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     MHW_VEBOX_SURFACE_STATE_CMD_PARAMS  mhwVeboxSurfaceStateCmdParams;
46     MHW_MI_FLUSH_DW_PARAMS              flushDwParams;
47     uint32_t                            streamID = 0;
48     const MHW_VEBOX_HEAP*               veboxHeap = nullptr;
49     MOS_CONTEXT*                        pOsContext = nullptr;
50     PMHW_MI_MMIOREGISTERS               pMmioRegisters = nullptr;
51     bool                                isPerfCollected = false;
52     MediaPerfProfiler*                  perfProfiler = nullptr;
53     uint32_t                            perfTag = 0;
54 
55     VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(surface);
56     VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(m_osInterface);
57     VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(pOsContext = m_osInterface->pOsContext);
58     VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(m_miItf);
59     VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(m_veboxItf);
60     VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(pMmioRegisters = m_miItf->GetMmioRegisters());
61 
62     if (surface->CompressionMode &&
63         surface->CompressionMode != MOS_MMC_MC &&
64         surface->CompressionMode != MOS_MMC_RC)
65     {
66         VPHAL_MEMORY_DECOMP_NORMALMESSAGE("Input surface is uncompressed, In_Place resolve is not needed");
67         return eStatus;
68     }
69 
70     if (!IsFormatSupported(surface))
71     {
72         VPHAL_MEMORY_DECOMP_NORMALMESSAGE("Input surface is not supported by Vebox, In_Place resolve can't be done");
73         return eStatus;
74     }
75 
76     m_osInterface->pfnSetGpuContext(m_osInterface, MOS_GPU_CONTEXT_VEBOX);
77     if (m_syncResource)
78     {
79         VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(m_osInterface->pfnRegisterResource(m_osInterface, m_syncResource, true, true));
80     }
81 
82     // Reset allocation list and house keeping
83     m_osInterface->pfnResetOsStates(m_osInterface);
84 
85     VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(m_veboxItf->GetVeboxHeapInfo(&veboxHeap));
86     VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(&surface->OsResource);
87     VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(m_osInterface->osCpInterface);
88 
89     // Check whether surface is ready for write
90     m_osInterface->pfnSyncOnResource(
91         m_osInterface,
92         &surface->OsResource,
93         MOS_GPU_CONTEXT_VEBOX,
94         true);
95 
96     // preprocess in cp first
97     m_osInterface->osCpInterface->PrepareResources((void**)&surface, 1, nullptr, 0);
98 
99     // initialize the command buffer struct
100     MOS_ZeroMemory(&cmdBuffer, sizeof(MOS_COMMAND_BUFFER));
101 
102     VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
103 
104     HalOcaInterfaceNext::On1stLevelBBStart(
105         cmdBuffer,
106         (MOS_CONTEXT_HANDLE)pOsContext,
107         m_osInterface->CurrentGpuContextHandle,
108         m_miItf,
109         *pMmioRegisters);
110 
111     VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(InitCommandBuffer(&cmdBuffer));
112 
113     if (m_multiprocesssinglebin)
114     {
115         perfTag = m_osInterface->pfnGetPerfTag(m_osInterface);
116         // check the decompress was called from whether media driver or apps
117         if (perfTag != VPHAL_NONE)
118         {
119             isPerfCollected = true;
120 
121             perfProfiler = MediaPerfProfiler::Instance();
122             VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(perfProfiler);
123             // clear the decompress tag to separate the vpblt perf tag
124             m_osInterface->pfnSetPerfTag(m_osInterface, VPHAL_NONE);
125             VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(perfProfiler->Initialize((void *)this, m_osInterface));
126             VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(perfProfiler->AddPerfCollectStartCmd((void *)this, m_osInterface, m_miItf, &cmdBuffer));
127         }
128     }
129 
130     // Prepare Vebox_Surface_State, surface input/and output are the same but the compressed status.
131     VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(SetupVeboxSurfaceState(&mhwVeboxSurfaceStateCmdParams, surface, nullptr));
132 
133     //---------------------------------
134     // Send Pvt MMCD CMD
135     //---------------------------------
136     VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(m_miItf->AddVeboxMMIOPrologCmd(&cmdBuffer));
137 
138 
139     //---------------------------------
140     // Send CMD: Vebox_Surface_State
141     //---------------------------------
142     VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(m_veboxItf->AddVeboxSurfaces(
143         &cmdBuffer,
144         &mhwVeboxSurfaceStateCmdParams));
145 
146     HalOcaInterfaceNext::OnDispatch(cmdBuffer, *m_osInterface, m_miItf, *pMmioRegisters);
147 
148     //---------------------------------
149     // Send CMD: Vebox_Tiling_Convert
150     //---------------------------------
151     VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(VeboxSendVeboxTileConvertCMD(&cmdBuffer, surface, nullptr, streamID));
152 
153     auto& par = m_miItf->GETPAR_MI_FLUSH_DW();
154     par = {};
155     VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(m_miItf->ADDCMD_MI_FLUSH_DW(&cmdBuffer));
156 
157     if (!m_osInterface->bEnableKmdMediaFrameTracking && veboxHeap)
158     {
159         auto& par = m_miItf->GETPAR_MI_FLUSH_DW();
160         par = {};
161         par.pOsResource = (PMOS_RESOURCE)&veboxHeap->DriverResource;
162         par.dwResourceOffset = veboxHeap->uiOffsetSync;
163         par.dwDataDW1 = veboxHeap->dwNextTag;
164         VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(m_miItf->ADDCMD_MI_FLUSH_DW(&cmdBuffer));
165     }
166 
167     HalOcaInterfaceNext::On1stLevelBBEnd(cmdBuffer, *m_osInterface);
168 
169     if (isPerfCollected)
170     {
171         VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(perfProfiler);
172         VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(perfProfiler->AddPerfCollectEndCmd((void *)this, m_osInterface, m_miItf, &cmdBuffer));
173     }
174 
175     VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(m_miItf->AddMiBatchBufferEnd(
176         &cmdBuffer,
177         nullptr));
178 
179     // Return unused command buffer space to OS
180     m_osInterface->pfnReturnCommandBuffer(
181         m_osInterface,
182         &cmdBuffer,
183         0);
184 
185     // Flush the command buffer
186     VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(
187         m_osInterface,
188         &cmdBuffer,
189         false));
190 
191     m_veboxItf->UpdateVeboxSync();
192 
193     // Restore the perf tag
194     if (isPerfCollected)
195     {
196         m_osInterface->pfnSetPerfTag(m_osInterface, perfTag);
197     }
198 
199     return eStatus;
200 }
201 
IsVeboxDecompressionEnabled()202 MOS_STATUS MediaMemDeCompNext_Xe_Lpm_Plus_Base::IsVeboxDecompressionEnabled()
203 {
204     bool                                customValue = false;
205     MOS_STATUS                          eStatus = MOS_STATUS_SUCCESS;
206 
207 #ifdef LINUX
208     customValue = true;  // enable VE Decompress on Linux
209 #else
210     customValue = true;
211 #endif
212 
213     ReadUserSetting(
214         m_userSettingPtr,
215         m_veboxMMCResolveEnabled,
216         __VPHAL_ENABLE_VEBOX_MMC_DECOMPRESS,
217         MediaUserSetting::Group::Device,
218         customValue,
219         true);
220 
221 #if (LINUX || _DEBUG || _RELEASE_INTERNAL)
222     // Read multi processes single binary flag
223     ReadUserSetting(
224         m_userSettingPtr,
225         m_multiprocesssinglebin,
226         __MEDIA_USER_FEATURE_VALUE_PERF_PROFILER_MUL_PROC_SINGLE_BIN,
227         MediaUserSetting::Group::Device);
228 #endif
229 
230     return eStatus;
231 }
232 
RenderDoubleBufferDecompCMD(PMOS_SURFACE inputSurface,PMOS_SURFACE outputSurface)233 MOS_STATUS MediaMemDeCompNext_Xe_Lpm_Plus_Base::RenderDoubleBufferDecompCMD(PMOS_SURFACE inputSurface, PMOS_SURFACE outputSurface)
234 {
235     MOS_STATUS                          eStatus = MOS_STATUS_SUCCESS;
236     MHW_VEBOX_STATE_CMD_PARAMS          veboxStateCmdParams;
237     MOS_COMMAND_BUFFER                  cmdBuffer;
238     MHW_VEBOX_SURFACE_STATE_CMD_PARAMS  mhwVeboxSurfaceStateCmdParams;
239     MHW_MI_FLUSH_DW_PARAMS              flushDwParams;
240     uint32_t                            streamID = 0;
241     const MHW_VEBOX_HEAP* veboxHeap = nullptr;
242     bool                                allocated = false;
243     bool                                outputLinearNon64Align = false;
244     bool                                inputLinearNon64Align = false;
245     PMOS_SURFACE                        copy_input = nullptr;
246     PMOS_SURFACE                        copy_output = nullptr;
247 
248     VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(inputSurface);
249     VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(outputSurface);
250 
251     if (!IsFormatSupported(inputSurface) || !IsFormatSupported(outputSurface))
252     {
253         VPHAL_MEMORY_DECOMP_NORMALMESSAGE("Input surface is not supported by Vebox, In_Place resolve can't be done");
254         return eStatus;
255     }
256 
257     if (inputSurface->TileType == MOS_TILE_LINEAR &&
258         outputSurface->TileType == MOS_TILE_LINEAR)
259     {
260         VPHAL_MEMORY_DECOMP_ASSERTMESSAGE("Input/Output pitch is all linear. Return unsupport!");
261         return MOS_STATUS_PLATFORM_NOT_SUPPORTED;
262     }
263     else if ((outputSurface->TileType == MOS_TILE_LINEAR && (!MOS_IS_ALIGNED(outputSurface->dwPitch, MHW_VEBOX_LINEAR_PITCH))))
264     {
265         VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(ReAllocateLinearSurface(
266             &m_tempLinearSurface,
267             "OutputLinearBuffer",
268             outputSurface->Format,
269             MOS_GFXRES_2D,
270             MOS_ALIGN_CEIL(outputSurface->dwWidth, MHW_VEBOX_LINEAR_PITCH),
271             outputSurface->dwHeight,
272             &allocated));
273 
274         if (allocated)
275         {
276             m_tempLinearSurface.dwWidth = outputSurface->dwWidth;
277             outputLinearNon64Align = true;
278             copy_input = inputSurface;
279             copy_output = &m_tempLinearSurface;
280         }
281         else
282         {
283             VPHAL_MEMORY_DECOMP_ASSERTMESSAGE("Input/Output pitch is not 64 aligned. Return Invalid Status!");
284             return MOS_STATUS_INVALID_PARAMETER;
285         }
286     }
287     else if ((inputSurface->TileType == MOS_TILE_LINEAR && (!MOS_IS_ALIGNED(inputSurface->dwPitch, MHW_VEBOX_LINEAR_PITCH))))
288     {
289         VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(ReAllocateLinearSurface(
290             &m_tempLinearSurface,
291             "OutputLinearBuffer",
292             inputSurface->Format,
293             MOS_GFXRES_2D,
294             MOS_ALIGN_CEIL(inputSurface->dwWidth, MHW_VEBOX_LINEAR_PITCH),
295             inputSurface->dwHeight,
296             &allocated));
297 
298         if (allocated)
299         {
300             m_tempLinearSurface.dwWidth = inputSurface->dwWidth;
301             inputLinearNon64Align = true;
302             copy_input = &m_tempLinearSurface;
303             copy_output = outputSurface;
304         }
305         else
306         {
307             VPHAL_MEMORY_DECOMP_ASSERTMESSAGE("Input/Output pitch is not 64 aligned. Return Invalid Status!");
308             return MOS_STATUS_INVALID_PARAMETER;
309         }
310     }
311     else
312     {
313         copy_input = inputSurface;
314         copy_output = outputSurface;
315         VPHAL_MEMORY_DECOMP_NORMALMESSAGE("Vebox Can handled copy conditions");
316     }
317 
318     m_osInterface->pfnSetGpuContext(m_osInterface, MOS_GPU_CONTEXT_VEBOX);
319 
320     // Reset allocation list and house keeping
321     m_osInterface->pfnResetOsStates(m_osInterface);
322 
323     VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(m_veboxItf->GetVeboxHeapInfo(&veboxHeap));
324     VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(&copy_input->OsResource);
325     VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(&copy_output->OsResource);
326     VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(m_osInterface->osCpInterface);
327 
328     //there is a new usage that input surface is clear and output surface is secure.
329     //replace Huc Copy by DoubleBuffer resolve to update ccs data.
330     //So need consolidate both input/output surface information to decide cp context.
331     PMOS_SURFACE surfaceArray[2];
332     surfaceArray[0] = copy_input;
333     surfaceArray[1] = copy_output;
334 
335     // preprocess in cp first
336     m_osInterface->osCpInterface->PrepareResources((void**)&surfaceArray, sizeof(surfaceArray) / sizeof(PMOS_SURFACE), nullptr, 0);
337 
338     if (inputLinearNon64Align)
339     {
340         VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(LinearCopyWith64Aligned(inputSurface, &m_tempLinearSurface));
341     }
342 
343     // initialize the command buffer struct
344     MOS_ZeroMemory(&cmdBuffer, sizeof(MOS_COMMAND_BUFFER));
345 
346     VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
347     VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(InitCommandBuffer(&cmdBuffer));
348 
349     // Prepare Vebox_Surface_State, surface input/and output are the same but the compressed status.
350     VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(SetupVeboxSurfaceState(&mhwVeboxSurfaceStateCmdParams, copy_input, copy_output));
351 
352     //---------------------------------
353     // Send Pvt MMCD CMD
354     //---------------------------------
355     VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(m_miItf->AddVeboxMMIOPrologCmd(&cmdBuffer));
356 
357     //---------------------------------
358     // Send CMD: Vebox_Surface_State
359     //---------------------------------
360     VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(m_veboxItf->AddVeboxSurfaces(
361         &cmdBuffer,
362         &mhwVeboxSurfaceStateCmdParams));
363 
364     //---------------------------------
365     // Send CMD: Vebox_Tiling_Convert
366     //---------------------------------
367     VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(VeboxSendVeboxTileConvertCMD(&cmdBuffer, copy_input, copy_output, streamID));
368 
369     MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
370 
371     auto& par = m_miItf->GETPAR_MI_FLUSH_DW();
372     par = {};
373     VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(m_miItf->ADDCMD_MI_FLUSH_DW(&cmdBuffer));
374 
375     if (!m_osInterface->bEnableKmdMediaFrameTracking && veboxHeap)
376     {
377         auto& par = m_miItf->GETPAR_MI_FLUSH_DW();
378         par = {};
379         par.pOsResource = (PMOS_RESOURCE)&veboxHeap->DriverResource;
380         par.dwResourceOffset = veboxHeap->uiOffsetSync;
381         par.dwDataDW1 = veboxHeap->dwNextTag;
382         VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(m_miItf->ADDCMD_MI_FLUSH_DW(&cmdBuffer));
383     }
384 
385     VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(m_miItf->AddMiBatchBufferEnd(
386         &cmdBuffer,
387         nullptr));
388 
389     // Return unused command buffer space to OS
390     m_osInterface->pfnReturnCommandBuffer(
391         m_osInterface,
392         &cmdBuffer,
393         0);
394 
395     // Flush the command buffer
396     VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(
397         m_osInterface,
398         &cmdBuffer,
399         false));
400 
401     m_veboxItf->UpdateVeboxSync();
402 
403     if (outputLinearNon64Align)
404     {
405         VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(LinearCopyWith64Aligned(&m_tempLinearSurface, outputSurface));
406     }
407 
408     return eStatus;
409 }
410 
LinearCopyWith64Aligned(PMOS_SURFACE inputSurface,PMOS_SURFACE outputSurface)411 MOS_STATUS MediaMemDeCompNext_Xe_Lpm_Plus_Base::LinearCopyWith64Aligned(PMOS_SURFACE inputSurface, PMOS_SURFACE outputSurface)
412 {
413     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
414     //if surface is linear buffer, use mos copy
415     if (inputSurface->TileType == MOS_TILE_LINEAR &&
416         outputSurface->TileType == MOS_TILE_LINEAR &&
417         inputSurface->Type == MOS_GFXRES_BUFFER &&
418         outputSurface->Type == MOS_GFXRES_BUFFER)
419     {
420         do
421         {
422             MOS_LOCK_PARAMS lockSourceFlags;
423             MOS_ZeroMemory(&lockSourceFlags, sizeof(MOS_LOCK_PARAMS));
424             lockSourceFlags.ReadOnly = 1;
425             lockSourceFlags.WriteOnly = 0;
426 
427             MOS_LOCK_PARAMS lockTargetFlags;
428             MOS_ZeroMemory(&lockTargetFlags, sizeof(MOS_LOCK_PARAMS));
429             lockTargetFlags.ReadOnly = 0;
430             lockTargetFlags.WriteOnly = 1;
431 
432             uint8_t* lockedSrcAddr = (uint8_t*)m_osInterface->pfnLockResource(m_osInterface, &inputSurface->OsResource, &lockSourceFlags);
433 
434             if (lockedSrcAddr == nullptr)
435             {
436                 //non lockable resource enabled, we can't lock source surface
437                 eStatus = MOS_STATUS_NULL_POINTER;
438                 VPHAL_MEMORY_DECOMP_ASSERTMESSAGE("Failed to lock non-lockable input resource, buffer copy failed, eStatus:%d.\n", eStatus);
439                 break;
440             }
441 
442             uint8_t* lockedTarAddr = (uint8_t*)m_osInterface->pfnLockResource(m_osInterface, &outputSurface->OsResource, &lockTargetFlags);
443 
444             if (lockedTarAddr == nullptr)
445             {
446                 eStatus = MOS_STATUS_NULL_POINTER;
447                 m_osInterface->pfnUnlockResource(m_osInterface, &inputSurface->OsResource);
448                 VPHAL_MEMORY_DECOMP_ASSERTMESSAGE("Failed to lock non-lockable output resource, buffer copy failed, eStatus:%d.\n", eStatus);
449                 break;
450             }
451             // This resource is a series of bytes. Is not 2 dimensional.
452 
453             for (uint32_t copy_height = 0; copy_height < inputSurface->dwHeight; copy_height++)
454             {
455                 uint32_t copy_width = MOS_MIN(inputSurface->dwPitch, outputSurface->dwPitch);
456                 eStatus = MOS_SecureMemcpy(lockedTarAddr, copy_width, lockedSrcAddr, copy_width);
457                 lockedSrcAddr += inputSurface->dwPitch;
458                 lockedTarAddr += outputSurface->dwPitch;
459             }
460             m_osInterface->pfnUnlockResource(m_osInterface, &inputSurface->OsResource);
461             m_osInterface->pfnUnlockResource(m_osInterface, &outputSurface->OsResource);
462 
463             if (eStatus != MOS_STATUS_SUCCESS)
464             {
465                 VPHAL_MEMORY_DECOMP_ASSERTMESSAGE("Failed to copy linear buffer from source to target, eStatus:%d.\n", eStatus);
466                 break;
467             }
468         } while (false);
469 
470         MOS_TraceEventExt(EVENT_MEDIA_COPY, EVENT_TYPE_END, nullptr, 0, nullptr, 0);
471         return eStatus;
472     }
473 
474     return eStatus;
475 }
476 
ReAllocateLinearSurface(PMOS_SURFACE pSurface,PCCHAR pSurfaceName,MOS_FORMAT format,MOS_GFXRES_TYPE DefaultResType,uint32_t dwWidth,uint32_t dwHeight,bool * pbAllocated)477 MOS_STATUS MediaMemDeCompNext_Xe_Lpm_Plus_Base::ReAllocateLinearSurface(PMOS_SURFACE pSurface, PCCHAR pSurfaceName, MOS_FORMAT format, MOS_GFXRES_TYPE DefaultResType, uint32_t dwWidth, uint32_t dwHeight, bool* pbAllocated)
478 {
479     MOS_STATUS              eStatus;
480     VPHAL_GET_SURFACE_INFO  Info;
481     MOS_ALLOC_GFXRES_PARAMS allocParams;
482 
483     //---------------------------------
484     VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(m_osInterface);
485     //---------------------------------
486 
487     eStatus = MOS_STATUS_SUCCESS;
488     *pbAllocated = false;
489 
490     if (!Mos_ResourceIsNull(&pSurface->OsResource) &&
491         (pSurface->dwWidth == dwWidth) &&
492         (pSurface->dwHeight == dwHeight) &&
493         (pSurface->Format == format))
494     {
495         *pbAllocated = true;
496         return eStatus;
497     }
498 
499     MOS_ZeroMemory(&allocParams, sizeof(MOS_ALLOC_GFXRES_PARAMS));
500 
501     allocParams.Type = DefaultResType;
502     allocParams.TileType = MOS_TILE_LINEAR;
503 
504     allocParams.dwWidth = dwWidth;
505     allocParams.dwHeight = dwHeight;
506     allocParams.Format = format;
507     allocParams.bIsCompressible = false;
508     allocParams.pBufName = pSurfaceName;
509     allocParams.dwArraySize = 1;
510     allocParams.ResUsageType = MOS_HW_RESOURCE_USAGE_VP_INTERNAL_READ_WRITE_FF;
511 
512     // Delete resource if already allocated
513     m_osInterface->pfnFreeResource(m_osInterface, &(pSurface->OsResource));
514 
515     // Allocate surface
516     VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource(
517         m_osInterface,
518         &allocParams,
519         &pSurface->OsResource));
520 
521     // Get surface information
522     MOS_ZeroMemory(&Info, sizeof(VPHAL_GET_SURFACE_INFO));
523 
524     // Pre-set to get surface info
525     pSurface->Format = format;
526     VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(GetResourceInfo(pSurface));
527     *pbAllocated = true;
528 
529     return eStatus;
530 }
531 
VeboxSendVeboxTileConvertCMD(PMOS_COMMAND_BUFFER cmdBuffer,PMOS_SURFACE inputSurface,PMOS_SURFACE outputSurface,uint32_t streamID)532 MOS_STATUS MediaMemDeCompNext_Xe_Lpm_Plus_Base::VeboxSendVeboxTileConvertCMD(PMOS_COMMAND_BUFFER cmdBuffer, PMOS_SURFACE inputSurface, PMOS_SURFACE outputSurface, uint32_t streamID)
533 {
534     MOS_STATUS                      eStatus = MOS_STATUS_SUCCESS;
535     MHW_VEBOX_SURFACE_PARAMS        inputSurfaceParam = {};
536     MHW_VEBOX_SURFACE_PARAMS        outputSurfaceParam = {};
537     PMOS_SURFACE                    surface = nullptr;
538 
539     MOS_UNUSED(streamID);
540     VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(cmdBuffer);
541     VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(inputSurface);
542     VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(m_osInterface);
543     VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(m_veboxItf);
544 
545     inputSurfaceParam.pOsResource       = &inputSurface->OsResource;
546     inputSurfaceParam.CompressionMode   = inputSurface->CompressionMode;
547     inputSurfaceParam.TileType          = inputSurface->TileType;
548     inputSurfaceParam.bGMMTileEnabled   = inputSurface->bGMMTileEnabled;
549     inputSurfaceParam.TileModeGMM       = inputSurface->TileModeGMM;
550     inputSurfaceParam.dwOffset          = inputSurface->dwOffset;
551 
552     // Set Output surface compression status
553     if (outputSurface)
554     {
555         // Double Buffer copy
556         outputSurfaceParam.pOsResource       = &outputSurface->OsResource;
557         outputSurfaceParam.CompressionMode   = outputSurface->CompressionMode;
558         outputSurfaceParam.TileType          = outputSurface->TileType;
559         outputSurfaceParam.bGMMTileEnabled   = outputSurface->bGMMTileEnabled;
560         outputSurfaceParam.TileModeGMM       = outputSurface->TileModeGMM;
561         outputSurfaceParam.dwOffset          = outputSurface->dwOffset;
562 
563     }
564     else
565     {
566         // In-Place Resolve
567         outputSurfaceParam = inputSurfaceParam;
568         if (outputSurfaceParam.CompressionMode != MOS_MMC_DISABLED)
569         {
570             outputSurfaceParam.CompressionMode = MOS_MMC_RC;
571         }
572     }
573 
574     VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(m_veboxItf->AddVeboxTilingConvert(cmdBuffer, &inputSurfaceParam, &outputSurfaceParam));
575 
576     return eStatus;
577 }
578