1 /*
2 * Copyright (c) 2019-2021, 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     vp_allocator.cpp
24 //! \brief    Defines the interface for vp resource allocate
25 //! \details  vp allocator will allocate and destory buffers, the caller
26 //!           can use directly
27 //!
28 
29 #include "vp_allocator.h"
30 #include "vp_utils.h"
31 #include "mos_solo_generic.h"
32 
33 using namespace vp;
34 
VpAllocator(PMOS_INTERFACE osInterface,MediaMemComp * mmc)35 VpAllocator::VpAllocator(PMOS_INTERFACE osInterface, MediaMemComp *mmc) :
36     m_osInterface(osInterface),
37     m_mmc(mmc)
38 {
39     m_allocator = MOS_New(Allocator, m_osInterface);
40     VP_PUBLIC_CHK_NULL_NO_STATUS_RETURN(m_allocator);
41 }
42 
~VpAllocator()43 VpAllocator::~VpAllocator()
44 {
45     if (m_allocator)
46     {
47         m_allocator->DestroyAllResources();
48         MOS_Delete(m_allocator);
49     }
50 }
51 
52 //Paried with DestroyResource or DestroyAllResources
AllocateResource(MOS_ALLOC_GFXRES_PARAMS & param,bool zeroOnAllocate)53 MOS_RESOURCE* VpAllocator::AllocateResource(MOS_ALLOC_GFXRES_PARAMS &param, bool zeroOnAllocate)
54 {
55     VP_FUNC_CALL();
56     if (!m_allocator)
57         return nullptr;
58 
59     return m_allocator->AllocateResource(param, zeroOnAllocate, COMPONENT_VPCommon);
60 }
61 
DestroyResource(MOS_RESOURCE * resource)62 MOS_STATUS VpAllocator::DestroyResource(MOS_RESOURCE *resource)
63 {
64     VP_FUNC_CALL();
65     VP_PUBLIC_CHK_NULL_RETURN(m_allocator);
66 
67     return m_allocator->DestroyResource(resource);
68 }
69 
DestroyAllResources()70 MOS_STATUS VpAllocator::DestroyAllResources()
71 {
72     VP_FUNC_CALL();
73     VP_PUBLIC_CHK_NULL_RETURN(m_allocator);
74 
75     return m_allocator->DestroyAllResources();
76 }
77 
78 //Paried with FreeResource
AllocateResource(MOS_RESOURCE * res,MOS_ALLOC_GFXRES_PARAMS & param)79 MOS_STATUS VpAllocator::AllocateResource(MOS_RESOURCE *res, MOS_ALLOC_GFXRES_PARAMS &param)
80 {
81     VP_FUNC_CALL();
82     if (!m_allocator)
83         return MOS_STATUS_NULL_POINTER;
84 
85     return m_allocator->AllocateResource(res, param);
86 }
87 
FreeResource(MOS_RESOURCE * resource)88 MOS_STATUS VpAllocator::FreeResource(MOS_RESOURCE *resource)
89 {
90     VP_FUNC_CALL();
91     VP_PUBLIC_CHK_NULL_RETURN(m_allocator);
92 
93     return m_allocator->FreeResource(resource);
94 }
95 
UpdateSurfacePlaneOffset(MOS_SURFACE & surf)96 void VpAllocator::UpdateSurfacePlaneOffset(MOS_SURFACE &surf)
97 {
98     VP_FUNC_CALL();
99     // dwOffset/YPlaneOffset/UPlaneOffset/VPlaneOffset will not be initialized during GetSurfaceInfo.
100     // Initialize them with RenderOffset when needed.
101     if (IS_RGB32_FORMAT(surf.Format) ||
102         IS_RGB16_FORMAT(surf.Format) ||
103         IS_RGB64_FORMAT(surf.Format) ||
104         surf.Format == Format_RGB    ||
105         surf.Format == Format_Y410)
106     {
107         surf.dwOffset                        = surf.RenderOffset.RGB.BaseOffset;
108         surf.YPlaneOffset.iSurfaceOffset     = surf.RenderOffset.RGB.BaseOffset;
109         surf.YPlaneOffset.iXOffset           = surf.RenderOffset.RGB.XOffset;
110         surf.YPlaneOffset.iYOffset           = surf.RenderOffset.RGB.YOffset;
111     }
112     else // YUV or PL3_RGB
113     {
114         // Get Y plane information (plane offset, X/Y offset)
115         surf.dwOffset                        = surf.RenderOffset.YUV.Y.BaseOffset;
116         surf.YPlaneOffset.iSurfaceOffset     = surf.RenderOffset.YUV.Y.BaseOffset;
117         surf.YPlaneOffset.iXOffset           = surf.RenderOffset.YUV.Y.XOffset;
118         surf.YPlaneOffset.iYOffset           = surf.RenderOffset.YUV.Y.YOffset;
119         surf.YPlaneOffset.iLockSurfaceOffset = surf.LockOffset.YUV.Y;
120 
121         // Get U/UV plane information (plane offset, X/Y offset)
122         surf.UPlaneOffset.iSurfaceOffset     = surf.RenderOffset.YUV.U.BaseOffset;
123         surf.UPlaneOffset.iXOffset           = surf.RenderOffset.YUV.U.XOffset;
124         surf.UPlaneOffset.iYOffset           = surf.RenderOffset.YUV.U.YOffset;
125         surf.UPlaneOffset.iLockSurfaceOffset = surf.LockOffset.YUV.U;
126 
127         // Get V plane information (plane offset, X/Y offset)
128         surf.VPlaneOffset.iSurfaceOffset     = surf.RenderOffset.YUV.V.BaseOffset;
129         surf.VPlaneOffset.iXOffset           = surf.RenderOffset.YUV.V.XOffset;
130         surf.VPlaneOffset.iYOffset           = surf.RenderOffset.YUV.V.YOffset;
131         surf.VPlaneOffset.iLockSurfaceOffset = surf.LockOffset.YUV.V;
132     }
133 }
134 
135 //Paried with AllocateSurface
AllocateSurface(MOS_ALLOC_GFXRES_PARAMS & param,bool zeroOnAllocate)136 MOS_SURFACE* VpAllocator::AllocateSurface(MOS_ALLOC_GFXRES_PARAMS &param, bool zeroOnAllocate)
137 {
138     VP_FUNC_CALL();
139     if (!m_allocator)
140         return nullptr;
141 
142     MOS_SURFACE* surf = m_allocator->AllocateSurface(param, zeroOnAllocate, COMPONENT_VPCommon);
143 
144     if (surf)
145     {
146         // Format is not initialized in Allocator::AllocateSurface. Remove it after
147         // it being fixed in Allocator::AllocateSurface.
148         surf->Format = param.Format;
149 
150         if (MOS_FAILED(SetMmcFlags(*surf)))
151         {
152             VP_PUBLIC_ASSERTMESSAGE("Set mmc flags failed during AllocateSurface!");
153             m_allocator->DestroySurface(surf);
154             return nullptr;
155         }
156 
157         UpdateSurfacePlaneOffset(*surf);
158     }
159 
160     return surf;
161 }
162 
DestroySurface(MOS_SURFACE * surface,MOS_GFXRES_FREE_FLAGS flags)163 MOS_STATUS VpAllocator::DestroySurface(MOS_SURFACE *surface, MOS_GFXRES_FREE_FLAGS flags)
164 {
165     VP_FUNC_CALL();
166     VP_PUBLIC_CHK_NULL_RETURN(m_allocator);
167 
168     return m_allocator->DestroySurface(surface, flags);
169 }
170 
AllocateVpSurface(MOS_ALLOC_GFXRES_PARAMS & param,bool zeroOnAllocate,VPHAL_CSPACE ColorSpace,uint32_t ChromaSiting)171 VP_SURFACE* VpAllocator::AllocateVpSurface(MOS_ALLOC_GFXRES_PARAMS &param, bool zeroOnAllocate, VPHAL_CSPACE ColorSpace, uint32_t ChromaSiting)
172 {
173     VP_FUNC_CALL();
174     VP_SURFACE *surface = MOS_New(VP_SURFACE);
175     if (nullptr == surface)
176     {
177         return nullptr;
178     }
179     MOS_ZeroMemory(surface, sizeof(VP_SURFACE));
180 
181     // Only used for Buffer surface
182     uint32_t bufferWidth  = 0;
183     uint32_t bufferHeight = 0;
184 
185 
186     if (param.Format == Format_Buffer)
187     {
188         bufferWidth   = param.dwWidth;
189         bufferHeight  = param.dwHeight;
190         param.dwWidth = param.dwWidth * param.dwHeight;
191         param.dwHeight = 1;
192     }
193 
194     surface->osSurface = AllocateSurface(param, zeroOnAllocate);
195 
196     if (nullptr == surface->osSurface)
197     {
198         MOS_Delete(surface);
199         MT_ERR1(MT_VP_HAL_ALLOC_SURF, MT_CODE_LINE, __LINE__);
200         return nullptr;
201     }
202 
203     surface->isResourceOwner = true;
204     surface->ColorSpace = ColorSpace;
205     surface->ChromaSiting = ChromaSiting;
206     surface->SampleType = SAMPLE_PROGRESSIVE; // Hardcode to SAMPLE_PROGRESSIVE for intermedia surface. Set to correct value for DI later.
207 
208     surface->rcSrc.left     = surface->rcSrc.top = 0;
209     surface->rcSrc.right    = surface->osSurface->dwWidth;
210     surface->rcSrc.bottom   = surface->osSurface->dwHeight;
211     surface->rcDst          = surface->rcSrc;
212     surface->rcMaxSrc       = surface->rcSrc;
213 
214 
215     if (param.Format == Format_Buffer)
216     {
217         surface->bufferWidth = bufferWidth;
218         surface->bufferHeight = bufferHeight;
219     }
220 
221     return surface;
222 }
223 
224 // Allocate vp surface from vphalSurf. Reuse the resource in vphalSurf.
AllocateVpSurface(VPHAL_SURFACE & vphalSurf)225 VP_SURFACE *VpAllocator::AllocateVpSurface(VPHAL_SURFACE &vphalSurf)
226 {
227     VP_FUNC_CALL();
228     if (Mos_ResourceIsNull(&vphalSurf.OsResource))
229     {
230         return nullptr;
231     }
232 
233     VP_SURFACE *surf = MOS_New(VP_SURFACE);
234 
235     if (nullptr == surf)
236     {
237         return nullptr;
238     }
239 
240     surf->osSurface = MOS_New(MOS_SURFACE);
241     if (nullptr == surf->osSurface)
242     {
243         MOS_Delete(surf);
244         return nullptr;
245     }
246 
247     surf->isResourceOwner = false;
248     surf->Clean();
249 
250     // Initialize the mos surface in vp surface structure.
251     MOS_SURFACE &osSurface = *surf->osSurface;
252     MOS_ZeroMemory(&osSurface, sizeof(MOS_SURFACE));
253 
254     // Set input parameters dwArraySlice, dwMipSlice and S3dChannel if needed later.
255     osSurface.Format                            = vphalSurf.Format;
256     osSurface.OsResource                        = vphalSurf.OsResource;
257 
258     if (MOS_FAILED(m_allocator->GetSurfaceInfo(&osSurface.OsResource, &osSurface)))
259     {
260         MOS_Delete(surf->osSurface);
261         MOS_Delete(surf);
262         return nullptr;
263     }
264 
265     // Align the format with vphal surface. Some format need be remapped in vphal surface.
266     // For example, format_420O is mapped to Format_NV12 in VpHal.
267     // But it is mapped to several different Formats in CodecHal under different conditions.
268     osSurface.Format                            = vphalSurf.Format;
269 
270     // Initialize other parameters in vp surface according to vphal surface.
271     surf->ColorSpace                            = vphalSurf.ColorSpace;
272     surf->ExtendedGamut                         = vphalSurf.ExtendedGamut;
273     surf->Palette                               = vphalSurf.Palette;
274     surf->bQueryVariance                        = vphalSurf.bQueryVariance;
275     surf->FrameID                               = vphalSurf.FrameID;
276     surf->uFwdRefCount                          = vphalSurf.uFwdRefCount;
277     surf->uBwdRefCount                          = vphalSurf.uBwdRefCount;
278     surf->pFwdRef                               = vphalSurf.pFwdRef;
279     surf->pBwdRef                               = vphalSurf.pBwdRef;
280     surf->SurfType                              = vphalSurf.SurfType;
281     surf->SampleType                            = vphalSurf.SampleType;
282     surf->ChromaSiting                          = vphalSurf.ChromaSiting;
283     surf->rcSrc                                 = vphalSurf.rcSrc;
284     surf->rcDst                                 = vphalSurf.rcDst;
285     surf->rcMaxSrc                              = vphalSurf.rcMaxSrc;
286 
287     if (MOS_FAILED(SetMmcFlags(osSurface)))
288     {
289         VP_PUBLIC_ASSERTMESSAGE("Set mmc flags failed during AllocateVpSurface!");
290         DestroyVpSurface(surf);
291         return nullptr;
292     }
293     return surf;
294 }
295 
296 // Allocate vp surface from vpSurfSrc. Reuse the resource in vpSurfSrc.
AllocateVpSurface(VP_SURFACE & vpSurfSrc)297 VP_SURFACE *VpAllocator::AllocateVpSurface(VP_SURFACE &vpSurfSrc)
298 {
299     VP_FUNC_CALL();
300     if (nullptr == vpSurfSrc.osSurface || Mos_ResourceIsNull(&vpSurfSrc.osSurface->OsResource))
301     {
302         return nullptr;
303     }
304 
305     VP_SURFACE *surf = MOS_New(VP_SURFACE);
306 
307     if (nullptr == surf)
308     {
309         return nullptr;
310     }
311 
312     MOS_SURFACE *osSurface = MOS_New(MOS_SURFACE);
313 
314     if (nullptr == osSurface)
315     {
316         MOS_Delete(surf);
317         return nullptr;
318     }
319 
320     *osSurface = *vpSurfSrc.osSurface;
321     *surf = vpSurfSrc;
322 
323     surf->osSurface = osSurface;
324     surf->isResourceOwner = false;
325 
326     return surf;
327 }
328 
329 // Allocate vp surface from osSurf. Reuse the resource in osSurf.
AllocateVpSurface(MOS_SURFACE & osSurf,VPHAL_CSPACE colorSpace,uint32_t chromaSiting,RECT rcSrc,RECT rcDst,VPHAL_SURFACE_TYPE SurfType,bool updatePlaneOffset)330 VP_SURFACE *VpAllocator::AllocateVpSurface(MOS_SURFACE &osSurf,
331     VPHAL_CSPACE colorSpace, uint32_t chromaSiting, RECT rcSrc, RECT rcDst, VPHAL_SURFACE_TYPE SurfType, bool updatePlaneOffset)
332 {
333     VP_FUNC_CALL();
334     if (Mos_ResourceIsNull(&osSurf.OsResource))
335     {
336         return nullptr;
337     }
338 
339     VP_SURFACE *surf = MOS_New(VP_SURFACE);
340 
341     if (nullptr == surf)
342     {
343         return nullptr;
344     }
345 
346     MOS_SURFACE *osSurface = MOS_New(MOS_SURFACE);
347 
348     if (nullptr == osSurface)
349     {
350         MOS_Delete(surf);
351         return nullptr;
352     }
353 
354     *osSurface = osSurf;
355     if (updatePlaneOffset)
356     {
357         UpdateSurfacePlaneOffset(*osSurface);
358     }
359 
360     MOS_ZeroMemory(surf, sizeof(VP_SURFACE));
361     surf->osSurface         = osSurface;
362     surf->isResourceOwner   = false;
363     surf->ColorSpace        = colorSpace;               //!< Color Space
364     surf->ChromaSiting      = chromaSiting;             //!< ChromaSiting
365     surf->rcSrc             = rcSrc;                    //!< Source rectangle
366     surf->rcDst             = rcDst;                    //!< Destination rectangle
367     surf->rcMaxSrc          = rcSrc;                    //!< Max source rectangle
368     surf->SurfType          = SurfType;                 //!< Surface type (context). Not in use for internal surface
369     surf->SampleType        = SAMPLE_PROGRESSIVE;       //!<  Interlaced/Progressive sample type.
370 
371     return surf;
372 }
373 
374 // Allocate empty vp surface.
AllocateVpSurface()375 VP_SURFACE *VpAllocator::AllocateVpSurface()
376 {
377     VP_FUNC_CALL();
378     // Allocate VpSurface without resource.
379     VP_SURFACE *surf = MOS_New(VP_SURFACE);
380 
381     if (nullptr == surf)
382     {
383         return nullptr;
384     }
385 
386     MOS_SURFACE *osSurface = MOS_New(MOS_SURFACE);
387 
388     if (nullptr == osSurface)
389     {
390         MOS_Delete(surf);
391         return nullptr;
392     }
393 
394     surf->osSurface = osSurface;
395     surf->isResourceOwner = false;
396     surf->Clean();
397 
398     return surf;
399 }
400 
401 // Copy surface info from src to dst. dst shares the resource of src.
CopyVpSurface(VP_SURFACE & dst,VP_SURFACE & src)402 MOS_STATUS VpAllocator::CopyVpSurface(VP_SURFACE &dst, VP_SURFACE &src)
403 {
404     VP_FUNC_CALL();
405     if (nullptr == dst.osSurface || nullptr == src.osSurface || dst.isResourceOwner)
406     {
407         return MOS_STATUS_INVALID_PARAMETER;
408     }
409 
410     MOS_SURFACE &osSurface = *dst.osSurface;
411     osSurface = *src.osSurface;
412     dst = src;
413 
414     dst.osSurface = &osSurface;
415     dst.isResourceOwner = false;
416 
417     return MOS_STATUS_SUCCESS;
418 }
419 
DestroyVpSurface(VP_SURFACE * & surface,bool deferredDestroyed,MOS_GFXRES_FREE_FLAGS flags)420 MOS_STATUS VpAllocator::DestroyVpSurface(VP_SURFACE* &surface, bool deferredDestroyed, MOS_GFXRES_FREE_FLAGS flags)
421 {
422     VP_FUNC_CALL();
423     MOS_STATUS status = MOS_STATUS_SUCCESS;
424     if (nullptr == surface)
425     {
426         return status;
427     }
428 
429     if (surface && nullptr == surface->osSurface)
430     {
431         // VP_SURFACE should always be allocated by interface in VpAllocator,
432         // which will ensure nullptr != surface->osSurface.
433         VP_PUBLIC_NORMALMESSAGE("Surfaces already been deleted, return status!");
434         return status;
435     }
436 
437     if (deferredDestroyed)
438     {
439         m_recycler.push_back(surface);
440         surface = nullptr;
441         return MOS_STATUS_SUCCESS;
442     }
443 
444     if (surface->isResourceOwner)
445     {
446         status = DestroySurface(surface->osSurface, flags);
447     }
448     else
449     {
450         MOS_Delete(surface->osSurface);
451     }
452 
453     MOS_Delete(surface);
454     return status;
455 }
456 
Lock(MOS_RESOURCE * resource,MOS_LOCK_PARAMS * lockFlag)457 void* VpAllocator::Lock(MOS_RESOURCE* resource, MOS_LOCK_PARAMS *lockFlag)
458 {
459     VP_FUNC_CALL();
460     if (!m_allocator)
461         return nullptr;
462 
463     return m_allocator->Lock(resource, lockFlag);
464 }
465 
LockResourceForWrite(MOS_RESOURCE * resource)466 void* VpAllocator::LockResourceForWrite(MOS_RESOURCE *resource)
467 {
468     VP_FUNC_CALL();
469     MOS_LOCK_PARAMS lockFlags;
470     MOS_ZeroMemory(&lockFlags, sizeof(MOS_LOCK_PARAMS));
471     lockFlags.WriteOnly = 1;
472 
473     if (!m_allocator)
474         return nullptr;
475 
476     return m_allocator->Lock(resource, &lockFlags);
477 }
478 
LockResourceWithNoOverwrite(MOS_RESOURCE * resource)479 void* VpAllocator::LockResourceWithNoOverwrite(MOS_RESOURCE *resource)
480 {
481     VP_FUNC_CALL();
482     MOS_LOCK_PARAMS lockFlags;
483     MOS_ZeroMemory(&lockFlags, sizeof(MOS_LOCK_PARAMS));
484     lockFlags.WriteOnly   = 1;
485     lockFlags.NoOverWrite = 1;
486 
487     if (!m_allocator)
488         return nullptr;
489 
490     return m_allocator->Lock(resource, &lockFlags);
491 }
492 
LockResourceForRead(MOS_RESOURCE * resource)493 void* VpAllocator::LockResourceForRead(MOS_RESOURCE *resource)
494 {
495     VP_FUNC_CALL();
496     MOS_LOCK_PARAMS lockFlags;
497     MOS_ZeroMemory(&lockFlags, sizeof(MOS_LOCK_PARAMS));
498     lockFlags.ReadOnly = 1;
499 
500     if (!m_allocator)
501         return nullptr;
502 
503     return m_allocator->Lock(resource, &lockFlags);
504 }
505 
UnLock(MOS_RESOURCE * resource)506 MOS_STATUS VpAllocator::UnLock(MOS_RESOURCE *resource)
507 {
508     VP_FUNC_CALL();
509     VP_PUBLIC_CHK_NULL_RETURN(m_allocator);
510 
511     return m_allocator->UnLock(resource);
512 }
513 
SkipResourceSync(MOS_RESOURCE * resource)514 MOS_STATUS VpAllocator::SkipResourceSync(MOS_RESOURCE *resource)
515 {
516     VP_FUNC_CALL();
517     VP_PUBLIC_CHK_NULL_RETURN(m_allocator);
518 
519     return m_allocator->SkipResourceSync(resource);
520 }
521 
GetSurfaceInfo(VPHAL_SURFACE * surface,VPHAL_GET_SURFACE_INFO & info)522 MOS_STATUS VpAllocator::GetSurfaceInfo(VPHAL_SURFACE *surface, VPHAL_GET_SURFACE_INFO &info)
523 {
524     VP_FUNC_CALL();
525     MOS_MEMCOMP_STATE mmcMode = MOS_MEMCOMP_DISABLED;
526     MOS_SURFACE       resDetails;
527 
528     VP_PUBLIC_CHK_NULL_RETURN(m_mmc);
529     VP_PUBLIC_CHK_NULL_RETURN(m_allocator);
530     VP_PUBLIC_CHK_NULL_RETURN(surface);
531 
532     VP_PUBLIC_ASSERT(!Mos_ResourceIsNull(&surface->OsResource));
533 
534     MOS_ZeroMemory(&resDetails, sizeof(MOS_SURFACE));
535     resDetails.dwArraySlice = info.ArraySlice;
536     resDetails.dwMipSlice   = info.MipSlice;
537     resDetails.S3dChannel   = info.S3dChannel;
538     resDetails.Format       = surface->Format;
539 
540     VP_PUBLIC_CHK_STATUS_RETURN(m_allocator->GetSurfaceInfo(&surface->OsResource, &resDetails));
541 
542     // Format_420O is mapped to Format_NV12 in VpHal here.
543     // But it is mapped to several different Formats in CodecHal under different conditions.
544     if (resDetails.Format == Format_420O)
545     {
546         resDetails.Format = Format_NV12;
547     }
548 
549     // Get resource information
550     surface->dwWidth         = resDetails.dwWidth;
551     surface->dwHeight        = resDetails.dwHeight;
552     surface->dwPitch         = resDetails.dwPitch;
553     surface->dwSlicePitch    = resDetails.dwSlicePitch;
554     surface->dwDepth         = resDetails.dwDepth;
555     surface->TileType        = resDetails.TileType;
556     surface->TileModeGMM     = resDetails.TileModeGMM;
557     surface->bGMMTileEnabled = resDetails.bGMMTileEnabled;
558     surface->bOverlay        = resDetails.bOverlay ? true : false;
559     surface->bFlipChain      = resDetails.bFlipChain ? true : false;
560     surface->Format          = resDetails.Format;
561     surface->bCompressible   = resDetails.bCompressible ? true : false;
562     surface->bIsCompressed   = resDetails.bIsCompressed ? true : false;
563 
564     if (IS_RGB32_FORMAT(surface->Format) ||
565         IS_RGB16_FORMAT(surface->Format) ||
566         IS_RGB64_FORMAT(surface->Format) ||
567         surface->Format == Format_RGB    ||
568         surface->Format == Format_Y410)
569     {
570         surface->dwOffset                    = resDetails.RenderOffset.RGB.BaseOffset;
571         surface->YPlaneOffset.iSurfaceOffset = resDetails.RenderOffset.RGB.BaseOffset;
572         surface->YPlaneOffset.iXOffset       = resDetails.RenderOffset.RGB.XOffset;
573         surface->YPlaneOffset.iYOffset       = resDetails.RenderOffset.RGB.YOffset;
574     }
575     else // YUV or PL3_RGB
576     {
577         // Get Y plane information (plane offset, X/Y offset)
578         surface->dwOffset                        = resDetails.RenderOffset.YUV.Y.BaseOffset;
579         surface->YPlaneOffset.iSurfaceOffset     = resDetails.RenderOffset.YUV.Y.BaseOffset;
580         surface->YPlaneOffset.iXOffset           = resDetails.RenderOffset.YUV.Y.XOffset;
581         surface->YPlaneOffset.iYOffset           = resDetails.RenderOffset.YUV.Y.YOffset;
582         surface->YPlaneOffset.iLockSurfaceOffset = resDetails.LockOffset.YUV.Y;
583 
584         // Get U/UV plane information (plane offset, X/Y offset)
585         surface->UPlaneOffset.iSurfaceOffset     = resDetails.RenderOffset.YUV.U.BaseOffset;
586         surface->UPlaneOffset.iXOffset           = resDetails.RenderOffset.YUV.U.XOffset;
587         surface->UPlaneOffset.iYOffset           = resDetails.RenderOffset.YUV.U.YOffset;
588         surface->UPlaneOffset.iLockSurfaceOffset = resDetails.LockOffset.YUV.U;
589 
590         // Get V plane information (plane offset, X/Y offset)
591         surface->VPlaneOffset.iSurfaceOffset     = resDetails.RenderOffset.YUV.V.BaseOffset;
592         surface->VPlaneOffset.iXOffset           = resDetails.RenderOffset.YUV.V.XOffset;
593         surface->VPlaneOffset.iYOffset           = resDetails.RenderOffset.YUV.V.YOffset;
594         surface->VPlaneOffset.iLockSurfaceOffset = resDetails.LockOffset.YUV.V;
595     }
596 
597     VP_PUBLIC_CHK_STATUS_RETURN(m_mmc->GetResourceMmcState(&surface->OsResource, mmcMode));
598     if (mmcMode &&
599         (surface->TileType == MOS_TILE_Y ||
600          surface->TileType == MOS_TILE_YS))
601     {
602         surface->bCompressible   = true;
603         surface->CompressionMode = (MOS_RESOURCE_MMC_MODE)mmcMode;
604     }
605     else
606     {
607         surface->CompressionMode = MOS_MMC_DISABLED;
608     }
609 
610     return MOS_STATUS_SUCCESS;
611 }
612 
GetSurfaceInfo(VP_SURFACE * surface,VPHAL_GET_SURFACE_INFO & info)613 MOS_STATUS VpAllocator::GetSurfaceInfo(VP_SURFACE* surface, VPHAL_GET_SURFACE_INFO& info)
614 {
615     VP_FUNC_CALL();
616     MOS_MEMCOMP_STATE mmcMode = MOS_MEMCOMP_DISABLED;
617     MOS_SURFACE       resDetails;
618 
619     VP_PUBLIC_CHK_NULL_RETURN(m_mmc);
620     VP_PUBLIC_CHK_NULL_RETURN(m_allocator);
621     VP_PUBLIC_CHK_NULL_RETURN(surface);
622     VP_PUBLIC_CHK_NULL_RETURN(surface->osSurface);
623 
624     if (Mos_ResourceIsNull(&surface->osSurface->OsResource))
625     {
626         VP_PUBLIC_NORMALMESSAGE("invalid resource handle");
627         return MOS_STATUS_INVALID_HANDLE;
628     }
629 
630     MOS_ZeroMemory(&resDetails, sizeof(MOS_SURFACE));
631     resDetails.dwArraySlice = info.ArraySlice;
632     resDetails.dwMipSlice   = info.MipSlice;
633     resDetails.S3dChannel   = info.S3dChannel;
634     resDetails.Format       = surface->osSurface->Format;
635 
636     VP_PUBLIC_CHK_STATUS_RETURN(m_allocator->GetSurfaceInfo(&surface->osSurface->OsResource, &resDetails));
637 
638     // Format_420O is mapped to Format_NV12 in VpHal here.
639     // But it is mapped to several different Formats in CodecHal under different conditions.
640     if (resDetails.Format == Format_420O)
641     {
642         resDetails.Format = Format_NV12;
643     }
644 
645     // Get resource information
646     surface->osSurface->dwWidth         = resDetails.dwWidth;
647     surface->osSurface->dwHeight        = resDetails.dwHeight;
648     surface->osSurface->dwPitch         = resDetails.dwPitch;
649     surface->osSurface->dwSlicePitch    = resDetails.dwSlicePitch;
650     surface->osSurface->dwDepth         = resDetails.dwDepth;
651     surface->osSurface->TileType        = resDetails.TileType;
652     surface->osSurface->TileModeGMM     = resDetails.TileModeGMM;
653     surface->osSurface->bGMMTileEnabled = resDetails.bGMMTileEnabled;
654     surface->osSurface->bOverlay        = resDetails.bOverlay ? true : false;
655     surface->osSurface->bFlipChain      = resDetails.bFlipChain ? true : false;
656     surface->osSurface->Format          = resDetails.Format;
657     surface->osSurface->bCompressible   = resDetails.bCompressible ? true : false;
658     surface->osSurface->bIsCompressed   = resDetails.bIsCompressed ? true : false;
659 
660     return MOS_STATUS_SUCCESS;
661 }
662 
AllocParamsInitType(MOS_ALLOC_GFXRES_PARAMS & allocParams,PVPHAL_SURFACE surface,MOS_GFXRES_TYPE defaultResType,MOS_TILE_TYPE defaultTileType)663 MOS_STATUS VpAllocator::AllocParamsInitType(
664     MOS_ALLOC_GFXRES_PARAMS     &allocParams,
665     PVPHAL_SURFACE              surface,
666     MOS_GFXRES_TYPE             defaultResType,
667     MOS_TILE_TYPE               defaultTileType)
668 {
669     VP_FUNC_CALL();
670     VP_PUBLIC_CHK_NULL_RETURN(surface);
671 
672 #if !EMUL && !LINUX
673     //  Need to reallocate surface according to expected tiletype instead of tiletype of the surface what we have
674     if ( surface                           != nullptr &&
675          surface->OsResource.pGmmResInfo   != nullptr &&
676          surface->TileType                 == defaultTileType)
677     {
678         // Reallocate but use same tile type and resource type as current
679         allocParams.TileType = surface->OsResource.TileType;
680         allocParams.Type     = surface->OsResource.ResType;
681     }
682     else
683 #endif
684     {
685         // First time allocation. Caller must specify default params
686         allocParams.Type     = defaultResType;
687         allocParams.TileType = defaultTileType;
688     }
689 
690     return MOS_STATUS_SUCCESS;
691 }
692 
AllocParamsInitType(MOS_ALLOC_GFXRES_PARAMS & allocParams,VP_SURFACE * surface,MOS_GFXRES_TYPE defaultResType,MOS_TILE_TYPE defaultTileType)693 MOS_STATUS VpAllocator::AllocParamsInitType(
694         MOS_ALLOC_GFXRES_PARAMS     &allocParams,
695         VP_SURFACE                  *surface,
696         MOS_GFXRES_TYPE             defaultResType,
697         MOS_TILE_TYPE               defaultTileType)
698 {
699     VP_FUNC_CALL();
700     //  Need to reallocate surface according to expected tiletype instead of tiletype of the surface what we have
701     if (surface != nullptr                                      &&
702         surface->osSurface != nullptr                           &&
703         surface->osSurface->OsResource.pGmmResInfo != nullptr   &&
704         surface->osSurface->TileType == defaultTileType)
705     {
706         // Reallocate but use same tile type and resource type as current
707         allocParams.TileType = surface->osSurface->TileType;
708         allocParams.Type     = surface->osSurface->Type;
709     }
710     else
711     {
712         // First time allocation. Caller must specify default params
713         allocParams.Type     = defaultResType;
714         allocParams.TileType = defaultTileType;
715     }
716 
717     return MOS_STATUS_SUCCESS;
718 }
719 
ReAllocateSurface(VP_SURFACE * & surface,PCCHAR surfaceName,MOS_FORMAT format,MOS_GFXRES_TYPE defaultResType,MOS_TILE_TYPE defaultTileType,uint32_t width,uint32_t height,bool compressible,MOS_RESOURCE_MMC_MODE compressionMode,bool & allocated,bool zeroOnAllocate,bool deferredDestroyed,MOS_HW_RESOURCE_DEF resUsageType,MOS_TILE_MODE_GMM tileModeByForce,Mos_MemPool memType,bool isNotLockable)720 MOS_STATUS VpAllocator::ReAllocateSurface(
721         VP_SURFACE             *&surface,
722         PCCHAR                  surfaceName,
723         MOS_FORMAT              format,
724         MOS_GFXRES_TYPE         defaultResType,
725         MOS_TILE_TYPE           defaultTileType,
726         uint32_t                width,
727         uint32_t                height,
728         bool                    compressible,
729         MOS_RESOURCE_MMC_MODE   compressionMode,
730         bool                    &allocated,
731         bool                    zeroOnAllocate,
732         bool                    deferredDestroyed,
733         MOS_HW_RESOURCE_DEF     resUsageType,
734         MOS_TILE_MODE_GMM       tileModeByForce,
735         Mos_MemPool             memType,
736         bool                    isNotLockable)
737 {
738     VP_FUNC_CALL();
739     MOS_STATUS              eStatus = MOS_STATUS_SUCCESS;
740     MOS_ALLOC_GFXRES_PARAMS allocParams = {};
741     MOS_GFXRES_FREE_FLAGS   resFreeFlags = {0};
742 
743     allocated = false;
744 
745     //---------------------------------
746     VP_PUBLIC_CHK_NULL_RETURN(m_allocator);
747 
748     if (!m_mmc->IsMmcEnabled())
749     {
750         compressible    = 0;
751         compressionMode = MOS_MMC_DISABLED;
752     }
753     //---------------------------------
754 
755     // compressible should be compared with bCompressible since it is inited by bCompressible in previous call
756     // TileType of surface should be compared since we need to reallocate surface if TileType changes
757     if (surface                                                       &&
758         surface->osSurface                                            &&
759         !Mos_ResourceIsNull(&surface->osSurface->OsResource)          &&
760         (surface->osSurface->Format               == format)          &&
761         ((surface->osSurface->bCompressible != 0) == compressible)    &&
762         (surface->osSurface->CompressionMode      == compressionMode) &&
763         (surface->osSurface->TileType             == defaultTileType) &&
764         ((Format_Buffer                           == format           &&
765           surface->bufferWidth                    == width            &&
766           surface->bufferHeight                   == height)          ||
767          (Format_Buffer                           != format           &&
768           surface->osSurface->dwWidth             == width            &&
769           surface->osSurface->dwHeight            == height))         )
770     {
771         return eStatus;
772     }
773 
774     if (surface && nullptr == surface->osSurface)
775     {
776         // VP_SURFACE should always be allocated by interface in VpAllocator,
777         // which will ensure nullptr != surface->osSurface.
778         VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_INVALID_PARAMETER);
779     }
780 
781     //if free the compressed surface, need set the sync dealloc flag as 1 for sync dealloc for aux table update
782     if (surface && IsSyncFreeNeededForMMCSurface(surface->osSurface))
783     {
784         resFreeFlags.SynchronousDestroy = 1;
785         VP_PUBLIC_NORMALMESSAGE("Set SynchronousDestroy flag for compressed resource %s", surfaceName);
786     }
787     VP_PUBLIC_CHK_STATUS_RETURN(DestroyVpSurface(surface, deferredDestroyed, resFreeFlags));
788 
789     AllocParamsInitType(allocParams, surface, defaultResType, defaultTileType);
790 
791     allocParams.dwWidth         = width;
792     allocParams.dwHeight        = height;
793     allocParams.Format          = format;
794     allocParams.bIsCompressible = compressible;
795     allocParams.CompressionMode = compressionMode;
796     allocParams.pBufName        = surfaceName;
797     allocParams.dwArraySize     = 1;
798     allocParams.ResUsageType    = resUsageType;
799     allocParams.m_tileModeByForce = tileModeByForce;
800     allocParams.dwMemType       = memType;
801     allocParams.Flags.bNotLockable = isNotLockable;
802 
803     surface = AllocateVpSurface(allocParams, zeroOnAllocate);
804     VP_PUBLIC_CHK_NULL_RETURN(surface);
805 
806     MT_LOG7(MT_VP_HAL_REALLOC_SURF, MT_NORMAL, MT_VP_HAL_INTER_SURF_TYPE, surfaceName ? *((int64_t*)surfaceName) : 0,
807         MT_SURF_WIDTH, width, MT_SURF_HEIGHT, height, MT_SURF_MOS_FORMAT, format, MT_SURF_TILE_MODE, surface->osSurface->TileModeGMM,
808         MT_SURF_COMP_ABLE, surface->osSurface->bCompressible, MT_SURF_COMP_MODE, surface->osSurface->CompressionMode);
809 
810     allocated = true;
811     return MOS_STATUS_SUCCESS;
812 }
813 
814 // for debug purpose
815 #if (_DEBUG || _RELEASE_INTERNAL)
ReAllocateSurface(PVPHAL_SURFACE surface,PCCHAR surfaceName,MOS_FORMAT format,MOS_GFXRES_TYPE defaultResType,MOS_TILE_TYPE defaultTileType,uint32_t width,uint32_t height,bool compressible,MOS_RESOURCE_MMC_MODE compressionMode,bool * allocated,MOS_HW_RESOURCE_DEF resUsageType,MOS_TILE_MODE_GMM tileModeByForce)816 MOS_STATUS VpAllocator::ReAllocateSurface(
817     PVPHAL_SURFACE        surface,
818     PCCHAR                surfaceName,
819     MOS_FORMAT            format,
820     MOS_GFXRES_TYPE       defaultResType,
821     MOS_TILE_TYPE         defaultTileType,
822     uint32_t              width,
823     uint32_t              height,
824     bool                  compressible,
825     MOS_RESOURCE_MMC_MODE compressionMode,
826     bool *                allocated,
827     MOS_HW_RESOURCE_DEF   resUsageType,
828     MOS_TILE_MODE_GMM     tileModeByForce)
829 {
830     VP_FUNC_CALL();
831     MOS_STATUS              eStatus;
832     VPHAL_GET_SURFACE_INFO  info;
833     MOS_ALLOC_GFXRES_PARAMS allocParams;
834     MOS_GFXRES_FREE_FLAGS   resFreeFlags = {0};
835 
836     //---------------------------------
837     VP_PUBLIC_ASSERT(&surface->OsResource);
838     //---------------------------------
839 
840     eStatus      = MOS_STATUS_SUCCESS;
841     *allocated = false;
842 
843     // compressible should be compared with compressible since it is inited by compressible in previous call
844     // TileType of surface should be compared since we need to reallocate surface if TileType changes
845     if (!Mos_ResourceIsNull(&surface->OsResource) &&
846         (surface->dwWidth == width) &&
847         (surface->dwHeight == height) &&
848         (surface->Format == format) &&
849         (surface->bCompressible == compressible) &&
850         (surface->CompressionMode == compressionMode) &&
851         (surface->TileType == defaultTileType))
852     {
853         return eStatus;
854     }
855 
856     MOS_ZeroMemory(&allocParams, sizeof(MOS_ALLOC_GFXRES_PARAMS));
857 
858     VpHal_AllocParamsInitType(&allocParams, surface, defaultResType, defaultTileType);
859 
860     allocParams.dwWidth           = width;
861     allocParams.dwHeight          = height;
862     allocParams.Format            = format;
863     allocParams.bIsCompressible   = compressible;
864     allocParams.CompressionMode   = compressionMode;
865     allocParams.pBufName          = surfaceName;
866     allocParams.dwArraySize       = 1;
867     allocParams.ResUsageType      = resUsageType;
868     allocParams.m_tileModeByForce = tileModeByForce;
869 
870     VP_PUBLIC_CHK_STATUS_RETURN(DestroyResource(&surface->OsResource));
871 
872     // Allocate surface
873     VP_PUBLIC_CHK_STATUS_RETURN(AllocateResource(&surface->OsResource, allocParams));
874 
875     // Get surface information
876     MOS_ZeroMemory(&info, sizeof(VPHAL_GET_SURFACE_INFO));
877 
878     // Pre-set to get surface info
879     surface->Format = format;
880 
881     VP_PUBLIC_CHK_STATUS_RETURN(GetSurfaceInfo(surface, info));
882 
883     *allocated = true;
884 
885     VP_PUBLIC_ASSERT(eStatus == MOS_STATUS_SUCCESS);
886     return eStatus;
887 }
888 #endif
889 
OsFillResource(PMOS_RESOURCE osResource,uint32_t size,uint8_t value)890 MOS_STATUS VpAllocator::OsFillResource(
891     PMOS_RESOURCE     osResource,
892     uint32_t          size,
893     uint8_t           value)
894 {
895     VP_FUNC_CALL();
896     VP_PUBLIC_CHK_NULL_RETURN(m_allocator);
897     return m_allocator->OsFillResource(osResource, size, value);
898 }
899 
ReadSurface(PVPHAL_SURFACE surface,uint32_t bpp,uint8_t * dst)900 MOS_STATUS VpAllocator::ReadSurface (
901     PVPHAL_SURFACE      surface,
902     uint32_t            bpp,
903     uint8_t             *dst)
904 {
905     VP_FUNC_CALL();
906     uint8_t         *src        = nullptr;
907     uint8_t         *tempSrc    = nullptr;
908     uint8_t         *tempDst    = nullptr;
909     uint32_t        size        = 0;
910     uint32_t        widthInBytes = 0;
911     uint32_t        y           = 0;
912     uint32_t        z           = 0;
913 
914     VP_PUBLIC_CHK_NULL_RETURN(m_allocator);
915 
916     //----------------------------------------------
917     VP_PUBLIC_ASSERT(surface);
918     VP_PUBLIC_ASSERT(surface->dwWidth   > 0);
919     VP_PUBLIC_ASSERT(surface->dwHeight  > 0);
920     VP_PUBLIC_ASSERT(surface->dwDepth   > 0);
921     VP_PUBLIC_ASSERT(surface->dwPitch >= surface->dwWidth);
922     VP_PUBLIC_ASSERT(bpp > 0);
923     VP_PUBLIC_ASSERT(dst);
924     VP_PUBLIC_ASSERT(!Mos_ResourceIsNull(&surface->OsResource));
925     //----------------------------------------------
926 
927     src = (uint8_t*)LockResourceForRead(&surface->OsResource);
928     VP_PUBLIC_CHK_NULL_RETURN(src);
929 
930     // Calculate Size in Bytes
931     size = surface->dwWidth * surface->dwHeight * surface->dwDepth * bpp/8;
932     widthInBytes = surface->dwWidth * bpp / 8;
933     if (surface->dwPitch == widthInBytes)
934     {
935         MOS_SecureMemcpy(dst, size, src, size);
936     }
937     else
938     {
939         tempSrc    = src;
940         tempDst    = dst;
941 
942         for (z = 0; z < surface->dwDepth; z++)
943         {
944             for (y = 0; y < surface->dwHeight; y++)
945             {
946                 MOS_SecureMemcpy(tempDst, widthInBytes, tempSrc, widthInBytes);
947                 tempSrc += surface->dwPitch;
948                 tempDst += widthInBytes;
949             }
950         }
951     }
952 
953     VP_PUBLIC_CHK_STATUS_RETURN(m_allocator->UnLock(&surface->OsResource));
954 
955     return MOS_STATUS_SUCCESS;
956 }
957 
WriteSurface(PVPHAL_SURFACE surface,uint32_t bpp,const uint8_t * src)958 MOS_STATUS VpAllocator::WriteSurface (
959     PVPHAL_SURFACE      surface,
960     uint32_t            bpp,
961     const uint8_t       *src)
962 {
963     VP_FUNC_CALL();
964     uint8_t             *dst        = nullptr;
965     uint8_t             *tempSrc    = nullptr;
966     uint8_t             *tempDst    = nullptr;
967     uint32_t            widthInBytes = 0;
968     uint32_t            size        = 0;
969     uint32_t            y           = 0;
970     uint32_t            z           = 0;
971 
972     VP_PUBLIC_CHK_NULL_RETURN(m_allocator);
973 
974     //----------------------------------------------
975     VP_PUBLIC_ASSERT(surface);
976     VP_PUBLIC_ASSERT(surface->dwWidth   > 0);
977     VP_PUBLIC_ASSERT(surface->dwHeight  > 0);
978     VP_PUBLIC_ASSERT(surface->dwDepth   > 0);
979     VP_PUBLIC_ASSERT(surface->dwPitch >= surface->dwWidth);
980     VP_PUBLIC_ASSERT(bpp > 0);
981     VP_PUBLIC_ASSERT(src);
982     VP_PUBLIC_ASSERT(!Mos_ResourceIsNull(&surface->OsResource));
983     //----------------------------------------------
984 
985     dst = (uint8_t*)LockResourceForWrite(&surface->OsResource);
986     VP_PUBLIC_CHK_NULL_RETURN(dst);
987 
988     // Calculate Size in Bytes
989     size = surface->dwWidth * surface->dwHeight * surface->dwDepth * bpp/8;
990     widthInBytes = surface->dwWidth * bpp/8;
991 
992     if (surface->dwPitch == widthInBytes)
993     {
994         MOS_SecureMemcpy(dst, size, src, size);
995     }
996     else
997     {
998         tempSrc    = (uint8_t*)src;
999         tempDst    = dst;
1000 
1001         for (z = 0; z < surface->dwDepth; z++)
1002         {
1003             for (y = 0; y < surface->dwHeight; y++)
1004             {
1005                 MOS_SecureMemcpy(tempDst, widthInBytes, tempSrc, widthInBytes);
1006                 tempSrc += widthInBytes;
1007                 tempDst += surface->dwPitch;
1008             }
1009         }
1010     }
1011 
1012     VP_PUBLIC_CHK_STATUS_RETURN(m_allocator->UnLock(&surface->OsResource));
1013 
1014     return MOS_STATUS_SUCCESS;
1015 }
1016 
WriteSurface(VP_SURFACE * vpsurface,uint32_t bpp,const uint8_t * src)1017 MOS_STATUS VpAllocator::WriteSurface(VP_SURFACE* vpsurface, uint32_t bpp, const uint8_t* src)
1018 {
1019     VP_FUNC_CALL();
1020     uint8_t* dst = nullptr;
1021     uint8_t* tempSrc = nullptr;
1022     uint8_t* tempDst = nullptr;
1023     uint32_t            widthInBytes = 0;
1024     uint32_t            size = 0;
1025     uint32_t            y = 0;
1026     uint32_t            z = 0;
1027     MOS_SURFACE* surface;
1028 
1029     VP_PUBLIC_CHK_NULL_RETURN(m_allocator);
1030 
1031     //----------------------------------------------
1032     VP_PUBLIC_ASSERT(vpsurface);
1033 
1034     surface = vpsurface->osSurface;
1035     VP_PUBLIC_ASSERT(surface);
1036 
1037     VP_PUBLIC_ASSERT(surface->dwWidth > 0);
1038     VP_PUBLIC_ASSERT(surface->dwHeight > 0);
1039     VP_PUBLIC_ASSERT(surface->dwDepth > 0);
1040     VP_PUBLIC_ASSERT(surface->dwPitch >= surface->dwWidth);
1041     VP_PUBLIC_ASSERT(bpp > 0);
1042     VP_PUBLIC_ASSERT(src);
1043     VP_PUBLIC_ASSERT(!Mos_ResourceIsNull(&surface->OsResource));
1044     //----------------------------------------------
1045 
1046     dst = (uint8_t*)LockResourceForWrite(&surface->OsResource);
1047     VP_PUBLIC_CHK_NULL_RETURN(dst);
1048 
1049     // Calculate Size in Bytes
1050     size = surface->dwWidth * surface->dwHeight * surface->dwDepth * bpp / 8;
1051     widthInBytes = surface->dwWidth * bpp / 8;
1052 
1053     if (surface->dwPitch == widthInBytes)
1054     {
1055         MOS_SecureMemcpy(dst, size, src, size);
1056     }
1057     else
1058     {
1059         tempSrc = (uint8_t*)src;
1060         tempDst = dst;
1061 
1062         for (z = 0; z < surface->dwDepth; z++)
1063         {
1064             for (y = 0; y < surface->dwHeight; y++)
1065             {
1066                 MOS_SecureMemcpy(tempDst, widthInBytes, tempSrc, widthInBytes);
1067                 tempSrc += widthInBytes;
1068                 tempDst += surface->dwPitch;
1069             }
1070         }
1071     }
1072 
1073     VP_PUBLIC_CHK_STATUS_RETURN(m_allocator->UnLock(&surface->OsResource));
1074 
1075     return MOS_STATUS_SUCCESS;
1076 }
1077 
Write1DSurface(VP_SURFACE * vpsurface,const uint8_t * src,uint32_t srcSize)1078 MOS_STATUS VpAllocator::Write1DSurface(VP_SURFACE* vpsurface, const uint8_t* src, uint32_t srcSize)
1079 {
1080     VP_FUNC_CALL();
1081     VP_PUBLIC_CHK_NULL_RETURN(vpsurface);
1082     VP_PUBLIC_CHK_NULL_RETURN(vpsurface->osSurface);
1083     VP_PUBLIC_CHK_NULL_RETURN(src);
1084     VP_PUBLIC_CHK_VALUE_RETURN(srcSize > 0, true);
1085     VP_PUBLIC_CHK_NULL_RETURN(m_allocator);
1086     VP_PUBLIC_CHK_VALUE_RETURN(vpsurface->osSurface->dwSize > 0, true);
1087 
1088 #if MOS_MEDIASOLO_SUPPORTED
1089     if (!m_osInterface->bSoloInUse)
1090 #endif
1091     {
1092         VP_PUBLIC_CHK_VALUE_RETURN(vpsurface->osSurface->Type, MOS_GFXRES_BUFFER);
1093     }
1094 
1095     VP_PUBLIC_ASSERT(!Mos_ResourceIsNull(&vpsurface->osSurface->OsResource));
1096 
1097     MOS_SURFACE* surface = vpsurface->osSurface;
1098     uint8_t* dst = (uint8_t*)LockResourceForWrite(&surface->OsResource);
1099 
1100     VP_PUBLIC_CHK_NULL_RETURN(dst);
1101 
1102     MOS_STATUS status = MOS_SecureMemcpy(dst, surface->dwSize, src, srcSize);
1103 
1104     VP_PUBLIC_CHK_STATUS_RETURN(m_allocator->UnLock(&surface->OsResource));
1105 
1106     return status;
1107 }
1108 
SyncOnResource(PMOS_RESOURCE osResource,bool bWriteOperation)1109 MOS_STATUS VpAllocator::SyncOnResource(
1110     PMOS_RESOURCE         osResource,
1111     bool                  bWriteOperation)
1112 {
1113     VP_FUNC_CALL();
1114     VP_PUBLIC_CHK_NULL_RETURN(m_allocator);
1115 
1116     return (m_allocator->SyncOnResource(osResource, bWriteOperation));
1117 }
1118 
UpdateResourceUsageType(PMOS_RESOURCE osResource,MOS_HW_RESOURCE_DEF resUsageType)1119 MOS_STATUS VpAllocator::UpdateResourceUsageType(
1120     PMOS_RESOURCE           osResource,
1121     MOS_HW_RESOURCE_DEF     resUsageType)
1122 {
1123     VP_FUNC_CALL();
1124     VP_PUBLIC_CHK_NULL_RETURN(m_allocator);
1125 
1126     return (m_allocator->UpdateResourceUsageType(osResource, resUsageType));
1127 }
1128 
1129 
IsSyncFreeNeededForMMCSurface(PMOS_SURFACE pOsSurface)1130 bool VpAllocator::IsSyncFreeNeededForMMCSurface(PMOS_SURFACE pOsSurface)
1131 {
1132     VP_FUNC_CALL();
1133     if (nullptr == pOsSurface)
1134     {
1135         return false;
1136     }
1137 
1138     return (m_allocator->isSyncFreeNeededForMMCSurface(pOsSurface));
1139 }
1140 
CleanRecycler()1141 void VpAllocator::CleanRecycler()
1142 {
1143     VP_FUNC_CALL();
1144     while (!m_recycler.empty())
1145     {
1146         MOS_GFXRES_FREE_FLAGS resFreeFlags = {};
1147         VP_SURFACE *surf = m_recycler.back();
1148         m_recycler.pop_back();
1149         //if free the compressed surface, need set the sync dealloc flag as 1 for sync dealloc for aux table update
1150         if (surf && IsSyncFreeNeededForMMCSurface(surf->osSurface))
1151         {
1152             resFreeFlags.SynchronousDestroy = 1;
1153             VP_PUBLIC_NORMALMESSAGE("Set SynchronousDestroy flag for compressed resource.");
1154         }
1155         DestroyVpSurface(surf, false, resFreeFlags);
1156     }
1157 }
1158 
IsEmpty()1159 bool VP_SURFACE::IsEmpty()
1160 {
1161     VP_FUNC_CALL();
1162     return nullptr == osSurface || Mos_ResourceIsNull(&osSurface->OsResource);
1163 }
1164 
Clean()1165 MOS_STATUS VP_SURFACE::Clean()
1166 {
1167     VP_FUNC_CALL();
1168     // The vp surface, which owns the resource, cannot be cleaned.
1169     if (isResourceOwner)
1170     {
1171         VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_INVALID_PARAMETER);
1172     }
1173     if (osSurface)
1174     {
1175         MOS_ZeroMemory(osSurface, sizeof(MOS_SURFACE));
1176     }
1177 
1178     isResourceOwner     = false;
1179     ColorSpace          = CSpace_Any;
1180     ChromaSiting        = 0;
1181     bQueryVariance      = 0;
1182     FrameID             = 0;
1183     ExtendedGamut       = false;
1184     SurfType            = SURF_NONE;
1185     uFwdRefCount        = 0;
1186     uBwdRefCount        = 0;
1187     pFwdRef             = nullptr;
1188     pBwdRef             = nullptr;
1189     SampleType          = SAMPLE_PROGRESSIVE;
1190     MOS_ZeroMemory(&Palette, sizeof(Palette));
1191     MOS_ZeroMemory(&rcSrc, sizeof(rcSrc));
1192     MOS_ZeroMemory(&rcDst, sizeof(rcDst));
1193     MOS_ZeroMemory(&rcMaxSrc, sizeof(rcMaxSrc));
1194     bVEBOXCroppingUsed  = false;
1195 
1196     return MOS_STATUS_SUCCESS;
1197 }
1198 
GetAllocationHandle(MOS_INTERFACE * osIntf)1199 uint64_t VP_SURFACE::GetAllocationHandle(MOS_INTERFACE* osIntf)
1200 {
1201     VP_FUNC_CALL();
1202 
1203 #if MOS_MEDIASOLO_SUPPORTED
1204     if (Mos_Solo_IsInUse(osIntf))
1205     {
1206         uint64_t handle = osSurface ? (uint64_t)osSurface->OsResource.pData : 0;
1207         if (handle)
1208         {
1209             return handle;
1210         }
1211         // Media solo external surface will come here, in which case,
1212         // AllocationHandle or bo->handle should be valid.
1213     }
1214 #endif
1215 
1216 #if(LINUX)
1217     if (osSurface && osSurface->OsResource.bo)
1218     {
1219         return osSurface->OsResource.bo->handle;
1220     }
1221     else
1222     {
1223         return 0;
1224     }
1225 #else
1226     return osSurface ? osSurface->OsResource.AllocationInfo.m_AllocationHandle : 0;
1227 #endif
1228 }
1229 
SetMmcFlags(MOS_SURFACE & osSurface)1230 MOS_STATUS VpAllocator::SetMmcFlags(MOS_SURFACE &osSurface)
1231 {
1232     VP_FUNC_CALL();
1233     VP_PUBLIC_CHK_NULL_RETURN(m_mmc);
1234 
1235     // Init MMC related flags.
1236     m_mmc->SetSurfaceMmcMode(&osSurface);
1237     if (osSurface.CompressionMode   &&
1238         (osSurface.TileType == MOS_TILE_Y ||
1239          osSurface.TileType == MOS_TILE_YS))
1240     {
1241         uint32_t mmcFormat   = 0;
1242 
1243         osSurface.bCompressible   = true;
1244         osSurface.bIsCompressed   = true;
1245         m_mmc->GetSurfaceMmcFormat(&osSurface, &mmcFormat);
1246         osSurface.CompressionFormat = mmcFormat;
1247     }
1248     else
1249     {
1250         // Do not modify the bCompressible flag even MmcMode is disable, since the surface size/pitch may be different
1251         // between Compressible and Uncompressible, which will affect the DN surface allocation.
1252         osSurface.bIsCompressed     = false;
1253         osSurface.CompressionMode   = MOS_MMC_DISABLED;
1254         osSurface.CompressionFormat = 0;
1255     }
1256 
1257     return MOS_STATUS_SUCCESS;
1258 }
1259