1 /*
2 * Copyright (c) 2019-2022, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 //!
23 //! \file 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 ¶m, 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 ¶m)
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 ¶m, 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 MOS_GFXRES_FREE_FLAGS resFreeFlags = {0};
168 if (IsSyncFreeNeededForMMCSurface(surface))
169 {
170 resFreeFlags.SynchronousDestroy = 1;
171 }
172 return m_allocator->DestroySurface(surface, resFreeFlags);
173 }
174
AllocateVpSurface(MOS_ALLOC_GFXRES_PARAMS & param,bool zeroOnAllocate,VPHAL_CSPACE ColorSpace,uint32_t ChromaSiting)175 VP_SURFACE* VpAllocator::AllocateVpSurface(MOS_ALLOC_GFXRES_PARAMS ¶m, bool zeroOnAllocate, VPHAL_CSPACE ColorSpace, uint32_t ChromaSiting)
176 {
177 VP_FUNC_CALL();
178 VP_SURFACE *surface = MOS_New(VP_SURFACE);
179 if (nullptr == surface)
180 {
181 return nullptr;
182 }
183 MOS_ZeroMemory(surface, sizeof(VP_SURFACE));
184
185 // Only used for Buffer surface
186 uint32_t bufferWidth = 0;
187 uint32_t bufferHeight = 0;
188
189
190 if (param.Format == Format_Buffer)
191 {
192 bufferWidth = param.dwWidth;
193 bufferHeight = param.dwHeight;
194 param.dwWidth = param.dwWidth * param.dwHeight;
195 param.dwHeight = 1;
196 }
197
198 surface->osSurface = AllocateSurface(param, zeroOnAllocate);
199
200 if (nullptr == surface->osSurface)
201 {
202 MOS_Delete(surface);
203 MT_ERR1(MT_VP_HAL_ALLOC_SURF, MT_CODE_LINE, __LINE__);
204 return nullptr;
205 }
206
207 surface->isResourceOwner = true;
208 surface->ColorSpace = ColorSpace;
209 surface->ChromaSiting = ChromaSiting;
210 surface->SampleType = SAMPLE_PROGRESSIVE; // Hardcode to SAMPLE_PROGRESSIVE for intermedia surface. Set to correct value for DI later.
211
212 surface->rcSrc.left = surface->rcSrc.top = 0;
213 surface->rcSrc.right = surface->osSurface->dwWidth;
214 surface->rcSrc.bottom = surface->osSurface->dwHeight;
215 surface->rcDst = surface->rcSrc;
216 surface->rcMaxSrc = surface->rcSrc;
217
218
219 if (param.Format == Format_Buffer)
220 {
221 surface->bufferWidth = bufferWidth;
222 surface->bufferHeight = bufferHeight;
223 }
224
225 return surface;
226 }
227
228 // Allocate vp surface from vphalSurf. Reuse the resource in vphalSurf.
AllocateVpSurface(VPHAL_SURFACE & vphalSurf)229 VP_SURFACE *VpAllocator::AllocateVpSurface(VPHAL_SURFACE &vphalSurf)
230 {
231 VP_FUNC_CALL();
232 if (Mos_ResourceIsNull(&vphalSurf.OsResource))
233 {
234 return nullptr;
235 }
236
237 VP_SURFACE *surf = MOS_New(VP_SURFACE);
238
239 if (nullptr == surf)
240 {
241 return nullptr;
242 }
243
244 surf->osSurface = MOS_New(MOS_SURFACE);
245 if (nullptr == surf->osSurface)
246 {
247 MOS_Delete(surf);
248 return nullptr;
249 }
250
251 surf->isResourceOwner = false;
252 surf->Clean();
253
254 // Initialize the mos surface in vp surface structure.
255 MOS_SURFACE &osSurface = *surf->osSurface;
256 MOS_ZeroMemory(&osSurface, sizeof(MOS_SURFACE));
257
258 // Set input parameters dwArraySlice, dwMipSlice and S3dChannel if needed later.
259 osSurface.Format = vphalSurf.Format;
260 osSurface.OsResource = vphalSurf.OsResource;
261
262 if (MOS_FAILED(m_allocator->GetSurfaceInfo(&osSurface.OsResource, &osSurface)))
263 {
264 MOS_Delete(surf->osSurface);
265 MOS_Delete(surf);
266 return nullptr;
267 }
268
269 // Align the format with vphal surface. Some format need be remapped in vphal surface.
270 // For example, format_420O is mapped to Format_NV12 in VpHal.
271 // But it is mapped to several different Formats in CodecHal under different conditions.
272 osSurface.Format = vphalSurf.Format;
273
274 // Add offset info
275 osSurface.dwOffset = vphalSurf.dwOffset;
276 osSurface.YPlaneOffset.iSurfaceOffset = vphalSurf.YPlaneOffset.iSurfaceOffset;
277 osSurface.YPlaneOffset.iXOffset = vphalSurf.YPlaneOffset.iXOffset;
278 osSurface.YPlaneOffset.iYOffset = vphalSurf.YPlaneOffset.iYOffset;
279 if (IS_RGB32_FORMAT(osSurface.Format) ||
280 IS_RGB16_FORMAT(osSurface.Format) ||
281 IS_RGB64_FORMAT(osSurface.Format) ||
282 osSurface.Format == Format_RGB ||
283 osSurface.Format == Format_Y410)
284 {
285 osSurface.dwOffset = vphalSurf.dwOffset;
286 osSurface.YPlaneOffset.iSurfaceOffset = vphalSurf.YPlaneOffset.iSurfaceOffset;
287 osSurface.YPlaneOffset.iXOffset = vphalSurf.YPlaneOffset.iXOffset;
288 osSurface.YPlaneOffset.iYOffset = vphalSurf.YPlaneOffset.iYOffset;
289 }
290 else // YUV or PL3_RGB
291 {
292 // Get Y plane information (plane offset, X/Y offset)
293 osSurface.dwOffset = vphalSurf.dwOffset;
294 osSurface.YPlaneOffset.iSurfaceOffset = vphalSurf.YPlaneOffset.iSurfaceOffset;
295 osSurface.YPlaneOffset.iXOffset = vphalSurf.YPlaneOffset.iXOffset;
296 osSurface.YPlaneOffset.iYOffset = vphalSurf.YPlaneOffset.iYOffset;
297 osSurface.YPlaneOffset.iLockSurfaceOffset = vphalSurf.YPlaneOffset.iLockSurfaceOffset;
298
299 // Get U/UV plane information (plane offset, X/Y offset)
300 osSurface.UPlaneOffset.iSurfaceOffset = vphalSurf.UPlaneOffset.iSurfaceOffset;
301 osSurface.UPlaneOffset.iXOffset = vphalSurf.UPlaneOffset.iXOffset;
302 osSurface.UPlaneOffset.iYOffset = vphalSurf.UPlaneOffset.iYOffset;
303 osSurface.UPlaneOffset.iLockSurfaceOffset = vphalSurf.UPlaneOffset.iLockSurfaceOffset;
304
305 // Get V plane information (plane offset, X/Y offset)
306 osSurface.VPlaneOffset.iSurfaceOffset = vphalSurf.VPlaneOffset.iSurfaceOffset;
307 osSurface.VPlaneOffset.iXOffset = vphalSurf.VPlaneOffset.iXOffset;
308 osSurface.VPlaneOffset.iYOffset = vphalSurf.VPlaneOffset.iYOffset;
309 osSurface.VPlaneOffset.iLockSurfaceOffset = vphalSurf.VPlaneOffset.iLockSurfaceOffset;
310 }
311
312 // Initialize other parameters in vp surface according to vphal surface.
313 surf->ColorSpace = vphalSurf.ColorSpace;
314 surf->ExtendedGamut = vphalSurf.ExtendedGamut;
315 surf->Palette = vphalSurf.Palette;
316 surf->bQueryVariance = vphalSurf.bQueryVariance;
317 surf->FrameID = vphalSurf.FrameID;
318 surf->uFwdRefCount = vphalSurf.uFwdRefCount;
319 surf->uBwdRefCount = vphalSurf.uBwdRefCount;
320 surf->pFwdRef = vphalSurf.pFwdRef;
321 surf->pBwdRef = vphalSurf.pBwdRef;
322 surf->SurfType = vphalSurf.SurfType;
323 surf->SampleType = vphalSurf.SampleType;
324 surf->ChromaSiting = vphalSurf.ChromaSiting;
325 surf->rcSrc = vphalSurf.rcSrc;
326 surf->rcDst = vphalSurf.rcDst;
327 surf->rcMaxSrc = vphalSurf.rcMaxSrc;
328
329 if (MOS_FAILED(SetMmcFlags(osSurface)))
330 {
331 VP_PUBLIC_ASSERTMESSAGE("Set mmc flags failed during AllocateVpSurface!");
332 DestroyVpSurface(surf);
333 return nullptr;
334 }
335 return surf;
336 }
337
338 // Allocate vp surface from vpSurfSrc. Reuse the resource in vpSurfSrc.
AllocateVpSurface(VP_SURFACE & vpSurfSrc)339 VP_SURFACE *VpAllocator::AllocateVpSurface(VP_SURFACE &vpSurfSrc)
340 {
341 VP_FUNC_CALL();
342 if (nullptr == vpSurfSrc.osSurface || Mos_ResourceIsNull(&vpSurfSrc.osSurface->OsResource))
343 {
344 return nullptr;
345 }
346
347 VP_SURFACE *surf = MOS_New(VP_SURFACE);
348
349 if (nullptr == surf)
350 {
351 return nullptr;
352 }
353
354 MOS_SURFACE *osSurface = MOS_New(MOS_SURFACE);
355
356 if (nullptr == osSurface)
357 {
358 MOS_Delete(surf);
359 return nullptr;
360 }
361
362 *osSurface = *vpSurfSrc.osSurface;
363 *surf = vpSurfSrc;
364
365 surf->osSurface = osSurface;
366 surf->isResourceOwner = false;
367
368 return surf;
369 }
370
371 // 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)372 VP_SURFACE *VpAllocator::AllocateVpSurface(MOS_SURFACE &osSurf,
373 VPHAL_CSPACE colorSpace, uint32_t chromaSiting, RECT rcSrc, RECT rcDst, VPHAL_SURFACE_TYPE SurfType, bool updatePlaneOffset)
374 {
375 VP_FUNC_CALL();
376 if (Mos_ResourceIsNull(&osSurf.OsResource))
377 {
378 return nullptr;
379 }
380
381 VP_SURFACE *surf = MOS_New(VP_SURFACE);
382
383 if (nullptr == surf)
384 {
385 return nullptr;
386 }
387
388 MOS_SURFACE *osSurface = MOS_New(MOS_SURFACE);
389
390 if (nullptr == osSurface)
391 {
392 MOS_Delete(surf);
393 return nullptr;
394 }
395
396 *osSurface = osSurf;
397 if (updatePlaneOffset)
398 {
399 UpdateSurfacePlaneOffset(*osSurface);
400 }
401
402 MOS_ZeroMemory(surf, sizeof(VP_SURFACE));
403 surf->osSurface = osSurface;
404 surf->isResourceOwner = false;
405 surf->ColorSpace = colorSpace; //!< Color Space
406 surf->ChromaSiting = chromaSiting; //!< ChromaSiting
407 surf->rcSrc = rcSrc; //!< Source rectangle
408 surf->rcDst = rcDst; //!< Destination rectangle
409 surf->rcMaxSrc = rcSrc; //!< Max source rectangle
410 surf->SurfType = SurfType; //!< Surface type (context). Not in use for internal surface
411 surf->SampleType = SAMPLE_PROGRESSIVE; //!< Interlaced/Progressive sample type.
412
413 return surf;
414 }
415
416 // Allocate empty vp surface.
AllocateVpSurface()417 VP_SURFACE *VpAllocator::AllocateVpSurface()
418 {
419 VP_FUNC_CALL();
420 // Allocate VpSurface without resource.
421 VP_SURFACE *surf = MOS_New(VP_SURFACE);
422
423 if (nullptr == surf)
424 {
425 return nullptr;
426 }
427
428 MOS_SURFACE *osSurface = MOS_New(MOS_SURFACE);
429
430 if (nullptr == osSurface)
431 {
432 MOS_Delete(surf);
433 return nullptr;
434 }
435
436 surf->osSurface = osSurface;
437 surf->isResourceOwner = false;
438 surf->Clean();
439
440 return surf;
441 }
442
443 // Copy surface info from src to dst. dst shares the resource of src.
CopyVpSurface(VP_SURFACE & dst,VP_SURFACE & src)444 MOS_STATUS VpAllocator::CopyVpSurface(VP_SURFACE &dst, VP_SURFACE &src)
445 {
446 VP_FUNC_CALL();
447 if (nullptr == dst.osSurface || nullptr == src.osSurface || dst.isResourceOwner)
448 {
449 return MOS_STATUS_INVALID_PARAMETER;
450 }
451
452 MOS_SURFACE &osSurface = *dst.osSurface;
453 osSurface = *src.osSurface;
454 dst = src;
455
456 dst.osSurface = &osSurface;
457 dst.isResourceOwner = false;
458
459 return MOS_STATUS_SUCCESS;
460 }
461
DestroyVpSurface(VP_SURFACE * & surface,bool deferredDestroyed,MOS_GFXRES_FREE_FLAGS flags)462 MOS_STATUS VpAllocator::DestroyVpSurface(VP_SURFACE* &surface, bool deferredDestroyed, MOS_GFXRES_FREE_FLAGS flags)
463 {
464 VP_FUNC_CALL();
465 MOS_STATUS status = MOS_STATUS_SUCCESS;
466 if (nullptr == surface)
467 {
468 return status;
469 }
470
471 if (surface && nullptr == surface->osSurface)
472 {
473 // VP_SURFACE should always be allocated by interface in VpAllocator,
474 // which will ensure nullptr != surface->osSurface.
475 VP_PUBLIC_NORMALMESSAGE("Surfaces already been deleted, return status!");
476 return status;
477 }
478
479 if (deferredDestroyed)
480 {
481 m_recycler.push_back(surface);
482 surface = nullptr;
483 return MOS_STATUS_SUCCESS;
484 }
485
486 if (surface->isResourceOwner)
487 {
488 #if !EMUL
489 MT_LOG5(MT_VP_HAL_DESTROY_SURF, MT_NORMAL,
490 MT_VP_HAL_SURF_ALLOC_PARAM_PTR, *(int64_t *)(&surface),
491 MT_VP_HAL_SURF_ALLOC_PARAM_MOS_SURF_PTR, *(int64_t *)(&surface->osSurface),
492 MT_VP_HAL_SURF_ALLOC_PARAM_IS_RES_OWNER, surface->isResourceOwner,
493 MT_VP_HAL_SURF_ALLOC_PARAM_HANDLE, static_cast<int64_t>(surface->GetAllocationHandle(m_osInterface)),
494 MT_VP_HAL_SURF_ALLOC_PARAM_SIZE, static_cast<int64_t>(surface->osSurface->OsResource.pGmmResInfo ? surface->osSurface->OsResource.pGmmResInfo->GetSizeAllocation() : 0));
495 VP_PUBLIC_NORMALMESSAGE(
496 "VP_HAL_DESTROY_SURF. "
497 "VP_HAL_Surface: %p, "
498 "VP_HAL_OsSurface: %p, "
499 "VP_HAL_isResourceOwner: %d, "
500 "VP_HAL_Surface_Handle: 0x%llx, "
501 "VP_HAL_Surface_Size: 0x%llx",
502 surface,
503 surface->osSurface,
504 surface->isResourceOwner ? 1 : 0,
505 surface->GetAllocationHandle(m_osInterface),
506 surface->osSurface->OsResource.pGmmResInfo ? surface->osSurface->OsResource.pGmmResInfo->GetSizeAllocation() : 0);
507
508 int64_t currentSize = static_cast<int64_t>(surface->osSurface->OsResource.pGmmResInfo ? surface->osSurface->OsResource.pGmmResInfo->GetSizeAllocation() : 0);
509 m_totalSize = m_totalSize - currentSize;
510 #endif
511 status = DestroySurface(surface->osSurface, flags);
512 }
513 else
514 {
515 MOS_Delete(surface->osSurface);
516 }
517
518 MOS_Delete(surface);
519 return status;
520 }
521
Lock(MOS_RESOURCE * resource,MOS_LOCK_PARAMS * lockFlag)522 void* VpAllocator::Lock(MOS_RESOURCE* resource, MOS_LOCK_PARAMS *lockFlag)
523 {
524 VP_FUNC_CALL();
525 if (!m_allocator)
526 return nullptr;
527
528 return m_allocator->Lock(resource, lockFlag);
529 }
530
LockResourceForWrite(MOS_RESOURCE * resource)531 void* VpAllocator::LockResourceForWrite(MOS_RESOURCE *resource)
532 {
533 VP_FUNC_CALL();
534 MOS_LOCK_PARAMS lockFlags;
535 MOS_ZeroMemory(&lockFlags, sizeof(MOS_LOCK_PARAMS));
536 lockFlags.WriteOnly = 1;
537
538 if (!m_allocator)
539 return nullptr;
540
541 return m_allocator->Lock(resource, &lockFlags);
542 }
543
LockResourceWithNoOverwrite(MOS_RESOURCE * resource)544 void* VpAllocator::LockResourceWithNoOverwrite(MOS_RESOURCE *resource)
545 {
546 VP_FUNC_CALL();
547 MOS_LOCK_PARAMS lockFlags;
548 MOS_ZeroMemory(&lockFlags, sizeof(MOS_LOCK_PARAMS));
549 lockFlags.WriteOnly = 1;
550 lockFlags.NoOverWrite = 1;
551
552 if (!m_allocator)
553 return nullptr;
554
555 return m_allocator->Lock(resource, &lockFlags);
556 }
557
LockResourceForRead(MOS_RESOURCE * resource)558 void* VpAllocator::LockResourceForRead(MOS_RESOURCE *resource)
559 {
560 VP_FUNC_CALL();
561 MOS_LOCK_PARAMS lockFlags;
562 MOS_ZeroMemory(&lockFlags, sizeof(MOS_LOCK_PARAMS));
563 lockFlags.ReadOnly = 1;
564
565 if (!m_allocator)
566 return nullptr;
567
568 return m_allocator->Lock(resource, &lockFlags);
569 }
570
UnLock(MOS_RESOURCE * resource)571 MOS_STATUS VpAllocator::UnLock(MOS_RESOURCE *resource)
572 {
573 VP_FUNC_CALL();
574 VP_PUBLIC_CHK_NULL_RETURN(m_allocator);
575
576 return m_allocator->UnLock(resource);
577 }
578
SkipResourceSync(MOS_RESOURCE * resource)579 MOS_STATUS VpAllocator::SkipResourceSync(MOS_RESOURCE *resource)
580 {
581 VP_FUNC_CALL();
582 VP_PUBLIC_CHK_NULL_RETURN(m_allocator);
583
584 return m_allocator->SkipResourceSync(resource);
585 }
586
GetSurfaceInfo(VPHAL_SURFACE * surface,VPHAL_GET_SURFACE_INFO & info)587 MOS_STATUS VpAllocator::GetSurfaceInfo(VPHAL_SURFACE *surface, VPHAL_GET_SURFACE_INFO &info)
588 {
589 VP_FUNC_CALL();
590 MOS_MEMCOMP_STATE mmcMode = MOS_MEMCOMP_DISABLED;
591 MOS_SURFACE resDetails;
592
593 VP_PUBLIC_CHK_NULL_RETURN(m_mmc);
594 VP_PUBLIC_CHK_NULL_RETURN(m_allocator);
595 VP_PUBLIC_CHK_NULL_RETURN(surface);
596
597 VP_PUBLIC_ASSERT(!Mos_ResourceIsNull(&surface->OsResource));
598
599 MOS_ZeroMemory(&resDetails, sizeof(MOS_SURFACE));
600 resDetails.dwArraySlice = info.ArraySlice;
601 resDetails.dwMipSlice = info.MipSlice;
602 resDetails.S3dChannel = info.S3dChannel;
603 resDetails.Format = surface->Format;
604
605 VP_PUBLIC_CHK_STATUS_RETURN(m_allocator->GetSurfaceInfo(&surface->OsResource, &resDetails));
606
607 // Format_420O is mapped to Format_NV12 in VpHal here.
608 // But it is mapped to several different Formats in CodecHal under different conditions.
609 if (resDetails.Format == Format_420O)
610 {
611 resDetails.Format = Format_NV12;
612 }
613
614 // Get resource information
615 surface->dwWidth = resDetails.dwWidth;
616 surface->dwHeight = resDetails.dwHeight;
617 surface->dwPitch = resDetails.dwPitch;
618 surface->dwYPitch = resDetails.dwYPitch;
619 surface->dwUPitch = resDetails.dwUPitch;
620 surface->dwVPitch = resDetails.dwVPitch;
621 surface->dwSlicePitch = resDetails.dwSlicePitch;
622 surface->dwDepth = resDetails.dwDepth;
623 surface->TileType = resDetails.TileType;
624 surface->TileModeGMM = resDetails.TileModeGMM;
625 surface->bGMMTileEnabled = resDetails.bGMMTileEnabled;
626 surface->bOverlay = resDetails.bOverlay ? true : false;
627 surface->bFlipChain = resDetails.bFlipChain ? true : false;
628 surface->Format = resDetails.Format;
629 surface->bCompressible = resDetails.bCompressible ? true : false;
630 surface->bIsCompressed = resDetails.bIsCompressed ? true : false;
631 surface->CacheSetting = resDetails.CacheSetting;
632
633 if (IS_RGB32_FORMAT(surface->Format) ||
634 IS_RGB16_FORMAT(surface->Format) ||
635 IS_RGB64_FORMAT(surface->Format) ||
636 surface->Format == Format_RGB ||
637 surface->Format == Format_Y410)
638 {
639 surface->dwOffset = resDetails.RenderOffset.RGB.BaseOffset;
640 surface->YPlaneOffset.iSurfaceOffset = resDetails.RenderOffset.RGB.BaseOffset;
641 surface->YPlaneOffset.iXOffset = resDetails.RenderOffset.RGB.XOffset;
642 surface->YPlaneOffset.iYOffset = resDetails.RenderOffset.RGB.YOffset;
643 }
644 else // YUV or PL3_RGB
645 {
646 // Get Y plane information (plane offset, X/Y offset)
647 surface->dwOffset = resDetails.RenderOffset.YUV.Y.BaseOffset;
648 surface->YPlaneOffset.iSurfaceOffset = resDetails.RenderOffset.YUV.Y.BaseOffset;
649 surface->YPlaneOffset.iXOffset = resDetails.RenderOffset.YUV.Y.XOffset;
650 surface->YPlaneOffset.iYOffset = resDetails.RenderOffset.YUV.Y.YOffset;
651 surface->YPlaneOffset.iLockSurfaceOffset = resDetails.LockOffset.YUV.Y;
652
653 // Get U/UV plane information (plane offset, X/Y offset)
654 surface->UPlaneOffset.iSurfaceOffset = resDetails.RenderOffset.YUV.U.BaseOffset;
655 surface->UPlaneOffset.iXOffset = resDetails.RenderOffset.YUV.U.XOffset;
656 surface->UPlaneOffset.iYOffset = resDetails.RenderOffset.YUV.U.YOffset;
657 surface->UPlaneOffset.iLockSurfaceOffset = resDetails.LockOffset.YUV.U;
658
659 // Get V plane information (plane offset, X/Y offset)
660 surface->VPlaneOffset.iSurfaceOffset = resDetails.RenderOffset.YUV.V.BaseOffset;
661 surface->VPlaneOffset.iXOffset = resDetails.RenderOffset.YUV.V.XOffset;
662 surface->VPlaneOffset.iYOffset = resDetails.RenderOffset.YUV.V.YOffset;
663 surface->VPlaneOffset.iLockSurfaceOffset = resDetails.LockOffset.YUV.V;
664 }
665
666 VP_PUBLIC_CHK_STATUS_RETURN(m_mmc->GetResourceMmcState(&surface->OsResource, mmcMode));
667 if (mmcMode &&
668 (surface->TileType == MOS_TILE_Y ||
669 surface->TileType == MOS_TILE_YS))
670 {
671 surface->bCompressible = true;
672 surface->CompressionMode = (mmcMode == MOS_MEMCOMP_MC) ? MOS_MMC_MC :
673 (mmcMode == MOS_MEMCOMP_RC) ? MOS_MMC_RC : MOS_MMC_DISABLED;
674 }
675 else
676 {
677 surface->CompressionMode = MOS_MMC_DISABLED;
678 }
679
680 return MOS_STATUS_SUCCESS;
681 }
682
GetSurfaceInfo(VP_SURFACE * surface,VPHAL_GET_SURFACE_INFO & info)683 MOS_STATUS VpAllocator::GetSurfaceInfo(VP_SURFACE* surface, VPHAL_GET_SURFACE_INFO& info)
684 {
685 VP_FUNC_CALL();
686 MOS_MEMCOMP_STATE mmcMode = MOS_MEMCOMP_DISABLED;
687 MOS_SURFACE resDetails;
688
689 VP_PUBLIC_CHK_NULL_RETURN(m_mmc);
690 VP_PUBLIC_CHK_NULL_RETURN(m_allocator);
691 VP_PUBLIC_CHK_NULL_RETURN(surface);
692 VP_PUBLIC_CHK_NULL_RETURN(surface->osSurface);
693
694 if (Mos_ResourceIsNull(&surface->osSurface->OsResource))
695 {
696 VP_PUBLIC_NORMALMESSAGE("invalid resource handle");
697 return MOS_STATUS_INVALID_HANDLE;
698 }
699
700 MOS_ZeroMemory(&resDetails, sizeof(MOS_SURFACE));
701 resDetails.dwArraySlice = info.ArraySlice;
702 resDetails.dwMipSlice = info.MipSlice;
703 resDetails.S3dChannel = info.S3dChannel;
704 resDetails.Format = surface->osSurface->Format;
705
706 VP_PUBLIC_CHK_STATUS_RETURN(m_allocator->GetSurfaceInfo(&surface->osSurface->OsResource, &resDetails));
707
708 // Format_420O is mapped to Format_NV12 in VpHal here.
709 // But it is mapped to several different Formats in CodecHal under different conditions.
710 if (resDetails.Format == Format_420O)
711 {
712 resDetails.Format = Format_NV12;
713 }
714
715 // Get resource information
716 surface->osSurface->dwWidth = resDetails.dwWidth;
717 surface->osSurface->dwHeight = resDetails.dwHeight;
718 surface->osSurface->dwPitch = resDetails.dwPitch;
719 surface->osSurface->dwSlicePitch = resDetails.dwSlicePitch;
720 surface->osSurface->dwDepth = resDetails.dwDepth;
721 surface->osSurface->TileType = resDetails.TileType;
722 surface->osSurface->TileModeGMM = resDetails.TileModeGMM;
723 surface->osSurface->bGMMTileEnabled = resDetails.bGMMTileEnabled;
724 surface->osSurface->bOverlay = resDetails.bOverlay ? true : false;
725 surface->osSurface->bFlipChain = resDetails.bFlipChain ? true : false;
726 surface->osSurface->Format = resDetails.Format;
727 surface->osSurface->bCompressible = resDetails.bCompressible ? true : false;
728 surface->osSurface->bIsCompressed = resDetails.bIsCompressed ? true : false;
729 surface->osSurface->CacheSetting = resDetails.CacheSetting;
730
731 return MOS_STATUS_SUCCESS;
732 }
733
AllocParamsInitType(MOS_ALLOC_GFXRES_PARAMS & allocParams,PVPHAL_SURFACE surface,MOS_GFXRES_TYPE defaultResType,MOS_TILE_TYPE defaultTileType)734 MOS_STATUS VpAllocator::AllocParamsInitType(
735 MOS_ALLOC_GFXRES_PARAMS &allocParams,
736 PVPHAL_SURFACE surface,
737 MOS_GFXRES_TYPE defaultResType,
738 MOS_TILE_TYPE defaultTileType)
739 {
740 VP_FUNC_CALL();
741 VP_PUBLIC_CHK_NULL_RETURN(surface);
742
743 #if !EMUL && !LINUX && !ANDROID
744 // Need to reallocate surface according to expected tiletype instead of tiletype of the surface what we have
745 if ( surface != nullptr &&
746 surface->OsResource.pGmmResInfo != nullptr &&
747 surface->TileType == defaultTileType)
748 {
749 // Reallocate but use same tile type and resource type as current
750 allocParams.TileType = surface->OsResource.TileType;
751 allocParams.Type = surface->OsResource.ResType;
752 }
753 else
754 #endif
755 {
756 // First time allocation. Caller must specify default params
757 allocParams.Type = defaultResType;
758 allocParams.TileType = defaultTileType;
759 }
760
761 return MOS_STATUS_SUCCESS;
762 }
763
AllocParamsInitType(MOS_ALLOC_GFXRES_PARAMS & allocParams,VP_SURFACE * surface,MOS_GFXRES_TYPE defaultResType,MOS_TILE_TYPE defaultTileType)764 MOS_STATUS VpAllocator::AllocParamsInitType(
765 MOS_ALLOC_GFXRES_PARAMS &allocParams,
766 VP_SURFACE *surface,
767 MOS_GFXRES_TYPE defaultResType,
768 MOS_TILE_TYPE defaultTileType)
769 {
770 VP_FUNC_CALL();
771 // Need to reallocate surface according to expected tiletype instead of tiletype of the surface what we have
772 if (surface != nullptr &&
773 surface->osSurface != nullptr &&
774 !Mos_ResourceIsNull(&surface->osSurface->OsResource) &&
775 surface->osSurface->TileType == defaultTileType)
776 {
777 // Reallocate but use same tile type and resource type as current
778 allocParams.TileType = surface->osSurface->TileType;
779 allocParams.Type = surface->osSurface->Type;
780 }
781 else
782 {
783 // First time allocation. Caller must specify default params
784 allocParams.Type = defaultResType;
785 allocParams.TileType = defaultTileType;
786 }
787
788 return MOS_STATUS_SUCCESS;
789 }
790
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,void * systemMemory,uint32_t depth)791 MOS_STATUS VpAllocator::ReAllocateSurface(
792 VP_SURFACE *&surface,
793 PCCHAR surfaceName,
794 MOS_FORMAT format,
795 MOS_GFXRES_TYPE defaultResType,
796 MOS_TILE_TYPE defaultTileType,
797 uint32_t width,
798 uint32_t height,
799 bool compressible,
800 MOS_RESOURCE_MMC_MODE compressionMode,
801 bool &allocated,
802 bool zeroOnAllocate,
803 bool deferredDestroyed,
804 MOS_HW_RESOURCE_DEF resUsageType,
805 MOS_TILE_MODE_GMM tileModeByForce,
806 Mos_MemPool memType,
807 bool isNotLockable,
808 void * systemMemory,
809 uint32_t depth)
810 {
811 VP_FUNC_CALL();
812 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
813 MOS_ALLOC_GFXRES_PARAMS allocParams = {};
814 MOS_GFXRES_FREE_FLAGS resFreeFlags = {0};
815
816 allocated = false;
817
818 //---------------------------------
819 VP_PUBLIC_CHK_NULL_RETURN(m_allocator);
820
821 if (!m_mmc->IsMmcEnabled() ||
822 !m_mmc->IsCompressibelSurfaceSupported())
823 {
824 compressible = 0;
825 compressionMode = MOS_MMC_DISABLED;
826 }
827 //---------------------------------
828
829 auto surfInfoCheck = [=](VP_SURFACE *&surface) -> bool
830 {
831 return (surface->osSurface->Format == format) &&
832 ((surface->osSurface->bCompressible != 0) == compressible) &&
833 (surface->osSurface->CompressionMode == compressionMode) &&
834 (surface->osSurface->TileType == defaultTileType ||
835 MOS_TILE_Y == defaultTileType &&
836 IS_Y_MAJOR_TILE_FORMAT(surface->osSurface->TileType)) &&
837 ((Format_Buffer == format &&
838 surface->bufferWidth == width &&
839 surface->bufferHeight == height) ||
840 (Format_Buffer != format &&
841 surface->osSurface->dwWidth == width &&
842 surface->osSurface->dwHeight == height) );
843 };
844
845 // compressible should be compared with bCompressible since it is inited by bCompressible in previous call
846 // TileType of surface should be compared since we need to reallocate surface if TileType changes
847 if (surface &&
848 surface->osSurface &&
849 !Mos_ResourceIsNull(&surface->osSurface->OsResource) &&
850 surfInfoCheck(surface) )
851 {
852 return eStatus;
853 }
854
855 // reuse the allocated buffer if the allocated size was larger than request size when OptimizeCpuTiming is enabled
856 if (m_osInterface->bOptimizeCpuTiming &&
857 surface &&
858 surface->osSurface &&
859 (!Mos_ResourceIsNull(&surface->osSurface->OsResource)) &&
860 (Format_Buffer == format) &&
861 (surface->bufferWidth * surface->bufferHeight >= width * height))
862 {
863 return eStatus;
864 }
865
866 if (surface && nullptr == surface->osSurface)
867 {
868 // VP_SURFACE should always be allocated by interface in VpAllocator,
869 // which will ensure nullptr != surface->osSurface.
870 VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_INVALID_PARAMETER);
871 }
872
873 //if free the compressed surface, need set the sync dealloc flag as 1 for sync dealloc for aux table update
874 if (surface && IsSyncFreeNeededForMMCSurface(surface->osSurface))
875 {
876 resFreeFlags.SynchronousDestroy = 1;
877 VP_PUBLIC_NORMALMESSAGE("Set SynchronousDestroy flag for compressed resource %s", surfaceName);
878 }
879 VP_PUBLIC_CHK_STATUS_RETURN(DestroyVpSurface(surface, deferredDestroyed, resFreeFlags));
880
881 AllocParamsInitType(allocParams, surface, defaultResType, defaultTileType);
882
883 allocParams.dwWidth = width;
884 allocParams.dwHeight = height;
885 allocParams.dwDepth = depth;
886 allocParams.Format = format;
887 allocParams.bIsCompressible = compressible;
888 allocParams.CompressionMode = compressionMode;
889 allocParams.pBufName = surfaceName;
890 allocParams.dwArraySize = 1;
891 allocParams.ResUsageType = resUsageType;
892 allocParams.m_tileModeByForce = tileModeByForce;
893 allocParams.dwMemType = memType;
894 allocParams.Flags.bNotLockable = isNotLockable;
895 allocParams.pSystemMemory = systemMemory;
896
897 surface = AllocateVpSurface(allocParams, zeroOnAllocate);
898 VP_PUBLIC_CHK_NULL_RETURN(surface);
899 VP_PUBLIC_CHK_NULL_RETURN(surface->osSurface);
900 if (Mos_ResourceIsNull(&surface->osSurface->OsResource))
901 {
902 VP_PUBLIC_CHK_NULL_RETURN(nullptr);
903 }
904
905 if (!surfInfoCheck(surface))
906 {
907 VP_PUBLIC_ASSERTMESSAGE("Allocated surface is not matched with allocating parameter.");
908 VP_PUBLIC_ASSERTMESSAGE("Allocated surface : format %d, compressible %d, compressionMode %d, tileType %d, bufferWidth %d, bufferHeight %d, width %d, height %d",
909 surface->osSurface->Format,
910 surface->osSurface->bCompressible,
911 surface->osSurface->CompressionMode,
912 surface->osSurface->TileType,
913 surface->bufferWidth,
914 surface->bufferHeight,
915 surface->osSurface->dwWidth,
916 surface->osSurface->dwHeight);
917 VP_PUBLIC_ASSERTMESSAGE("Parameter to allocate : format %d, compressible %d, compressionMode %d, tileType %d, width %d, height %d",
918 format,
919 compressible,
920 compressionMode,
921 defaultTileType,
922 width,
923 height);
924 }
925
926 MT_LOG7(MT_VP_HAL_REALLOC_SURF, MT_NORMAL, MT_VP_HAL_INTER_SURF_TYPE, surfaceName ? *((int64_t*)surfaceName) : 0,
927 MT_SURF_WIDTH, width, MT_SURF_HEIGHT, height, MT_SURF_MOS_FORMAT, format, MT_SURF_TILE_MODE, surface->osSurface->TileModeGMM,
928 MT_SURF_COMP_ABLE, surface->osSurface->bCompressible, MT_SURF_COMP_MODE, surface->osSurface->CompressionMode);
929
930 #if !EMUL
931 MT_LOG6(MT_VP_HAL_REALLOC_SURF, MT_NORMAL,
932 MT_VP_HAL_SURF_ALLOC_PARAM_PTR, *(int64_t *)(&surface),
933 MT_VP_HAL_SURF_ALLOC_PARAM_MOS_SURF_PTR, *(int64_t *)(&surface->osSurface),
934 MT_VP_HAL_SURF_ALLOC_PARAM_IS_RES_OWNER, surface->isResourceOwner,
935 MT_VP_HAL_SURF_ALLOC_PARAM_HANDLE, static_cast<int64_t>(surface->GetAllocationHandle(m_osInterface)),
936 MT_VP_HAL_SURF_ALLOC_PARAM_SIZE, static_cast<int64_t>(surface->osSurface->OsResource.pGmmResInfo ? surface->osSurface->OsResource.pGmmResInfo->GetSizeAllocation() : 0),
937 MT_VP_HAL_SURF_ALLOC_PARAM_NAME, surfaceName ? *((int64_t *)surfaceName) : 0);
938 VP_PUBLIC_NORMALMESSAGE(
939 "VP_HAL_REALLOC_SURF. "
940 "VP_HAL_Surface: %p, "
941 "VP_HAL_OsSurface: %p, "
942 "VP_HAL_isResourceOwner: %d, "
943 "VP_HAL_Surface_Handle: 0x%llx, "
944 "VP_HAL_Surface_Size: 0x%llx, "
945 "VP_HAL_Surface_Name: %s",
946 surface,
947 surface->osSurface,
948 surface->isResourceOwner ? 1 : 0,
949 surface->GetAllocationHandle(m_osInterface),
950 surface->osSurface->OsResource.pGmmResInfo ? surface->osSurface->OsResource.pGmmResInfo->GetSizeAllocation() : 0,
951 surfaceName ? surfaceName : "");
952 int64_t currentSize = static_cast<int64_t>(surface->osSurface->OsResource.pGmmResInfo ? surface->osSurface->OsResource.pGmmResInfo->GetSizeAllocation() : 0);
953 m_totalSize = m_totalSize + currentSize;
954 m_peakSize = m_peakSize > m_totalSize ? m_peakSize : m_totalSize;
955 #endif
956 allocated = true;
957 return MOS_STATUS_SUCCESS;
958 }
959
960 // for debug purpose
961 #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)962 MOS_STATUS VpAllocator::ReAllocateSurface(
963 PVPHAL_SURFACE surface,
964 PCCHAR surfaceName,
965 MOS_FORMAT format,
966 MOS_GFXRES_TYPE defaultResType,
967 MOS_TILE_TYPE defaultTileType,
968 uint32_t width,
969 uint32_t height,
970 bool compressible,
971 MOS_RESOURCE_MMC_MODE compressionMode,
972 bool * allocated,
973 MOS_HW_RESOURCE_DEF resUsageType,
974 MOS_TILE_MODE_GMM tileModeByForce)
975 {
976 VP_FUNC_CALL();
977 MOS_STATUS eStatus;
978 VPHAL_GET_SURFACE_INFO info;
979 MOS_ALLOC_GFXRES_PARAMS allocParams;
980 MOS_GFXRES_FREE_FLAGS resFreeFlags = {0};
981
982 //---------------------------------
983 VP_PUBLIC_ASSERT(&surface->OsResource);
984 //---------------------------------
985
986 eStatus = MOS_STATUS_SUCCESS;
987 *allocated = false;
988
989 // compressible should be compared with compressible since it is inited by compressible in previous call
990 // TileType of surface should be compared since we need to reallocate surface if TileType changes
991 if (!Mos_ResourceIsNull(&surface->OsResource) &&
992 (surface->dwWidth == width) &&
993 (surface->dwHeight == height) &&
994 (surface->Format == format) &&
995 (surface->bCompressible == compressible) &&
996 (surface->CompressionMode == compressionMode) &&
997 (surface->TileType == defaultTileType))
998 {
999 return eStatus;
1000 }
1001
1002 // reuse the allocated buffer if the allocated size was larger than request size when OptimizeCpuTiming is enabled
1003 if (m_osInterface->bOptimizeCpuTiming &&
1004 (!Mos_ResourceIsNull(&surface->OsResource)) &&
1005 (Format_Buffer == format) &&
1006 (surface->dwWidth * surface->dwHeight >= width * height))
1007 {
1008 return eStatus;
1009 }
1010
1011 MOS_ZeroMemory(&allocParams, sizeof(MOS_ALLOC_GFXRES_PARAMS));
1012
1013 VpHal_AllocParamsInitType(&allocParams, surface, defaultResType, defaultTileType);
1014
1015 allocParams.dwWidth = width;
1016 allocParams.dwHeight = height;
1017 allocParams.Format = format;
1018 allocParams.bIsCompressible = compressible;
1019 allocParams.CompressionMode = compressionMode;
1020 allocParams.pBufName = surfaceName;
1021 allocParams.dwArraySize = 1;
1022 allocParams.ResUsageType = resUsageType;
1023 allocParams.m_tileModeByForce = tileModeByForce;
1024
1025 VP_PUBLIC_CHK_STATUS_RETURN(DestroyResource(&surface->OsResource));
1026
1027 // Allocate surface
1028 VP_PUBLIC_CHK_STATUS_RETURN(AllocateResource(&surface->OsResource, allocParams));
1029
1030 // Get surface information
1031 MOS_ZeroMemory(&info, sizeof(VPHAL_GET_SURFACE_INFO));
1032
1033 // Pre-set to get surface info
1034 surface->Format = format;
1035
1036 VP_PUBLIC_CHK_STATUS_RETURN(GetSurfaceInfo(surface, info));
1037
1038 *allocated = true;
1039
1040 VP_PUBLIC_ASSERT(eStatus == MOS_STATUS_SUCCESS);
1041 return eStatus;
1042 }
1043 #endif
1044
OsFillResource(PMOS_RESOURCE osResource,uint32_t size,uint8_t value)1045 MOS_STATUS VpAllocator::OsFillResource(
1046 PMOS_RESOURCE osResource,
1047 uint32_t size,
1048 uint8_t value)
1049 {
1050 VP_FUNC_CALL();
1051 VP_PUBLIC_CHK_NULL_RETURN(m_allocator);
1052 return m_allocator->OsFillResource(osResource, size, value);
1053 }
1054
ReadSurface(PVPHAL_SURFACE surface,uint32_t bpp,uint8_t * dst)1055 MOS_STATUS VpAllocator::ReadSurface (
1056 PVPHAL_SURFACE surface,
1057 uint32_t bpp,
1058 uint8_t *dst)
1059 {
1060 VP_FUNC_CALL();
1061 uint8_t *src = nullptr;
1062 uint8_t *tempSrc = nullptr;
1063 uint8_t *tempDst = nullptr;
1064 uint32_t size = 0;
1065 uint32_t widthInBytes = 0;
1066 uint32_t y = 0;
1067 uint32_t z = 0;
1068
1069 VP_PUBLIC_CHK_NULL_RETURN(m_allocator);
1070
1071 //----------------------------------------------
1072 VP_PUBLIC_ASSERT(surface);
1073 VP_PUBLIC_ASSERT(surface->dwWidth > 0);
1074 VP_PUBLIC_ASSERT(surface->dwHeight > 0);
1075 VP_PUBLIC_ASSERT(surface->dwDepth > 0);
1076 VP_PUBLIC_ASSERT(surface->dwPitch >= surface->dwWidth);
1077 VP_PUBLIC_ASSERT(bpp > 0);
1078 VP_PUBLIC_ASSERT(dst);
1079 VP_PUBLIC_ASSERT(!Mos_ResourceIsNull(&surface->OsResource));
1080 //----------------------------------------------
1081
1082 src = (uint8_t*)LockResourceForRead(&surface->OsResource);
1083 VP_PUBLIC_CHK_NULL_RETURN(src);
1084
1085 // Calculate Size in Bytes
1086 size = surface->dwWidth * surface->dwHeight * surface->dwDepth * bpp/8;
1087 widthInBytes = surface->dwWidth * bpp / 8;
1088 if (surface->dwPitch == widthInBytes)
1089 {
1090 MOS_SecureMemcpy(dst, size, src, size);
1091 }
1092 else
1093 {
1094 tempSrc = src;
1095 tempDst = dst;
1096
1097 for (z = 0; z < surface->dwDepth; z++)
1098 {
1099 for (y = 0; y < surface->dwHeight; y++)
1100 {
1101 MOS_SecureMemcpy(tempDst, widthInBytes, tempSrc, widthInBytes);
1102 tempSrc += surface->dwPitch;
1103 tempDst += widthInBytes;
1104 }
1105 }
1106 }
1107
1108 VP_PUBLIC_CHK_STATUS_RETURN(m_allocator->UnLock(&surface->OsResource));
1109
1110 return MOS_STATUS_SUCCESS;
1111 }
1112
WriteSurface(PVPHAL_SURFACE surface,uint32_t bpp,const uint8_t * src)1113 MOS_STATUS VpAllocator::WriteSurface (
1114 PVPHAL_SURFACE surface,
1115 uint32_t bpp,
1116 const uint8_t *src)
1117 {
1118 VP_FUNC_CALL();
1119 uint8_t *dst = nullptr;
1120 uint8_t *tempSrc = nullptr;
1121 uint8_t *tempDst = nullptr;
1122 uint32_t widthInBytes = 0;
1123 uint32_t size = 0;
1124 uint32_t y = 0;
1125 uint32_t z = 0;
1126
1127 VP_PUBLIC_CHK_NULL_RETURN(m_allocator);
1128
1129 //----------------------------------------------
1130 VP_PUBLIC_ASSERT(surface);
1131 VP_PUBLIC_ASSERT(surface->dwWidth > 0);
1132 VP_PUBLIC_ASSERT(surface->dwHeight > 0);
1133 VP_PUBLIC_ASSERT(surface->dwDepth > 0);
1134 VP_PUBLIC_ASSERT(surface->dwPitch >= surface->dwWidth);
1135 VP_PUBLIC_ASSERT(bpp > 0);
1136 VP_PUBLIC_ASSERT(src);
1137 VP_PUBLIC_ASSERT(!Mos_ResourceIsNull(&surface->OsResource));
1138 //----------------------------------------------
1139
1140 dst = (uint8_t*)LockResourceForWrite(&surface->OsResource);
1141 VP_PUBLIC_CHK_NULL_RETURN(dst);
1142
1143 // Calculate Size in Bytes
1144 size = surface->dwWidth * surface->dwHeight * surface->dwDepth * bpp/8;
1145 widthInBytes = surface->dwWidth * bpp/8;
1146
1147 if (surface->dwPitch == widthInBytes)
1148 {
1149 MOS_SecureMemcpy(dst, size, src, size);
1150 }
1151 else
1152 {
1153 tempSrc = (uint8_t*)src;
1154 tempDst = dst;
1155
1156 for (z = 0; z < surface->dwDepth; z++)
1157 {
1158 for (y = 0; y < surface->dwHeight; y++)
1159 {
1160 MOS_SecureMemcpy(tempDst, widthInBytes, tempSrc, widthInBytes);
1161 tempSrc += widthInBytes;
1162 tempDst += surface->dwPitch;
1163 }
1164 }
1165 }
1166
1167 VP_PUBLIC_CHK_STATUS_RETURN(m_allocator->UnLock(&surface->OsResource));
1168
1169 return MOS_STATUS_SUCCESS;
1170 }
1171
WriteSurface(VP_SURFACE * vpsurface,uint32_t bpp,const uint8_t * src)1172 MOS_STATUS VpAllocator::WriteSurface(VP_SURFACE* vpsurface, uint32_t bpp, const uint8_t* src)
1173 {
1174 VP_FUNC_CALL();
1175 uint8_t* dst = nullptr;
1176 uint8_t* tempSrc = nullptr;
1177 uint8_t* tempDst = nullptr;
1178 uint32_t widthInBytes = 0;
1179 uint32_t size = 0;
1180 uint32_t y = 0;
1181 uint32_t z = 0;
1182 MOS_SURFACE* surface;
1183
1184 VP_PUBLIC_CHK_NULL_RETURN(m_allocator);
1185
1186 //----------------------------------------------
1187 VP_PUBLIC_ASSERT(vpsurface);
1188
1189 surface = vpsurface->osSurface;
1190 VP_PUBLIC_ASSERT(surface);
1191
1192 VP_PUBLIC_ASSERT(surface->dwWidth > 0);
1193 VP_PUBLIC_ASSERT(surface->dwHeight > 0);
1194 VP_PUBLIC_ASSERT(surface->dwDepth > 0);
1195 VP_PUBLIC_ASSERT(surface->dwPitch >= surface->dwWidth);
1196 VP_PUBLIC_ASSERT(bpp > 0);
1197 VP_PUBLIC_ASSERT(src);
1198 VP_PUBLIC_ASSERT(!Mos_ResourceIsNull(&surface->OsResource));
1199 //----------------------------------------------
1200
1201 dst = (uint8_t*)LockResourceForWrite(&surface->OsResource);
1202 VP_PUBLIC_CHK_NULL_RETURN(dst);
1203
1204 // Calculate Size in Bytes
1205 size = surface->dwWidth * surface->dwHeight * surface->dwDepth * bpp / 8;
1206 widthInBytes = surface->dwWidth * bpp / 8;
1207
1208 if (surface->dwPitch == widthInBytes)
1209 {
1210 MOS_SecureMemcpy(dst, size, src, size);
1211 }
1212 else
1213 {
1214 tempSrc = (uint8_t*)src;
1215 tempDst = dst;
1216
1217 for (z = 0; z < surface->dwDepth; z++)
1218 {
1219 for (y = 0; y < surface->dwHeight; y++)
1220 {
1221 MOS_SecureMemcpy(tempDst, widthInBytes, tempSrc, widthInBytes);
1222 tempSrc += widthInBytes;
1223 tempDst += surface->dwPitch;
1224 }
1225 }
1226 }
1227
1228 VP_PUBLIC_CHK_STATUS_RETURN(m_allocator->UnLock(&surface->OsResource));
1229
1230 return MOS_STATUS_SUCCESS;
1231 }
1232
Write1DSurface(VP_SURFACE * vpsurface,const uint8_t * src,uint32_t srcSize)1233 MOS_STATUS VpAllocator::Write1DSurface(VP_SURFACE* vpsurface, const uint8_t* src, uint32_t srcSize)
1234 {
1235 VP_FUNC_CALL();
1236 VP_PUBLIC_CHK_NULL_RETURN(vpsurface);
1237 VP_PUBLIC_CHK_NULL_RETURN(vpsurface->osSurface);
1238 VP_PUBLIC_CHK_NULL_RETURN(src);
1239 VP_PUBLIC_CHK_VALUE_RETURN(srcSize > 0, true);
1240 VP_PUBLIC_CHK_NULL_RETURN(m_allocator);
1241 VP_PUBLIC_CHK_VALUE_RETURN(vpsurface->osSurface->dwSize > 0, true);
1242
1243 #if MOS_MEDIASOLO_SUPPORTED
1244 if (!m_osInterface->bSoloInUse)
1245 #endif
1246 {
1247 VP_PUBLIC_CHK_VALUE_RETURN(vpsurface->osSurface->Type, MOS_GFXRES_BUFFER);
1248 }
1249
1250 VP_PUBLIC_ASSERT(!Mos_ResourceIsNull(&vpsurface->osSurface->OsResource));
1251
1252 MOS_SURFACE* surface = vpsurface->osSurface;
1253 uint8_t* dst = (uint8_t*)LockResourceForWrite(&surface->OsResource);
1254
1255 VP_PUBLIC_CHK_NULL_RETURN(dst);
1256
1257 MOS_STATUS status = MOS_SecureMemcpy(dst, surface->dwSize, src, srcSize);
1258
1259 VP_PUBLIC_CHK_STATUS_RETURN(m_allocator->UnLock(&surface->OsResource));
1260
1261 return status;
1262 }
1263
SyncOnResource(PMOS_RESOURCE osResource,bool bWriteOperation)1264 MOS_STATUS VpAllocator::SyncOnResource(
1265 PMOS_RESOURCE osResource,
1266 bool bWriteOperation)
1267 {
1268 VP_FUNC_CALL();
1269 VP_PUBLIC_CHK_NULL_RETURN(m_allocator);
1270
1271 return (m_allocator->SyncOnResource(osResource, bWriteOperation));
1272 }
1273
UpdateResourceUsageType(PMOS_RESOURCE osResource,MOS_HW_RESOURCE_DEF resUsageType)1274 MOS_STATUS VpAllocator::UpdateResourceUsageType(
1275 PMOS_RESOURCE osResource,
1276 MOS_HW_RESOURCE_DEF resUsageType)
1277 {
1278 VP_FUNC_CALL();
1279 VP_PUBLIC_CHK_NULL_RETURN(m_allocator);
1280
1281 return (m_allocator->UpdateResourceUsageType(osResource, resUsageType));
1282 }
1283
1284
IsSyncFreeNeededForMMCSurface(PMOS_SURFACE pOsSurface)1285 bool VpAllocator::IsSyncFreeNeededForMMCSurface(PMOS_SURFACE pOsSurface)
1286 {
1287 VP_FUNC_CALL();
1288 if (nullptr == pOsSurface)
1289 {
1290 return false;
1291 }
1292
1293 return (m_allocator->isSyncFreeNeededForMMCSurface(pOsSurface));
1294 }
1295
CleanRecycler()1296 void VpAllocator::CleanRecycler()
1297 {
1298 VP_FUNC_CALL();
1299 while (!m_recycler.empty())
1300 {
1301 MOS_GFXRES_FREE_FLAGS resFreeFlags = {};
1302 VP_SURFACE *surf = m_recycler.back();
1303 m_recycler.pop_back();
1304 //if free the compressed surface, need set the sync dealloc flag as 1 for sync dealloc for aux table update
1305 if (surf && IsSyncFreeNeededForMMCSurface(surf->osSurface))
1306 {
1307 resFreeFlags.SynchronousDestroy = 1;
1308 VP_PUBLIC_NORMALMESSAGE("Set SynchronousDestroy flag for compressed resource.");
1309 }
1310 DestroyVpSurface(surf, false, resFreeFlags);
1311 }
1312 }
1313
AllocateCPUResource(PMOS_RESOURCE osResource,size_t linearAddress,uint32_t dataSize,uint32_t height,uint64_t width,uint64_t planePitch,uint32_t CpTag,GMM_RESOURCE_FORMAT Format)1314 MOS_STATUS VpAllocator::AllocateCPUResource(PMOS_RESOURCE osResource, size_t linearAddress, uint32_t dataSize, uint32_t height, uint64_t width, uint64_t planePitch, uint32_t CpTag, GMM_RESOURCE_FORMAT Format)
1315 {
1316 VP_FUNC_CALL();
1317 MOS_STATUS eStatusKey = MOS_STATUS_SUCCESS;
1318 //Create MOS_GFXRES_BUFFER type resource
1319
1320 size_t linearAddressAligned = 0;
1321 uint32_t addedShiftLeftOffset = 0;
1322 MOS_ALLOC_GFXRES_PARAMS sParams;
1323
1324 if ((linearAddress & 0xf) || (linearAddress == 0))
1325 {
1326 VP_PUBLIC_NORMALMESSAGE("Error: Start address of system memory is not 16-byte aligned!");
1327 return MOS_STATUS_UNKNOWN;
1328 }
1329 if (sizeof(void *) == 8) //64-bit
1330 {
1331 linearAddressAligned = linearAddress & ADDRESS_PAGE_ALIGNMENT_MASK_X64;
1332 }
1333 else //32-bit
1334 {
1335 linearAddressAligned = linearAddress & ADDRESS_PAGE_ALIGNMENT_MASK_X86;
1336 }
1337 //Calculate Left Shift offset
1338 addedShiftLeftOffset = (uint32_t)(linearAddress - linearAddressAligned);
1339 VP_PUBLIC_NORMALMESSAGE("System memory address: 0x%x, Aligned address: 0x%x, offset: %u", linearAddress, linearAddressAligned, addedShiftLeftOffset);
1340
1341 MOS_ZeroMemory(&sParams, sizeof(MOS_ALLOC_GFXRES_PARAMS));
1342 sParams.Type = MOS_GFXRES_BUFFER;
1343 sParams.dwBytes = dataSize + addedShiftLeftOffset;
1344 sParams.pSystemMemory = (void *)linearAddressAligned;
1345 sParams.TileType = MOS_TILE_LINEAR;
1346 sParams.Format = Format_Buffer;
1347 sParams.pBufName = "cpuResourceBuffer_1D";
1348 sParams.bBypassMODImpl = 1;
1349 sParams.bIsPersistent = 1;
1350
1351 eStatusKey = m_osInterface->pfnAllocateResource(m_osInterface, &sParams, osResource);
1352 if (eStatusKey != MOS_STATUS_SUCCESS)
1353 {
1354 VP_PUBLIC_NORMALMESSAGE("Error: m_osInterface.pfnAllocateResource failed!");
1355 return eStatusKey;
1356 }
1357 #if !EMUL
1358 osResource->pGmmResInfo->GetSetCpSurfTag(true, CpTag);
1359 osResource->pGmmResInfo->OverridePitch(planePitch);
1360
1361 osResource->pGmmResInfo->OverrideSurfaceFormat(Format);
1362 osResource->pGmmResInfo->OverrideSurfaceType(RESOURCE_2D);
1363 osResource->pGmmResInfo->OverrideBaseWidth(width);
1364 osResource->pGmmResInfo->OverrideBaseHeight(height);
1365
1366 osResource->pGmmResInfo->OverridePlanarXOffset(GMM_NO_PLANE, (GMM_GFX_SIZE_T)addedShiftLeftOffset);
1367 osResource->pGmmResInfo->OverridePlanarYOffset(GMM_NO_PLANE, 0);
1368 osResource->pGmmResInfo->OverridePlanarXOffset(GMM_PLANE_Y, (GMM_GFX_SIZE_T)addedShiftLeftOffset);
1369 osResource->pGmmResInfo->OverridePlanarYOffset(GMM_PLANE_Y, 0);
1370 #endif
1371
1372 return eStatusKey;
1373
1374 }
1375
IsEmpty()1376 bool VP_SURFACE::IsEmpty()
1377 {
1378 VP_FUNC_CALL();
1379 return nullptr == osSurface || Mos_ResourceIsNull(&osSurface->OsResource);
1380 }
1381
Clean()1382 MOS_STATUS VP_SURFACE::Clean()
1383 {
1384 VP_FUNC_CALL();
1385 // The vp surface, which owns the resource, cannot be cleaned.
1386 if (isResourceOwner)
1387 {
1388 VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_INVALID_PARAMETER);
1389 }
1390 if (osSurface)
1391 {
1392 MOS_ZeroMemory(osSurface, sizeof(MOS_SURFACE));
1393 }
1394
1395 isResourceOwner = false;
1396 ColorSpace = CSpace_Any;
1397 ChromaSiting = 0;
1398 bQueryVariance = 0;
1399 FrameID = 0;
1400 ExtendedGamut = false;
1401 SurfType = SURF_NONE;
1402 uFwdRefCount = 0;
1403 uBwdRefCount = 0;
1404 pFwdRef = nullptr;
1405 pBwdRef = nullptr;
1406 SampleType = SAMPLE_PROGRESSIVE;
1407 MOS_ZeroMemory(&Palette, sizeof(Palette));
1408 MOS_ZeroMemory(&rcSrc, sizeof(rcSrc));
1409 MOS_ZeroMemory(&rcDst, sizeof(rcDst));
1410 MOS_ZeroMemory(&rcMaxSrc, sizeof(rcMaxSrc));
1411 bVEBOXCroppingUsed = false;
1412
1413 return MOS_STATUS_SUCCESS;
1414 }
1415
GetAllocationHandle(MOS_INTERFACE * osIntf)1416 uint64_t VP_SURFACE::GetAllocationHandle(MOS_INTERFACE* osIntf)
1417 {
1418 VP_FUNC_CALL();
1419 if (nullptr == osIntf)
1420 {
1421 return 0;
1422 }
1423 #if MOS_MEDIASOLO_SUPPORTED
1424 if (osIntf && osIntf->bSoloInUse)
1425 {
1426 uint64_t handle = osSurface ? (uint64_t)osSurface->OsResource.pData : 0;
1427 if (handle)
1428 {
1429 return handle;
1430 }
1431 // Media solo external surface will come here, in which case,
1432 // AllocationHandle or bo->handle should be valid.
1433 }
1434 #endif
1435
1436 if (nullptr == osSurface || nullptr == osIntf)
1437 {
1438 return 0;
1439 }
1440 return osIntf->pfnGetResourceHandle(osIntf->osStreamState, &osSurface->OsResource);
1441 }
1442
SetMmcFlags(MOS_SURFACE & osSurface)1443 MOS_STATUS VpAllocator::SetMmcFlags(MOS_SURFACE &osSurface)
1444 {
1445 VP_FUNC_CALL();
1446 VP_PUBLIC_CHK_NULL_RETURN(m_mmc);
1447
1448 // Init MMC related flags.
1449 m_mmc->SetSurfaceMmcMode(&osSurface);
1450 if (osSurface.CompressionMode &&
1451 (osSurface.TileType == MOS_TILE_Y ||
1452 osSurface.TileType == MOS_TILE_YS))
1453 {
1454 uint32_t mmcFormat = 0;
1455
1456 osSurface.bCompressible = true;
1457 osSurface.bIsCompressed = true;
1458 VP_PUBLIC_CHK_STATUS_RETURN(m_mmc->GetSurfaceMmcFormat(&osSurface, &mmcFormat));
1459 osSurface.CompressionFormat = mmcFormat;
1460 }
1461 else
1462 {
1463 // Do not modify the bCompressible flag even MmcMode is disable, since the surface size/pitch may be different
1464 // between Compressible and Uncompressible, which will affect the DN surface allocation.
1465 osSurface.bIsCompressed = false;
1466 osSurface.CompressionMode = MOS_MMC_DISABLED;
1467 osSurface.CompressionFormat = 0;
1468 }
1469
1470 return MOS_STATUS_SUCCESS;
1471 }
1472
GetResourceCache(uint32_t feature,bool bOut,ENGINE_TYPE engineType,MOS_COMPONENT id)1473 MOS_HW_RESOURCE_DEF VpAllocator::GetResourceCache(uint32_t feature, bool bOut, ENGINE_TYPE engineType, MOS_COMPONENT id)
1474 {
1475 VP_FUNC_CALL();
1476 MOS_CACHE_ELEMENT element(MOS_CODEC_RESOURCE_USAGE_BEGIN_CODEC, MOS_CODEC_RESOURCE_USAGE_BEGIN_CODEC);
1477 bool res = m_osInterface->pfnGetCacheSetting(id, SUFACE_TYPE_ASSIGNED(feature), bOut, engineType, element, false);
1478 if (res == false)
1479 {
1480 VP_PUBLIC_ASSERTMESSAGE("Resource %u was not found in cache manager, use default usage MOS_HW_RESOURCE_USAGE_VP_INTERNAL_READ_WRITE_RENDER!", feature);
1481 return MOS_HW_RESOURCE_USAGE_VP_INTERNAL_READ_WRITE_RENDER;
1482 }
1483
1484 VP_PUBLIC_NORMALMESSAGE("Resource %u was found in cache manager, use mocs usage %u!", feature, element.mocsUsageType);
1485 return element.mocsUsageType;
1486 }
1487