xref: /aosp_15_r20/external/intel-media-driver/media_driver/linux/common/ddi/media_libva_util.cpp (revision ba62d9d3abf0e404f2022b4cd7a85e107f48596f)
1 /*
2 * Copyright (c) 2009-2022, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 //!
23 //! \file      media_libva_util.cpp
24 //! \brief     libva(and its extension) utility
25 //!
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <pthread.h>
30 #include <sys/time.h>
31 #include <unistd.h>
32 #include <sys/types.h>
33 #include <sys/stat.h>
34 #include <fcntl.h>
35 #include <dlfcn.h>
36 #include <errno.h>
37 #include "inttypes.h"
38 
39 #include "media_libva_util.h"
40 #include "mos_utilities.h"
41 #include "mos_os.h"
42 #include "mos_defs.h"
43 #include "hwinfo_linux.h"
44 #include "media_ddi_decode_base.h"
45 #include "media_ddi_encode_base.h"
46 #include "media_libva_decoder.h"
47 #include "media_libva_encoder.h"
48 #include "media_libva_caps.h"
49 #include "memory_policy_manager.h"
50 #include "drm_fourcc.h"
51 
52 // default protected surface tag
53 #define PROTECTED_SURFACE_TAG   0x3000f
54 
55 #ifdef DEBUG
56 static int32_t         frameCountFps   = -1;
57 static struct timeval  tv1;
58 static pthread_mutex_t fpsMutex        = PTHREAD_MUTEX_INITIALIZER;
59 static int32_t         vaFpsSampleSize = 100;
60 
61 #define LENGTH_OF_FPS_FILE_NAME 128
62 
63 #ifdef ANDROID
64 #define FPS_FILE_NAME   "/mnt/sdcard/fps.txt"
65 #else
66 #define FPS_FILE_NAME   "./fps.txt"
67 #endif
68 #endif
69 #ifdef DEBUG
DdiMediaUtil_MediaPrintFps()70 void DdiMediaUtil_MediaPrintFps()
71 {
72     struct timeval tv2;
73 
74     if (0 == vaFpsSampleSize)
75     {
76         return;
77     }
78     gettimeofday(&tv2, 0);
79 
80     pthread_mutex_lock(&fpsMutex);
81     if (-1 == frameCountFps)
82     {
83         gettimeofday(&tv1, 0);
84     }
85 
86     if (++frameCountFps >= vaFpsSampleSize)
87     {
88         char   fpsFileName[LENGTH_OF_FPS_FILE_NAME];
89         FILE   *fp = nullptr;
90         char   temp[LENGTH_OF_FPS_FILE_NAME];
91 
92         int64_t diff  = (tv2.tv_sec - tv1.tv_sec)*1000000 + tv2.tv_usec - tv1.tv_usec;
93         float fps     = frameCountFps / (diff / 1000000.0);
94         DDI_NORMALMESSAGE("FPS:%6.4f, Interval:%11lu.", fps,((uint64_t)tv2.tv_sec)*1000 + (tv2.tv_usec/1000));
95         sprintf(temp,"FPS:%6.4f, Interval:%" PRIu64"\n", fps,((uint64_t)tv2.tv_sec)*1000 + (tv2.tv_usec/1000));
96 
97         MOS_ZeroMemory(fpsFileName,LENGTH_OF_FPS_FILE_NAME);
98         sprintf(fpsFileName, FPS_FILE_NAME);
99         if ((fp = fopen(fpsFileName, "wb")) == nullptr)
100         {
101             pthread_mutex_unlock(&fpsMutex);
102             DDI_ASSERTMESSAGE("Unable to open fps file.");
103         }
104 
105         fwrite(temp, 1, strlen(temp), fp);
106         fclose(fp);
107         frameCountFps = -1;
108     }
109     pthread_mutex_unlock(&fpsMutex);
110 }
111 #else
DdiMediaUtil_MediaPrintFps()112 void DdiMediaUtil_MediaPrintFps()
113 {
114     return;
115 }
116 #endif
117 
118 /*
119  * DdiMediaUtil_IsExternalSurface
120  *    Descripion: if the bo of media surface was allocated from App,
121  *                should return true, otherwise, false. In current implemeation
122  *                external buffer passed with pSurfDesc.
123 */
DdiMediaUtil_IsExternalSurface(PDDI_MEDIA_SURFACE surface)124 bool DdiMediaUtil_IsExternalSurface(PDDI_MEDIA_SURFACE surface)
125 {
126     if ( nullptr == surface )
127     {
128         return false;
129     }
130     else if ( surface->pSurfDesc == nullptr )
131     {
132         return false;
133     }
134     else
135     {
136         if (surface->pSurfDesc->uiVaMemType == VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM ||
137             surface->pSurfDesc->uiVaMemType == VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME ||
138             surface->pSurfDesc->uiVaMemType == VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2 ||
139 #if VA_CHECK_VERSION(1, 21, 0)
140             surface->pSurfDesc->uiVaMemType == VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_3 ||
141 #endif
142             surface->pSurfDesc->uiVaMemType == VA_SURFACE_ATTRIB_MEM_TYPE_USER_PTR)
143         {
144             return true;
145         }else
146         {
147             return false;
148         }
149     }
150 }
151 
152 //!
153 //! \brief  Allocate surface
154 //!
155 //! \param  [in] format
156 //!         Ddi media format
157 //! \param  [in] width
158 //!         Width of the region
159 //! \param  [in] height
160 //!         Height of the region
161 //! \param  [out] mediaSurface
162 //!         Pointer to ddi media surface
163 //! \param  [in] mediaDrvCtx
164 //!         Pointer to ddi media context
165 //!
166 //! \return VAStatus
167 //!     VA_STATUS_SUCCESS if success, else fail reason
168 //!
DdiMediaUtil_AllocateSurface(DDI_MEDIA_FORMAT format,int32_t width,int32_t height,PDDI_MEDIA_SURFACE mediaSurface,PDDI_MEDIA_CONTEXT mediaDrvCtx)169 VAStatus DdiMediaUtil_AllocateSurface(
170     DDI_MEDIA_FORMAT            format,
171     int32_t                     width,
172     int32_t                     height,
173     PDDI_MEDIA_SURFACE          mediaSurface,
174     PDDI_MEDIA_CONTEXT          mediaDrvCtx)
175 {
176     uint32_t                    pitch = 0;
177     MOS_LINUX_BO               *bo = nullptr;
178     GMM_RESCREATE_PARAMS        gmmParams;
179     GMM_RESCREATE_CUSTOM_PARAMS_2 gmmCustomParams;
180     GMM_RESOURCE_INFO          *gmmResourceInfo = nullptr;
181 
182     DDI_CHK_NULL(mediaSurface, "mediaSurface is nullptr", VA_STATUS_ERROR_INVALID_BUFFER);
183     DDI_CHK_NULL(mediaDrvCtx, "mediaDrvCtx is nullptr", VA_STATUS_ERROR_INVALID_BUFFER);
184     DDI_CHK_NULL(mediaDrvCtx->pGmmClientContext, "mediaDrvCtx->pGmmClientContext is nullptr", VA_STATUS_ERROR_INVALID_BUFFER);
185 
186     int32_t size          = 0;
187     uint32_t tileformat   = TILING_NONE;
188     VAStatus hRes         = VA_STATUS_SUCCESS;
189     int32_t alignedWidth  = width;
190     int32_t alignedHeight = height;
191     uint32_t cpTag        = 0;
192     int mem_type          = mediaSurface->memType;
193 #ifdef _MMC_SUPPORTED
194     bool bMemCompEnable   = true;
195 #else
196     bool bMemCompEnable   = false;
197 #endif
198     bool bMemCompRC       = false;
199 
200     switch (format)
201     {
202         case Media_Format_X8R8G8B8:
203         case Media_Format_X8B8G8R8:
204         case Media_Format_A8B8G8R8:
205         case Media_Format_R8G8B8A8:
206         case Media_Format_R5G6B5:
207         case Media_Format_R8G8B8:
208         case Media_Format_R10G10B10A2:
209         case Media_Format_B10G10R10A2:
210         case Media_Format_R10G10B10X2:
211         case Media_Format_B10G10R10X2:
212         case Media_Format_A16R16G16B16:
213         case Media_Format_A16B16G16R16:
214             if (VA_SURFACE_ATTRIB_USAGE_HINT_ENCODER != mediaSurface->surfaceUsageHint     &&
215                 !(mediaSurface->surfaceUsageHint & VA_SURFACE_ATTRIB_USAGE_HINT_VPP_WRITE))
216             {
217                 tileformat = TILING_NONE;
218                 break;
219             }
220         case Media_Format_YV12:
221         case Media_Format_I420:
222         case Media_Format_IYUV:
223             if (VA_SURFACE_ATTRIB_USAGE_HINT_ENCODER != mediaSurface->surfaceUsageHint   &&
224                 !(mediaSurface->surfaceUsageHint & VA_SURFACE_ATTRIB_USAGE_HINT_VPP_WRITE))
225             {
226                 tileformat = TILING_NONE;
227                 alignedWidth = MOS_ALIGN_CEIL(width, 2);
228                 alignedHeight = MOS_ALIGN_CEIL(height, 2);
229                 break;
230             }
231 
232         case Media_Format_RGBP:
233         case Media_Format_BGRP:
234             if (VA_SURFACE_ATTRIB_USAGE_HINT_ENCODER != mediaSurface->surfaceUsageHint   &&
235                 !(mediaSurface->surfaceUsageHint & VA_SURFACE_ATTRIB_USAGE_HINT_DECODER) &&
236                 !(mediaSurface->surfaceUsageHint & VA_SURFACE_ATTRIB_USAGE_HINT_VPP_WRITE))
237             {
238                 tileformat = TILING_NONE;
239                 break;
240             }
241         case Media_Format_A8R8G8B8:
242             if (VA_SURFACE_ATTRIB_USAGE_HINT_ENCODER != mediaSurface->surfaceUsageHint     &&
243                 !(mediaSurface->surfaceUsageHint & VA_SURFACE_ATTRIB_USAGE_HINT_DECODER)   &&
244                 !(mediaSurface->surfaceUsageHint & VA_SURFACE_ATTRIB_USAGE_HINT_VPP_WRITE) &&
245                 !(MEDIA_IS_SKU(&mediaDrvCtx->SkuTable, FtrRenderCompressionOnly)           &&
246                   MEDIA_IS_SKU(&mediaDrvCtx->SkuTable, FtrE2ECompression)))
247             {
248                 tileformat = TILING_NONE;
249                 break;
250             }
251         case Media_Format_NV12:
252         case Media_Format_NV21:
253         case Media_Format_444P:
254         case Media_Format_422H:
255         case Media_Format_411P:
256         case Media_Format_422V:
257         case Media_Format_IMC3:
258         case Media_Format_400P:
259         case Media_Format_P010:
260         case Media_Format_P012:
261         case Media_Format_P016:
262         case Media_Format_YUY2:
263         case Media_Format_Y210:
264 #if VA_CHECK_VERSION(1, 9, 0)
265         case Media_Format_Y212:
266 #endif
267         case Media_Format_Y216:
268         case Media_Format_AYUV:
269 #if VA_CHECK_VERSION(1, 13, 0)
270         case Media_Format_XYUV:
271 #endif
272         case Media_Format_Y410:
273 #if VA_CHECK_VERSION(1, 9, 0)
274         case Media_Format_Y412:
275 #endif
276         case Media_Format_Y416:
277         case Media_Format_Y8:
278         case Media_Format_Y16S:
279         case Media_Format_Y16U:
280         case Media_Format_VYUY:
281         case Media_Format_YVYU:
282         case Media_Format_UYVY:
283             if (VA_SURFACE_ATTRIB_USAGE_HINT_ENCODER != mediaSurface->surfaceUsageHint &&
284                 !(mediaSurface->surfaceUsageHint & VA_SURFACE_ATTRIB_USAGE_HINT_VPP_WRITE))
285             {
286 #if UFO_GRALLOC_NEW_FORMAT
287                 //Planar type surface align 64 to improve performance.
288                 alignedHeight = MOS_ALIGN_CEIL(height, 64);
289 #else
290                 //Planar type surface align 32 to improve performance.
291                 alignedHeight = MOS_ALIGN_CEIL(height, 32);
292 #endif
293             }
294             alignedWidth = MOS_ALIGN_CEIL(width, 8);
295             if (mediaSurface->surfaceUsageHint & VA_SURFACE_ATTRIB_USAGE_HINT_VPP_WRITE)
296             {
297                 if ((format == Media_Format_YV12) ||
298                     (format == Media_Format_I420))
299                 {
300                     alignedWidth = MOS_ALIGN_CEIL(width, 128);
301                 }
302 
303                 if ((format == Media_Format_NV12) ||
304                     (format == Media_Format_P010) ||
305                     (format == Media_Format_RGBP) ||
306                     (format == Media_Format_BGRP))
307                 {
308 #if UFO_GRALLOC_NEW_FORMAT
309                     //Planar type surface align 64 to improve performance.
310                     alignedHeight = MOS_ALIGN_CEIL(height, 64);
311 #else
312                     //Planar type surface align 32 to improve performance.
313                     alignedHeight = MOS_ALIGN_CEIL(height, 32);
314 #endif
315                 }
316             }
317             tileformat = TILING_Y;
318             break;
319         case Media_Format_Buffer:
320             tileformat = TILING_NONE;
321             break;
322         default:
323             DDI_ASSERTMESSAGE("Unsupported format");
324             hRes = VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
325             goto finish;
326     }
327     //different alignment requirement for different codec and different platform
328     //for MPEG2 and AVC , it should be 16
329     //for HEVC on the platform pre-gen12 (include), it is 64
330     //may need api change for to convey different codec usage.
331     if(VA_SURFACE_ATTRIB_USAGE_HINT_ENCODER & mediaSurface->surfaceUsageHint)
332     {
333         alignedWidth = MOS_ALIGN_CEIL(alignedWidth, 16);
334         alignedHeight = MOS_ALIGN_CEIL(alignedHeight, 16);
335     }
336 
337     if (DdiMediaUtil_IsExternalSurface(mediaSurface))
338     {
339         // Default set as compression not supported, surface compression import only support from Memory Type VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2 or VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_3
340         bMemCompEnable   = false;
341         bMemCompRC       = false;
342         pitch            = mediaSurface->pSurfDesc->uiPitches[0];
343         DDI_CHK_CONDITION(pitch == 0, "Invalid pich.", VA_STATUS_ERROR_INVALID_PARAMETER);
344         // DRM buffer allocated by Application, No need to re-allocate new DRM buffer
345         if ((mediaSurface->pSurfDesc->uiVaMemType == VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM) ||
346             (mediaSurface->pSurfDesc->uiVaMemType == VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME))
347         {
348             if (mediaSurface->pSurfDesc->uiVaMemType == VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM)
349             {
350                 bo = mos_bo_create_from_name(mediaDrvCtx->pDrmBufMgr, "MEDIA", mediaSurface->pSurfDesc->ulBuffer);
351             }
352             else
353             {
354                 struct mos_drm_bo_alloc_prime alloc_prime;
355                 alloc_prime.name = "prime";
356                 alloc_prime.prime_fd = mediaSurface->pSurfDesc->ulBuffer;
357                 alloc_prime.size = mediaSurface->pSurfDesc->uiSize;
358                 alloc_prime.pat_index = PAT_INDEX_INVALID; //Setting with default pat index 0 in legacy ddi
359                 bo = mos_bo_create_from_prime(mediaDrvCtx->pDrmBufMgr, &alloc_prime);
360             }
361 
362             if (bo != nullptr)
363             {
364                 uint32_t swizzle_mode;
365                 //Overwrite the tile format that matches the exteral buffer
366                 mos_bo_get_tiling(bo, &tileformat, &swizzle_mode);
367                 if(tileformat == 0)
368                 {
369                     tileformat = mediaSurface->pSurfDesc->uiFlags & VA_SURFACE_EXTBUF_DESC_ENABLE_TILING? TILING_Y:TILING_NONE;
370                 }
371             }
372             else
373             {
374                 DDI_ASSERTMESSAGE("Failed to create drm buffer object according to input buffer descriptor.");
375                 return VA_STATUS_ERROR_ALLOCATION_FAILED;
376             }
377         }
378         else if (
379 #if VA_CHECK_VERSION(1, 21, 0)
380                 mediaSurface->pSurfDesc->uiVaMemType == VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_3 ||
381 #endif
382                 mediaSurface->pSurfDesc->uiVaMemType == VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2)
383         {
384             struct mos_drm_bo_alloc_prime alloc_prime;
385             alloc_prime.name = "prime";
386             alloc_prime.prime_fd = mediaSurface->pSurfDesc->ulBuffer;
387             alloc_prime.size = mediaSurface->pSurfDesc->uiSize;
388             alloc_prime.pat_index = PAT_INDEX_INVALID; //Setting with default pat index 0 in legacy ddi
389             bo = mos_bo_create_from_prime(mediaDrvCtx->pDrmBufMgr, &alloc_prime);
390             if( bo != nullptr )
391             {
392                 pitch = mediaSurface->pSurfDesc->uiPitches[0];
393 
394                 DDI_CHK_NULL(mediaDrvCtx->m_caps, "nullptr m_caps", VA_STATUS_ERROR_INVALID_CONTEXT);
395                 if (VA_STATUS_SUCCESS != mediaDrvCtx->m_caps->SetExternalSurfaceTileFormat(mediaSurface, tileformat, bMemCompEnable, bMemCompRC)) {
396                     DDI_ASSERTMESSAGE("Unsupported modifier.");
397                     hRes = VA_STATUS_ERROR_INVALID_PARAMETER;
398                     goto finish;
399                 }
400             }
401             else
402             {
403                 DDI_ASSERTMESSAGE("Failed to create drm buffer object according to input buffer descriptor.");
404                 return VA_STATUS_ERROR_ALLOCATION_FAILED;
405             }
406         }
407         else if( mediaSurface->pSurfDesc->uiVaMemType == VA_SURFACE_ATTRIB_MEM_TYPE_USER_PTR )
408         {
409             struct mos_drm_bo_alloc_userptr alloc_uptr;
410             alloc_uptr.name = "SysSurface";
411             alloc_uptr.addr = (void *)mediaSurface->pSurfDesc->ulBuffer;
412             alloc_uptr.tiling_mode = mediaSurface->pSurfDesc->uiTile;
413             alloc_uptr.stride = pitch;
414             alloc_uptr.size = mediaSurface->pSurfDesc->uiBuffserSize;
415 
416             bo = mos_bo_alloc_userptr( mediaDrvCtx->pDrmBufMgr, &alloc_uptr);
417 
418             if (bo != nullptr)
419             {
420                 uint32_t swizzle_mode;
421                 //Overwrite the tile format that matches the exteral buffer
422                 mos_bo_get_tiling(bo, &tileformat, &swizzle_mode);
423             }
424             else
425             {
426                 DDI_ASSERTMESSAGE("Failed to create drm buffer vmap.");
427                 return VA_STATUS_ERROR_ALLOCATION_FAILED;
428             }
429         }
430         else
431         {
432             DDI_ASSERTMESSAGE("Unsupported external surface memory type.");
433             return VA_STATUS_ERROR_ALLOCATION_FAILED;
434         }
435 
436         // Set cp flag to indicate the secure surface
437         if (mediaSurface->pSurfDesc->uiFlags & VA_SURFACE_EXTBUF_DESC_PROTECTED)
438         {
439             cpTag = PROTECTED_SURFACE_TAG;
440         }
441 
442         int32_t baseHeight = 0;
443         DDI_CHK_CONDITION(mediaSurface->pSurfDesc->uiPlanes == 0,
444             "Invalid plane number.",
445             VA_STATUS_ERROR_INVALID_PARAMETER);
446         if (mediaSurface->pSurfDesc->uiPlanes == 1)
447         {
448             DDI_CHK_CONDITION(mediaSurface->pSurfDesc->uiSize == 0,
449                 "Invalid Size.",
450                 VA_STATUS_ERROR_INVALID_PARAMETER);
451             baseHeight = mediaSurface->pSurfDesc->uiSize / pitch;
452         }
453         else
454         {
455             DDI_CHK_CONDITION(mediaSurface->pSurfDesc->uiOffsets[1] == 0,
456                 "Invalid offset.",
457                 VA_STATUS_ERROR_INVALID_PARAMETER);
458             baseHeight = mediaSurface->pSurfDesc->uiOffsets[1] / pitch;
459         }
460         // Create GmmResourceInfo
461         MOS_ZeroMemory(&gmmCustomParams, sizeof(gmmCustomParams));
462         gmmCustomParams.Type          = RESOURCE_2D;
463         gmmCustomParams.Format        = mediaDrvCtx->m_caps->ConvertMediaFmtToGmmFmt(format);
464         if ((format == Media_Format_YV12) || \
465             (format == Media_Format_I420) || \
466             (format == Media_Format_IYUV) || \
467             (format == Media_Format_NV12) || \
468             (format == Media_Format_NV21)) {
469             // Align width to 2 for specific planar formats to handle
470             // odd dimensions for external non-compressible surfaces
471             gmmCustomParams.BaseWidth64 = MOS_ALIGN_CEIL(width, 2);
472         } else {
473             gmmCustomParams.BaseWidth64 = width;
474         }
475         gmmCustomParams.BaseHeight    = baseHeight;
476         gmmCustomParams.Pitch         = pitch;
477         gmmCustomParams.Size          = mediaSurface->pSurfDesc->uiSize;
478         gmmCustomParams.BaseAlignment = 4096;
479         gmmCustomParams.NoOfPlanes    = mediaSurface->pSurfDesc->uiPlanes;
480         gmmCustomParams.CpTag         = cpTag;
481         switch (tileformat)
482         {
483             case TILING_Y:
484                 gmmCustomParams.Flags.Info.TiledY = true;
485                 gmmCustomParams.Flags.Gpu.MMC    = false;
486                 if (MEDIA_IS_SKU(&mediaDrvCtx->SkuTable, FtrE2ECompression) &&
487                     (!MEDIA_IS_WA(&mediaDrvCtx->WaTable, WaDisableVPMmc)    &&
488                     !MEDIA_IS_WA(&mediaDrvCtx->WaTable, WaDisableCodecMmc)) &&
489                     bMemCompEnable)
490                 {
491                     gmmCustomParams.Flags.Gpu.MMC               = true;
492                     gmmCustomParams.Flags.Info.MediaCompressed  = 1;
493                     gmmCustomParams.Flags.Info.RenderCompressed = 0;
494                     gmmCustomParams.Flags.Gpu.CCS               = 1;
495                     gmmCustomParams.Flags.Gpu.RenderTarget      = 1;
496                     gmmCustomParams.Flags.Gpu.UnifiedAuxSurface = 1;
497 
498                     if (bMemCompRC)
499                     {
500                         gmmCustomParams.Flags.Info.MediaCompressed  = 0;
501                         gmmCustomParams.Flags.Info.RenderCompressed = 1;
502                     }
503 
504                     if(MEDIA_IS_SKU(&mediaDrvCtx->SkuTable, FtrRenderCompressionOnly))
505                     {
506                         gmmCustomParams.Flags.Info.MediaCompressed = 0;
507 
508                         if (format == Media_Format_X8R8G8B8 ||
509                             format == Media_Format_X8B8G8R8 ||
510                             format == Media_Format_A8B8G8R8 ||
511                             format == Media_Format_A8R8G8B8 ||
512                             format == Media_Format_R8G8B8A8)
513                         {
514                             gmmCustomParams.Flags.Info.MediaCompressed  = 0;
515                             gmmCustomParams.Flags.Info.RenderCompressed = 1;
516                         }
517                     }
518 
519                     if(MEDIA_IS_SKU(&mediaDrvCtx->SkuTable, FtrFlatPhysCCS))
520                     {
521                         gmmCustomParams.Flags.Gpu.UnifiedAuxSurface = 0;
522                     }
523                 }
524                 break;
525             case TILING_X:
526                 gmmCustomParams.Flags.Info.TiledX = true;
527                 break;
528             case TILING_NONE:
529             default:
530                 gmmCustomParams.Flags.Info.Linear = true;
531         }
532 
533         if(bMemCompEnable)
534         {
535             gmmCustomParams.AuxSurf.BaseAlignment = {0};
536             gmmCustomParams.NoOfPlanes = mediaSurface->pSurfDesc->uiPlanes/2;
537             gmmCustomParams.Size = (gmmCustomParams.NoOfPlanes == 1) ? mediaSurface->pSurfDesc->uiOffsets[1]:mediaSurface->pSurfDesc->uiOffsets[2];
538         }
539         switch(gmmCustomParams.NoOfPlanes)
540         {
541             case 1:
542                 gmmCustomParams.PlaneOffset.X[GMM_PLANE_Y] = 0;
543                 gmmCustomParams.PlaneOffset.Y[GMM_PLANE_Y] = mediaSurface->pSurfDesc->uiOffsets[0] / pitch;
544                 if (bMemCompEnable)
545                 {
546                     gmmCustomParams.AuxSurf.Size = mediaSurface->pSurfDesc->uiSize - gmmCustomParams.Size;
547                     gmmCustomParams.AuxSurf.Pitch = mediaSurface->pSurfDesc->uiPitches[1];
548                     gmmCustomParams.AuxSurf.PlaneOffset.X[GMM_PLANE_Y] = 0;
549                     gmmCustomParams.AuxSurf.PlaneOffset.Y[GMM_PLANE_Y] = 0;
550                 }
551                 break;
552             case 2:
553                 gmmCustomParams.PlaneOffset.X[GMM_PLANE_Y] = 0;
554                 gmmCustomParams.PlaneOffset.Y[GMM_PLANE_Y] = mediaSurface->pSurfDesc->uiOffsets[0] / pitch;
555                 gmmCustomParams.PlaneOffset.X[GMM_PLANE_U] = 0;
556                 gmmCustomParams.PlaneOffset.Y[GMM_PLANE_U] = mediaSurface->pSurfDesc->uiOffsets[1] / pitch;
557                 gmmCustomParams.PlaneOffset.X[GMM_PLANE_V] = 0;
558                 gmmCustomParams.PlaneOffset.Y[GMM_PLANE_V] = mediaSurface->pSurfDesc->uiOffsets[1] / pitch;
559                 if (bMemCompEnable)
560                 {
561                     gmmCustomParams.AuxSurf.Size = (mediaSurface->pSurfDesc->uiOffsets[3] - mediaSurface->pSurfDesc->uiOffsets[2]) * 2;
562                     gmmCustomParams.AuxSurf.Pitch = mediaSurface->pSurfDesc->uiPitches[2];
563                     gmmCustomParams.AuxSurf.PlaneOffset.X[GMM_PLANE_Y] = 0;
564                     gmmCustomParams.AuxSurf.PlaneOffset.Y[GMM_PLANE_Y] = 0;
565                     gmmCustomParams.AuxSurf.PlaneOffset.X[GMM_PLANE_U] = (mediaSurface->pSurfDesc->uiOffsets[3]
566                                                                     - mediaSurface->pSurfDesc->uiOffsets[2]);
567                     gmmCustomParams.AuxSurf.PlaneOffset.Y[GMM_PLANE_U] = 0;
568                     gmmCustomParams.AuxSurf.PlaneOffset.X[GMM_PLANE_V] = (mediaSurface->pSurfDesc->uiOffsets[3]
569                                                                     - mediaSurface->pSurfDesc->uiOffsets[2]);
570                     gmmCustomParams.AuxSurf.PlaneOffset.Y[GMM_PLANE_V] = 0;
571                 }
572                 break;
573             case 3:
574                 if (mediaSurface->format == Media_Format_YV12)
575                 {
576                     gmmCustomParams.PlaneOffset.X[GMM_PLANE_Y] = 0;
577                     gmmCustomParams.PlaneOffset.Y[GMM_PLANE_Y] = mediaSurface->pSurfDesc->uiOffsets[0] / pitch;
578                     gmmCustomParams.PlaneOffset.X[GMM_PLANE_U] = 0;
579                     gmmCustomParams.PlaneOffset.Y[GMM_PLANE_U] = mediaSurface->pSurfDesc->uiOffsets[2] / pitch;
580                     gmmCustomParams.PlaneOffset.X[GMM_PLANE_V] = 0;
581                     gmmCustomParams.PlaneOffset.Y[GMM_PLANE_V] = mediaSurface->pSurfDesc->uiOffsets[1] / pitch;
582                 }
583                 else
584                 {
585                     gmmCustomParams.PlaneOffset.X[GMM_PLANE_Y] = 0;
586                     gmmCustomParams.PlaneOffset.Y[GMM_PLANE_Y] = mediaSurface->pSurfDesc->uiOffsets[0] / pitch;
587                     gmmCustomParams.PlaneOffset.X[GMM_PLANE_U] = 0;
588                     gmmCustomParams.PlaneOffset.Y[GMM_PLANE_U] = mediaSurface->pSurfDesc->uiOffsets[1] / pitch;
589                     gmmCustomParams.PlaneOffset.X[GMM_PLANE_V] = 0;
590                     gmmCustomParams.PlaneOffset.Y[GMM_PLANE_V] = mediaSurface->pSurfDesc->uiOffsets[2] / pitch;
591                 }
592                 break;
593             default:
594                 DDI_ASSERTMESSAGE("Invalid plane number.");
595                 return VA_STATUS_ERROR_ALLOCATION_FAILED;
596         }
597         gmmResourceInfo = mediaDrvCtx->pGmmClientContext->CreateCustomResInfoObject_2(&gmmCustomParams);
598 
599         if(nullptr == gmmResourceInfo)
600         {
601             DDI_ASSERTMESSAGE("Gmm Create Resource Failed.");
602             hRes = VA_STATUS_ERROR_ALLOCATION_FAILED;
603             goto finish;
604         }
605         int gmmTiledType = gmmResourceInfo->GetTileType();
606         if (bo)
607         {
608             mediaSurface->pGmmResourceInfo = gmmResourceInfo;
609             mediaSurface->bMapped          = false;
610             mediaSurface->format           = format;
611             mediaSurface->iWidth           = width;
612             mediaSurface->iHeight          = gmmResourceInfo->GetBaseHeight();
613             mediaSurface->iRealHeight      = height;
614             mediaSurface->iPitch           = pitch;
615             mediaSurface->iRefCount        = 0;
616             mediaSurface->bo               = bo;
617             mediaSurface->TileType         = tileformat;
618             mediaSurface->isTiled          = (tileformat != TILING_NONE) ? 1 : 0;
619             mediaSurface->pData            = (uint8_t*) bo->virt;
620             DDI_VERBOSEMESSAGE("Allocate external surface %7d bytes (%d x %d resource). gmmTiledType %d", mediaSurface->pSurfDesc->uiSize, width, height, gmmTiledType);
621             uint32_t event[] = {bo->handle, format, width, height, pitch, bo->size, tileformat, cpTag};
622             MOS_TraceEventExt(EVENT_VA_SURFACE, EVENT_TYPE_INFO, event, sizeof(event), &gmmResourceInfo->GetResFlags(), sizeof(GMM_RESOURCE_FLAG));
623         }
624         else
625         {
626             DDI_ASSERTMESSAGE("Fail to allocate external surface");
627             return VA_STATUS_ERROR_ALLOCATION_FAILED;
628         }
629     }
630     else
631     {
632         if (mediaSurface->pSurfDesc)
633         {
634             if( mediaSurface->pSurfDesc->uiFlags & VA_SURFACE_EXTBUF_DESC_ENABLE_TILING )
635             {
636                 tileformat = TILING_Y;
637             }
638             else if (mediaSurface->pSurfDesc->uiVaMemType == VA_SURFACE_ATTRIB_MEM_TYPE_VA)
639             {
640                 tileformat = TILING_NONE;
641                 alignedHeight = height;
642                 if (format == Media_Format_YV12 ||
643                     format == Media_Format_I420)
644                 {
645                     alignedHeight = MOS_ALIGN_CEIL(height, 2);
646                 }
647             }
648         }
649 
650         // Create GmmResourceInfo
651         MOS_ZeroMemory(&gmmParams, sizeof(gmmParams));
652         gmmParams.BaseWidth         = alignedWidth;
653         gmmParams.BaseHeight        = alignedHeight;
654         gmmParams.ArraySize         = 1;
655         gmmParams.Type              = RESOURCE_2D;
656         gmmParams.Format            = mediaDrvCtx->m_caps->ConvertMediaFmtToGmmFmt(format);
657         DDI_CHK_CONDITION(gmmParams.Format == GMM_FORMAT_INVALID, "Unsupported format", VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT);
658         switch (tileformat)
659         {
660             case TILING_Y:
661                 // Disable MMC for application required surfaces, because some cases' output streams have corruption.
662                 gmmParams.Flags.Gpu.MMC    = false;
663                 if (MEDIA_IS_SKU(&mediaDrvCtx->SkuTable, FtrE2ECompression)             &&
664                     (!MEDIA_IS_WA(&mediaDrvCtx->WaTable, WaDisableVPMmc)                &&
665                     !MEDIA_IS_WA(&mediaDrvCtx->WaTable, WaDisableCodecMmc))             &&
666                     MEDIA_IS_SKU(&mediaDrvCtx->SkuTable, FtrCompressibleSurfaceDefault) &&
667                     bMemCompEnable)
668                 {
669                     gmmParams.Flags.Gpu.MMC               = true;
670                     gmmParams.Flags.Info.MediaCompressed  = 1;
671                     gmmParams.Flags.Info.RenderCompressed = 0;
672                     gmmParams.Flags.Gpu.CCS               = 1;
673                     gmmParams.Flags.Gpu.RenderTarget      = 1;
674                     gmmParams.Flags.Gpu.UnifiedAuxSurface = 1;
675 
676                     if (bMemCompRC)
677                     {
678                         gmmParams.Flags.Info.MediaCompressed  = 0;
679                         gmmParams.Flags.Info.RenderCompressed = 1;
680                     }
681 
682                     if(MEDIA_IS_SKU(&mediaDrvCtx->SkuTable, FtrRenderCompressionOnly))
683                     {
684                         gmmParams.Flags.Info.MediaCompressed = 0;
685 
686                         if (format == Media_Format_X8R8G8B8 ||
687                             format == Media_Format_X8B8G8R8 ||
688                             format == Media_Format_A8B8G8R8 ||
689                             format == Media_Format_A8R8G8B8 ||
690                             format == Media_Format_R8G8B8A8)
691                         {
692                             gmmParams.Flags.Info.MediaCompressed  = 0;
693                             gmmParams.Flags.Info.RenderCompressed = 1;
694                         }
695                         else
696                         {
697                             gmmParams.Flags.Gpu.MMC               = false;
698                             gmmParams.Flags.Info.MediaCompressed  = 0;
699                             gmmParams.Flags.Info.RenderCompressed = 0;
700                             gmmParams.Flags.Gpu.CCS               = 0;
701                             gmmParams.Flags.Gpu.UnifiedAuxSurface = 0;
702                         }
703                     }
704                 }
705                 break;
706             case TILING_X:
707                 gmmParams.Flags.Info.TiledX    = true;
708                 break;
709             default:
710                 gmmParams.Flags.Info.Linear    = true;
711         }
712         gmmParams.Flags.Gpu.Video = true;
713         gmmParams.Flags.Info.LocalOnly = MEDIA_IS_SKU(&mediaDrvCtx->SkuTable, FtrLocalMemory);
714 
715         mediaSurface->pGmmResourceInfo = gmmResourceInfo = mediaDrvCtx->pGmmClientContext->CreateResInfoObject(&gmmParams);
716 
717         if(nullptr == gmmResourceInfo)
718         {
719             DDI_ASSERTMESSAGE("Gmm Create Resource Failed.");
720             hRes = VA_STATUS_ERROR_ALLOCATION_FAILED;
721             goto finish;
722         }
723 
724         uint32_t    gmmPitch  = (uint32_t)gmmResourceInfo->GetRenderPitch();
725         uint32_t    gmmSize   = (uint32_t)gmmResourceInfo->GetSizeSurface();
726         uint32_t    gmmHeight = gmmResourceInfo->GetBaseHeight();
727 
728         if ( 0 == gmmPitch || 0 == gmmSize || 0 == gmmHeight)
729         {
730             DDI_ASSERTMESSAGE("Gmm Create Resource Failed.");
731             hRes = VA_STATUS_ERROR_ALLOCATION_FAILED;
732             goto finish;
733         }
734 
735         switch (gmmResourceInfo->GetTileType())
736         {
737             case GMM_TILED_Y:
738                 tileformat = TILING_Y;
739                 break;
740             case GMM_TILED_X:
741                 tileformat = TILING_X;
742                 break;
743             case GMM_NOT_TILED:
744                 tileformat = TILING_NONE;
745                 break;
746             default:
747                 tileformat = TILING_Y;
748                 break;
749         }
750 
751         MemoryPolicyParameter memPolicyPar;
752         MOS_ZeroMemory(&memPolicyPar, sizeof(MemoryPolicyParameter));
753 
754         memPolicyPar.skuTable = &mediaDrvCtx->SkuTable;
755         memPolicyPar.waTable = &mediaDrvCtx->WaTable;
756         memPolicyPar.resInfo = mediaSurface->pGmmResourceInfo;
757         memPolicyPar.resName = "Media Surface";
758         memPolicyPar.preferredMemType = (MEDIA_IS_WA(&mediaDrvCtx->WaTable, WaForceAllocateLML4)) ? MOS_MEMPOOL_DEVICEMEMORY : mem_type;
759 
760         mem_type = MemoryPolicyManager::UpdateMemoryPolicy(&memPolicyPar);
761 
762         if ( tileformat == TILING_NONE )
763         {
764             struct mos_drm_bo_alloc alloc;
765             alloc.name = "MEDIA";
766             alloc.size = gmmSize;
767             alloc.alignment = 4096;
768             alloc.ext.mem_type = mem_type;
769 
770             bo = mos_bo_alloc(mediaDrvCtx->pDrmBufMgr, &alloc);
771             pitch = gmmPitch;
772         }
773         else
774         {
775             struct mos_drm_bo_alloc_tiled alloc_tiled;
776             alloc_tiled.name = "MEDIA";
777             alloc_tiled.x = gmmPitch;
778             alloc_tiled.y = (gmmSize + gmmPitch -1)/gmmPitch;
779             alloc_tiled.cpp = 1;
780             alloc_tiled.ext.tiling_mode = tileformat;
781             alloc_tiled.ext.mem_type = mem_type;
782 
783             bo = mos_bo_alloc_tiled(mediaDrvCtx->pDrmBufMgr, &alloc_tiled);
784             pitch = alloc_tiled.pitch;
785         }
786 
787         mediaSurface->bMapped = false;
788         if (bo)
789         {
790             mediaSurface->format      = format;
791             mediaSurface->iWidth      = width;
792             mediaSurface->iHeight     = gmmHeight;
793             mediaSurface->iRealHeight = height;
794             mediaSurface->iPitch      = pitch;
795             mediaSurface->iRefCount   = 0;
796             mediaSurface->bo          = bo;
797             mediaSurface->TileType    = tileformat;
798             mediaSurface->isTiled     = (tileformat != TILING_NONE) ? 1 : 0;
799             mediaSurface->pData       = (uint8_t*) bo->virt;
800             DDI_VERBOSEMESSAGE("Alloc %7d bytes (%d x %d resource, gmmTiledType %d).",gmmSize, width, height, gmmResourceInfo->GetTileType());
801             uint32_t event[] = {bo->handle, format, width, height, pitch, bo->size, tileformat, cpTag};
802             MOS_TraceEventExt(EVENT_VA_SURFACE, EVENT_TYPE_INFO, event, sizeof(event), &gmmResourceInfo->GetResFlags(), sizeof(GMM_RESOURCE_FLAG));
803         }
804         else
805         {
806             DDI_ASSERTMESSAGE("Fail to Alloc %7d bytes (%d x %d resource).",gmmSize, width, height);
807             hRes = VA_STATUS_ERROR_ALLOCATION_FAILED;
808             goto finish;
809         }
810     }
811 
812 
813 finish:
814     return hRes;
815 }
816 
817 //!
818 //! \brief  Allocate buffer
819 //!
820 //! \param  [in] format
821 //!         Ddi media format
822 //! \param  [in] size
823 //!         Size of the region
824 //! \param  [out] mediaBuffer
825 //!         Pointer to ddi media buffer
826 //! \param  [in] bufmgr
827 //!         Mos buffer manager
828 //!
829 //! \return VAStatus
830 //!     VA_STATUS_SUCCESS if success, else fail reason
831 //!
DdiMediaUtil_AllocateBuffer(DDI_MEDIA_FORMAT format,int32_t size,PDDI_MEDIA_BUFFER mediaBuffer,MOS_BUFMGR * bufmgr)832 VAStatus DdiMediaUtil_AllocateBuffer(
833     DDI_MEDIA_FORMAT            format,
834     int32_t                     size,
835     PDDI_MEDIA_BUFFER           mediaBuffer,
836     MOS_BUFMGR                 *bufmgr)
837 {
838 
839     DDI_CHK_NULL(mediaBuffer, "mediaBuffer is nullptr", VA_STATUS_ERROR_INVALID_BUFFER);
840     DDI_CHK_NULL(mediaBuffer->pMediaCtx, "mediaBuffer->pMediaCtx is nullptr", VA_STATUS_ERROR_INVALID_BUFFER);
841     DDI_CHK_NULL(mediaBuffer->pMediaCtx->pGmmClientContext, "mediaBuffer->pMediaCtx->pGmmClientContext is nullptr", VA_STATUS_ERROR_INVALID_BUFFER);
842     if(format >= Media_Format_Count)
843        return VA_STATUS_ERROR_INVALID_PARAMETER;
844 
845     VAStatus     hRes = VA_STATUS_SUCCESS;
846     int32_t      mem_type = MOS_MEMPOOL_VIDEOMEMORY;
847 
848     // create fake GmmResourceInfo
849     GMM_RESCREATE_PARAMS    gmmParams;
850     MOS_ZeroMemory(&gmmParams, sizeof(gmmParams));
851     gmmParams.BaseWidth             = 1;
852     gmmParams.BaseHeight            = 1;
853     gmmParams.ArraySize             = 0;
854     gmmParams.Type                  = RESOURCE_1D;
855     gmmParams.Format                = GMM_FORMAT_GENERIC_8BIT;
856     gmmParams.Flags.Gpu.Video       = true;
857     gmmParams.Flags.Info.Linear     = true;
858     DDI_CHK_NULL(mediaBuffer->pMediaCtx, "MediaCtx is null", VA_STATUS_ERROR_INVALID_BUFFER);
859     gmmParams.Flags.Info.LocalOnly = MEDIA_IS_SKU(&mediaBuffer->pMediaCtx->SkuTable, FtrLocalMemory);
860 
861     mediaBuffer->pGmmResourceInfo = mediaBuffer->pMediaCtx->pGmmClientContext->CreateResInfoObject(&gmmParams);
862 
863     DDI_CHK_NULL(mediaBuffer->pGmmResourceInfo, "pGmmResourceInfo is nullptr", VA_STATUS_ERROR_INVALID_BUFFER);
864     mediaBuffer->pGmmResourceInfo->OverrideSize(mediaBuffer->iSize);
865     mediaBuffer->pGmmResourceInfo->OverrideBaseWidth(mediaBuffer->iSize);
866     mediaBuffer->pGmmResourceInfo->OverridePitch(mediaBuffer->iSize);
867 
868     MemoryPolicyParameter memPolicyPar;
869     MOS_ZeroMemory(&memPolicyPar, sizeof(MemoryPolicyParameter));
870 
871     memPolicyPar.skuTable = &mediaBuffer->pMediaCtx->SkuTable;
872     memPolicyPar.waTable = &mediaBuffer->pMediaCtx->WaTable;
873     memPolicyPar.resInfo = mediaBuffer->pGmmResourceInfo;
874     memPolicyPar.resName = "Media Buffer";
875     memPolicyPar.uiType = mediaBuffer->uiType;
876     memPolicyPar.preferredMemType = mediaBuffer->bUseSysGfxMem ? MOS_MEMPOOL_SYSTEMMEMORY : 0;
877 
878     mem_type = MemoryPolicyManager::UpdateMemoryPolicy(&memPolicyPar);
879 
880     struct mos_drm_bo_alloc alloc;
881     alloc.name = "Media Buffer";
882     alloc.size = size;
883     alloc.alignment = 4096;
884     alloc.ext.mem_type = mem_type;
885     MOS_LINUX_BO *bo  = mos_bo_alloc(bufmgr, &alloc);
886 
887     mediaBuffer->bMapped = false;
888     if (bo)
889     {
890         mediaBuffer->format     = format;
891         mediaBuffer->iSize      = size;
892         mediaBuffer->iRefCount  = 0;
893         mediaBuffer->bo         = bo;
894         mediaBuffer->pData      = (uint8_t*) bo->virt;
895 
896         DDI_VERBOSEMESSAGE("Alloc %8d bytes resource.",size);
897         uint32_t event[] = {bo->handle, format, size, 1, size, bo->size, 0, 0};
898         MOS_TraceEventExt(EVENT_VA_BUFFER, EVENT_TYPE_INFO, event, sizeof(event), &mediaBuffer->pGmmResourceInfo->GetResFlags(), sizeof(GMM_RESOURCE_FLAG));
899     }
900     else
901     {
902         DDI_ASSERTMESSAGE("Fail to Alloc %8d bytes resource.",size);
903         hRes = VA_STATUS_ERROR_ALLOCATION_FAILED;
904         goto finish;
905     }
906 
907 finish:
908     return hRes;
909 }
910 
911 //!
912 //! \brief  Allocate 2D buffer
913 //!
914 //! \param  [in] height
915 //!         Height of the region
916 //! \param  [in] width
917 //!         Width of the region
918 //! \param  [out] mediaBuffer
919 //!         Pointer to ddi media buffer
920 //! \param  [in] bufmgr
921 //!         Mos buffer manager
922 //!
923 //! \return VAStatus
924 //!     VA_STATUS_SUCCESS if success, else fail reason
925 //!
DdiMediaUtil_Allocate2DBuffer(uint32_t height,uint32_t width,PDDI_MEDIA_BUFFER mediaBuffer,MOS_BUFMGR * bufmgr)926 VAStatus DdiMediaUtil_Allocate2DBuffer(
927     uint32_t                    height,
928     uint32_t                    width,
929     PDDI_MEDIA_BUFFER           mediaBuffer,
930     MOS_BUFMGR                 *bufmgr)
931 {
932     DDI_CHK_NULL(mediaBuffer, "mediaBuffer is nullptr", VA_STATUS_ERROR_INVALID_BUFFER);
933     DDI_CHK_NULL(mediaBuffer->pMediaCtx, "mediaBuffer->pMediaCtx is nullptr", VA_STATUS_ERROR_INVALID_BUFFER);
934     DDI_CHK_NULL(mediaBuffer->pMediaCtx->pGmmClientContext, "mediaBuffer->pMediaCtx->pGmmClientContext is nullptr", VA_STATUS_ERROR_INVALID_BUFFER);
935 
936     int32_t  size           = 0;
937     uint32_t tileformat     = TILING_NONE;
938     VAStatus hRes           = VA_STATUS_SUCCESS;
939     int32_t  mem_type       = MOS_MEMPOOL_VIDEOMEMORY;
940 
941     // Create GmmResourceInfo
942     GMM_RESCREATE_PARAMS        gmmParams;
943     MOS_ZeroMemory(&gmmParams, sizeof(gmmParams));
944     gmmParams.BaseWidth             = width;
945     gmmParams.BaseHeight            = height;
946     gmmParams.ArraySize             = 1;
947     gmmParams.Type                  = RESOURCE_2D;
948     gmmParams.Format                = GMM_FORMAT_GENERIC_8BIT;
949 
950     DDI_CHK_CONDITION(gmmParams.Format == GMM_FORMAT_INVALID,
951                          "Unsupported format",
952                          VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT);
953 
954     gmmParams.Flags.Info.Linear = true;
955     gmmParams.Flags.Gpu.Video   = true;
956     DDI_CHK_NULL(mediaBuffer->pMediaCtx, "MediaCtx is null", VA_STATUS_ERROR_INVALID_BUFFER);
957     gmmParams.Flags.Info.LocalOnly = MEDIA_IS_SKU(&mediaBuffer->pMediaCtx->SkuTable, FtrLocalMemory);
958     GMM_RESOURCE_INFO          *gmmResourceInfo;
959     mediaBuffer->pGmmResourceInfo = gmmResourceInfo = mediaBuffer->pMediaCtx->pGmmClientContext->CreateResInfoObject(&gmmParams);
960 
961     if(nullptr == gmmResourceInfo)
962     {
963         DDI_VERBOSEMESSAGE("Gmm Create Resource Failed.");
964         hRes = VA_STATUS_ERROR_ALLOCATION_FAILED;
965         return hRes;
966     }
967     uint32_t    gmmPitch;
968     uint32_t    gmmSize;
969     uint32_t    gmmHeight;
970     gmmPitch    = (uint32_t)gmmResourceInfo->GetRenderPitch();
971     gmmSize     = (uint32_t)gmmResourceInfo->GetSizeSurface();
972     gmmHeight   = gmmResourceInfo->GetBaseHeight();
973 
974     MemoryPolicyParameter memPolicyPar;
975     MOS_ZeroMemory(&memPolicyPar, sizeof(MemoryPolicyParameter));
976 
977     memPolicyPar.skuTable = &mediaBuffer->pMediaCtx->SkuTable;
978     memPolicyPar.waTable = &mediaBuffer->pMediaCtx->WaTable;
979     memPolicyPar.resInfo = mediaBuffer->pGmmResourceInfo;
980     memPolicyPar.resName = "Media 2D Buffer";
981     memPolicyPar.uiType   = mediaBuffer->uiType;
982     memPolicyPar.preferredMemType = mediaBuffer->bUseSysGfxMem ? MOS_MEMPOOL_SYSTEMMEMORY : 0;
983 
984     mem_type = MemoryPolicyManager::UpdateMemoryPolicy(&memPolicyPar);
985 
986     MOS_LINUX_BO  *bo;
987     struct mos_drm_bo_alloc alloc;
988     alloc.name = "Media 2D Buffer";
989     alloc.size = gmmSize;
990     alloc.alignment = 4096;
991     alloc.ext.mem_type = mem_type;
992     bo = mos_bo_alloc(bufmgr, &alloc);
993 
994     mediaBuffer->bMapped = false;
995     if (bo)
996     {
997         mediaBuffer->format     = Media_Format_2DBuffer;
998         mediaBuffer->uiWidth    = width;
999         mediaBuffer->uiHeight   = gmmHeight;
1000         mediaBuffer->uiPitch    = gmmPitch;
1001         mediaBuffer->iSize      = gmmSize;
1002         mediaBuffer->iRefCount  = 0;
1003         mediaBuffer->bo         = bo;
1004         mediaBuffer->TileType   = tileformat;
1005         mediaBuffer->pData      = (uint8_t*) bo->virt;
1006         DDI_VERBOSEMESSAGE("Alloc %7d bytes (%d x %d resource)\n",size, width, height);
1007         uint32_t event[] = {bo->handle, mediaBuffer->format, width, height, gmmPitch, bo->size, tileformat, 0};
1008         MOS_TraceEventExt(EVENT_VA_BUFFER, EVENT_TYPE_INFO, event, sizeof(event), &gmmResourceInfo->GetResFlags(), sizeof(GMM_RESOURCE_FLAG));
1009     }
1010     else
1011     {
1012         DDI_VERBOSEMESSAGE("Fail to Alloc %7d bytes (%d x %d resource)\n", size, width, height);
1013         hRes = VA_STATUS_ERROR_ALLOCATION_FAILED;
1014     }
1015 
1016 finish:
1017     return hRes;
1018 }
1019 
DdiMediaUtil_CreateSurface(DDI_MEDIA_SURFACE * surface,PDDI_MEDIA_CONTEXT mediaDrvCtx)1020 VAStatus DdiMediaUtil_CreateSurface(DDI_MEDIA_SURFACE  *surface, PDDI_MEDIA_CONTEXT mediaDrvCtx)
1021 {
1022     VAStatus hr = VA_STATUS_SUCCESS;
1023 
1024     DDI_CHK_NULL(surface, "nullptr surface", VA_STATUS_ERROR_INVALID_BUFFER);
1025 
1026     // better to differentiate 1D and 2D type
1027     hr = DdiMediaUtil_AllocateSurface(surface->format,
1028                          surface->iWidth,
1029                          surface->iHeight,
1030                          surface,
1031                          mediaDrvCtx);
1032     if (VA_STATUS_SUCCESS == hr && nullptr != surface->bo)
1033         surface->base = surface->name;
1034 
1035     return hr;
1036 }
1037 
DdiMediaUtil_CreateBuffer(DDI_MEDIA_BUFFER * buffer,MOS_BUFMGR * bufmgr)1038 VAStatus DdiMediaUtil_CreateBuffer(DDI_MEDIA_BUFFER *buffer, MOS_BUFMGR *bufmgr)
1039 {
1040     VAStatus hr = VA_STATUS_SUCCESS;
1041 
1042     DDI_CHK_NULL(buffer, "nullptr buffer", VA_STATUS_ERROR_INVALID_BUFFER);
1043 
1044     DDI_CHK_LESS(buffer->format, Media_Format_Count, "Invalid buffer->format", VA_STATUS_ERROR_INVALID_PARAMETER);
1045 
1046     if (buffer->format == Media_Format_CPU)
1047     {
1048         buffer->pData= (uint8_t*)MOS_AllocAndZeroMemory(buffer->iSize);
1049         if (nullptr == buffer->pData)
1050             hr = VA_STATUS_ERROR_ALLOCATION_FAILED;
1051     }
1052 
1053     else
1054     {
1055         if (Media_Format_2DBuffer == buffer->format)
1056         {
1057             hr = DdiMediaUtil_Allocate2DBuffer(buffer->uiHeight,
1058                                   buffer->uiWidth,
1059                                   buffer,
1060                                   bufmgr);
1061          }
1062          else
1063          {
1064              hr = DdiMediaUtil_AllocateBuffer(buffer->format,
1065                                  buffer->iSize,
1066                                  buffer,
1067                                  bufmgr);
1068          }
1069     }
1070 
1071     buffer->uiLockedBufID   = VA_INVALID_ID;
1072     buffer->uiLockedImageID = VA_INVALID_ID;
1073     buffer->iRefCount       = 0;
1074 
1075     return hr;
1076 }
1077 
1078 VAStatus SwizzleSurface(PDDI_MEDIA_CONTEXT mediaCtx, PGMM_RESOURCE_INFO pGmmResInfo, void *pLockedAddr, uint32_t TileType, uint8_t* pResourceBase, bool bUpload);
1079 
CreateShadowResource(DDI_MEDIA_SURFACE * surface)1080 static VAStatus CreateShadowResource(DDI_MEDIA_SURFACE *surface)
1081 {
1082     VAStatus vaStatus = VA_STATUS_SUCCESS;
1083     DDI_CHK_NULL(surface, "nullptr surface", VA_STATUS_ERROR_INVALID_SURFACE);
1084 
1085     if (surface->pGmmResourceInfo->GetSetCpSurfTag(0, 0) != 0)
1086     {
1087         return VA_STATUS_ERROR_INVALID_SURFACE;
1088     }
1089 
1090     // 422V fallback to SW swizzle
1091     if (surface->iWidth < 64 || surface->iRealHeight < 64 || (surface->iPitch % 64 != 0) || surface->format == Media_Format_P016 || surface->format == Media_Format_422V)
1092     {
1093         return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
1094     }
1095 
1096     surface->pShadowBuffer = (DDI_MEDIA_BUFFER *)MOS_AllocAndZeroMemory(sizeof(DDI_MEDIA_BUFFER));
1097     DDI_CHK_NULL(surface->pShadowBuffer, "Failed to allocate shadow buffer", VA_STATUS_ERROR_INVALID_BUFFER);
1098     surface->pShadowBuffer->pMediaCtx = surface->pMediaCtx;
1099     surface->pShadowBuffer->bUseSysGfxMem = true;
1100     surface->pShadowBuffer->iSize = surface->pGmmResourceInfo->GetSizeSurface();
1101 
1102     vaStatus = DdiMediaUtil_AllocateBuffer(Media_Format_Buffer,
1103                                  surface->pShadowBuffer->iSize,
1104                                  surface->pShadowBuffer,
1105                                  surface->pMediaCtx->pDrmBufMgr);
1106 
1107     if (vaStatus != VA_STATUS_SUCCESS)
1108     {
1109         MOS_FreeMemory(surface->pShadowBuffer);
1110         surface->pShadowBuffer = nullptr;
1111     }
1112 
1113     return vaStatus;
1114 }
1115 
1116 //!
1117 //! \brief  Swizzle surface by Hardware, current only support VEBOX
1118 //!
1119 //! \param  [in] surface
1120 //!         Pointer of surface
1121 //! \param  [in] isDeSwizzle
1122 //!         Whether it's de-swizzling or not
1123 //!         Swizzling    - copying from video memory to temporary buffer
1124 //!         De-swizzling - copying from temporary buffer to video memory
1125 //!
1126 //! \return VAStatus
1127 //!     VA_STATUS_SUCCESS if success, else fail reason
1128 //!
SwizzleSurfaceByHW(DDI_MEDIA_SURFACE * surface,bool isDeSwizzle=false)1129 static VAStatus SwizzleSurfaceByHW(DDI_MEDIA_SURFACE *surface, bool isDeSwizzle = false)
1130 {
1131     DDI_CHK_NULL(surface, "nullptr surface", VA_STATUS_ERROR_INVALID_SURFACE);
1132     DDI_CHK_NULL(surface->pMediaCtx, "nullptr media context", VA_STATUS_ERROR_INVALID_CONTEXT);
1133 
1134     MOS_CONTEXT mosCtx = { };
1135     PERF_DATA perfData = { };
1136     PDDI_MEDIA_CONTEXT mediaDrvCtx = surface->pMediaCtx;
1137     VAStatus vaStatus = VA_STATUS_SUCCESS;
1138 
1139     // Get the buf manager for codechal create
1140     mosCtx.bufmgr          = mediaDrvCtx->pDrmBufMgr;
1141     mosCtx.m_gpuContextMgr = mediaDrvCtx->m_gpuContextMgr;
1142     mosCtx.m_cmdBufMgr     = mediaDrvCtx->m_cmdBufMgr;
1143     mosCtx.fd              = mediaDrvCtx->fd;
1144     mosCtx.iDeviceId       = mediaDrvCtx->iDeviceId;
1145     mosCtx.m_skuTable      = mediaDrvCtx->SkuTable;
1146     mosCtx.m_waTable       = mediaDrvCtx->WaTable;
1147     mosCtx.m_gtSystemInfo  = *mediaDrvCtx->pGtSystemInfo;
1148     mosCtx.m_platform      = mediaDrvCtx->platform;
1149 
1150     mosCtx.ppMediaMemDecompState = &mediaDrvCtx->pMediaMemDecompState;
1151     mosCtx.pfnMemoryDecompress   = mediaDrvCtx->pfnMemoryDecompress;
1152     mosCtx.pfnMediaMemoryCopy    = mediaDrvCtx->pfnMediaMemoryCopy;
1153     mosCtx.pfnMediaMemoryCopy2D  = mediaDrvCtx->pfnMediaMemoryCopy2D;
1154     mosCtx.pPerfData             = &perfData;
1155     mosCtx.m_gtSystemInfo        = *mediaDrvCtx->pGtSystemInfo;
1156     mosCtx.m_auxTableMgr         = mediaDrvCtx->m_auxTableMgr;
1157     mosCtx.pGmmClientContext     = mediaDrvCtx->pGmmClientContext;
1158     mosCtx.m_userSettingPtr      = mediaDrvCtx->m_userSettingPtr;
1159 
1160     mosCtx.m_osDeviceContext     = mediaDrvCtx->m_osDeviceContext;
1161 
1162     MOS_RESOURCE source = {};
1163     MOS_RESOURCE target = {};
1164 
1165     if (isDeSwizzle)
1166     {
1167         DdiMedia_MediaBufferToMosResource(surface->pShadowBuffer, &source);
1168         DdiMedia_MediaSurfaceToMosResource(surface, &target);
1169     }
1170     else
1171     {
1172         DdiMedia_MediaSurfaceToMosResource(surface, &source);
1173         DdiMedia_MediaBufferToMosResource(surface->pShadowBuffer, &target);
1174     }
1175 
1176     DdiMediaUtil_LockMutex(&mediaDrvCtx->MemDecompMutex);
1177     vaStatus = mediaDrvCtx->pfnMediaMemoryTileConvert(
1178             &mosCtx,
1179             &source,
1180             &target,
1181             surface->pGmmResourceInfo->GetBaseWidth(),
1182             surface->pGmmResourceInfo->GetBaseHeight(),
1183             0,
1184             0,
1185             !isDeSwizzle,
1186             false);
1187     DdiMediaUtil_UnLockMutex(&mediaDrvCtx->MemDecompMutex);
1188     return vaStatus;
1189 }
1190 
DdiMediaUtil_LockSurface(DDI_MEDIA_SURFACE * surface,uint32_t flag)1191 void* DdiMediaUtil_LockSurface(DDI_MEDIA_SURFACE* surface, uint32_t flag)
1192 {
1193     DDI_CHK_NULL(surface, "nullptr surface", nullptr);
1194     DDI_CHK_NULL(surface->pMediaCtx, "nullptr surface->pMediaCtx", nullptr);
1195     if (MEDIA_IS_SKU(&surface->pMediaCtx->SkuTable, FtrLocalMemory))
1196     {
1197         if ((MosUtilities::MosAtomicIncrement(&surface->iRefCount) == 1) && (false == surface->bMapped))
1198         {
1199            return  DdiMediaUtil_LockSurfaceInternal(surface, flag);
1200         }
1201         else
1202         {
1203             DDI_VERBOSEMESSAGE("line %d, invalide operation for lockSurface. the surface reference count = %d", __LINE__, surface->iRefCount);
1204         }
1205     }
1206     else
1207     {
1208          if ((surface->iRefCount == 0) && (false == surface->bMapped))
1209          {
1210              DdiMediaUtil_LockSurfaceInternal(surface, flag);
1211          }
1212          else
1213          {
1214              // do nothing here
1215          }
1216          surface->iRefCount++;
1217     }
1218 
1219     return surface->pData;
1220 
1221 }
1222 
1223 // add thread protection for multiple thread?
DdiMediaUtil_LockSurfaceInternal(DDI_MEDIA_SURFACE * surface,uint32_t flag)1224 void* DdiMediaUtil_LockSurfaceInternal(DDI_MEDIA_SURFACE  *surface, uint32_t flag)
1225 {
1226     DDI_CHK_NULL(surface, "nullptr surface", nullptr);
1227     DDI_CHK_NULL(surface->bo, "nullptr surface->bo", nullptr);
1228 
1229     if (surface->pMediaCtx->bIsAtomSOC)
1230     {
1231         mos_bo_map_gtt(surface->bo);
1232     }
1233     else
1234     {
1235         if (surface->TileType == TILING_NONE)
1236         {
1237             mos_bo_map(surface->bo, flag & MOS_LOCKFLAG_WRITEONLY);
1238         }
1239         else if ((surface->pMediaCtx->m_useSwSwizzling) && !(flag & MOS_LOCKFLAG_NO_SWIZZLE))
1240         {
1241             uint64_t surfSize = surface->pGmmResourceInfo->GetSizeMainSurface();
1242             DDI_CHK_CONDITION((surface->TileType != TILING_Y), "Unsupported tile type", nullptr);
1243             DDI_CHK_CONDITION((surfSize <= 0 || surface->iPitch <= 0), "Invalid surface size or pitch", nullptr);
1244 
1245             VAStatus vaStatus = VA_STATUS_SUCCESS;
1246             if (MEDIA_IS_SKU(&surface->pMediaCtx->SkuTable, FtrLocalMemory))
1247             {
1248                 if (surface->pShadowBuffer == nullptr)
1249                 {
1250                     CreateShadowResource(surface);
1251                 }
1252 
1253                 if (surface->pShadowBuffer != nullptr)
1254                 {
1255                     vaStatus = SwizzleSurfaceByHW(surface);
1256                     int err = 0;
1257                     if (vaStatus == VA_STATUS_SUCCESS)
1258                     {
1259                         err = mos_bo_map(surface->pShadowBuffer->bo, flag & MOS_LOCKFLAG_WRITEONLY);
1260                     }
1261 
1262                     if (vaStatus != VA_STATUS_SUCCESS || err != 0)
1263                     {
1264                         DdiMediaUtil_FreeBuffer(surface->pShadowBuffer);
1265                         MOS_FreeMemory(surface->pShadowBuffer);
1266                         surface->pShadowBuffer = nullptr;
1267                     }
1268                 }
1269             }
1270 
1271             mos_bo_map(surface->bo, flag & MOS_LOCKFLAG_WRITEONLY);
1272 
1273             if (surface->pShadowBuffer == nullptr)
1274             {
1275                 if (surface->pSystemShadow == nullptr)
1276                 {
1277                     surface->pSystemShadow = (uint8_t*)MOS_AllocMemory(surface->bo->size);
1278                     DDI_CHK_CONDITION((surface->pSystemShadow == nullptr), "Failed to allocate shadow surface", nullptr);
1279                 }
1280 
1281                 vaStatus = SwizzleSurface(surface->pMediaCtx,
1282                                                    surface->pGmmResourceInfo,
1283                                                    surface->bo->virt,
1284                                                    (MOS_TILE_TYPE)surface->TileType,
1285                                                    (uint8_t *)surface->pSystemShadow,
1286                                                    false);
1287                 DDI_CHK_CONDITION((vaStatus != VA_STATUS_SUCCESS), "SwizzleSurface failed", nullptr);
1288             }
1289 
1290         }
1291         else if (flag & MOS_LOCKFLAG_NO_SWIZZLE)
1292         {
1293             mos_bo_map(surface->bo, flag & MOS_LOCKFLAG_READONLY);
1294         }
1295         else if (flag & MOS_LOCKFLAG_WRITEONLY)
1296         {
1297             mos_bo_map_gtt(surface->bo);
1298         }
1299         else
1300         {
1301             mos_bo_map_unsynchronized(surface->bo);     // only call mmap_gtt ioctl
1302             mos_bo_start_gtt_access(surface->bo, 0);    // set to GTT domain,0 means readonly
1303         }
1304     }
1305     surface->uiMapFlag = flag;
1306     if (surface->pShadowBuffer)
1307     {
1308         surface->pData = (uint8_t *)surface->pShadowBuffer->bo->virt;
1309     }
1310     else if (surface->pSystemShadow)
1311     {
1312         surface->pData = surface->pSystemShadow;
1313     }
1314     else
1315     {
1316         surface->pData = (uint8_t*) surface->bo->virt;
1317     }
1318     surface->data_size = surface->bo->size;
1319     surface->bMapped = true;
1320 
1321     return surface->pData;
1322 }
1323 
DdiMediaUtil_UnlockSurface(DDI_MEDIA_SURFACE * surface)1324 void DdiMediaUtil_UnlockSurface(DDI_MEDIA_SURFACE *surface)
1325 {
1326     DDI_CHK_NULL(surface, "nullptr surface", );
1327     DDI_CHK_NULL(surface->pMediaCtx, "nullptr surface->pMediaCtx", );
1328     if (0 == surface->iRefCount)
1329      return;
1330 
1331     if (MEDIA_IS_SKU(&surface->pMediaCtx->SkuTable, FtrLocalMemory))
1332     {
1333         if (MosUtilities::MosAtomicDecrement(&surface->iRefCount) == 0 && (true == surface->bMapped))
1334         {
1335             DdiMediaUtil_UnlockSurfaceInternal(surface);
1336         }
1337         else
1338         {
1339             DDI_VERBOSEMESSAGE("invalide operation for unlockSurface. the surface reference count = %d", surface->iRefCount);
1340         }
1341     }
1342     else
1343     {
1344         if ((1 == surface->iRefCount) && (true == surface->bMapped))
1345         {
1346            DdiMediaUtil_UnlockSurfaceInternal(surface);
1347         }
1348         else
1349         {
1350            DDI_VERBOSEMESSAGE("invalide operation for unlockSurface. the surface reference count = %d", surface->iRefCount);
1351         }
1352         surface->iRefCount --;
1353     }
1354 }
1355 
DdiMediaUtil_UnlockSurfaceInternal(DDI_MEDIA_SURFACE * surface)1356 void DdiMediaUtil_UnlockSurfaceInternal(DDI_MEDIA_SURFACE  *surface)
1357 {
1358     DDI_CHK_NULL(surface, "nullptr surface",);
1359     DDI_CHK_NULL(surface->bo, "nullptr surface->bo", );
1360 
1361     if (surface->pMediaCtx->bIsAtomSOC)
1362     {
1363         mos_bo_unmap_gtt(surface->bo);
1364     }
1365     else
1366     {
1367         if (surface->TileType == TILING_NONE)
1368         {
1369            mos_bo_unmap(surface->bo);
1370         }
1371         else if (surface->pShadowBuffer != nullptr)
1372         {
1373             SwizzleSurfaceByHW(surface, true);
1374 
1375             mos_bo_unmap(surface->pShadowBuffer->bo);
1376             mos_bo_unmap(surface->bo);
1377         }
1378         else if (surface->pSystemShadow)
1379         {
1380             SwizzleSurface(surface->pMediaCtx,
1381                            surface->pGmmResourceInfo,
1382                            surface->bo->virt,
1383                            (MOS_TILE_TYPE)surface->TileType,
1384                            (uint8_t *)surface->pSystemShadow,
1385                            true);
1386 
1387             MOS_FreeMemory(surface->pSystemShadow);
1388             surface->pSystemShadow = nullptr;
1389 
1390             mos_bo_unmap(surface->bo);
1391         }
1392         else if(surface->uiMapFlag & MOS_LOCKFLAG_NO_SWIZZLE)
1393         {
1394             mos_bo_unmap(surface->bo);
1395         }
1396         else
1397         {
1398            mos_bo_unmap_gtt(surface->bo);
1399         }
1400     }
1401     surface->pData       = nullptr;
1402     surface->bo->virt    = nullptr;
1403     surface->bMapped     = false;
1404 }
1405 
1406 // add thread protection for multiple thread?
1407 // MapBuffer?
DdiMediaUtil_LockBuffer(DDI_MEDIA_BUFFER * buf,uint32_t flag)1408 void* DdiMediaUtil_LockBuffer(DDI_MEDIA_BUFFER *buf, uint32_t flag)
1409 {
1410     DDI_CHK_NULL(buf, "nullptr buf", nullptr);
1411     if((Media_Format_CPU != buf->format) && (false == buf->bMapped))
1412     {
1413         if (nullptr != buf->pSurface)
1414         {
1415             DdiMediaUtil_LockSurface(buf->pSurface, flag);
1416             buf->pData = buf->pSurface->pData;
1417         }
1418         else
1419         {
1420             if (buf->pMediaCtx->bIsAtomSOC)
1421             {
1422                 mos_bo_map_gtt(buf->bo);
1423             }
1424             else
1425             {
1426                 if (buf->TileType == TILING_NONE)
1427                 {
1428                     mos_bo_map(buf->bo, ((MOS_LOCKFLAG_READONLY | MOS_LOCKFLAG_WRITEONLY) & flag));
1429                 }
1430                 else
1431                 {
1432                     mos_bo_map_gtt(buf->bo);
1433                 }
1434              }
1435 
1436             buf->pData = (uint8_t*)(buf->bo->virt);
1437         }
1438 
1439         buf->bMapped = true;
1440         buf->iRefCount++;
1441     }
1442     else if ((Media_Format_CPU == buf->format) && (false == buf->bMapped))
1443     {
1444         buf->bMapped = true;
1445         buf->iRefCount++;
1446     }
1447     else
1448     {
1449         buf->iRefCount++;
1450     }
1451 
1452     return buf->pData;
1453 }
1454 
DdiMediaUtil_UnlockBuffer(DDI_MEDIA_BUFFER * buf)1455 void DdiMediaUtil_UnlockBuffer(DDI_MEDIA_BUFFER *buf)
1456 {
1457     DDI_CHK_NULL(buf, "nullptr buf", );
1458     if (0 == buf->iRefCount)
1459         return;
1460     if((true == buf->bMapped) && (Media_Format_CPU != buf->format) && (1 == buf->iRefCount))
1461     {
1462         if (nullptr != buf->pSurface)
1463         {
1464             DdiMediaUtil_UnlockSurface(buf->pSurface);
1465         }
1466         else
1467         {
1468              if (buf->pMediaCtx->bIsAtomSOC)
1469              {
1470                  mos_bo_unmap_gtt(buf->bo);
1471              }
1472              else
1473              {
1474                  if (buf->TileType == TILING_NONE)
1475                  {
1476                      mos_bo_unmap(buf->bo);
1477                  }
1478                  else
1479                  {
1480                      mos_bo_unmap_gtt(buf->bo);
1481                  }
1482             }
1483             buf->bo->virt = nullptr;
1484         }
1485 
1486         buf->pData       = nullptr;
1487 
1488         buf->bMapped     = false;
1489     }
1490     else if ((true == buf->bMapped) && (Media_Format_CPU == buf->format) && (1 == buf->iRefCount))
1491     {
1492         buf->bMapped     = false;
1493     }
1494     else
1495     {
1496         // do nothing here
1497     }
1498     buf->iRefCount--;
1499 }
1500 
1501 // should ref_count added for bo?
DdiMediaUtil_FreeSurface(DDI_MEDIA_SURFACE * surface)1502 void DdiMediaUtil_FreeSurface(DDI_MEDIA_SURFACE *surface)
1503 {
1504     DDI_CHK_NULL(surface, "nullptr surface", );
1505     DDI_CHK_NULL(surface->bo, "nullptr surface->bo", );
1506     DDI_CHK_NULL(surface->pMediaCtx, "nullptr surface->pMediaCtx", );
1507     DDI_CHK_NULL(surface->pMediaCtx->pGmmClientContext, "nullptr surface->pMediaCtx->pGmmClientContext", );
1508 
1509     // Unmap Aux mapping if the surface was mapped
1510     if (surface->pMediaCtx->m_auxTableMgr)
1511     {
1512         surface->pMediaCtx->m_auxTableMgr->UnmapResource(surface->pGmmResourceInfo, surface->bo);
1513     }
1514 
1515     // free shadow buffer it created
1516     if (surface->pShadowBuffer != nullptr)
1517     {
1518         DdiMediaUtil_FreeBuffer(surface->pShadowBuffer);
1519         MOS_FreeMemory(surface->pShadowBuffer);
1520         surface->pShadowBuffer = nullptr;
1521     }
1522 
1523     if(surface->bMapped)
1524     {
1525         DdiMediaUtil_UnlockSurface(surface);
1526         DDI_VERBOSEMESSAGE("DDI: try to free a locked surface.");
1527     }
1528     mos_bo_unreference(surface->bo);
1529     // For External Buffer, only needs to destory SurfaceDescriptor
1530     if (surface->pSurfDesc)
1531     {
1532         MOS_FreeMemory(surface->pSurfDesc);
1533         surface->pSurfDesc = nullptr;
1534     }
1535 
1536     if (nullptr != surface->pGmmResourceInfo)
1537     {
1538         surface->pMediaCtx->pGmmClientContext->DestroyResInfoObject(surface->pGmmResourceInfo);
1539         surface->pGmmResourceInfo = nullptr;
1540     }
1541 }
1542 
1543 
1544 // should ref_count added for bo?
DdiMediaUtil_FreeBuffer(DDI_MEDIA_BUFFER * buf)1545 void DdiMediaUtil_FreeBuffer(DDI_MEDIA_BUFFER  *buf)
1546 {
1547     DDI_CHK_NULL(buf, "nullptr", );
1548     // calling sequence checking
1549     if (buf->bMapped)
1550     {
1551         DdiMediaUtil_UnlockBuffer(buf);
1552         DDI_VERBOSEMESSAGE("DDI: try to free a locked buffer.");
1553     }
1554     if (buf->format == Media_Format_CPU)
1555     {
1556         MOS_FreeMemory(buf->pData);
1557         buf->pData = nullptr;
1558     }
1559     else
1560     {
1561         mos_bo_unreference(buf->bo);
1562         buf->bo = nullptr;
1563     }
1564 
1565     if (nullptr != buf->pMediaCtx && nullptr != buf->pMediaCtx->pGmmClientContext && nullptr != buf->pGmmResourceInfo)
1566     {
1567         buf->pMediaCtx->pGmmClientContext->DestroyResInfoObject(buf->pGmmResourceInfo);
1568         buf->pGmmResourceInfo = nullptr;
1569     }
1570 }
1571 
1572 ///////////////////////////////////////////////////////////////////////////////////////////////////////
1573 // purpose: fill a rect structure with the regsion specified by parameters
1574 // rect[in]: input pointer to the rect
1575 // offset_x: x offset of the region
1576 // offset_y: y offset of the region
1577 // width:    width of the region
1578 // hiehgt:   height of the regsion
1579 ////////////////////////////////////////////////////////////////////////////////////////////////////
DdiMediaUtil_FillPositionToRect(RECT * rect,int16_t offset_x,int16_t offset_y,int16_t width,int16_t height)1580 VAStatus DdiMediaUtil_FillPositionToRect(RECT *rect, int16_t offset_x, int16_t offset_y, int16_t width, int16_t height)
1581 {
1582     DDI_CHK_NULL(rect, "Invalid Rect.", VA_STATUS_ERROR_INVALID_PARAMETER);
1583 
1584     rect->left   = offset_x;
1585     rect->top    = offset_y;
1586     rect->right  = offset_x + width;
1587     rect->bottom = offset_y + height;
1588 
1589     return VA_STATUS_SUCCESS;
1590 }
1591 
DdiMediaUtil_InitMutex(PMEDIA_MUTEX_T mutex)1592 void DdiMediaUtil_InitMutex(PMEDIA_MUTEX_T  mutex)
1593 {
1594     pthread_mutex_init(mutex, nullptr);
1595 }
1596 
DdiMediaUtil_DestroyMutex(PMEDIA_MUTEX_T mutex)1597 void DdiMediaUtil_DestroyMutex(PMEDIA_MUTEX_T  mutex)
1598 {
1599     int32_t ret = pthread_mutex_destroy(mutex);
1600     if(ret != 0)
1601     {
1602         DDI_NORMALMESSAGE("can't destroy the mutex!\n");
1603     }
1604 }
1605 
DdiMediaUtil_LockMutex(PMEDIA_MUTEX_T mutex)1606 void DdiMediaUtil_LockMutex(PMEDIA_MUTEX_T  mutex)
1607 {
1608     int32_t ret = pthread_mutex_lock(mutex);
1609     if(ret != 0)
1610     {
1611         DDI_NORMALMESSAGE("can't lock the mutex!\n");
1612     }
1613 }
1614 
DdiMediaUtil_UnLockMutex(PMEDIA_MUTEX_T mutex)1615 void DdiMediaUtil_UnLockMutex(PMEDIA_MUTEX_T  mutex)
1616 {
1617     int32_t ret = pthread_mutex_unlock(mutex);
1618     if(ret != 0)
1619     {
1620         DDI_NORMALMESSAGE("can't unlock the mutex!\n");
1621     }
1622 }
1623 
DdiMediaUtil_DestroySemaphore(PMEDIA_SEM_T sem)1624 void DdiMediaUtil_DestroySemaphore(PMEDIA_SEM_T  sem)
1625 {
1626     int32_t ret = sem_destroy(sem);
1627     if(ret != 0)
1628     {
1629         DDI_NORMALMESSAGE("can't destroy the semaphore!\n");
1630     }
1631 }
1632 
DdiMediaUtil_WaitSemaphore(PMEDIA_SEM_T sem)1633 void DdiMediaUtil_WaitSemaphore(PMEDIA_SEM_T  sem)
1634 {
1635     int32_t ret = sem_wait(sem);
1636     if(ret != 0)
1637     {
1638         DDI_NORMALMESSAGE("wait semaphore error!\n");
1639     }
1640 }
1641 
DdiMediaUtil_TryWaitSemaphore(PMEDIA_SEM_T sem)1642 int32_t DdiMediaUtil_TryWaitSemaphore(PMEDIA_SEM_T  sem)
1643 {
1644     return sem_trywait(sem);
1645 }
1646 
DdiMediaUtil_PostSemaphore(PMEDIA_SEM_T sem)1647 void DdiMediaUtil_PostSemaphore(PMEDIA_SEM_T  sem)
1648 {
1649     int32_t ret = sem_post(sem);
1650     if(ret != 0)
1651     {
1652         DDI_NORMALMESSAGE("post semaphore error!\n");
1653     }
1654 }
1655 
1656 // heap related
DdiMediaUtil_AllocPMediaSurfaceFromHeap(PDDI_MEDIA_HEAP surfaceHeap)1657 PDDI_MEDIA_SURFACE_HEAP_ELEMENT DdiMediaUtil_AllocPMediaSurfaceFromHeap(PDDI_MEDIA_HEAP surfaceHeap)
1658 {
1659     DDI_CHK_NULL(surfaceHeap, "nullptr surfaceHeap", nullptr);
1660 
1661     PDDI_MEDIA_SURFACE_HEAP_ELEMENT  mediaSurfaceHeapElmt = nullptr;
1662 
1663     if (nullptr == surfaceHeap->pFirstFreeHeapElement)
1664     {
1665         void *newHeapBase = MOS_ReallocMemory(surfaceHeap->pHeapBase, (surfaceHeap->uiAllocatedHeapElements + DDI_MEDIA_HEAP_INCREMENTAL_SIZE) * sizeof(DDI_MEDIA_SURFACE_HEAP_ELEMENT));
1666 
1667         if (nullptr == newHeapBase)
1668         {
1669             DDI_ASSERTMESSAGE("DDI: realloc failed.");
1670             return nullptr;
1671         }
1672         surfaceHeap->pHeapBase                    = newHeapBase;
1673         PDDI_MEDIA_SURFACE_HEAP_ELEMENT surfaceHeapBase  = (PDDI_MEDIA_SURFACE_HEAP_ELEMENT)surfaceHeap->pHeapBase;
1674         surfaceHeap->pFirstFreeHeapElement        = (void*)(&surfaceHeapBase[surfaceHeap->uiAllocatedHeapElements]);
1675         for (int32_t i = 0; i < (DDI_MEDIA_HEAP_INCREMENTAL_SIZE); i++)
1676         {
1677             mediaSurfaceHeapElmt                  = &surfaceHeapBase[surfaceHeap->uiAllocatedHeapElements + i];
1678             mediaSurfaceHeapElmt->pNextFree       = (i == (DDI_MEDIA_HEAP_INCREMENTAL_SIZE - 1))? nullptr : &surfaceHeapBase[surfaceHeap->uiAllocatedHeapElements + i + 1];
1679             mediaSurfaceHeapElmt->uiVaSurfaceID   = surfaceHeap->uiAllocatedHeapElements + i;
1680             mediaSurfaceHeapElmt->pSurface        = nullptr;
1681         }
1682         surfaceHeap->uiAllocatedHeapElements     += DDI_MEDIA_HEAP_INCREMENTAL_SIZE;
1683     }
1684 
1685     mediaSurfaceHeapElmt                          = (PDDI_MEDIA_SURFACE_HEAP_ELEMENT)surfaceHeap->pFirstFreeHeapElement;
1686     surfaceHeap->pFirstFreeHeapElement            = mediaSurfaceHeapElmt->pNextFree;
1687 
1688     return mediaSurfaceHeapElmt;
1689 }
1690 
1691 
DdiMediaUtil_ReleasePMediaSurfaceFromHeap(PDDI_MEDIA_HEAP surfaceHeap,uint32_t vaSurfaceID)1692 void DdiMediaUtil_ReleasePMediaSurfaceFromHeap(PDDI_MEDIA_HEAP surfaceHeap, uint32_t vaSurfaceID)
1693 {
1694     DDI_CHK_NULL(surfaceHeap, "nullptr surfaceHeap", );
1695 
1696     DDI_CHK_LESS(vaSurfaceID, surfaceHeap->uiAllocatedHeapElements, "invalid surface id", );
1697     PDDI_MEDIA_SURFACE_HEAP_ELEMENT mediaSurfaceHeapBase                   = (PDDI_MEDIA_SURFACE_HEAP_ELEMENT)surfaceHeap->pHeapBase;
1698     DDI_CHK_NULL(mediaSurfaceHeapBase, "nullptr mediaSurfaceHeapBase", );
1699 
1700     PDDI_MEDIA_SURFACE_HEAP_ELEMENT mediaSurfaceHeapElmt                   = &mediaSurfaceHeapBase[vaSurfaceID];
1701     DDI_CHK_NULL(mediaSurfaceHeapElmt->pSurface, "surface is already released", );
1702     void *firstFree                         = surfaceHeap->pFirstFreeHeapElement;
1703     surfaceHeap->pFirstFreeHeapElement     = (void*)mediaSurfaceHeapElmt;
1704     mediaSurfaceHeapElmt->pNextFree        = (PDDI_MEDIA_SURFACE_HEAP_ELEMENT)firstFree;
1705     mediaSurfaceHeapElmt->pSurface         = nullptr;
1706 }
1707 
1708 
DdiMediaUtil_AllocPMediaBufferFromHeap(PDDI_MEDIA_HEAP bufferHeap)1709 PDDI_MEDIA_BUFFER_HEAP_ELEMENT DdiMediaUtil_AllocPMediaBufferFromHeap(PDDI_MEDIA_HEAP bufferHeap)
1710 {
1711     DDI_CHK_NULL(bufferHeap, "nullptr bufferHeap", nullptr);
1712 
1713     PDDI_MEDIA_BUFFER_HEAP_ELEMENT  mediaBufferHeapElmt = nullptr;
1714     if (nullptr == bufferHeap->pFirstFreeHeapElement)
1715     {
1716         void *newHeapBase = MOS_ReallocMemory(bufferHeap->pHeapBase, (bufferHeap->uiAllocatedHeapElements + DDI_MEDIA_HEAP_INCREMENTAL_SIZE) * sizeof(DDI_MEDIA_BUFFER_HEAP_ELEMENT));
1717         if (nullptr == newHeapBase)
1718         {
1719             DDI_ASSERTMESSAGE("DDI: realloc failed.");
1720             return nullptr;
1721         }
1722         bufferHeap->pHeapBase                                 = newHeapBase;
1723         PDDI_MEDIA_BUFFER_HEAP_ELEMENT mediaBufferHeapBase    = (PDDI_MEDIA_BUFFER_HEAP_ELEMENT)bufferHeap->pHeapBase;
1724         bufferHeap->pFirstFreeHeapElement     = (void*)(&mediaBufferHeapBase[bufferHeap->uiAllocatedHeapElements]);
1725         for (int32_t i = 0; i < (DDI_MEDIA_HEAP_INCREMENTAL_SIZE); i++)
1726         {
1727             mediaBufferHeapElmt               = &mediaBufferHeapBase[bufferHeap->uiAllocatedHeapElements + i];
1728             mediaBufferHeapElmt->pNextFree    = (i == (DDI_MEDIA_HEAP_INCREMENTAL_SIZE - 1))? nullptr : &mediaBufferHeapBase[bufferHeap->uiAllocatedHeapElements + i + 1];
1729             mediaBufferHeapElmt->uiVaBufferID = bufferHeap->uiAllocatedHeapElements + i;
1730         }
1731         bufferHeap->uiAllocatedHeapElements  += DDI_MEDIA_HEAP_INCREMENTAL_SIZE;
1732     }
1733 
1734     mediaBufferHeapElmt                       = (PDDI_MEDIA_BUFFER_HEAP_ELEMENT)bufferHeap->pFirstFreeHeapElement;
1735     bufferHeap->pFirstFreeHeapElement         = mediaBufferHeapElmt->pNextFree;
1736     return mediaBufferHeapElmt;
1737 }
1738 
1739 
DdiMediaUtil_ReleasePMediaBufferFromHeap(PDDI_MEDIA_HEAP bufferHeap,uint32_t vaBufferID)1740 void DdiMediaUtil_ReleasePMediaBufferFromHeap(PDDI_MEDIA_HEAP bufferHeap, uint32_t vaBufferID)
1741 {
1742     DDI_CHK_NULL(bufferHeap, "nullptr bufferHeap", );
1743 
1744     DDI_CHK_LESS(vaBufferID, bufferHeap->uiAllocatedHeapElements, "invalid buffer id", );
1745     PDDI_MEDIA_BUFFER_HEAP_ELEMENT mediaBufferHeapBase                    = (PDDI_MEDIA_BUFFER_HEAP_ELEMENT)bufferHeap->pHeapBase;
1746     PDDI_MEDIA_BUFFER_HEAP_ELEMENT mediaBufferHeapElmt                    = &mediaBufferHeapBase[vaBufferID];
1747     DDI_CHK_NULL(mediaBufferHeapElmt->pBuffer, "buffer is already released", );
1748     void *firstFree                        = bufferHeap->pFirstFreeHeapElement;
1749     bufferHeap->pFirstFreeHeapElement      = (void*)mediaBufferHeapElmt;
1750     mediaBufferHeapElmt->pNextFree         = (PDDI_MEDIA_BUFFER_HEAP_ELEMENT)firstFree;
1751     mediaBufferHeapElmt->pBuffer           = nullptr;
1752 }
1753 
DdiMediaUtil_AllocPVAImageFromHeap(PDDI_MEDIA_HEAP imageHeap)1754 PDDI_MEDIA_IMAGE_HEAP_ELEMENT DdiMediaUtil_AllocPVAImageFromHeap(PDDI_MEDIA_HEAP imageHeap)
1755 {
1756     PDDI_MEDIA_IMAGE_HEAP_ELEMENT   vaimageHeapElmt = nullptr;
1757 
1758     DDI_CHK_NULL(imageHeap, "nullptr imageHeap", nullptr);
1759 
1760     if (nullptr == imageHeap->pFirstFreeHeapElement)
1761     {
1762         void *newHeapBase = MOS_ReallocMemory(imageHeap->pHeapBase, (imageHeap->uiAllocatedHeapElements + DDI_MEDIA_HEAP_INCREMENTAL_SIZE) * sizeof(DDI_MEDIA_IMAGE_HEAP_ELEMENT));
1763 
1764         if (nullptr == newHeapBase)
1765         {
1766             DDI_ASSERTMESSAGE("DDI: realloc failed.");
1767             return nullptr;
1768         }
1769         imageHeap->pHeapBase                           = newHeapBase;
1770         PDDI_MEDIA_IMAGE_HEAP_ELEMENT vaimageHeapBase  = (PDDI_MEDIA_IMAGE_HEAP_ELEMENT)imageHeap->pHeapBase;
1771         imageHeap->pFirstFreeHeapElement               = (void*)(&vaimageHeapBase[imageHeap->uiAllocatedHeapElements]);
1772         for (int32_t i = 0; i < (DDI_MEDIA_HEAP_INCREMENTAL_SIZE); i++)
1773         {
1774             vaimageHeapElmt                   = &vaimageHeapBase[imageHeap->uiAllocatedHeapElements + i];
1775             vaimageHeapElmt->pNextFree        = (i == (DDI_MEDIA_HEAP_INCREMENTAL_SIZE - 1))? nullptr : &vaimageHeapBase[imageHeap->uiAllocatedHeapElements + i + 1];
1776             vaimageHeapElmt->uiVaImageID      = imageHeap->uiAllocatedHeapElements + i;
1777         }
1778         imageHeap->uiAllocatedHeapElements   += DDI_MEDIA_HEAP_INCREMENTAL_SIZE;
1779 
1780     }
1781 
1782     vaimageHeapElmt                           = (PDDI_MEDIA_IMAGE_HEAP_ELEMENT)imageHeap->pFirstFreeHeapElement;
1783     imageHeap->pFirstFreeHeapElement          = vaimageHeapElmt->pNextFree;
1784     return vaimageHeapElmt;
1785 }
1786 
1787 
DdiMediaUtil_ReleasePVAImageFromHeap(PDDI_MEDIA_HEAP imageHeap,uint32_t vaImageID)1788 void DdiMediaUtil_ReleasePVAImageFromHeap(PDDI_MEDIA_HEAP imageHeap, uint32_t vaImageID)
1789 {
1790     PDDI_MEDIA_IMAGE_HEAP_ELEMENT    vaImageHeapBase = nullptr;
1791     PDDI_MEDIA_IMAGE_HEAP_ELEMENT    vaImageHeapElmt = nullptr;
1792     void                            *firstFree      = nullptr;
1793 
1794     DDI_CHK_NULL(imageHeap, "nullptr imageHeap", );
1795 
1796     DDI_CHK_LESS(vaImageID, imageHeap->uiAllocatedHeapElements, "invalid image id", );
1797     vaImageHeapBase                    = (PDDI_MEDIA_IMAGE_HEAP_ELEMENT)imageHeap->pHeapBase;
1798     vaImageHeapElmt                    = &vaImageHeapBase[vaImageID];
1799     DDI_CHK_NULL(vaImageHeapElmt->pImage, "image is already released", );
1800     firstFree                          = imageHeap->pFirstFreeHeapElement;
1801     imageHeap->pFirstFreeHeapElement   = (void*)vaImageHeapElmt;
1802     vaImageHeapElmt->pNextFree         = (PDDI_MEDIA_IMAGE_HEAP_ELEMENT)firstFree;
1803     vaImageHeapElmt->pImage            = nullptr;
1804 }
1805 
DdiMediaUtil_AllocPVAContextFromHeap(PDDI_MEDIA_HEAP vaContextHeap)1806 PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT DdiMediaUtil_AllocPVAContextFromHeap(PDDI_MEDIA_HEAP vaContextHeap)
1807 {
1808     PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT   vacontextHeapElmt = nullptr;
1809     DDI_CHK_NULL(vaContextHeap, "nullptr vaContextHeap", nullptr);
1810 
1811     if (nullptr == vaContextHeap->pFirstFreeHeapElement)
1812     {
1813         void *newHeapBase = MOS_ReallocMemory(vaContextHeap->pHeapBase, (vaContextHeap->uiAllocatedHeapElements + DDI_MEDIA_HEAP_INCREMENTAL_SIZE) * sizeof(DDI_MEDIA_VACONTEXT_HEAP_ELEMENT));
1814 
1815         if (nullptr == newHeapBase)
1816         {
1817             DDI_ASSERTMESSAGE("DDI: realloc failed.");
1818             return nullptr;
1819         }
1820         vaContextHeap->pHeapBase                            = newHeapBase;
1821         PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT vacontextHeapBase = (PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT)vaContextHeap->pHeapBase;
1822         vaContextHeap->pFirstFreeHeapElement        = (void*)(&(vacontextHeapBase[vaContextHeap->uiAllocatedHeapElements]));
1823         for (int32_t i = 0; i < (DDI_MEDIA_HEAP_INCREMENTAL_SIZE); i++)
1824         {
1825             vacontextHeapElmt                       = &vacontextHeapBase[vaContextHeap->uiAllocatedHeapElements + i];
1826             vacontextHeapElmt->pNextFree            = (i == (DDI_MEDIA_HEAP_INCREMENTAL_SIZE - 1))? nullptr : &vacontextHeapBase[vaContextHeap->uiAllocatedHeapElements + i + 1];
1827             vacontextHeapElmt->uiVaContextID        = vaContextHeap->uiAllocatedHeapElements + i;
1828             vacontextHeapElmt->pVaContext           = nullptr;
1829         }
1830         vaContextHeap->uiAllocatedHeapElements     += DDI_MEDIA_HEAP_INCREMENTAL_SIZE;
1831     }
1832 
1833     vacontextHeapElmt                               = (PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT)vaContextHeap->pFirstFreeHeapElement;
1834     vaContextHeap->pFirstFreeHeapElement            = vacontextHeapElmt->pNextFree;
1835     return vacontextHeapElmt;
1836 }
1837 
1838 
DdiMediaUtil_ReleasePVAContextFromHeap(PDDI_MEDIA_HEAP vaContextHeap,uint32_t vaContextID)1839 void DdiMediaUtil_ReleasePVAContextFromHeap(PDDI_MEDIA_HEAP vaContextHeap, uint32_t vaContextID)
1840 {
1841     DDI_CHK_NULL(vaContextHeap, "nullptr vaContextHeap", );
1842     DDI_CHK_LESS(vaContextID, vaContextHeap->uiAllocatedHeapElements, "invalid context id", );
1843     PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT vaContextHeapBase = (PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT)vaContextHeap->pHeapBase;
1844     PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT vaContextHeapElmt = &vaContextHeapBase[vaContextID];
1845     DDI_CHK_NULL(vaContextHeapElmt->pVaContext, "context is already released", );
1846     void *firstFree                        = vaContextHeap->pFirstFreeHeapElement;
1847     vaContextHeap->pFirstFreeHeapElement   = (void*)vaContextHeapElmt;
1848     vaContextHeapElmt->pNextFree           = (PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT)firstFree;
1849     vaContextHeapElmt->pVaContext          = nullptr;
1850 }
1851 
DdiMediaUtil_UnRefBufObjInMediaBuffer(PDDI_MEDIA_BUFFER buf)1852 void DdiMediaUtil_UnRefBufObjInMediaBuffer(PDDI_MEDIA_BUFFER buf)
1853 {
1854     mos_bo_unreference(buf->bo);
1855 }
1856 
1857 // Open Intel's Graphics Device to get the file descriptor
DdiMediaUtil_OpenGraphicsAdaptor(char * devName)1858 int32_t DdiMediaUtil_OpenGraphicsAdaptor(char *devName)
1859 {
1860     struct stat st;
1861     int32_t    hDevice = -1;
1862     if(nullptr == devName)
1863     {
1864         DDI_ASSERTMESSAGE("Invalid Graphics Node");
1865         return -1;
1866     }
1867 
1868     hDevice = open (devName, O_RDWR);
1869     if (-1 == hDevice)
1870     {
1871         DDI_ASSERTMESSAGE("Cannot open '%s': %d, %s.", devName, errno, strerror (errno));
1872         return -1;
1873     }
1874 
1875     if (-1 == fstat (hDevice, &st))
1876     {
1877         DDI_ASSERTMESSAGE("Cannot identify '%s': %d, %s.", devName, errno, strerror (errno));
1878         close(hDevice);
1879         return -1;
1880     }
1881 
1882     if (!S_ISCHR (st.st_mode))
1883     {
1884         DDI_ASSERTMESSAGE("%s is no device.", devName);
1885         close(hDevice);
1886         return -1;
1887     }
1888     return hDevice;
1889 }
1890 
DdiMediaUtil_UnRegisterRTSurfaces(VADriverContextP ctx,PDDI_MEDIA_SURFACE surface)1891 VAStatus DdiMediaUtil_UnRegisterRTSurfaces(
1892     VADriverContextP    ctx,
1893     PDDI_MEDIA_SURFACE surface)
1894 {
1895     DDI_CHK_NULL(ctx,"nullptr context!", VA_STATUS_ERROR_INVALID_CONTEXT);
1896     PDDI_MEDIA_CONTEXT mediaCtx   = DdiMedia_GetMediaContext(ctx);
1897     DDI_CHK_NULL(mediaCtx,"nullptr mediaCtx!", VA_STATUS_ERROR_INVALID_CONTEXT);
1898     DDI_CHK_NULL(surface, "nullptr surface!", VA_STATUS_ERROR_INVALID_PARAMETER);
1899 
1900     //Look through all decode contexts to unregister the surface in each decode context's RTtable.
1901     if (mediaCtx->pDecoderCtxHeap != nullptr)
1902     {
1903         PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT decVACtxHeapBase;
1904 
1905         DdiMediaUtil_LockMutex(&mediaCtx->DecoderMutex);
1906         decVACtxHeapBase  = (PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT)mediaCtx->pDecoderCtxHeap->pHeapBase;
1907         for (uint32_t j = 0; j < mediaCtx->pDecoderCtxHeap->uiAllocatedHeapElements; j++)
1908         {
1909             if (decVACtxHeapBase[j].pVaContext != nullptr)
1910             {
1911                 PDDI_DECODE_CONTEXT  decCtx = (PDDI_DECODE_CONTEXT)decVACtxHeapBase[j].pVaContext;
1912                 if (decCtx && decCtx->m_ddiDecode)
1913                 {
1914                     //not check the return value since the surface may not be registered in the context. pay attention to LOGW.
1915                     decCtx->m_ddiDecode->UnRegisterRTSurfaces(&decCtx->RTtbl, surface);
1916                 }
1917             }
1918         }
1919         DdiMediaUtil_UnLockMutex(&mediaCtx->DecoderMutex);
1920     }
1921     if (mediaCtx->pEncoderCtxHeap != nullptr)
1922     {
1923         PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT pEncVACtxHeapBase;
1924 
1925         DdiMediaUtil_LockMutex(&mediaCtx->EncoderMutex);
1926         pEncVACtxHeapBase  = (PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT)mediaCtx->pEncoderCtxHeap->pHeapBase;
1927         for (uint32_t j = 0; j < mediaCtx->pEncoderCtxHeap->uiAllocatedHeapElements; j++)
1928         {
1929             if (pEncVACtxHeapBase[j].pVaContext != nullptr)
1930             {
1931                 PDDI_ENCODE_CONTEXT  pEncCtx = (PDDI_ENCODE_CONTEXT)pEncVACtxHeapBase[j].pVaContext;
1932                 if (pEncCtx && pEncCtx->m_encode)
1933                 {
1934                     //not check the return value since the surface may not be registered in the context. pay attention to LOGW.
1935                     pEncCtx->m_encode->UnRegisterRTSurfaces(&pEncCtx->RTtbl, surface);
1936                 }
1937             }
1938         }
1939         DdiMediaUtil_UnLockMutex(&mediaCtx->EncoderMutex);
1940     }
1941 
1942     return VA_STATUS_SUCCESS;
1943 }
1944 
DdiMediaUtil_SetMediaResetEnableFlag(PDDI_MEDIA_CONTEXT mediaCtx)1945 VAStatus DdiMediaUtil_SetMediaResetEnableFlag(PDDI_MEDIA_CONTEXT mediaCtx)
1946 {
1947     bool enableReset = false;
1948     mediaCtx->bMediaResetEnable = false;
1949 
1950     DDI_CHK_NULL(mediaCtx,"nullptr mediaCtx!", VA_STATUS_ERROR_INVALID_CONTEXT);
1951 
1952     if(!MEDIA_IS_SKU(&mediaCtx->SkuTable, FtrSWMediaReset))
1953     {
1954         mediaCtx->bMediaResetEnable = false;
1955         return VA_STATUS_SUCCESS;
1956     }
1957 
1958     mediaCtx->bMediaResetEnable = true;
1959 #if (_DEBUG || _RELEASE_INTERNAL)
1960     ReadUserSettingForDebug(
1961         mediaCtx->m_userSettingPtr,
1962         enableReset,
1963         __MEDIA_USER_FEATURE_VALUE_MEDIA_RESET_ENABLE,
1964         MediaUserSetting::Group::Device);
1965     mediaCtx->bMediaResetEnable = enableReset;
1966 #endif
1967 
1968     if(!mediaCtx->bMediaResetEnable)
1969     {
1970         return VA_STATUS_SUCCESS;
1971     }
1972 
1973     char* mediaResetEnv = getenv("INTEL_MEDIA_RESET_WATCHDOG");
1974     if(mediaResetEnv)
1975     {
1976         mediaCtx->bMediaResetEnable = strcmp(mediaResetEnv, "1") ? false : true;
1977         return VA_STATUS_SUCCESS;
1978     }
1979 
1980     return VA_STATUS_SUCCESS;
1981 }
1982