1 /*
2 * Copyright (c) 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     media_mem_decompression_next.cpp
24 //! \brief    Defines data structures and interfaces for media memory decompression.
25 //! \details
26 //!
27 #include "media_mem_decompression_next.h"
28 #include "vp_utils.h"
29 #include "renderhal.h"
30 #include "mos_os_cp_interface_specific.h"
31 
MediaMemDeCompNext()32 MediaMemDeCompNext::MediaMemDeCompNext():
33     m_osInterface(nullptr),
34     m_veboxItf(nullptr),
35     m_miItf(nullptr),
36     m_cpInterface(nullptr)
37 {
38     m_veboxMMCResolveEnabled = false;
39     if (!m_renderMutex)
40     {
41         m_renderMutex = MosUtilities::MosCreateMutex();
42     }
43 }
44 
~MediaMemDeCompNext()45 MediaMemDeCompNext::~MediaMemDeCompNext()
46 {
47     MOS_STATUS              eStatus;
48 
49     if (m_veboxItf)
50     {
51         m_veboxItf->DestroyHeap();
52     }
53 
54     if (m_cpInterface)
55     {
56         if (m_osInterface)
57         {
58             m_osInterface->pfnDeleteMhwCpInterface(m_cpInterface);
59             m_cpInterface = nullptr;
60         }
61         else
62         {
63             VPHAL_MEMORY_DECOMP_ASSERTMESSAGE("Failed to destroy cpInterface.");
64         }
65     }
66 
67     if (m_osInterface)
68     {
69         m_osInterface->pfnDestroy(m_osInterface, false);
70         MOS_FreeMemory(m_osInterface);
71         m_osInterface = nullptr;
72     }
73     if (m_renderMutex)
74     {
75         MosUtilities::MosDestroyMutex(m_renderMutex);
76         m_renderMutex = nullptr;
77     }
78 }
79 
MemoryDecompress(PMOS_RESOURCE targetResource)80 MOS_STATUS MediaMemDeCompNext::MemoryDecompress(PMOS_RESOURCE targetResource)
81 {
82     MOS_STATUS              eStatus = MOS_STATUS_SUCCESS;
83     MOS_SURFACE             targetSurface = {};
84 
85     MHW_FUNCTION_ENTER;
86 
87     VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(targetResource);
88     MOS_TraceEventExt(EVENT_MEDIA_COPY, EVENT_TYPE_START, nullptr, 0, nullptr, 0);
89 #if MOS_MEDIASOLO_SUPPORTED
90     if (m_osInterface->bSoloInUse)
91     {
92         // Bypass
93     }
94     else
95 #endif
96     {
97         if (m_veboxMMCResolveEnabled)
98         {
99             MOS_ZeroMemory(&targetSurface, sizeof(MOS_SURFACE));
100 
101             targetSurface.Format = Format_Invalid;
102             targetSurface.OsResource = *targetResource;
103             VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(GetResourceInfo(&targetSurface));
104 
105             //Get context before proceeding
106             auto gpuContext = m_osInterface->CurrentGpuContextOrdinal;
107 
108             if (targetSurface.bCompressible)
109             {
110                 VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(m_renderMutex);
111                 MosUtilities::MosLockMutex(m_renderMutex);
112 
113 #if (_DEBUG || _RELEASE_INTERNAL) && !defined(LINUX)
114                 TRACEDATA_MEDIA_MEM_DECOMP eventData = {0};
115                 TRACEDATA_MEDIA_MEM_DECOMP_INIT(
116                     eventData,
117                     targetResource->AllocationInfo.m_AllocationHandle,
118                     targetSurface.dwWidth,
119                     targetSurface.dwHeight,
120                     targetSurface.Format,
121                     *((int64_t *)&targetResource->pGmmResInfo->GetResFlags().Gpu),
122                     *((int64_t *)&targetResource->pGmmResInfo->GetResFlags().Info)
123                 );
124                 MOS_TraceEventExt(EVENT_DDI_MEDIA_MEM_DECOMP_CALLBACK, EVENT_TYPE_INFO, &eventData, sizeof(eventData), nullptr, 0);
125 #endif
126                 eStatus = RenderDecompCMD(&targetSurface);
127                 if (eStatus != MOS_STATUS_SUCCESS)
128                 {
129                     MosUtilities::MosUnlockMutex(m_renderMutex);
130                     VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(eStatus);
131                 }
132                 else
133                 {
134                     MosUtilities::MosUnlockMutex(m_renderMutex);
135                 }
136             }
137         }
138     }
139     MOS_TraceEventExt(EVENT_MEDIA_COPY, EVENT_TYPE_END, nullptr, 0, nullptr, 0);
140     return eStatus;
141 }
142 
MediaMemoryCopy(PMOS_RESOURCE inputResource,PMOS_RESOURCE outputResource,bool outputCompressed)143 MOS_STATUS MediaMemDeCompNext::MediaMemoryCopy(PMOS_RESOURCE inputResource, PMOS_RESOURCE outputResource, bool outputCompressed)
144 {
145     MOS_STATUS eStatus             = MOS_STATUS_SUCCESS;
146     bool       bValidInputSurface  = false;
147     bool       bValidOutputSurface = false;
148 
149     MHW_FUNCTION_ENTER;
150 
151     VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(inputResource);
152     VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(outputResource);
153     MOS_TraceEventExt(EVENT_MEDIA_COPY, EVENT_TYPE_START, nullptr, 0, nullptr, 0);
154 
155     MOS_SURFACE             sourceSurface = {};
156     MOS_SURFACE             targetSurface = {};
157 
158     MOS_ZeroMemory(&targetSurface, sizeof(MOS_SURFACE));
159     MOS_ZeroMemory(&sourceSurface, sizeof(MOS_SURFACE));
160 
161     targetSurface.Format     = Format_Invalid;
162     targetSurface.OsResource = *outputResource;
163 
164 #if !defined(LINUX) && !defined(ANDROID) && !EMUL && !_VULKAN
165     // for Double Buffer copy, clear the allocationInfo temply
166     MOS_ZeroMemory(&targetSurface.OsResource.AllocationInfo, sizeof(SResidencyInfo));
167 #endif
168 
169     sourceSurface.Format = Format_Invalid;
170     sourceSurface.OsResource = *inputResource;
171     VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(GetResourceInfo(&targetSurface));
172     VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(GetResourceInfo(&sourceSurface));
173 
174 #if (_DEBUG || _RELEASE_INTERNAL)
175     {
176         // Read user feature key to force outputCompressed
177         ReadUserSettingForDebug(
178             m_userSettingPtr,
179             outputCompressed,
180             __VPHAL_VEBOX_FORCE_VP_MEMCOPY_OUTPUTCOMPRESSED,
181             MediaUserSetting::Group::Sequence);
182     }
183 #endif
184 
185     if (!outputCompressed && targetSurface.CompressionMode != MOS_MMC_DISABLED)
186     {
187         targetSurface.CompressionMode = MOS_MMC_RC;
188     }
189 
190     //if surface is linear buffer, use mos copy
191     if (sourceSurface.TileType == MOS_TILE_LINEAR &&
192         targetSurface.TileType == MOS_TILE_LINEAR &&
193         sourceSurface.Type == MOS_GFXRES_BUFFER &&
194         targetSurface.Type == MOS_GFXRES_BUFFER)
195     {
196         do
197         {
198             MOS_LOCK_PARAMS lockSourceFlags;
199             MOS_ZeroMemory(&lockSourceFlags, sizeof(MOS_LOCK_PARAMS));
200             lockSourceFlags.ReadOnly = 1;
201             lockSourceFlags.WriteOnly = 0;
202 
203             MOS_LOCK_PARAMS lockTargetFlags;
204             MOS_ZeroMemory(&lockTargetFlags, sizeof(MOS_LOCK_PARAMS));
205             lockTargetFlags.ReadOnly = 0;
206             lockTargetFlags.WriteOnly = 1;
207 
208             uint8_t* lockedSrcAddr = (uint8_t*)m_osInterface->pfnLockResource(m_osInterface, &sourceSurface.OsResource, &lockSourceFlags);
209 
210             if (lockedSrcAddr == nullptr)
211             {
212                 //non lockable resource enabled, we can't lock source surface
213                 eStatus = MOS_STATUS_NULL_POINTER;
214                 VPHAL_MEMORY_DECOMP_ASSERTMESSAGE("Failed to lock non-lockable input resource, buffer copy failed, eStatus:%d.\n", eStatus);
215                 MT_ERR2(MT_VE_DECOMP_COPY, MT_SURF_IS_INPUT, 1, MT_VE_DECOMP_COPY_SURF_LOCK_STATUS, eStatus);
216                 break;
217             }
218 
219             uint8_t* lockedTarAddr = (uint8_t*)m_osInterface->pfnLockResource(m_osInterface, &targetSurface.OsResource, &lockTargetFlags);
220 
221             if (lockedTarAddr == nullptr)
222             {
223                 eStatus = MOS_STATUS_NULL_POINTER;
224                 m_osInterface->pfnUnlockResource(m_osInterface, &sourceSurface.OsResource);
225                 VPHAL_MEMORY_DECOMP_ASSERTMESSAGE("Failed to lock non-lockable output resource, buffer copy failed, eStatus:%d.\n", eStatus);
226                 MT_ERR2(MT_VE_DECOMP_COPY, MT_SURF_IS_OUTPUT, 1, MT_VE_DECOMP_COPY_SURF_LOCK_STATUS, eStatus);
227                 break;
228             }
229             // This resource is a series of bytes. Is not 2 dimensional.
230             uint32_t sizeSrcMain    = sourceSurface.dwSize;
231             uint32_t sizeTargetMain = targetSurface.dwSize;
232             eStatus = MOS_SecureMemcpy(lockedTarAddr, sizeTargetMain, lockedSrcAddr, sizeSrcMain);
233             m_osInterface->pfnUnlockResource(m_osInterface, &sourceSurface.OsResource);
234             m_osInterface->pfnUnlockResource(m_osInterface, &targetSurface.OsResource);
235 
236             if (eStatus != MOS_STATUS_SUCCESS)
237             {
238                 VPHAL_MEMORY_DECOMP_ASSERTMESSAGE("Failed to copy linear buffer from source to target, eStatus:%d.\n", eStatus);
239                 MT_ERR1(MT_VE_DECOMP_COPY, MT_MOS_STATUS, eStatus);
240                 break;
241             }
242         } while (false);
243 
244         MOS_TraceEventExt(EVENT_MEDIA_COPY, EVENT_TYPE_END, nullptr, 0, nullptr, 0);
245         return eStatus;
246     }
247 
248     // if source surface or target surface is non-64align linear, return error here
249     if ((sourceSurface.dwPitch % 64 != 0 && sourceSurface.TileType == MOS_TILE_LINEAR) ||
250         (targetSurface.dwPitch % 64 != 0 && targetSurface.TileType == MOS_TILE_LINEAR))
251     {
252         eStatus = MOS_STATUS_INVALID_PARAMETER;
253         VPHAL_MEMORY_DECOMP_ASSERTMESSAGE("VEBOX does not support non-64align pitch linear surface, eStatus:%d.\n", eStatus);
254         MT_ERR2(MT_VE_DECOMP_COPY, MT_SURF_PITCH, sourceSurface.dwPitch, MT_SURF_PITCH, targetSurface.dwPitch);
255         MOS_TraceEventExt(EVENT_MEDIA_COPY, EVENT_TYPE_END, nullptr, 0, nullptr, 0);
256         return eStatus;
257     }
258 
259     //Check whether surface is valid, or it will cause page fault
260     m_osInterface->pfnVerifyMosSurface(&sourceSurface, bValidInputSurface);
261     m_osInterface->pfnVerifyMosSurface(&targetSurface, bValidOutputSurface);
262     if (!bValidInputSurface || !bValidOutputSurface)
263     {
264         VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(MOS_STATUS_INVALID_PARAMETER);
265     }
266 
267     //Get context before proceeding
268     auto gpuContext = m_osInterface->CurrentGpuContextOrdinal;
269 
270     // Sync for Vebox read
271     m_osInterface->pfnSyncOnResource(
272         m_osInterface,
273         &sourceSurface.OsResource,
274         MOS_GPU_CONTEXT_VEBOX,
275         false);
276 
277     // Sync for Vebox write
278     m_osInterface->pfnSyncOnResource(
279         m_osInterface,
280         &targetSurface.OsResource,
281         MOS_GPU_CONTEXT_VEBOX,
282         false);
283 
284 #if (_DEBUG || _RELEASE_INTERNAL) && !defined(LINUX)
285     TRACEDATA_MEDIACOPY eventData = {0};
286     TRACEDATA_MEDIACOPY_INIT(
287         eventData,
288         inputResource->AllocationInfo.m_AllocationHandle,
289         sourceSurface.dwWidth,
290         sourceSurface.dwHeight,
291         sourceSurface.Format,
292         *((int64_t *)&inputResource->pGmmResInfo->GetResFlags().Gpu),
293         *((int64_t *)&inputResource->pGmmResInfo->GetResFlags().Info),
294         inputResource->pGmmResInfo->GetSetCpSurfTag(0, 0),
295         outputResource->AllocationInfo.m_AllocationHandle,
296         targetSurface.dwWidth,
297         targetSurface.dwHeight,
298         targetSurface.Format,
299         *((int64_t *)&outputResource->pGmmResInfo->GetResFlags().Gpu),
300         *((int64_t *)&outputResource->pGmmResInfo->GetResFlags().Info),
301         outputResource->pGmmResInfo->GetSetCpSurfTag(0, 0)
302 
303     );
304     MOS_TraceEventExt(EVENT_MEDIA_COPY, EVENT_TYPE_INFO, &eventData, sizeof(eventData), nullptr, 0);
305 #endif
306 
307     VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(RenderDoubleBufferDecompCMD(&sourceSurface, &targetSurface));
308 
309     MOS_TraceEventExt(EVENT_MEDIA_COPY, EVENT_TYPE_END, nullptr, 0, nullptr, 0);
310     return eStatus;
311 }
312 
MediaMemoryCopy2D(PMOS_RESOURCE inputResource,PMOS_RESOURCE outputResource,uint32_t copyPitch,uint32_t copyHeight,uint32_t copyInputOffset,uint32_t copyOutputOffset,uint32_t bpp,bool outputCompressed)313 MOS_STATUS MediaMemDeCompNext::MediaMemoryCopy2D(PMOS_RESOURCE inputResource, PMOS_RESOURCE outputResource, uint32_t copyPitch, uint32_t copyHeight, uint32_t copyInputOffset, uint32_t copyOutputOffset, uint32_t bpp, bool outputCompressed)
314 {
315     MOS_STATUS eStatus             = MOS_STATUS_SUCCESS;
316     bool       bValidInputSurface  = false;
317     bool       bValidOutputSurface = false;
318 
319     MHW_FUNCTION_ENTER;
320 
321     VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(inputResource);
322     VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(outputResource);
323     MOS_TraceEventExt(EVENT_MEDIA_COPY, EVENT_TYPE_START, nullptr, 0, nullptr, 0);
324 
325     MOS_SURFACE             sourceSurface;
326     MOS_SURFACE             targetSurface;
327 
328     MOS_ZeroMemory(&targetSurface, sizeof(MOS_SURFACE));
329     MOS_ZeroMemory(&sourceSurface, sizeof(MOS_SURFACE));
330 
331     targetSurface.Format = Format_Invalid;
332     targetSurface.OsResource = *outputResource;
333 
334 #if !defined(LINUX) && !defined(ANDROID) && !EMUL && !_VULKAN
335     // for Double Buffer copy, clear the allocationInfo temply
336     MOS_ZeroMemory(&targetSurface.OsResource.AllocationInfo, sizeof(SResidencyInfo));
337 #endif
338 
339     sourceSurface.Format = Format_Invalid;
340     sourceSurface.OsResource = *inputResource;
341     VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(GetResourceInfo(&targetSurface));
342     VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(GetResourceInfo(&sourceSurface));
343 
344 #if (_DEBUG || _RELEASE_INTERNAL)
345     {
346         // Read user feature key to Force outputCompressed
347         ReadUserSettingForDebug(
348             m_userSettingPtr,
349             outputCompressed,
350             __VPHAL_VEBOX_FORCE_VP_MEMCOPY_OUTPUTCOMPRESSED,
351             MediaUserSetting::Group::Sequence);
352     }
353 #endif
354 
355     if (!outputCompressed && targetSurface.CompressionMode != MOS_MMC_DISABLED)
356     {
357         targetSurface.CompressionMode = MOS_MMC_RC;
358     }
359 
360     //Get context before proceeding
361     auto gpuContext = m_osInterface->CurrentGpuContextOrdinal;
362     uint32_t pixelInByte = 1;
363 
364     switch (bpp)
365     {
366     case 8:
367         targetSurface.Format = Format_Y8;
368         sourceSurface.Format = Format_Y8;
369         pixelInByte = 1;
370         break;
371     case 16:
372         targetSurface.Format = Format_Y16U;
373         sourceSurface.Format = Format_Y16U;
374         pixelInByte = 2;
375         break;
376     case 32:
377         targetSurface.Format = Format_AYUV;
378         sourceSurface.Format = Format_AYUV;
379         pixelInByte = 4;
380         break;
381     case 64:
382         targetSurface.Format = Format_Y416;
383         sourceSurface.Format = Format_Y416;
384         pixelInByte = 8;
385         break;
386     default:
387         targetSurface.Format = Format_Y8;
388         sourceSurface.Format = Format_Y8;
389         pixelInByte = 1;
390         break;
391     }
392 
393 
394     sourceSurface.dwOffset = copyInputOffset;
395     targetSurface.dwOffset = copyOutputOffset;
396 
397     sourceSurface.dwWidth = copyPitch / pixelInByte;
398     sourceSurface.dwPitch  = copyPitch;
399     sourceSurface.dwHeight = copyHeight;
400     targetSurface.dwWidth = copyPitch / pixelInByte;
401     targetSurface.dwPitch  = copyPitch;
402     targetSurface.dwHeight = copyHeight;
403 
404     //Check whether surface is valid, or it will cause page fault
405     m_osInterface->pfnVerifyMosSurface(&sourceSurface, bValidInputSurface);
406     m_osInterface->pfnVerifyMosSurface(&targetSurface, bValidOutputSurface);
407     if (!bValidInputSurface || !bValidOutputSurface)
408     {
409         VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(MOS_STATUS_INVALID_PARAMETER);
410     }
411 
412     // Sync for Vebox write
413     m_osInterface->pfnSyncOnResource(
414         m_osInterface,
415         &sourceSurface.OsResource,
416         MOS_GPU_CONTEXT_VEBOX,
417         false);
418 
419     VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(RenderDoubleBufferDecompCMD(&sourceSurface, &targetSurface));
420 
421     MOS_TraceEventExt(EVENT_MEDIA_COPY, EVENT_TYPE_END, nullptr, 0, nullptr, 0);
422     return eStatus;
423 }
424 
MediaMemoryTileConvert(PMOS_RESOURCE inputResource,PMOS_RESOURCE outputResource,uint32_t copyWidth,uint32_t copyHeight,uint32_t copyInputOffset,uint32_t copyOutputOffset,bool isTileToLinear,bool outputCompressed)425 MOS_STATUS MediaMemDeCompNext::MediaMemoryTileConvert(PMOS_RESOURCE inputResource, PMOS_RESOURCE outputResource, uint32_t copyWidth, uint32_t copyHeight, uint32_t copyInputOffset, uint32_t copyOutputOffset, bool isTileToLinear, bool outputCompressed)
426 {
427     MOS_STATUS                          eStatus = MOS_STATUS_SUCCESS;
428 
429     MHW_FUNCTION_ENTER;
430 
431     VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(inputResource);
432     VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(outputResource);
433     MOS_TraceEventExt(EVENT_MEDIA_COPY, EVENT_TYPE_START, nullptr, 0, nullptr, 0);
434 
435     MOS_SURFACE             sourceSurface;
436     MOS_SURFACE             targetSurface;
437 
438     MOS_ZeroMemory(&targetSurface, sizeof(MOS_SURFACE));
439     MOS_ZeroMemory(&sourceSurface, sizeof(MOS_SURFACE));
440 
441     targetSurface.Format = Format_Invalid;
442     targetSurface.OsResource = *outputResource;
443 
444 #if !defined(LINUX) && !defined(ANDROID) && !EMUL && !_VULKAN
445     // for Double Buffer copy, clear the allocationInfo temply
446     MOS_ZeroMemory(&targetSurface.OsResource.AllocationInfo, sizeof(SResidencyInfo));
447 #endif
448 
449     sourceSurface.Format = Format_Invalid;
450     sourceSurface.OsResource = *inputResource;
451     VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(GetResourceInfo(&targetSurface));
452     VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(GetResourceInfo(&sourceSurface));
453 
454     if (targetSurface.TileType == MOS_TILE_LINEAR &&
455         sourceSurface.TileType == MOS_TILE_LINEAR)
456     {
457         VPHAL_MEMORY_DECOMP_NORMALMESSAGE("unsupport linear to linear convert, return unsupport feature");
458         MT_ERR2(MT_VE_DECOMP_COPY, MT_SURF_TILE_TYPE, MOS_TILE_LINEAR, MT_SURF_TILE_TYPE, MOS_TILE_LINEAR);
459         return MOS_STATUS_PLATFORM_NOT_SUPPORTED;
460     }
461 
462     MOS_FORMAT format = Format_Any;
463     if (isTileToLinear)
464     {
465         if (!IsFormatSupported(&sourceSurface))
466         {
467             VPHAL_MEMORY_DECOMP_NORMALMESSAGE("unsupport processing format, return unsupport feature");
468             MT_ERR2(MT_VE_DECOMP_COPY, MT_SURF_MOS_FORMAT, sourceSurface.Format, MT_SURF_IS_INPUT, 1);
469             return MOS_STATUS_PLATFORM_NOT_SUPPORTED;
470         }
471 
472         format = sourceSurface.Format;
473         copyHeight = sourceSurface.dwHeight;
474     }
475     else
476     {
477         if (!IsFormatSupported(&targetSurface))
478         {
479             VPHAL_MEMORY_DECOMP_NORMALMESSAGE("unsupport processing format, return unsupport feature");
480             MT_ERR2(MT_VE_DECOMP_COPY, MT_SURF_MOS_FORMAT, targetSurface.Format, MT_SURF_IS_OUTPUT, 1);
481             return MOS_STATUS_PLATFORM_NOT_SUPPORTED;
482         }
483 
484         format = targetSurface.Format;
485         copyHeight = targetSurface.dwHeight;
486     }
487 
488     if (!outputCompressed && targetSurface.CompressionMode != MOS_MMC_DISABLED)
489     {
490         targetSurface.CompressionMode = MOS_MMC_RC;
491     }
492 
493     //Get context before proceeding
494     auto gpuContext = m_osInterface->CurrentGpuContextOrdinal;
495 
496     targetSurface.Format = format;
497     sourceSurface.Format = format;
498 
499     sourceSurface.dwOffset = copyInputOffset;
500     targetSurface.dwOffset = copyOutputOffset;
501 
502     sourceSurface.dwWidth = copyWidth;
503     sourceSurface.dwHeight = copyHeight;
504     targetSurface.dwWidth = copyWidth;
505     targetSurface.dwHeight = copyHeight;
506 
507     // Sync for Vebox write
508     m_osInterface->pfnSyncOnResource(
509         m_osInterface,
510         &targetSurface.OsResource,
511         MOS_GPU_CONTEXT_VEBOX,
512         false);
513 
514     VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(RenderDoubleBufferDecompCMD(&sourceSurface, &targetSurface));
515 
516     MOS_TraceEventExt(EVENT_MEDIA_COPY, EVENT_TYPE_END, nullptr, 0, nullptr, 0);
517     return eStatus;
518 }
519 
Initialize(PMOS_INTERFACE osInterface,MhwInterfacesNext * mhwInterfaces)520 MOS_STATUS MediaMemDeCompNext::Initialize(PMOS_INTERFACE osInterface, MhwInterfacesNext* mhwInterfaces)
521 {
522     MOS_STATUS                  eStatus         = MOS_STATUS_SUCCESS;
523     MHW_VEBOX_GPUNODE_LIMIT     gpuNodeLimit    = {};
524     MOS_GPU_NODE                veboxGpuNode    = MOS_GPU_NODE_VE;
525     MOS_GPU_CONTEXT             veboxGpuContext = MOS_GPU_CONTEXT_VEBOX;
526 
527     VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(osInterface);
528     VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(mhwInterfaces);
529     VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(mhwInterfaces->m_cpInterface);
530     VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(mhwInterfaces->m_miItf);
531     VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(mhwInterfaces->m_veboxItf);
532 
533     m_osInterface = osInterface;
534     m_cpInterface = mhwInterfaces->m_cpInterface;
535     m_miItf       = mhwInterfaces->m_miItf;
536     m_veboxItf    = mhwInterfaces->m_veboxItf;
537 
538     m_userSettingPtr = m_osInterface->pfnGetUserSettingInstance(m_osInterface);
539 
540     // Set-Up Vebox decompression enable or not
541     IsVeboxDecompressionEnabled();
542 
543     if (m_veboxItf)
544     {
545         gpuNodeLimit.bCpEnabled = (m_osInterface->osCpInterface->IsCpEnabled()) ? true : false;
546 
547         // Check GPU Node decide logic together in this function
548         VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(m_veboxItf->FindVeboxGpuNodeToUse(&gpuNodeLimit));
549 
550         veboxGpuNode = (MOS_GPU_NODE)(gpuNodeLimit.dwGpuNodeToUse);
551         veboxGpuContext = (veboxGpuNode == MOS_GPU_NODE_VE) ? MOS_GPU_CONTEXT_VEBOX : MOS_GPU_CONTEXT_VEBOX2;
552 
553         // Create VEBOX/VEBOX2 Context
554         VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(m_veboxItf->CreateGpuContext(
555             m_osInterface,
556             veboxGpuContext,
557             veboxGpuNode));
558 
559         // Register Vebox GPU context with the Batch Buffer completion event
560         VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(m_osInterface->pfnRegisterBBCompleteNotifyEvent(
561             m_osInterface,
562             MOS_GPU_CONTEXT_VEBOX));
563 
564         const MHW_VEBOX_HEAP* veboxHeap = nullptr;
565         VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(m_veboxItf->GetVeboxHeapInfo(&veboxHeap));
566         if (veboxHeap == nullptr)
567         {
568             m_veboxItf->CreateHeap();
569         }
570     }
571 
572     return eStatus;
573 }
574 
GetResourceInfo(PMOS_SURFACE surface)575 MOS_STATUS MediaMemDeCompNext::GetResourceInfo(PMOS_SURFACE surface)
576 {
577     MOS_STATUS  eStatus = MOS_STATUS_SUCCESS;
578 
579     VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(m_osInterface);
580     VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(surface);
581 
582     MOS_SURFACE resDetails;
583     MOS_ZeroMemory(&resDetails, sizeof(resDetails));
584     resDetails.Format = Format_Invalid;
585 
586     VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(m_osInterface->pfnGetResourceInfo(
587         m_osInterface,
588         &surface->OsResource,
589         &resDetails));
590 
591     surface->Format                         = resDetails.Format;
592     surface->dwWidth                        = resDetails.dwWidth;
593     surface->dwHeight                       = resDetails.dwHeight;
594     surface->dwPitch                        = resDetails.dwPitch;
595     surface->dwDepth                        = resDetails.dwDepth;
596     surface->bArraySpacing                  = resDetails.bArraySpacing;
597     surface->TileType                       = resDetails.TileType;
598     surface->TileModeGMM                    = resDetails.TileModeGMM;
599     surface->bGMMTileEnabled                = resDetails.bGMMTileEnabled;
600     surface->bCompressible                  = resDetails.bCompressible;
601     surface->bIsCompressed                  = resDetails.bIsCompressed;
602     surface->dwOffset                       = resDetails.RenderOffset.YUV.Y.BaseOffset;
603     surface->YPlaneOffset.iSurfaceOffset    = resDetails.RenderOffset.YUV.Y.BaseOffset;
604     surface->YPlaneOffset.iXOffset          = resDetails.RenderOffset.YUV.Y.XOffset;
605     surface->YPlaneOffset.iYOffset          = resDetails.RenderOffset.YUV.Y.YOffset;
606     surface->UPlaneOffset.iSurfaceOffset    = resDetails.RenderOffset.YUV.U.BaseOffset;
607     surface->UPlaneOffset.iXOffset          = resDetails.RenderOffset.YUV.U.XOffset;
608     surface->UPlaneOffset.iYOffset          = resDetails.RenderOffset.YUV.U.YOffset;
609     surface->VPlaneOffset.iSurfaceOffset    = resDetails.RenderOffset.YUV.V.BaseOffset;
610     surface->VPlaneOffset.iXOffset          = resDetails.RenderOffset.YUV.V.XOffset;
611     surface->VPlaneOffset.iYOffset          = resDetails.RenderOffset.YUV.V.YOffset;
612     surface->dwSize = (uint32_t)surface->OsResource.pGmmResInfo->GetSizeMainSurface();
613 
614     MOS_MEMCOMP_STATE mmcMode;
615 
616     MOS_ZeroMemory(&mmcMode, sizeof(mmcMode));
617     m_osInterface->pfnGetMemoryCompressionMode(m_osInterface, &surface->OsResource, &mmcMode);
618     surface->CompressionMode = (MOS_RESOURCE_MMC_MODE)mmcMode;
619 
620     if (mmcMode)
621     {
622         m_osInterface->pfnGetMemoryCompressionFormat(m_osInterface, &surface->OsResource, &surface->CompressionFormat);
623         if ((surface->TileType == MOS_TILE_Y ||
624             surface->TileType == MOS_TILE_YS))
625         {
626             surface->bCompressible   = true;
627             surface->bIsCompressed   = true;
628             surface->CompressionMode = (MOS_RESOURCE_MMC_MODE)mmcMode;
629         }
630     }
631 
632     return eStatus;
633 }
634 
635 #define SURFACE_DW_UY_OFFSET(pSurface) \
636     ((pSurface) != nullptr ? ((pSurface)->UPlaneOffset.iSurfaceOffset - (pSurface)->dwOffset) / (pSurface)->dwPitch + (pSurface)->UPlaneOffset.iYOffset : 0)
637 
638 #define SURFACE_DW_VY_OFFSET(pSurface) \
639     ((pSurface) != nullptr ? ((pSurface)->VPlaneOffset.iSurfaceOffset - (pSurface)->dwOffset) / (pSurface)->dwPitch + (pSurface)->VPlaneOffset.iYOffset : 0)
640 
641 
SetupVeboxSurfaceState(PMHW_VEBOX_SURFACE_STATE_CMD_PARAMS mhwVeboxSurfaceStateCmdParams,PMOS_SURFACE inputSurface,PMOS_SURFACE outputSurface)642 MOS_STATUS MediaMemDeCompNext::SetupVeboxSurfaceState(PMHW_VEBOX_SURFACE_STATE_CMD_PARAMS mhwVeboxSurfaceStateCmdParams, PMOS_SURFACE inputSurface, PMOS_SURFACE outputSurface)
643 {
644  MOS_STATUS              eStatus = MOS_STATUS_SUCCESS;
645     bool  inputIsLinearBuffer = false;
646     bool  outputIsLinearBuffer = false;
647     uint32_t bpp = 1;
648     uint32_t inputWidth = 0;
649     uint32_t outputWidth = 0;
650 
651     VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(inputSurface);
652     VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(mhwVeboxSurfaceStateCmdParams);
653 
654     MOS_ZeroMemory(mhwVeboxSurfaceStateCmdParams, sizeof(*mhwVeboxSurfaceStateCmdParams));
655 
656     mhwVeboxSurfaceStateCmdParams->SurfInput.bActive    = mhwVeboxSurfaceStateCmdParams->SurfOutput.bActive    = true;
657     mhwVeboxSurfaceStateCmdParams->SurfInput.dwBitDepth = mhwVeboxSurfaceStateCmdParams->SurfOutput.dwBitDepth = inputSurface->dwDepth;
658     mhwVeboxSurfaceStateCmdParams->SurfInput.dwHeight   = mhwVeboxSurfaceStateCmdParams->SurfOutput.dwHeight   =
659         MOS_MIN(inputSurface->dwHeight, ((outputSurface!= nullptr) ? outputSurface->dwHeight : inputSurface->dwHeight));
660     mhwVeboxSurfaceStateCmdParams->SurfInput.dwWidth    = mhwVeboxSurfaceStateCmdParams->SurfOutput.dwWidth    =
661         MOS_MIN(inputSurface->dwWidth, ((outputSurface != nullptr) ? outputSurface->dwWidth : inputSurface->dwWidth));
662     mhwVeboxSurfaceStateCmdParams->SurfInput.Format     = mhwVeboxSurfaceStateCmdParams->SurfOutput.Format     = inputSurface->Format;
663 
664     MOS_SURFACE inputDetails, outputDetails;
665     MOS_ZeroMemory(&inputDetails, sizeof(inputDetails));
666     MOS_ZeroMemory(&outputDetails, sizeof(outputDetails));
667     inputDetails.Format = Format_Invalid;
668     outputDetails.Format = Format_Invalid;
669 
670     if (inputSurface)
671     {
672         VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(m_osInterface->pfnGetResourceInfo(
673             m_osInterface,
674             &inputSurface->OsResource,
675             &inputDetails));
676     }
677 
678     if (outputSurface)
679     {
680         VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(m_osInterface->pfnGetResourceInfo(
681             m_osInterface,
682             &outputSurface->OsResource,
683             &outputDetails));
684 
685         // Following settings are enabled only when outputSurface is availble
686         inputIsLinearBuffer  = (inputDetails.dwHeight == 1) ? true : false;
687         outputIsLinearBuffer = (outputDetails.dwHeight == 1) ? true : false;
688 
689         inputWidth = inputSurface->dwWidth;
690         outputWidth = outputSurface->dwWidth;
691 
692         if (inputIsLinearBuffer)
693         {
694             bpp = outputDetails.dwPitch / outputDetails.dwWidth;
695             if (outputDetails.dwPitch % outputDetails.dwWidth != 0)
696             {
697                 inputWidth = outputDetails.dwPitch / bpp;
698             }
699         }
700         else if (outputIsLinearBuffer)
701         {
702             bpp = inputDetails.dwPitch / inputDetails.dwWidth;
703             if (inputDetails.dwPitch % inputDetails.dwWidth != 0)
704             {
705                 outputWidth = inputDetails.dwPitch / bpp;
706             }
707         }
708         else
709         {
710             VPHAL_MEMORY_DECOMP_NORMALMESSAGE("2D to 2D, no need for bpp setting.");
711         }
712     }
713 
714 
715     if (inputSurface->dwPitch > 0            &&
716        (inputSurface->Format == Format_P010  ||
717         inputSurface->Format == Format_P016  ||
718         inputSurface->Format == Format_NV12))
719     {
720         mhwVeboxSurfaceStateCmdParams->SurfInput.dwUYoffset = (!inputIsLinearBuffer) ? SURFACE_DW_UY_OFFSET(inputSurface) :
721                                                               inputSurface->dwHeight;
722 
723         if (outputSurface)
724         {
725             mhwVeboxSurfaceStateCmdParams->SurfOutput.dwUYoffset = (!outputIsLinearBuffer) ? SURFACE_DW_UY_OFFSET(outputSurface) :
726                                                                    outputSurface->dwHeight;
727         }
728         else
729         {
730             mhwVeboxSurfaceStateCmdParams->SurfOutput.dwUYoffset = mhwVeboxSurfaceStateCmdParams->SurfInput.dwUYoffset;
731         }
732     }
733 
734     mhwVeboxSurfaceStateCmdParams->SurfInput.rcMaxSrc.left   = mhwVeboxSurfaceStateCmdParams->SurfOutput.rcMaxSrc.left   = 0;
735     mhwVeboxSurfaceStateCmdParams->SurfInput.rcMaxSrc.right  = mhwVeboxSurfaceStateCmdParams->SurfOutput.rcMaxSrc.right  = (long)(mhwVeboxSurfaceStateCmdParams->SurfInput.dwWidth);
736     mhwVeboxSurfaceStateCmdParams->SurfInput.rcMaxSrc.top    = mhwVeboxSurfaceStateCmdParams->SurfOutput.rcMaxSrc.top    = 0;
737     mhwVeboxSurfaceStateCmdParams->SurfInput.rcMaxSrc.bottom = mhwVeboxSurfaceStateCmdParams->SurfOutput.rcMaxSrc.bottom = (long)(mhwVeboxSurfaceStateCmdParams->SurfInput.dwHeight);
738     mhwVeboxSurfaceStateCmdParams->bOutputValid = true;
739 
740     // if output surface is null, then Inplace resolve happens
741     if (!outputSurface)
742     {
743         mhwVeboxSurfaceStateCmdParams->SurfInput.TileType        = mhwVeboxSurfaceStateCmdParams->SurfOutput.TileType            = inputSurface->TileType;
744         mhwVeboxSurfaceStateCmdParams->SurfInput.TileModeGMM     = mhwVeboxSurfaceStateCmdParams->SurfOutput.TileModeGMM         = inputSurface->TileModeGMM;
745         mhwVeboxSurfaceStateCmdParams->SurfInput.bGMMTileEnabled = mhwVeboxSurfaceStateCmdParams->SurfOutput.bGMMTileEnabled     = inputSurface->bGMMTileEnabled;
746         mhwVeboxSurfaceStateCmdParams->SurfOutput.dwPitch        = mhwVeboxSurfaceStateCmdParams->SurfInput.dwPitch              = inputSurface->dwPitch;
747         mhwVeboxSurfaceStateCmdParams->SurfInput.pOsResource     = mhwVeboxSurfaceStateCmdParams->SurfOutput.pOsResource         = &(inputSurface->OsResource);
748         mhwVeboxSurfaceStateCmdParams->SurfInput.dwYoffset       = mhwVeboxSurfaceStateCmdParams->SurfOutput.dwYoffset           = inputSurface->YPlaneOffset.iYOffset;
749 
750         mhwVeboxSurfaceStateCmdParams->SurfInput.dwCompressionFormat = mhwVeboxSurfaceStateCmdParams->SurfOutput.dwCompressionFormat =
751             inputSurface->CompressionFormat;
752     }
753     else
754     // double buffer resolve
755     {
756         mhwVeboxSurfaceStateCmdParams->SurfInput.TileType             = inputSurface->TileType;
757         mhwVeboxSurfaceStateCmdParams->SurfInput.TileModeGMM          = inputSurface->TileModeGMM;
758         mhwVeboxSurfaceStateCmdParams->SurfInput.bGMMTileEnabled      = inputSurface->bGMMTileEnabled;
759         mhwVeboxSurfaceStateCmdParams->SurfOutput.TileType            = outputSurface->TileType;
760         mhwVeboxSurfaceStateCmdParams->SurfOutput.TileModeGMM         = outputSurface->TileModeGMM;
761         mhwVeboxSurfaceStateCmdParams->SurfOutput.bGMMTileEnabled     = outputSurface->bGMMTileEnabled;
762 
763         // When surface is 1D but processed as 2D, fake a min(pitch, width) is needed as the pitch API passed may less surface width in 1D surface
764         mhwVeboxSurfaceStateCmdParams->SurfInput.dwPitch              = (inputIsLinearBuffer) ?
765                                                                          MOS_MIN(inputWidth * bpp, inputSurface->dwPitch) : inputSurface->dwPitch;
766         mhwVeboxSurfaceStateCmdParams->SurfOutput.dwPitch             = (outputIsLinearBuffer) ?
767                                                                          MOS_MIN(outputWidth * bpp, outputSurface->dwPitch) : outputSurface->dwPitch;
768         mhwVeboxSurfaceStateCmdParams->SurfInput.pOsResource          = &(inputSurface->OsResource);
769         mhwVeboxSurfaceStateCmdParams->SurfOutput.pOsResource         = &(outputSurface->OsResource);
770         mhwVeboxSurfaceStateCmdParams->SurfInput.dwYoffset            = inputSurface->YPlaneOffset.iYOffset;
771         mhwVeboxSurfaceStateCmdParams->SurfOutput.dwYoffset           = outputSurface->YPlaneOffset.iYOffset;
772         mhwVeboxSurfaceStateCmdParams->SurfInput.dwCompressionFormat  = inputSurface->CompressionFormat;
773         mhwVeboxSurfaceStateCmdParams->SurfOutput.dwCompressionFormat = outputSurface->CompressionFormat;
774     }
775 
776     return eStatus;
777 }
778 
InitCommandBuffer(PMOS_COMMAND_BUFFER cmdBuffer)779 MOS_STATUS MediaMemDeCompNext::InitCommandBuffer(PMOS_COMMAND_BUFFER cmdBuffer)
780 {
781     PMOS_INTERFACE                   osInterface         = nullptr;
782     MOS_STATUS                       eStatus             = MOS_STATUS_SUCCESS;
783     uint32_t                         iRemaining          = 0;
784     PMOS_RESOURCE                    gpuStatusBuffer     = nullptr;
785     RENDERHAL_GENERIC_PROLOG_PARAMS  genericPrologParams = {};
786 
787     //---------------------------------------------
788     VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(cmdBuffer);
789     VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(m_osInterface);
790     VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(m_miItf);
791     //---------------------------------------------
792     osInterface = m_osInterface;
793 
794     MOS_GPU_CONTEXT gpuContext = m_osInterface->pfnGetGpuContext(m_osInterface);
795 
796 #ifndef EMUL
797     if (osInterface->bEnableKmdMediaFrameTracking)
798     {
799         // Get GPU Status buffer
800         VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(osInterface->pfnGetGpuStatusBufferResource(osInterface, gpuStatusBuffer));
801         VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(gpuStatusBuffer);
802         // Register the buffer
803         VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(osInterface->pfnRegisterResource(osInterface, gpuStatusBuffer, true, true));
804 
805         genericPrologParams.bEnableMediaFrameTracking = true;
806         genericPrologParams.presMediaFrameTrackingSurface = gpuStatusBuffer;
807         genericPrologParams.dwMediaFrameTrackingTag = osInterface->pfnGetGpuStatusTag(osInterface, osInterface->CurrentGpuContextOrdinal);
808         genericPrologParams.dwMediaFrameTrackingAddrOffset = osInterface->pfnGetGpuStatusTagOffset(osInterface, osInterface->CurrentGpuContextOrdinal);
809 
810         // Increment GPU Status Tag
811         osInterface->pfnIncrementGpuStatusTag(osInterface, osInterface->CurrentGpuContextOrdinal);
812     }
813 #endif
814 
815     if (genericPrologParams.bEnableMediaFrameTracking)
816     {
817         VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(genericPrologParams.presMediaFrameTrackingSurface);
818         cmdBuffer->Attributes.bEnableMediaFrameTracking      = genericPrologParams.bEnableMediaFrameTracking;
819         cmdBuffer->Attributes.dwMediaFrameTrackingTag        = genericPrologParams.dwMediaFrameTrackingTag;
820         cmdBuffer->Attributes.dwMediaFrameTrackingAddrOffset = genericPrologParams.dwMediaFrameTrackingAddrOffset;
821         cmdBuffer->Attributes.resMediaFrameTrackingSurface   = genericPrologParams.presMediaFrameTrackingSurface;
822     }
823 
824     // initialize command buffer attributes
825     cmdBuffer->Attributes.bTurboMode = false;
826     cmdBuffer->Attributes.bMediaPreemptionEnabled = false;
827     cmdBuffer->Attributes.dwMediaFrameTrackingAddrOffset = 0;
828 
829     MHW_GENERIC_PROLOG_PARAMS genericPrologMhwParams;
830     MOS_ZeroMemory(&genericPrologMhwParams, sizeof(genericPrologMhwParams));
831     genericPrologMhwParams.pOsInterface  = m_osInterface;
832     genericPrologMhwParams.pvMiInterface = nullptr;
833     genericPrologMhwParams.bMmcEnabled   = true;
834     VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(Mhw_SendGenericPrologCmdNext(
835         cmdBuffer,
836         &genericPrologMhwParams,
837         m_miItf));
838 
839     return eStatus;
840 }
841 
IsFormatSupported(PMOS_SURFACE surface)842 bool MediaMemDeCompNext::IsFormatSupported(PMOS_SURFACE surface)
843 {
844     bool    bRet = false;
845 
846     if (surface->Format == Format_R10G10B10A2 ||
847         surface->Format == Format_B10G10R10A2 ||
848         surface->Format == Format_Y410 ||
849         surface->Format == Format_Y210)
850     {
851         // Re-map RGB10/RGB10/Y410/Y210 as AYUV
852         surface->Format = Format_AYUV;
853     }
854 
855     if (surface->Format == Format_A8 ||
856         surface->Format == Format_Y8 ||
857         surface->Format == Format_L8 ||
858         surface->Format == Format_P8 ||
859         surface->Format == Format_STMM)
860     {
861         surface->Format = Format_P8;
862     }
863 
864     if (surface->Format == Format_IMC3 ||
865         surface->Format == Format_444P ||
866         surface->Format == Format_422H ||
867         surface->Format == Format_422V ||
868         surface->Format == Format_411P ||
869         surface->Format == Format_411R ||
870         surface->Format == Format_444P ||
871         surface->Format == Format_RGBP ||
872         surface->Format == Format_BGRP ||
873         surface->Format == Format_400P ||
874         surface->Format == Format_420O)
875     {
876         surface->Format = Format_P8;
877         surface->dwHeight = surface->dwSize / surface->dwPitch;
878     }
879 
880     if (IS_RGB64_FLOAT_FORMAT(surface->Format) ||
881         IS_RGB64_FORMAT(surface->Format)       ||
882        (surface->Format == Format_G32R32F))
883     {
884         surface->Format = Format_Y416;
885     }
886 
887     // Check if Sample Format is supported for decompression
888     if (surface->Format != Format_NV12 &&
889         surface->Format != Format_AYUV &&
890         surface->Format != Format_Y416 &&
891         surface->Format != Format_P010 &&
892         surface->Format != Format_P016 &&
893         !IS_PA_FORMAT(surface->Format) &&
894         surface->Format != Format_A8R8G8B8 &&
895         surface->Format != Format_A8B8G8R8 &&
896         surface->Format != Format_X8R8G8B8 &&
897         surface->Format != Format_X8B8G8R8 &&
898         surface->Format != Format_P8 &&
899         surface->Format != Format_Y16U)
900     {
901         VPHAL_MEMORY_DECOMP_NORMALMESSAGE("Unsupported Source Format '0x%08x' for VEBOX Decompression.", surface->Format);
902         return false;
903     }
904 
905     return true;;
906 }
907