xref: /aosp_15_r20/external/intel-media-driver/media_softlet/linux/common/ddi/media_libva_util_next.cpp (revision ba62d9d3abf0e404f2022b4cd7a85e107f48596f)
1 /*
2 * Copyright (c) 2021-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_next.cpp
24 //! \brief    libva util next implementaion.
25 //!
26 #include <sys/time.h>
27 #include "inttypes.h"
28 #include "media_libva_util_next.h"
29 #include "media_interfaces_mcpy_next.h"
30 #include "mos_utilities.h"
31 #include "mos_os.h"
32 #include "mos_defs.h"
33 #include "hwinfo_linux.h"
34 #include "ddi_decode_base_specific.h"
35 #include "media_ddi_encode_base.h"
36 //#include "ddi_libva_decoder_specific.h"
37 #include "media_libva_decoder.h"
38 #include "media_libva_encoder.h"
39 #include "memory_policy_manager.h"
40 #include "drm_fourcc.h"
41 
42 // will remove when mtl open source
43 #define INTEL_PRELIM_ID_FLAG         (1ULL << 55)
44 
45 #define intel_prelim_fourcc_mod_code(val) \
46     (fourcc_mod_code(INTEL, (val)) | INTEL_PRELIM_ID_FLAG)
47 
48 /* this definition is to avoid duplicate drm_fourcc.h this file is updated seldom */
49 #ifndef I915_FORMAT_MOD_4_TILED_MTL_MC_CCS
50 #define I915_FORMAT_MOD_4_TILED_MTL_MC_CCS    fourcc_mod_code(INTEL, 14)
51 #endif
52 #ifndef I915_FORMAT_MOD_4_TILED_MTL_RC_CCS_CC
53 #define I915_FORMAT_MOD_4_TILED_MTL_RC_CCS_CC    fourcc_mod_code(INTEL, 15)
54 #endif
55 #ifndef I915_FORMAT_MOD_4_TILED_LNL_CCS
56 #define I915_FORMAT_MOD_4_TILED_LNL_CCS    fourcc_mod_code(INTEL, 16)
57 #endif
58 #ifndef I915_FORMAT_MOD_4_TILED_BMG_CCS
59 #define I915_FORMAT_MOD_4_TILED_BMG_CCS     fourcc_mod_code(INTEL, 17)
60 #endif
61 
62 // default protected surface tag
63 #define PROTECTED_SURFACE_TAG   0x3000f
64 
65 int32_t         MediaLibvaUtilNext::m_frameCountFps             = -1;
66 struct timeval  MediaLibvaUtilNext::m_tv1                       = {};
67 pthread_mutex_t MediaLibvaUtilNext::m_fpsMutex                  = PTHREAD_MUTEX_INITIALIZER;
68 int32_t         MediaLibvaUtilNext::m_vaFpsSampleSize           = 100;
69 bool            MediaLibvaUtilNext::m_isMediaFpsPrintFpsEnabled = false;
70 
SetDefaultTileFormat(DDI_MEDIA_FORMAT format,uint32_t surfaceUsageHint,MEDIA_FEATURE_TABLE * skuTable,MEDIA_SURFACE_ALLOCATE_PARAM & params)71 VAStatus MediaLibvaUtilNext::SetDefaultTileFormat(
72     DDI_MEDIA_FORMAT             format,
73     uint32_t                     surfaceUsageHint,
74     MEDIA_FEATURE_TABLE          *skuTable,
75     MEDIA_SURFACE_ALLOCATE_PARAM &params
76     )
77 {
78     VAStatus status        = VA_STATUS_SUCCESS;
79     uint32_t tileFormat    = TILING_Y;
80     DDI_FUNC_ENTER;
81     DDI_CHK_NULL(skuTable, "skuTable is nullptr", VA_STATUS_ERROR_INVALID_PARAMETER);
82 
83     switch (format)
84     {
85         case Media_Format_X8R8G8B8:
86         case Media_Format_X8B8G8R8:
87         case Media_Format_A8B8G8R8:
88         case Media_Format_R8G8B8A8:
89         case Media_Format_R5G6B5:
90         case Media_Format_R8G8B8:
91         case Media_Format_R10G10B10A2:
92         case Media_Format_B10G10R10A2:
93         case Media_Format_R10G10B10X2:
94         case Media_Format_B10G10R10X2:
95         case Media_Format_A16R16G16B16:
96         case Media_Format_A16B16G16R16:
97         case Media_Format_YV12:
98         case Media_Format_I420:
99         case Media_Format_IYUV:
100             if (VA_SURFACE_ATTRIB_USAGE_HINT_ENCODER != surfaceUsageHint   &&
101                 !(surfaceUsageHint & VA_SURFACE_ATTRIB_USAGE_HINT_VPP_WRITE))
102             {
103                 tileFormat = TILING_NONE;
104             }
105             break;
106         case Media_Format_RGBP:
107         case Media_Format_BGRP:
108             if (VA_SURFACE_ATTRIB_USAGE_HINT_ENCODER != surfaceUsageHint   &&
109                 !(surfaceUsageHint & VA_SURFACE_ATTRIB_USAGE_HINT_VPP_WRITE))
110             {
111                 if(!(surfaceUsageHint & VA_SURFACE_ATTRIB_USAGE_HINT_DECODER))
112                 {
113                     tileFormat = TILING_NONE;
114                     break;
115                 }
116                 //Planar type surface align 32 to improve performance.
117                 params.alignedHeight = MOS_ALIGN_CEIL(params.height, 32);
118             }
119             params.alignedWidth = MOS_ALIGN_CEIL(params.width, 8);
120             if (surfaceUsageHint & VA_SURFACE_ATTRIB_USAGE_HINT_VPP_WRITE)
121             {
122                 if (format == Media_Format_RGBP)
123                 {
124                     //Planar type surface align 32 to improve performance.
125                     params.alignedHeight = MOS_ALIGN_CEIL(params.height, 32);
126                 }
127             }
128             tileFormat = TILING_Y;
129             break;
130         case Media_Format_A8R8G8B8:
131             if (VA_SURFACE_ATTRIB_USAGE_HINT_ENCODER != surfaceUsageHint     &&
132                 !(surfaceUsageHint & VA_SURFACE_ATTRIB_USAGE_HINT_DECODER)   &&
133                 !(surfaceUsageHint & VA_SURFACE_ATTRIB_USAGE_HINT_VPP_WRITE) &&
134                 !(MEDIA_IS_SKU(skuTable, FtrRenderCompressionOnly)           &&
135                   MEDIA_IS_SKU(skuTable, FtrE2ECompression)))
136             {
137                 tileFormat = TILING_NONE;
138             }
139             break;
140         case Media_Format_NV12:
141         case Media_Format_NV21:
142         case Media_Format_444P:
143         case Media_Format_422H:
144         case Media_Format_411P:
145         case Media_Format_422V:
146         case Media_Format_IMC3:
147         case Media_Format_400P:
148         case Media_Format_P010:
149         case Media_Format_P012:
150         case Media_Format_P016:
151         case Media_Format_YUY2:
152         case Media_Format_Y210:
153 #if VA_CHECK_VERSION(1, 9, 0)
154         case Media_Format_Y212:
155 #endif
156         case Media_Format_Y216:
157         case Media_Format_AYUV:
158 #if VA_CHECK_VERSION(1, 13, 0)
159         case Media_Format_XYUV:
160 #endif
161         case Media_Format_Y410:
162 #if VA_CHECK_VERSION(1, 9, 0)
163         case Media_Format_Y412:
164 #endif
165         case Media_Format_Y416:
166         case Media_Format_Y8:
167         case Media_Format_Y16S:
168         case Media_Format_Y16U:
169         case Media_Format_VYUY:
170         case Media_Format_YVYU:
171         case Media_Format_UYVY:
172             if (VA_SURFACE_ATTRIB_USAGE_HINT_ENCODER != surfaceUsageHint &&
173                 !(surfaceUsageHint & VA_SURFACE_ATTRIB_USAGE_HINT_VPP_WRITE))
174             {
175                 //Planar type surface align 32 to improve performance.
176                 params.alignedHeight = MOS_ALIGN_CEIL(params.height, 32);
177             }
178             params.alignedWidth = MOS_ALIGN_CEIL(params.width, 8);
179             if (surfaceUsageHint & VA_SURFACE_ATTRIB_USAGE_HINT_VPP_WRITE)
180             {
181                 if ((format == Media_Format_NV12) || (format == Media_Format_P010))
182                 {
183                     //Planar type surface align 32 to improve performance.
184                     params.alignedHeight = MOS_ALIGN_CEIL(params.height, 32);
185                 }
186             }
187             tileFormat = TILING_Y;
188             break;
189         case Media_Format_Buffer:
190             tileFormat = TILING_NONE;
191             break;
192         default:
193             tileFormat = TILING_NONE;
194             DDI_ASSERTMESSAGE("Unsupported format");
195             status = VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
196     }
197 
198     if (VA_SURFACE_ATTRIB_USAGE_HINT_ENCODER & surfaceUsageHint)
199     {
200         params.alignedWidth  = MOS_ALIGN_CEIL(params.alignedWidth, 16);
201         params.alignedHeight = MOS_ALIGN_CEIL(params.alignedHeight, 16);
202     }
203     params.tileFormat    = tileFormat;
204     return status;
205 }
206 
InitSurfaceAllocateParams(MEDIA_SURFACE_ALLOCATE_PARAM & params,int32_t width,int32_t height,DDI_MEDIA_FORMAT format,int memType,uint32_t surfaceUsageHint)207 void MediaLibvaUtilNext::InitSurfaceAllocateParams(
208     MEDIA_SURFACE_ALLOCATE_PARAM &params,
209     int32_t                      width,
210     int32_t                      height,
211     DDI_MEDIA_FORMAT             format,
212     int                          memType,
213     uint32_t                     surfaceUsageHint)
214 {
215     DDI_FUNC_ENTER;
216     params.pitch          = 0;
217     params.tileFormat     = TILING_NONE;
218     params.alignedWidth   = params.width = width;
219     params.alignedHeight  = params.height = height;
220     params.format         = format;
221     params.cpTag          = 0;
222     params.memType        = memType;
223 #ifdef _MMC_SUPPORTED
224     params.bMemCompEnable = true;
225 #else
226     params.bMemCompEnable = false;
227 #endif
228     params.bMemCompRC     = false;
229     return;
230 }
231 
SetSurfaceParameterFromModifier(MEDIA_SURFACE_ALLOCATE_PARAM & params,uint64_t modifier)232 VAStatus MediaLibvaUtilNext::SetSurfaceParameterFromModifier(
233     MEDIA_SURFACE_ALLOCATE_PARAM &params,
234     uint64_t                     modifier)
235 {
236     DDI_FUNC_ENTER;
237     switch (modifier)
238     {
239         case I915_FORMAT_MOD_4_TILED:
240             params.tileFormat = TILING_Y;
241             params.bMemCompEnable = false;
242             break;
243         case I915_FORMAT_MOD_4_TILED_LNL_CCS:
244         case I915_FORMAT_MOD_4_TILED_BMG_CCS:
245             params.tileFormat = TILING_Y;
246             params.bMemCompEnable = true;
247             break;
248         case I915_FORMAT_MOD_4_TILED_MTL_RC_CCS_CC:
249             params.tileFormat = TILING_Y;
250             params.bMemCompEnable = true;
251             params.bMemCompRC = true;
252             break;
253         case I915_FORMAT_MOD_4_TILED_MTL_MC_CCS:
254             params.tileFormat = TILING_Y;
255             params.bMemCompEnable = true;
256             params.bMemCompRC = false;
257             break;
258         case DRM_FORMAT_MOD_LINEAR:
259             params.tileFormat = TILING_NONE;
260             params.bMemCompEnable = false;
261             break;
262         case I915_FORMAT_MOD_X_TILED:
263             params.tileFormat = TILING_X;
264             params.bMemCompEnable = false;
265             break;
266         case I915_FORMAT_MOD_Y_TILED:
267         case I915_FORMAT_MOD_Yf_TILED:
268             params.tileFormat = TILING_Y;
269             params.bMemCompEnable = false;
270             break;
271         case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS:
272             params.tileFormat = TILING_Y;
273             params.bMemCompEnable = true;
274             params.bMemCompRC = true;
275             break;
276         case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS:
277             params.tileFormat = TILING_Y;
278             params.bMemCompEnable = true;
279             params.bMemCompRC = false;
280             break;
281         default:
282             DDI_ASSERTMESSAGE("Unsupported modifier.");
283             return VA_STATUS_ERROR_INVALID_PARAMETER;
284     }
285     return VA_STATUS_SUCCESS;
286 }
287 
GenerateGmmParamsForNoneCompressionExternalSurface(GMM_RESCREATE_CUSTOM_PARAMS & gmmCustomParams,MEDIA_SURFACE_ALLOCATE_PARAM & params,PDDI_MEDIA_SURFACE mediaSurface)288 VAStatus MediaLibvaUtilNext::GenerateGmmParamsForNoneCompressionExternalSurface(
289     GMM_RESCREATE_CUSTOM_PARAMS  &gmmCustomParams,
290     MEDIA_SURFACE_ALLOCATE_PARAM &params,
291     PDDI_MEDIA_SURFACE           mediaSurface)
292 {
293     DDI_FUNC_ENTER;
294     DDI_CHK_NULL(mediaSurface,            "mediaSurface is nullptr",      VA_STATUS_ERROR_INVALID_BUFFER);
295     DDI_CHK_NULL(mediaSurface->pSurfDesc, "mediaSurface desc is nullptr", VA_STATUS_ERROR_INVALID_BUFFER);
296 
297     int32_t baseHeight = 0;
298     DDI_CHK_CONDITION(mediaSurface->pSurfDesc->uiPlanes == 0,
299         "Invalid plane number.",
300         VA_STATUS_ERROR_INVALID_PARAMETER);
301 
302     if (mediaSurface->pSurfDesc->uiPlanes == 1)
303     {
304         DDI_CHK_CONDITION(mediaSurface->pSurfDesc->uiSize == 0,
305             "Invalid Size.",
306             VA_STATUS_ERROR_INVALID_PARAMETER);
307         baseHeight = mediaSurface->pSurfDesc->uiSize / params.pitch;
308     }
309     else
310     {
311         DDI_CHK_CONDITION(mediaSurface->pSurfDesc->uiOffsets[1] == 0,
312             "Invalid offset.",
313             VA_STATUS_ERROR_INVALID_PARAMETER);
314         baseHeight = mediaSurface->pSurfDesc->uiOffsets[1] / params.pitch;
315     }
316 
317     // Create GmmResourceInfo
318     gmmCustomParams.Type          = RESOURCE_2D;
319     gmmCustomParams.Format        = ConvertMediaFmtToGmmFmt(params.format);
320     if ((params.format == Media_Format_YV12) || \
321         (params.format == Media_Format_I420) || \
322         (params.format == Media_Format_IYUV) || \
323         (params.format == Media_Format_NV12) || \
324         (params.format == Media_Format_P010) || \
325         (params.format == Media_Format_P012) || \
326         (params.format == Media_Format_P016) || \
327         (params.format == Media_Format_NV21)) {
328         // Align width to 2 for specific planar formats to handle
329         // odd dimensions for external non-compressible surfaces
330         gmmCustomParams.BaseWidth64 = MOS_ALIGN_CEIL(params.width, 2);
331     } else {
332         gmmCustomParams.BaseWidth64 = params.width;
333     }
334     gmmCustomParams.BaseHeight    = baseHeight;
335     gmmCustomParams.Pitch         = params.pitch;
336     gmmCustomParams.Size          = mediaSurface->pSurfDesc->uiSize;
337     gmmCustomParams.BaseAlignment = 4096;
338     gmmCustomParams.NoOfPlanes    = mediaSurface->pSurfDesc->uiPlanes;
339     gmmCustomParams.CpTag         = params.cpTag;
340     switch (params.tileFormat)
341     {
342         case TILING_Y:
343             gmmCustomParams.Flags.Info.TiledY = true;
344             break;
345         case TILING_X:
346             gmmCustomParams.Flags.Info.TiledX = true;
347             break;
348         case TILING_NONE:
349         default:
350             gmmCustomParams.Flags.Info.Linear = true;
351     }
352 
353     switch (mediaSurface->pSurfDesc->uiPlanes)
354     {
355         case 1:
356             gmmCustomParams.PlaneOffset.X[GMM_PLANE_Y] = 0;
357             gmmCustomParams.PlaneOffset.Y[GMM_PLANE_Y] = mediaSurface->pSurfDesc->uiOffsets[0] / params.pitch;
358             break;
359         case 2:
360             gmmCustomParams.PlaneOffset.X[GMM_PLANE_Y] = 0;
361             gmmCustomParams.PlaneOffset.Y[GMM_PLANE_Y] = mediaSurface->pSurfDesc->uiOffsets[0] / params.pitch;
362             gmmCustomParams.PlaneOffset.X[GMM_PLANE_U] = 0;
363             gmmCustomParams.PlaneOffset.Y[GMM_PLANE_U] = mediaSurface->pSurfDesc->uiOffsets[1] / params.pitch;
364             gmmCustomParams.PlaneOffset.X[GMM_PLANE_V] = 0;
365             gmmCustomParams.PlaneOffset.Y[GMM_PLANE_V] = mediaSurface->pSurfDesc->uiOffsets[1] / params.pitch;
366             break;
367         case 3:
368             if (mediaSurface->format == Media_Format_YV12)
369             {
370                 gmmCustomParams.PlaneOffset.X[GMM_PLANE_Y] = 0;
371                 gmmCustomParams.PlaneOffset.Y[GMM_PLANE_Y] = mediaSurface->pSurfDesc->uiOffsets[0] / params.pitch;
372                 gmmCustomParams.PlaneOffset.X[GMM_PLANE_U] = 0;
373                 gmmCustomParams.PlaneOffset.Y[GMM_PLANE_U] = mediaSurface->pSurfDesc->uiOffsets[2] / params.pitch;
374                 gmmCustomParams.PlaneOffset.X[GMM_PLANE_V] = 0;
375                 gmmCustomParams.PlaneOffset.Y[GMM_PLANE_V] = mediaSurface->pSurfDesc->uiOffsets[1] / params.pitch;
376             }
377             else
378             {
379                 gmmCustomParams.PlaneOffset.X[GMM_PLANE_Y] = 0;
380                 gmmCustomParams.PlaneOffset.Y[GMM_PLANE_Y] = mediaSurface->pSurfDesc->uiOffsets[0] / params.pitch;
381                 gmmCustomParams.PlaneOffset.X[GMM_PLANE_U] = 0;
382                 gmmCustomParams.PlaneOffset.Y[GMM_PLANE_U] = mediaSurface->pSurfDesc->uiOffsets[1] / params.pitch;
383                 gmmCustomParams.PlaneOffset.X[GMM_PLANE_V] = 0;
384                 gmmCustomParams.PlaneOffset.Y[GMM_PLANE_V] = mediaSurface->pSurfDesc->uiOffsets[2] / params.pitch;
385             }
386             break;
387         default:
388             DDI_ASSERTMESSAGE("Invalid plane number.");
389             return VA_STATUS_ERROR_ALLOCATION_FAILED;
390     }
391 
392     return VA_STATUS_SUCCESS;
393 }
394 
GenerateGmmParamsForCompressionExternalSurface(GMM_RESCREATE_CUSTOM_PARAMS_2 & gmmCustomParams,MEDIA_SURFACE_ALLOCATE_PARAM & params,PDDI_MEDIA_SURFACE mediaSurface,PDDI_MEDIA_CONTEXT mediaDrvCtx)395 VAStatus MediaLibvaUtilNext::GenerateGmmParamsForCompressionExternalSurface(
396     GMM_RESCREATE_CUSTOM_PARAMS_2 &gmmCustomParams,
397     MEDIA_SURFACE_ALLOCATE_PARAM &params,
398     PDDI_MEDIA_SURFACE           mediaSurface,
399     PDDI_MEDIA_CONTEXT           mediaDrvCtx)
400 {
401     DDI_FUNC_ENTER;
402     DDI_CHK_NULL(mediaSurface,            "mediaSurface is nullptr",      VA_STATUS_ERROR_INVALID_BUFFER);
403     DDI_CHK_NULL(mediaSurface->pSurfDesc, "mediaSurface desc is nullptr", VA_STATUS_ERROR_INVALID_BUFFER);
404     DDI_CHK_NULL(mediaDrvCtx, "media context is nullptr", VA_STATUS_ERROR_INVALID_CONTEXT);
405     // Create GmmResourceInfo
406     gmmCustomParams.Type          = RESOURCE_2D;
407     gmmCustomParams.Format        = ConvertMediaFmtToGmmFmt(params.format);
408     if ((params.format == Media_Format_YV12) || \
409         (params.format == Media_Format_I420) || \
410         (params.format == Media_Format_IYUV) || \
411         (params.format == Media_Format_NV12) || \
412         (params.format == Media_Format_NV21)) {
413         // Align width to 2 for specific planar formats to handle
414         // odd dimensions for external non-compressible surfaces
415         gmmCustomParams.BaseWidth64 = MOS_ALIGN_CEIL(params.alignedWidth, 2);
416     } else {
417         gmmCustomParams.BaseWidth64 = params.alignedWidth;
418     }
419     gmmCustomParams.BaseHeight    = params.alignedHeight;
420     gmmCustomParams.Pitch         = params.pitch;
421     gmmCustomParams.Size          = mediaSurface->pSurfDesc->uiSize;
422     gmmCustomParams.BaseAlignment = 4096;
423     gmmCustomParams.NoOfPlanes    = mediaSurface->pSurfDesc->uiPlanes;
424     gmmCustomParams.CpTag         = params.cpTag;
425     switch (params.tileFormat)
426     {
427         case TILING_Y:
428             gmmCustomParams.Flags.Info.TiledY = true;
429             gmmCustomParams.Flags.Gpu.MMC    = false;
430             if (MEDIA_IS_SKU(&mediaDrvCtx->SkuTable, FtrE2ECompression) &&
431                 (!MEDIA_IS_WA(&mediaDrvCtx->WaTable, WaDisableVPMmc)    &&
432                 !MEDIA_IS_WA(&mediaDrvCtx->WaTable, WaDisableCodecMmc)) &&
433                 params.bMemCompEnable)
434             {
435                 gmmCustomParams.Flags.Gpu.MMC               = true;
436                 gmmCustomParams.Flags.Info.MediaCompressed  = 1;
437                 gmmCustomParams.Flags.Info.RenderCompressed = 0;
438                 gmmCustomParams.Flags.Gpu.CCS               = 1;
439                 gmmCustomParams.Flags.Gpu.RenderTarget      = 1;
440                 gmmCustomParams.Flags.Gpu.UnifiedAuxSurface = 1;
441 
442                 if (params.bMemCompRC)
443                 {
444                     gmmCustomParams.Flags.Info.MediaCompressed  = 0;
445                     gmmCustomParams.Flags.Info.RenderCompressed = 1;
446                 }
447 
448                 if(MEDIA_IS_SKU(&mediaDrvCtx->SkuTable, FtrRenderCompressionOnly))
449                 {
450                     gmmCustomParams.Flags.Info.MediaCompressed = 0;
451 
452                     if (params.format == Media_Format_X8R8G8B8 ||
453                         params.format == Media_Format_X8B8G8R8 ||
454                         params.format == Media_Format_A8B8G8R8 ||
455                         params.format == Media_Format_A8R8G8B8 ||
456                         params.format == Media_Format_R8G8B8A8)
457                     {
458                         gmmCustomParams.Flags.Info.MediaCompressed  = 0;
459                         gmmCustomParams.Flags.Info.RenderCompressed = 1;
460                     }
461                 }
462 
463                 if(MEDIA_IS_SKU(&mediaDrvCtx->SkuTable, FtrFlatPhysCCS))
464                 {
465                     gmmCustomParams.Flags.Gpu.UnifiedAuxSurface = 0;
466                 }
467             }
468             break;
469         case TILING_X:
470             gmmCustomParams.Flags.Info.TiledX = true;
471             break;
472         case TILING_NONE:
473         default:
474             gmmCustomParams.Flags.Info.Linear = true;
475     }
476 
477     if(MEDIA_IS_SKU(&mediaDrvCtx->SkuTable, FtrFlatPhysCCS))
478     {
479         switch (mediaSurface->pSurfDesc->uiPlanes)
480         {
481             case 1:
482                 gmmCustomParams.PlaneOffset.X[GMM_PLANE_Y] = 0;
483                 gmmCustomParams.PlaneOffset.Y[GMM_PLANE_Y] = mediaSurface->pSurfDesc->uiOffsets[0] / params.pitch;
484                 break;
485             case 2:
486                 gmmCustomParams.PlaneOffset.X[GMM_PLANE_Y] = 0;
487                 gmmCustomParams.PlaneOffset.Y[GMM_PLANE_Y] = mediaSurface->pSurfDesc->uiOffsets[0] / params.pitch;
488                 gmmCustomParams.PlaneOffset.X[GMM_PLANE_U] = 0;
489                 gmmCustomParams.PlaneOffset.Y[GMM_PLANE_U] = mediaSurface->pSurfDesc->uiOffsets[1] / params.pitch;
490                 gmmCustomParams.PlaneOffset.X[GMM_PLANE_V] = 0;
491                 gmmCustomParams.PlaneOffset.Y[GMM_PLANE_V] = mediaSurface->pSurfDesc->uiOffsets[1] / params.pitch;
492                 break;
493             case 3:
494                 if (mediaSurface->format == Media_Format_YV12)
495                 {
496                     gmmCustomParams.PlaneOffset.X[GMM_PLANE_Y] = 0;
497                     gmmCustomParams.PlaneOffset.Y[GMM_PLANE_Y] = mediaSurface->pSurfDesc->uiOffsets[0] / params.pitch;
498                     gmmCustomParams.PlaneOffset.X[GMM_PLANE_U] = 0;
499                     gmmCustomParams.PlaneOffset.Y[GMM_PLANE_U] = mediaSurface->pSurfDesc->uiOffsets[2] / params.pitch;
500                     gmmCustomParams.PlaneOffset.X[GMM_PLANE_V] = 0;
501                     gmmCustomParams.PlaneOffset.Y[GMM_PLANE_V] = mediaSurface->pSurfDesc->uiOffsets[1] / params.pitch;
502                 }
503                 else
504                 {
505                     gmmCustomParams.PlaneOffset.X[GMM_PLANE_Y] = 0;
506                     gmmCustomParams.PlaneOffset.Y[GMM_PLANE_Y] = mediaSurface->pSurfDesc->uiOffsets[0] / params.pitch;
507                     gmmCustomParams.PlaneOffset.X[GMM_PLANE_U] = 0;
508                     gmmCustomParams.PlaneOffset.Y[GMM_PLANE_U] = mediaSurface->pSurfDesc->uiOffsets[1] / params.pitch;
509                     gmmCustomParams.PlaneOffset.X[GMM_PLANE_V] = 0;
510                     gmmCustomParams.PlaneOffset.Y[GMM_PLANE_V] = mediaSurface->pSurfDesc->uiOffsets[2] / params.pitch;
511                 }
512                 break;
513             default:
514                 DDI_ASSERTMESSAGE("Invalid plane number.");
515                 return VA_STATUS_ERROR_ALLOCATION_FAILED;
516         }
517     }
518     else
519     {
520         // build Aux SW map for platfroms w/o physical map
521         gmmCustomParams.AuxSurf.BaseAlignment = {0};
522         gmmCustomParams.NoOfPlanes = mediaSurface->pSurfDesc->uiPlanes/2;
523         gmmCustomParams.Size = (gmmCustomParams.NoOfPlanes == 1) ? mediaSurface->pSurfDesc->uiOffsets[1]:mediaSurface->pSurfDesc->uiOffsets[2];
524         switch(gmmCustomParams.NoOfPlanes)
525         {
526             case 1:
527                 gmmCustomParams.PlaneOffset.X[GMM_PLANE_Y] = 0;
528                 gmmCustomParams.PlaneOffset.Y[GMM_PLANE_Y] = mediaSurface->pSurfDesc->uiOffsets[0] / params.pitch;
529                 gmmCustomParams.AuxSurf.Size = mediaSurface->pSurfDesc->uiSize - gmmCustomParams.Size;
530                 gmmCustomParams.AuxSurf.Pitch = mediaSurface->pSurfDesc->uiPitches[1];
531                 gmmCustomParams.AuxSurf.PlaneOffset.X[GMM_PLANE_Y] = 0;
532                 gmmCustomParams.AuxSurf.PlaneOffset.Y[GMM_PLANE_Y] = 0;
533                 break;
534             case 2:
535                 gmmCustomParams.PlaneOffset.X[GMM_PLANE_Y] = 0;
536                 gmmCustomParams.PlaneOffset.Y[GMM_PLANE_Y] = mediaSurface->pSurfDesc->uiOffsets[0] / params.pitch;
537                 gmmCustomParams.PlaneOffset.X[GMM_PLANE_U] = 0;
538                 gmmCustomParams.PlaneOffset.Y[GMM_PLANE_U] = mediaSurface->pSurfDesc->uiOffsets[1] / params.pitch;
539                 gmmCustomParams.PlaneOffset.X[GMM_PLANE_V] = 0;
540                 gmmCustomParams.PlaneOffset.Y[GMM_PLANE_V] = mediaSurface->pSurfDesc->uiOffsets[1] / params.pitch;
541                 gmmCustomParams.AuxSurf.Size = (mediaSurface->pSurfDesc->uiOffsets[3] - mediaSurface->pSurfDesc->uiOffsets[2]) * 2;
542                 gmmCustomParams.AuxSurf.Pitch = mediaSurface->pSurfDesc->uiPitches[2];
543                 gmmCustomParams.AuxSurf.PlaneOffset.X[GMM_PLANE_Y] = 0;
544                 gmmCustomParams.AuxSurf.PlaneOffset.Y[GMM_PLANE_Y] = 0;
545                 gmmCustomParams.AuxSurf.PlaneOffset.X[GMM_PLANE_U] = (mediaSurface->pSurfDesc->uiOffsets[3]
546                                                             - mediaSurface->pSurfDesc->uiOffsets[2]);
547                 gmmCustomParams.AuxSurf.PlaneOffset.Y[GMM_PLANE_U] = 0;
548                 gmmCustomParams.AuxSurf.PlaneOffset.X[GMM_PLANE_V] = (mediaSurface->pSurfDesc->uiOffsets[3]
549                                                             - mediaSurface->pSurfDesc->uiOffsets[2]);
550                 gmmCustomParams.AuxSurf.PlaneOffset.Y[GMM_PLANE_V] = 0;
551                 break;
552             case 3:
553                 if (mediaSurface->format == Media_Format_YV12)
554                 {
555                     gmmCustomParams.PlaneOffset.X[GMM_PLANE_Y] = 0;
556                     gmmCustomParams.PlaneOffset.Y[GMM_PLANE_Y] = mediaSurface->pSurfDesc->uiOffsets[0] / params.pitch;
557                     gmmCustomParams.PlaneOffset.X[GMM_PLANE_U] = 0;
558                     gmmCustomParams.PlaneOffset.Y[GMM_PLANE_U] = mediaSurface->pSurfDesc->uiOffsets[2] / params.pitch;
559                     gmmCustomParams.PlaneOffset.X[GMM_PLANE_V] = 0;
560                     gmmCustomParams.PlaneOffset.Y[GMM_PLANE_V] = mediaSurface->pSurfDesc->uiOffsets[1] / params.pitch;
561                 }
562                 else
563                 {
564                     gmmCustomParams.PlaneOffset.X[GMM_PLANE_Y] = 0;
565                     gmmCustomParams.PlaneOffset.Y[GMM_PLANE_Y] = mediaSurface->pSurfDesc->uiOffsets[0] / params.pitch;
566                     gmmCustomParams.PlaneOffset.X[GMM_PLANE_U] = 0;
567                     gmmCustomParams.PlaneOffset.Y[GMM_PLANE_U] = mediaSurface->pSurfDesc->uiOffsets[1] / params.pitch;
568                     gmmCustomParams.PlaneOffset.X[GMM_PLANE_V] = 0;
569                     gmmCustomParams.PlaneOffset.Y[GMM_PLANE_V] = mediaSurface->pSurfDesc->uiOffsets[2] / params.pitch;
570                 }
571                 break;
572             default:
573                 DDI_ASSERTMESSAGE("Invalid plane number.");
574                 return VA_STATUS_ERROR_ALLOCATION_FAILED;
575         }
576     }
577 
578     return VA_STATUS_SUCCESS;
579 }
580 
CreateExternalSurface(MEDIA_SURFACE_ALLOCATE_PARAM & params,PDDI_MEDIA_SURFACE mediaSurface,PDDI_MEDIA_CONTEXT mediaDrvCtx)581 VAStatus MediaLibvaUtilNext::CreateExternalSurface(
582     MEDIA_SURFACE_ALLOCATE_PARAM &params,
583     PDDI_MEDIA_SURFACE           mediaSurface,
584     PDDI_MEDIA_CONTEXT           mediaDrvCtx)
585 {
586     DDI_FUNC_ENTER;
587     DDI_CHK_NULL(mediaSurface,                   "mediaSurface is nullptr",      VA_STATUS_ERROR_INVALID_BUFFER);
588     DDI_CHK_NULL(mediaSurface->pSurfDesc,        "mediaSurface desc is nullptr", VA_STATUS_ERROR_INVALID_BUFFER);
589     DDI_CHK_NULL(mediaDrvCtx,                    "media context is nullptr",     VA_STATUS_ERROR_INVALID_CONTEXT);
590     DDI_CHK_NULL(mediaDrvCtx->pDrmBufMgr,        "drm buffer mgr is nullptr",    VA_STATUS_ERROR_INVALID_BUFFER);
591     DDI_CHK_NULL(mediaDrvCtx->pGmmClientContext, "gmm context is nullptr",       VA_STATUS_ERROR_INVALID_CONTEXT);
592 
593     GMM_RESOURCE_INFO  *gmmResourceInfo = nullptr;
594     MOS_LINUX_BO       *bo = nullptr;
595     uint32_t           swizzle_mode;
596     unsigned int       patIndex = PAT_INDEX_INVALID;
597     VAStatus           status = VA_STATUS_SUCCESS;
598 
599     // 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
600     params.bMemCompEnable = false;
601     params.bMemCompRC = false;
602     params.pitch = mediaSurface->pSurfDesc->uiPitches[0];
603     DDI_CHK_CONDITION(params.pitch == 0, "Invalid pich.", VA_STATUS_ERROR_INVALID_PARAMETER);
604 
605     // Set cp flag to indicate the secure surface
606     if (mediaSurface->pSurfDesc->uiFlags & VA_SURFACE_EXTBUF_DESC_PROTECTED)
607     {
608         params.cpTag = PROTECTED_SURFACE_TAG;
609     }
610 
611     switch(mediaSurface->pSurfDesc->uiVaMemType)
612     {
613         case VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM:
614         case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME:
615             params.tileFormat = mediaSurface->pSurfDesc->uiFlags & VA_SURFACE_EXTBUF_DESC_ENABLE_TILING ? TILING_Y : TILING_NONE;
616             break;
617         case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2:
618             params.pitch = mediaSurface->pSurfDesc->uiPitches[0];
619             status = SetSurfaceParameterFromModifier(params, mediaSurface->pSurfDesc->modifier);
620             if(status != VA_STATUS_SUCCESS)
621             {
622                 DDI_ASSERTMESSAGE("Set surface from modifier failed.");
623                 return status;
624             }
625             break;
626 #if VA_CHECK_VERSION(1, 21, 0)
627         case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_3:
628             params.pitch = mediaSurface->pSurfDesc->uiPitches[0];
629             status = SetSurfaceParameterFromModifier(params, mediaSurface->pSurfDesc->modifier);
630             if(status != VA_STATUS_SUCCESS)
631             {
632                 DDI_ASSERTMESSAGE("Set surface from modifier failed.");
633                 return status;
634             }
635             break;
636 #endif
637         case VA_SURFACE_ATTRIB_MEM_TYPE_USER_PTR:
638             params.tileFormat = TILE_NONE;
639             break;
640     }
641 
642 
643     GMM_RESCREATE_CUSTOM_PARAMS_2 gmmCustomParams;
644     MOS_ZeroMemory(&gmmCustomParams, sizeof(gmmCustomParams));
645     if (VA_SURFACE_ATTRIB_MEM_TYPE_USER_PTR == mediaSurface->pSurfDesc->uiVaMemType)
646     {
647         gmmCustomParams.Usage = GMM_RESOURCE_USAGE_STAGING;
648         gmmCustomParams.Type = RESOURCE_1D;
649     }
650 
651     if (params.bMemCompEnable)
652     {
653         status = GenerateGmmParamsForCompressionExternalSurface(gmmCustomParams, params, mediaSurface, mediaDrvCtx);
654         if(status != VA_STATUS_SUCCESS)
655         {
656             DDI_ASSERTMESSAGE("Generate gmmParams for compression external surface failed.");
657             return status;
658         }
659 
660         gmmResourceInfo = mediaDrvCtx->pGmmClientContext->CreateCustomResInfoObject_2(&gmmCustomParams);
661     }
662     else
663     {
664         status = GenerateGmmParamsForNoneCompressionExternalSurface(gmmCustomParams, params, mediaSurface);
665         if(status != VA_STATUS_SUCCESS)
666         {
667             DDI_ASSERTMESSAGE("Generate gmmParams for none compression external surface failed.");
668             return status;
669         }
670 
671         gmmResourceInfo = mediaDrvCtx->pGmmClientContext->CreateCustomResInfoObject(&gmmCustomParams);
672     }
673 
674     DDI_CHK_NULL(gmmResourceInfo, "Gmm create resource failed", VA_STATUS_ERROR_ALLOCATION_FAILED);
675 
676     patIndex = MosInterface::GetPATIndexFromGmm(mediaDrvCtx->pGmmClientContext, gmmResourceInfo);
677 
678     // DRM buffer allocated by Application, No need to re-allocate new DRM buffer
679     switch (mediaSurface->pSurfDesc->uiVaMemType)
680     {
681         case VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM:
682             bo = mos_bo_create_from_name(mediaDrvCtx->pDrmBufMgr, "MEDIA", mediaSurface->pSurfDesc->ulBuffer);
683             break;
684         case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME:
685         case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2:
686 #if VA_CHECK_VERSION(1, 21, 0)
687         case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_3:
688 #endif
689         {
690             struct mos_drm_bo_alloc_prime alloc_prime;
691             alloc_prime.name = "prime";
692             alloc_prime.prime_fd = mediaSurface->pSurfDesc->ulBuffer;
693             alloc_prime.size = mediaSurface->pSurfDesc->uiSize;
694             alloc_prime.pat_index = patIndex;
695 
696             bo = mos_bo_create_from_prime(mediaDrvCtx->pDrmBufMgr, &alloc_prime);
697         }
698             break;
699         case VA_SURFACE_ATTRIB_MEM_TYPE_USER_PTR:
700         {
701             struct mos_drm_bo_alloc_userptr alloc_uptr;
702             alloc_uptr.name = "SysSurface";
703             alloc_uptr.addr = (void *)mediaSurface->pSurfDesc->ulBuffer;
704             alloc_uptr.tiling_mode = mediaSurface->pSurfDesc->uiTile;
705             alloc_uptr.stride = params.pitch;
706             alloc_uptr.size = mediaSurface->pSurfDesc->uiBuffserSize;
707             alloc_uptr.pat_index = patIndex;
708 
709             bo = mos_bo_alloc_userptr(mediaDrvCtx->pDrmBufMgr, &alloc_uptr);
710         }
711             break;
712     }
713 
714     if (nullptr == bo)
715     {
716         DDI_ASSERTMESSAGE("Failed to create drm buffer object according to input buffer descriptor.");
717         mediaDrvCtx->pGmmClientContext->DestroyResInfoObject(gmmResourceInfo);
718         return VA_STATUS_ERROR_ALLOCATION_FAILED;
719     }
720 
721     mediaSurface->pGmmResourceInfo = gmmResourceInfo;
722     mediaSurface->bMapped          = false;
723     mediaSurface->format           = params.format;
724     mediaSurface->iWidth           = params.width;
725     mediaSurface->iHeight          = gmmResourceInfo->GetBaseHeight();
726     mediaSurface->iRealHeight      = params.height;
727     mediaSurface->iPitch           = params.pitch;
728     mediaSurface->iRefCount        = 0;
729     mediaSurface->bo               = bo;
730     mediaSurface->TileType         = params.tileFormat;
731     mediaSurface->isTiled          = (params.tileFormat != TILING_NONE) ? 1 : 0;
732     mediaSurface->pData            = (uint8_t*) bo->virt;
733     DDI_VERBOSEMESSAGE("Allocate external surface %7d bytes (%d x %d resource).", mediaSurface->pSurfDesc->uiSize, params.width, params.height);
734     uint32_t event[] = {bo->handle, params.format, params.width, params.height, params.pitch, bo->size, params.tileFormat, params.cpTag};
735     MOS_TraceEventExt(EVENT_VA_SURFACE, EVENT_TYPE_INFO, event, sizeof(event), &gmmResourceInfo->GetResFlags(), sizeof(GMM_RESOURCE_FLAG));
736 
737     return VA_STATUS_SUCCESS;
738 }
739 
GenerateGmmParamsForInternalSurface(GMM_RESCREATE_PARAMS & gmmParams,MEDIA_SURFACE_ALLOCATE_PARAM & params,PDDI_MEDIA_CONTEXT mediaDrvCtx)740 VAStatus MediaLibvaUtilNext::GenerateGmmParamsForInternalSurface(
741     GMM_RESCREATE_PARAMS         &gmmParams,
742     MEDIA_SURFACE_ALLOCATE_PARAM &params,
743     PDDI_MEDIA_CONTEXT           mediaDrvCtx)
744 {
745     DDI_FUNC_ENTER;
746     DDI_CHK_NULL(mediaDrvCtx, "media context is nullptr", VA_STATUS_ERROR_INVALID_CONTEXT);
747 
748     MosUtilities::MosZeroMemory(&gmmParams, sizeof(gmmParams));
749     gmmParams.BaseWidth         = params.alignedWidth;
750     gmmParams.BaseHeight        = params.alignedHeight;
751     gmmParams.ArraySize         = 1;
752     gmmParams.Type              = RESOURCE_2D;
753     gmmParams.Format            = ConvertMediaFmtToGmmFmt(params.format);
754 
755     DDI_CHK_CONDITION(gmmParams.Format == GMM_FORMAT_INVALID, "Unsupported format", VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT);
756 
757     switch (params.tileFormat)
758     {
759         case TILING_Y:
760             // Disable MMC for application required surfaces, because some cases' output streams have corruption.
761             gmmParams.Flags.Gpu.MMC    = false;
762             if (MEDIA_IS_SKU(&mediaDrvCtx->SkuTable, FtrE2ECompression)             &&
763                 (!MEDIA_IS_WA(&mediaDrvCtx->WaTable, WaDisableVPMmc)                &&
764                 !MEDIA_IS_WA(&mediaDrvCtx->WaTable,  WaDisableCodecMmc))            &&
765                 MEDIA_IS_SKU(&mediaDrvCtx->SkuTable, FtrCompressibleSurfaceDefault) &&
766                 params.bMemCompEnable)
767             {
768                 gmmParams.Flags.Gpu.MMC               = true;
769                 gmmParams.Flags.Info.MediaCompressed  = 1;
770                 gmmParams.Flags.Info.RenderCompressed = 0;
771                 gmmParams.Flags.Gpu.CCS               = 1;
772                 gmmParams.Flags.Gpu.RenderTarget      = 1;
773                 gmmParams.Flags.Gpu.UnifiedAuxSurface = 1;
774 
775                 if (params.bMemCompRC)
776                 {
777                     gmmParams.Flags.Info.MediaCompressed  = 0;
778                     gmmParams.Flags.Info.RenderCompressed = 1;
779                 }
780 
781                 if (MEDIA_IS_SKU(&mediaDrvCtx->SkuTable, FtrRenderCompressionOnly))
782                 {
783                     gmmParams.Flags.Info.MediaCompressed = 0;
784 
785                     if (params.format == Media_Format_X8R8G8B8 ||
786                         params.format == Media_Format_X8B8G8R8 ||
787                         params.format == Media_Format_A8B8G8R8 ||
788                         params.format == Media_Format_A8R8G8B8 ||
789                         params.format == Media_Format_R8G8B8A8)
790                     {
791                         gmmParams.Flags.Info.MediaCompressed  = 0;
792                         gmmParams.Flags.Info.RenderCompressed = 1;
793                     }
794                     else
795                     {
796                         gmmParams.Flags.Gpu.MMC               = false;
797                         gmmParams.Flags.Info.MediaCompressed  = 0;
798                         gmmParams.Flags.Info.RenderCompressed = 0;
799                         gmmParams.Flags.Gpu.CCS               = 0;
800                         gmmParams.Flags.Gpu.UnifiedAuxSurface = 0;
801                     }
802                 }
803             }
804             // For ARGB surface, always allocate it as tile4.
805             // This is a WA for ExportSurfaceHandle because modifer for tile64 isn't defined.
806             if ((params.format == Media_Format_A8R8G8B8 ||
807                 params.format == Media_Format_B10G10R10A2 ||
808                 params.format == Media_Format_A8B8G8R8 ||
809                 params.format == Media_Format_X8R8G8B8) && !MEDIA_IS_SKU(&mediaDrvCtx->SkuTable, FtrTileY))
810             {
811                 gmmParams.Flags.Info.Tile4 = true;
812             }
813             break;
814         case TILING_X:
815             gmmParams.Flags.Info.TiledX    = true;
816             break;
817         default:
818             gmmParams.Flags.Info.Linear    = true;
819     }
820     gmmParams.Flags.Gpu.Video = true;
821     gmmParams.Flags.Info.LocalOnly = MEDIA_IS_SKU(&mediaDrvCtx->SkuTable, FtrLocalMemory);
822 
823     return VA_STATUS_SUCCESS;
824 }
825 
CreateInternalSurface(MEDIA_SURFACE_ALLOCATE_PARAM & params,PDDI_MEDIA_SURFACE mediaSurface,PDDI_MEDIA_CONTEXT mediaDrvCtx)826 VAStatus MediaLibvaUtilNext::CreateInternalSurface(
827     MEDIA_SURFACE_ALLOCATE_PARAM &params,
828     PDDI_MEDIA_SURFACE           mediaSurface,
829     PDDI_MEDIA_CONTEXT           mediaDrvCtx)
830 {
831     DDI_FUNC_ENTER;
832     DDI_CHK_NULL(mediaSurface,                   "mediaSurface is nullptr",      VA_STATUS_ERROR_INVALID_BUFFER);
833     DDI_CHK_NULL(mediaDrvCtx,                    "media context is nullptr",     VA_STATUS_ERROR_INVALID_CONTEXT);
834     DDI_CHK_NULL(mediaDrvCtx->pGmmClientContext, "gmm context is nullptr",       VA_STATUS_ERROR_INVALID_CONTEXT);
835 
836     VAStatus              status           = VA_STATUS_SUCCESS;
837     MOS_LINUX_BO          *bo              = nullptr;
838     GMM_RESCREATE_PARAMS  gmmParams        = {};
839     GMM_RESOURCE_INFO     *gmmResourceInfo = nullptr;
840     if (mediaSurface->pSurfDesc)
841     {
842         if (mediaSurface->pSurfDesc->uiFlags & VA_SURFACE_EXTBUF_DESC_ENABLE_TILING )
843         {
844             params.tileFormat = TILING_Y;
845         }
846         else if (mediaSurface->pSurfDesc->uiVaMemType == VA_SURFACE_ATTRIB_MEM_TYPE_VA)
847         {
848             params.tileFormat = TILING_NONE;
849             params.alignedHeight = params.height;
850         }
851     }
852 
853     status = GenerateGmmParamsForInternalSurface(gmmParams, params, mediaDrvCtx);
854     if(status != VA_STATUS_SUCCESS)
855     {
856         DDI_ASSERTMESSAGE("Generate gmmParams for internal surface failed.");
857         return status;
858     }
859 
860     mediaSurface->pGmmResourceInfo = gmmResourceInfo = mediaDrvCtx->pGmmClientContext->CreateResInfoObject(&gmmParams);
861     DDI_CHK_NULL(gmmResourceInfo, "Gmm create resource failed", VA_STATUS_ERROR_ALLOCATION_FAILED);
862 
863     uint32_t  gmmPitch  = (uint32_t)gmmResourceInfo->GetRenderPitch();
864     uint32_t  gmmSize   = (uint32_t)gmmResourceInfo->GetSizeSurface();
865     uint32_t  gmmHeight = gmmResourceInfo->GetBaseHeight();
866 
867     if (0 == gmmPitch || 0 == gmmSize || 0 == gmmHeight)
868     {
869         DDI_ASSERTMESSAGE("Gmm Create Resource Failed.");
870         return VA_STATUS_ERROR_ALLOCATION_FAILED;
871     }
872 
873     switch (gmmResourceInfo->GetTileType())
874     {
875         case GMM_TILED_Y:
876             params.tileFormat = TILING_Y;
877             break;
878         case GMM_TILED_X:
879             params.tileFormat = TILING_X;
880             break;
881         case GMM_NOT_TILED:
882             params.tileFormat = TILING_NONE;
883             break;
884         default:
885             params.tileFormat = TILING_Y;
886             break;
887     }
888 
889     MemoryPolicyParameter memPolicyPar;
890     MosUtilities::MosZeroMemory(&memPolicyPar, sizeof(MemoryPolicyParameter));
891 
892     memPolicyPar.skuTable = &mediaDrvCtx->SkuTable;
893     memPolicyPar.waTable  = &mediaDrvCtx->WaTable;
894     memPolicyPar.resInfo  = mediaSurface->pGmmResourceInfo;
895     memPolicyPar.resName  = "Media Surface";
896     memPolicyPar.preferredMemType = (MEDIA_IS_WA(&mediaDrvCtx->WaTable, WaForceAllocateLML4)) ? MOS_MEMPOOL_DEVICEMEMORY : params.memType;
897 
898     params.memType = MemoryPolicyManager::UpdateMemoryPolicy(&memPolicyPar);
899 
900     unsigned int patIndex = MosInterface::GetPATIndexFromGmm(mediaDrvCtx->pGmmClientContext, gmmResourceInfo);
901     bool isCpuCacheable   = gmmResourceInfo->GetResFlags().Info.Cacheable;
902 
903     if ( params.tileFormat == TILING_NONE )
904     {
905         struct mos_drm_bo_alloc alloc;
906         alloc.name = "Media";
907         alloc.size = gmmSize;
908         alloc.alignment = 4096;
909         alloc.ext.tiling_mode = TILING_NONE;
910         alloc.ext.mem_type = params.memType;
911         alloc.ext.pat_index = patIndex;
912         alloc.ext.cpu_cacheable = isCpuCacheable;
913         bo = mos_bo_alloc(mediaDrvCtx->pDrmBufMgr, &alloc);
914         params.pitch = gmmPitch;
915     }
916     else
917     {
918         struct mos_drm_bo_alloc_tiled alloc_tiled;
919         alloc_tiled.name = "MEDIA";
920         alloc_tiled.x = gmmPitch;
921         alloc_tiled.y = (gmmSize + gmmPitch -1)/gmmPitch;
922         alloc_tiled.cpp = 1;
923         alloc_tiled.ext.tiling_mode = params.tileFormat;
924         alloc_tiled.ext.mem_type = params.memType;;
925         alloc_tiled.ext.pat_index = patIndex;
926         alloc_tiled.ext.cpu_cacheable = isCpuCacheable;
927 
928         bo = mos_bo_alloc_tiled(mediaDrvCtx->pDrmBufMgr, &alloc_tiled);
929         params.pitch = alloc_tiled.pitch;
930     }
931 
932     mediaSurface->bMapped = false;
933     DDI_CHK_NULL(bo, "Failed to create drm buffer object according to input buffer descriptor." ,VA_STATUS_ERROR_ALLOCATION_FAILED);
934 
935     mediaSurface->format      = params.format;
936     mediaSurface->iWidth      = params.width;
937     mediaSurface->iHeight     = gmmHeight;
938     mediaSurface->iRealHeight = params.height;
939     mediaSurface->iPitch      = params.pitch;
940     mediaSurface->iRefCount   = 0;
941     mediaSurface->bo          = bo;
942     mediaSurface->TileType    = params.tileFormat;
943     mediaSurface->isTiled     = (params.tileFormat != TILING_NONE) ? 1 : 0;
944     mediaSurface->pData       = (uint8_t*) bo->virt;
945     DDI_VERBOSEMESSAGE("Alloc %7d bytes (%d x %d resource, gmmTiledType %d)).",gmmSize, params.width, params.height, gmmResourceInfo->GetTileType());
946     uint32_t event[] = {bo->handle, params.format, params.width, params.height, params.pitch, bo->size, params.tileFormat, params.cpTag};
947     MOS_TraceEventExt(EVENT_VA_SURFACE, EVENT_TYPE_INFO, event, sizeof(event), &gmmResourceInfo->GetResFlags(), sizeof(GMM_RESOURCE_FLAG));
948 
949     return VA_STATUS_SUCCESS;
950 }
951 
AllocateSurface(DDI_MEDIA_FORMAT format,int32_t width,int32_t height,PDDI_MEDIA_SURFACE mediaSurface,PDDI_MEDIA_CONTEXT mediaDrvCtx)952 VAStatus MediaLibvaUtilNext::AllocateSurface(
953     DDI_MEDIA_FORMAT            format,
954     int32_t                     width,
955     int32_t                     height,
956     PDDI_MEDIA_SURFACE          mediaSurface,
957     PDDI_MEDIA_CONTEXT          mediaDrvCtx)
958 {
959     VAStatus                     status = VA_STATUS_SUCCESS;
960     MEDIA_SURFACE_ALLOCATE_PARAM params = {};
961     DDI_FUNC_ENTER;
962     DDI_CHK_NULL(mediaSurface,                   "mediaSurface is nullptr",                   VA_STATUS_ERROR_INVALID_BUFFER);
963     DDI_CHK_NULL(mediaDrvCtx,                    "mediaDrvCtx is nullptr",                    VA_STATUS_ERROR_INVALID_BUFFER);
964     DDI_CHK_NULL(mediaDrvCtx->pGmmClientContext, "mediaDrvCtx->pGmmClientContext is nullptr", VA_STATUS_ERROR_INVALID_BUFFER);
965 
966     InitSurfaceAllocateParams(params, width, height, format,
967         mediaSurface->memType, mediaSurface->surfaceUsageHint);
968 
969     status = SetDefaultTileFormat(format, mediaSurface->surfaceUsageHint, &mediaDrvCtx->SkuTable, params);
970     if (status != VA_STATUS_SUCCESS)
971     {
972         DDI_ASSERTMESSAGE("Get tile format failed.");
973         return status;
974     }
975 
976     if (IsExternalSurface(mediaSurface))
977     {
978         return CreateExternalSurface(params, mediaSurface, mediaDrvCtx);
979     }
980     else
981     {
982         return CreateInternalSurface(params, mediaSurface, mediaDrvCtx);
983     }
984 }
985 
IsExternalSurface(PDDI_MEDIA_SURFACE surface)986 bool MediaLibvaUtilNext::IsExternalSurface(PDDI_MEDIA_SURFACE surface)
987 {
988     DDI_FUNC_ENTER;
989     if (nullptr == surface)
990     {
991         return false;
992     }
993     else if (surface->pSurfDesc == nullptr)
994     {
995         return false;
996     }
997     else
998     {
999         if (surface->pSurfDesc->uiVaMemType == VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM ||
1000             surface->pSurfDesc->uiVaMemType == VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME ||
1001             surface->pSurfDesc->uiVaMemType == VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2 ||
1002 #if VA_CHECK_VERSION(1, 21, 0)
1003             surface->pSurfDesc->uiVaMemType == VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_3 ||
1004 #endif
1005             surface->pSurfDesc->uiVaMemType == VA_SURFACE_ATTRIB_MEM_TYPE_USER_PTR)
1006         {
1007             return true;
1008         }
1009         else
1010         {
1011             return false;
1012         }
1013     }
1014 }
1015 
AllocPMediaSurfaceFromHeap(PDDI_MEDIA_HEAP surfaceHeap)1016 PDDI_MEDIA_SURFACE_HEAP_ELEMENT MediaLibvaUtilNext::AllocPMediaSurfaceFromHeap(PDDI_MEDIA_HEAP surfaceHeap)
1017 {
1018     PDDI_MEDIA_SURFACE_HEAP_ELEMENT  mediaSurfaceHeapElmt = nullptr;
1019     DDI_FUNC_ENTER;
1020     DDI_CHK_NULL(surfaceHeap, "nullptr surfaceHeap", nullptr);
1021 
1022     if (nullptr == surfaceHeap->pFirstFreeHeapElement)
1023     {
1024         void *newHeapBase = MOS_ReallocMemory(surfaceHeap->pHeapBase, (surfaceHeap->uiAllocatedHeapElements + DDI_MEDIA_HEAP_INCREMENTAL_SIZE) * sizeof(DDI_MEDIA_SURFACE_HEAP_ELEMENT));
1025 
1026         if (nullptr == newHeapBase)
1027         {
1028             DDI_ASSERTMESSAGE("DDI: realloc failed.");
1029             return nullptr;
1030         }
1031         surfaceHeap->pHeapBase                    = newHeapBase;
1032         PDDI_MEDIA_SURFACE_HEAP_ELEMENT surfaceHeapBase  = (PDDI_MEDIA_SURFACE_HEAP_ELEMENT)surfaceHeap->pHeapBase;
1033         surfaceHeap->pFirstFreeHeapElement        = (void*)(&surfaceHeapBase[surfaceHeap->uiAllocatedHeapElements]);
1034         for (int32_t i = 0; i < (DDI_MEDIA_HEAP_INCREMENTAL_SIZE); i++)
1035         {
1036             mediaSurfaceHeapElmt                  = &surfaceHeapBase[surfaceHeap->uiAllocatedHeapElements + i];
1037             mediaSurfaceHeapElmt->pNextFree       = (i == (DDI_MEDIA_HEAP_INCREMENTAL_SIZE - 1))? nullptr : &surfaceHeapBase[surfaceHeap->uiAllocatedHeapElements + i + 1];
1038             mediaSurfaceHeapElmt->uiVaSurfaceID   = surfaceHeap->uiAllocatedHeapElements + i;
1039         }
1040         surfaceHeap->uiAllocatedHeapElements     += DDI_MEDIA_HEAP_INCREMENTAL_SIZE;
1041     }
1042 
1043     mediaSurfaceHeapElmt                          = (PDDI_MEDIA_SURFACE_HEAP_ELEMENT)surfaceHeap->pFirstFreeHeapElement;
1044     surfaceHeap->pFirstFreeHeapElement            = mediaSurfaceHeapElmt->pNextFree;
1045 
1046     return mediaSurfaceHeapElmt;
1047 }
1048 
ReleasePMediaSurfaceFromHeap(PDDI_MEDIA_HEAP surfaceHeap,uint32_t vaSurfaceID)1049 void MediaLibvaUtilNext::ReleasePMediaSurfaceFromHeap(PDDI_MEDIA_HEAP surfaceHeap, uint32_t vaSurfaceID)
1050 {
1051     DDI_FUNC_ENTER;
1052     DDI_CHK_NULL(surfaceHeap, "nullptr surfaceHeap", );
1053 
1054     DDI_CHK_LESS(vaSurfaceID, surfaceHeap->uiAllocatedHeapElements, "invalid surface id", );
1055     PDDI_MEDIA_SURFACE_HEAP_ELEMENT mediaSurfaceHeapBase                   = (PDDI_MEDIA_SURFACE_HEAP_ELEMENT)surfaceHeap->pHeapBase;
1056     DDI_CHK_NULL(mediaSurfaceHeapBase, "nullptr mediaSurfaceHeapBase", );
1057 
1058     PDDI_MEDIA_SURFACE_HEAP_ELEMENT mediaSurfaceHeapElmt                   = &mediaSurfaceHeapBase[vaSurfaceID];
1059     DDI_CHK_NULL(mediaSurfaceHeapElmt->pSurface, "surface is already released", );
1060     void *firstFree                        = surfaceHeap->pFirstFreeHeapElement;
1061     surfaceHeap->pFirstFreeHeapElement     = (void*)mediaSurfaceHeapElmt;
1062     mediaSurfaceHeapElmt->pNextFree        = (PDDI_MEDIA_SURFACE_HEAP_ELEMENT)firstFree;
1063     mediaSurfaceHeapElmt->pSurface         = nullptr;
1064 }
1065 
CreateSurface(DDI_MEDIA_SURFACE * surface,PDDI_MEDIA_CONTEXT mediaDrvCtx)1066 VAStatus MediaLibvaUtilNext::CreateSurface(DDI_MEDIA_SURFACE  *surface, PDDI_MEDIA_CONTEXT mediaDrvCtx)
1067 {
1068     VAStatus hr = VA_STATUS_SUCCESS;
1069     DDI_FUNC_ENTER;
1070     DDI_CHK_NULL(surface, "nullptr surface", VA_STATUS_ERROR_INVALID_BUFFER);
1071 
1072     // better to differentiate 1D and 2D type
1073     hr = AllocateSurface(surface->format,
1074                          surface->iWidth,
1075                          surface->iHeight,
1076                          surface,
1077                          mediaDrvCtx);
1078     if (VA_STATUS_SUCCESS == hr && nullptr != surface->bo)
1079     {
1080         surface->base = surface->name;
1081     }
1082 
1083     return hr;
1084 }
1085 
ConvertMediaFmtToGmmFmt(DDI_MEDIA_FORMAT format)1086 GMM_RESOURCE_FORMAT MediaLibvaUtilNext::ConvertMediaFmtToGmmFmt(DDI_MEDIA_FORMAT format)
1087 {
1088     DDI_FUNC_ENTER;
1089     switch (format)
1090     {
1091         case Media_Format_X8R8G8B8   : return GMM_FORMAT_B8G8R8X8_UNORM_TYPE;
1092         case Media_Format_A8R8G8B8   : return GMM_FORMAT_B8G8R8A8_UNORM_TYPE;
1093         case Media_Format_X8B8G8R8   : return GMM_FORMAT_R8G8B8X8_UNORM_TYPE;
1094         case Media_Format_A8B8G8R8   : return GMM_FORMAT_R8G8B8A8_UNORM_TYPE;
1095         case Media_Format_R8G8B8A8   : return GMM_FORMAT_R8G8B8A8_UNORM_TYPE;
1096         case Media_Format_R5G6B5     : return GMM_FORMAT_B5G6R5_UNORM_TYPE;
1097         case Media_Format_R8G8B8     : return GMM_FORMAT_R8G8B8_UNORM;
1098         case Media_Format_RGBP       : return GMM_FORMAT_RGBP;
1099         case Media_Format_BGRP       : return GMM_FORMAT_BGRP;
1100         case Media_Format_NV12       : return GMM_FORMAT_NV12_TYPE;
1101         case Media_Format_NV21       : return GMM_FORMAT_NV21_TYPE;
1102         case Media_Format_YUY2       : return GMM_FORMAT_YUY2;
1103         case Media_Format_YVYU       : return GMM_FORMAT_YVYU;
1104         case Media_Format_UYVY       : return GMM_FORMAT_UYVY;
1105         case Media_Format_VYUY       : return GMM_FORMAT_VYUY;
1106         case Media_Format_YV12       : return GMM_FORMAT_YV12_TYPE;
1107         case Media_Format_IYUV       : return GMM_FORMAT_IYUV_TYPE;
1108         case Media_Format_I420       : return GMM_FORMAT_I420_TYPE;
1109         case Media_Format_444P       : return GMM_FORMAT_MFX_JPEG_YUV444_TYPE;
1110         case Media_Format_422H       : return GMM_FORMAT_MFX_JPEG_YUV422H_TYPE;
1111         case Media_Format_411P       : return GMM_FORMAT_MFX_JPEG_YUV411_TYPE;
1112         case Media_Format_422V       : return GMM_FORMAT_MFX_JPEG_YUV422V_TYPE;
1113         case Media_Format_IMC3       : return GMM_FORMAT_IMC3_TYPE;
1114         case Media_Format_400P       : return GMM_FORMAT_GENERIC_8BIT;
1115         case Media_Format_Buffer     : return GMM_FORMAT_RENDER_8BIT;
1116         case Media_Format_P010       : return GMM_FORMAT_P010_TYPE;
1117         case Media_Format_R10G10B10A2: return GMM_FORMAT_R10G10B10A2_UNORM_TYPE;
1118         case Media_Format_B10G10R10A2: return GMM_FORMAT_B10G10R10A2_UNORM_TYPE;
1119         case Media_Format_R10G10B10X2: return GMM_FORMAT_R10G10B10A2_UNORM_TYPE;
1120         case Media_Format_B10G10R10X2: return GMM_FORMAT_B10G10R10A2_UNORM_TYPE;
1121         case Media_Format_P012       : return GMM_FORMAT_P016_TYPE;
1122         case Media_Format_P016       : return GMM_FORMAT_P016_TYPE;
1123         case Media_Format_Y210       : return GMM_FORMAT_Y210_TYPE;
1124 #if VA_CHECK_VERSION(1, 9, 0)
1125         case Media_Format_Y212       : return GMM_FORMAT_Y212_TYPE;
1126 #endif
1127         case Media_Format_Y216       : return GMM_FORMAT_Y216_TYPE;
1128         case Media_Format_AYUV       : return GMM_FORMAT_AYUV_TYPE;
1129 #if VA_CHECK_VERSION(1, 13, 0)
1130         case Media_Format_XYUV       : return GMM_FORMAT_AYUV_TYPE;
1131 #endif
1132         case Media_Format_Y410       : return GMM_FORMAT_Y410_TYPE;
1133 #if VA_CHECK_VERSION(1, 9, 0)
1134         case Media_Format_Y412       : return GMM_FORMAT_Y412_TYPE;
1135 #endif
1136         case Media_Format_Y416       : return GMM_FORMAT_Y416_TYPE;
1137         case Media_Format_Y8         : return GMM_FORMAT_MEDIA_Y8_UNORM;
1138         case Media_Format_Y16S       : return GMM_FORMAT_MEDIA_Y16_SNORM;
1139         case Media_Format_Y16U       : return GMM_FORMAT_MEDIA_Y16_UNORM;
1140         case Media_Format_A16R16G16B16: return GMM_FORMAT_B16G16R16A16_UNORM;
1141         case Media_Format_A16B16G16R16: return GMM_FORMAT_R16G16B16A16_UNORM;
1142         default                      : return GMM_FORMAT_INVALID;
1143     }
1144 }
1145 
WaitSemaphore(PMEDIA_SEM_T sem)1146 void MediaLibvaUtilNext::WaitSemaphore(PMEDIA_SEM_T sem)
1147 {
1148     DDI_FUNC_ENTER;
1149     int32_t ret = sem_wait(sem);
1150     if (ret != 0)
1151     {
1152         DDI_NORMALMESSAGE("wait semaphore error!\n");
1153     }
1154 }
1155 
TryWaitSemaphore(PMEDIA_SEM_T sem)1156 int32_t MediaLibvaUtilNext::TryWaitSemaphore(PMEDIA_SEM_T sem)
1157 {
1158     return sem_trywait(sem);
1159 }
1160 
PostSemaphore(PMEDIA_SEM_T sem)1161 void MediaLibvaUtilNext::PostSemaphore(PMEDIA_SEM_T sem)
1162 {
1163     int32_t ret = sem_post(sem);
1164     if (ret != 0)
1165     {
1166         DDI_NORMALMESSAGE("post semaphore error!\n");
1167     }
1168 }
1169 
DestroySemaphore(PMEDIA_SEM_T sem)1170 void MediaLibvaUtilNext::DestroySemaphore(PMEDIA_SEM_T sem)
1171 {
1172     int32_t ret = sem_destroy(sem);
1173     if(ret != 0)
1174     {
1175         DDI_NORMALMESSAGE("can't destroy the semaphore!\n");
1176     }
1177 }
1178 
UnRegisterRTSurfaces(VADriverContextP ctx,PDDI_MEDIA_SURFACE surface)1179 VAStatus MediaLibvaUtilNext::UnRegisterRTSurfaces(
1180     VADriverContextP    ctx,
1181     PDDI_MEDIA_SURFACE  surface)
1182 {
1183     DDI_FUNC_ENTER;
1184     DDI_CHK_NULL(ctx, "nullptr context!", VA_STATUS_ERROR_INVALID_CONTEXT);
1185     PDDI_MEDIA_CONTEXT mediaCtx   = GetMediaContext(ctx);
1186     DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx!", VA_STATUS_ERROR_INVALID_CONTEXT);
1187     DDI_CHK_NULL(surface,  "nullptr surface!",  VA_STATUS_ERROR_INVALID_PARAMETER);
1188 
1189     //Look through all decode contexts to unregister the surface in each decode context's RTtable.
1190     if (mediaCtx->pDecoderCtxHeap != nullptr)
1191     {
1192         PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT decVACtxHeapBase = nullptr;
1193 
1194         MosUtilities::MosLockMutex(&mediaCtx->DecoderMutex);
1195         decVACtxHeapBase  = (PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT)mediaCtx->pDecoderCtxHeap->pHeapBase;
1196         for (uint32_t j = 0; j < mediaCtx->pDecoderCtxHeap->uiAllocatedHeapElements; j++)
1197         {
1198             if (decVACtxHeapBase[j].pVaContext != nullptr)
1199             {
1200                 decode::PDDI_DECODE_CONTEXT decCtx = (decode::PDDI_DECODE_CONTEXT)decVACtxHeapBase[j].pVaContext;
1201                 if (decCtx && decCtx->m_ddiDecodeNext)
1202                 {
1203                     //not check the return value since the surface may not be registered in the context. pay attention to LOGW.
1204                     decCtx->m_ddiDecodeNext->UnRegisterRTSurfaces(&decCtx->RTtbl, surface);
1205                 }
1206             }
1207         }
1208         MosUtilities::MosUnlockMutex(&mediaCtx->DecoderMutex);
1209     }
1210     if (mediaCtx->pEncoderCtxHeap != nullptr)
1211     {
1212         PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT pEncVACtxHeapBase = nullptr;
1213 
1214         MosUtilities::MosLockMutex(&mediaCtx->EncoderMutex);
1215         pEncVACtxHeapBase  = (PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT)mediaCtx->pEncoderCtxHeap->pHeapBase;
1216         for (uint32_t j = 0; j < mediaCtx->pEncoderCtxHeap->uiAllocatedHeapElements; j++)
1217         {
1218             if (pEncVACtxHeapBase[j].pVaContext != nullptr)
1219             {
1220                 PDDI_ENCODE_CONTEXT  pEncCtx = (PDDI_ENCODE_CONTEXT)pEncVACtxHeapBase[j].pVaContext;
1221                 if (pEncCtx && pEncCtx->m_encode)
1222                 {
1223                     //not check the return value since the surface may not be registered in the context. pay attention to LOGW.
1224                     pEncCtx->m_encode->UnRegisterRTSurfaces(&pEncCtx->RTtbl, surface);
1225                 }
1226             }
1227         }
1228         MosUtilities::MosUnlockMutex(&mediaCtx->EncoderMutex);
1229     }
1230 
1231     return VA_STATUS_SUCCESS;
1232 }
1233 
FreeSurface(DDI_MEDIA_SURFACE * surface)1234 void MediaLibvaUtilNext::FreeSurface(DDI_MEDIA_SURFACE *surface)
1235 {
1236     DDI_FUNC_ENTER;
1237     DDI_CHK_NULL(surface, "nullptr surface", );
1238     DDI_CHK_NULL(surface->bo, "nullptr surface->bo", );
1239     DDI_CHK_NULL(surface->pMediaCtx, "nullptr surface->pMediaCtx", );
1240     DDI_CHK_NULL(surface->pMediaCtx->pGmmClientContext, "nullptr surface->pMediaCtx->pGmmClientContext", );
1241 
1242     // Unmap Aux mapping if the surface was mapped
1243     if (surface->pMediaCtx->m_auxTableMgr)
1244     {
1245         surface->pMediaCtx->m_auxTableMgr->UnmapResource(surface->pGmmResourceInfo, surface->bo);
1246     }
1247 
1248     if(surface->bMapped)
1249     {
1250         UnlockSurface(surface);
1251         DDI_VERBOSEMESSAGE("DDI: try to free a locked surface.");
1252     }
1253     mos_bo_unreference(surface->bo);
1254     // For External Buffer, only needs to destory SurfaceDescriptor
1255     if (surface->pSurfDesc)
1256     {
1257         MOS_FreeMemory(surface->pSurfDesc);
1258         surface->pSurfDesc = nullptr;
1259     }
1260 
1261     if (nullptr != surface->pGmmResourceInfo)
1262     {
1263         surface->pMediaCtx->pGmmClientContext->DestroyResInfoObject(surface->pGmmResourceInfo);
1264         surface->pGmmResourceInfo = nullptr;
1265     }
1266 }
1267 
FreeBuffer(DDI_MEDIA_BUFFER * buf)1268 void MediaLibvaUtilNext::FreeBuffer(DDI_MEDIA_BUFFER  *buf)
1269 {
1270     DDI_FUNC_ENTER;
1271     DDI_CHK_NULL(buf, "nullptr", );
1272     // calling sequence checking
1273     if (buf->bMapped)
1274     {
1275         UnlockBuffer(buf);
1276         DDI_VERBOSEMESSAGE("DDI: try to free a locked buffer.");
1277     }
1278     if (buf->format == Media_Format_CPU)
1279     {
1280         MOS_FreeMemory(buf->pData);
1281         buf->pData = nullptr;
1282     }
1283     else
1284     {
1285         mos_bo_unreference(buf->bo);
1286         buf->bo = nullptr;
1287     }
1288 
1289     if (nullptr != buf->pMediaCtx && nullptr != buf->pMediaCtx->pGmmClientContext && nullptr != buf->pGmmResourceInfo)
1290     {
1291         buf->pMediaCtx->pGmmClientContext->DestroyResInfoObject(buf->pGmmResourceInfo);
1292         buf->pGmmResourceInfo = nullptr;
1293     }
1294 }
1295 
LockSurface(DDI_MEDIA_SURFACE * surface,uint32_t flag)1296 void* MediaLibvaUtilNext::LockSurface(DDI_MEDIA_SURFACE *surface, uint32_t flag)
1297 {
1298     DDI_FUNC_ENTER;
1299     DDI_CHK_NULL(surface,            "nullptr surface",            nullptr);
1300     DDI_CHK_NULL(surface->pMediaCtx, "nullptr surface->pMediaCtx", nullptr);
1301 
1302     if (MEDIA_IS_SKU(&surface->pMediaCtx->SkuTable, FtrLocalMemory))
1303     {
1304         if ((MosUtilities::MosAtomicIncrement(&surface->iRefCount) == 1) && (false == surface->bMapped))
1305         {
1306            return LockSurfaceInternal(surface, flag);
1307         }
1308         else
1309         {
1310             DDI_VERBOSEMESSAGE("line %d, invalide operation for lockSurface. the surface reference count = %d", __LINE__, surface->iRefCount);
1311         }
1312     }
1313     else
1314     {
1315          if ((surface->iRefCount == 0) && (false == surface->bMapped))
1316          {
1317             LockSurfaceInternal(surface, flag);
1318          }
1319          else
1320          {
1321              // do nothing here
1322          }
1323          surface->iRefCount++;
1324     }
1325 
1326     return surface->pData;
1327 }
1328 
LockSurfaceInternal(DDI_MEDIA_SURFACE * surface,uint32_t flag)1329 void* MediaLibvaUtilNext::LockSurfaceInternal(DDI_MEDIA_SURFACE  *surface, uint32_t flag)
1330 {
1331     int      err      = 0;
1332     VAStatus vaStatus = VA_STATUS_SUCCESS;
1333     DDI_FUNC_ENTER;
1334 
1335     DDI_CHK_NULL(surface, "nullptr surface", nullptr);
1336     DDI_CHK_NULL(surface->bo, "nullptr surface->bo", nullptr);
1337     DDI_CHK_NULL(surface->pMediaCtx, "nullptr surface->pMediaCtx", nullptr);
1338 
1339     // non-tield surface
1340     if (surface->TileType == TILING_NONE)
1341     {
1342         mos_bo_map(surface->bo, flag & MOS_LOCKFLAG_WRITEONLY);
1343         surface->pData     = (uint8_t*)surface->bo->virt;
1344         surface->data_size = surface->bo->size;
1345         surface->bMapped   = true;
1346 
1347         return surface->pData;
1348     }
1349 
1350     auto DoHwSwizzle = [&]()->bool
1351     {
1352         if (MEDIA_IS_SKU(&surface->pMediaCtx->SkuTable, FtrUseSwSwizzling))
1353         {
1354             return false;
1355         }
1356         // RGBP not supported by ve.
1357         if (surface->format == Media_Format_RGBP)
1358         {
1359             return false;
1360         }
1361         if (!surface->pShadowBuffer)
1362         {
1363             vaStatus = CreateShadowResource(surface);
1364             if (vaStatus != VA_STATUS_SUCCESS)
1365             {
1366                 return false;
1367             }
1368         }
1369 
1370         vaStatus = SwizzleSurfaceByHW(surface);
1371         if (vaStatus == VA_STATUS_SUCCESS)
1372         {
1373             err = mos_bo_map(surface->pShadowBuffer->bo, flag & MOS_LOCKFLAG_WRITEONLY);
1374             if (err == 0)
1375             {
1376                 surface->pData     = (uint8_t *)surface->pShadowBuffer->bo->virt;
1377                 return true;
1378             }
1379         }
1380 
1381         // HW swizzle failed
1382         FreeBuffer(surface->pShadowBuffer);
1383         MOS_Delete(surface->pShadowBuffer);
1384         surface->pShadowBuffer = nullptr;
1385         return false;
1386     };
1387 
1388     auto DoSwSwizzle = [&]()->bool
1389     {
1390         mos_bo_map(surface->bo, flag & MOS_LOCKFLAG_WRITEONLY);
1391 
1392         surface->pSystemShadow = MOS_NewArray(uint8_t, surface->bo->size);
1393         if (!surface->pSystemShadow)
1394         {
1395             return false;
1396         }
1397 
1398         vaStatus = SwizzleSurface(surface->pMediaCtx,
1399                                     surface->pGmmResourceInfo,
1400                                     surface->bo->virt,
1401                                     (MOS_TILE_TYPE)surface->TileType,
1402                                     (uint8_t *)surface->pSystemShadow,
1403                                     false);
1404         if(vaStatus == VA_STATUS_SUCCESS)
1405         {
1406             surface->pData = surface->pSystemShadow;
1407             return true;
1408         }
1409 
1410         // SW swizzle failed
1411         MOS_DeleteArray(surface->pSystemShadow);
1412         surface->pSystemShadow = nullptr;
1413         return false;
1414     };
1415 
1416     if (!DoHwSwizzle())
1417     {
1418         if (!DoSwSwizzle())
1419         {
1420             DDI_ASSERTMESSAGE("Swizzle failed!");
1421             return nullptr;
1422         }
1423     }
1424 
1425     surface->uiMapFlag = flag;
1426     surface->data_size = surface->bo->size;
1427     surface->bMapped   = true;
1428 
1429     return surface->pData;
1430 }
1431 
UnlockSurface(DDI_MEDIA_SURFACE * surface)1432 void MediaLibvaUtilNext::UnlockSurface(DDI_MEDIA_SURFACE  *surface)
1433 {
1434     DDI_FUNC_ENTER;
1435     DDI_CHK_NULL(surface, "nullptr surface", );
1436     DDI_CHK_NULL(surface->bo, "nullptr surface->bo", );
1437     if (0 == surface->iRefCount)
1438     {
1439         return;
1440     }
1441 
1442     if((true == surface->bMapped) && (1 == surface->iRefCount))
1443     {
1444         if (surface->pMediaCtx->bIsAtomSOC)
1445         {
1446             mos_bo_unmap_gtt(surface->bo);
1447         }
1448         else
1449         {
1450             if (surface->TileType == TILING_NONE)
1451             {
1452                mos_bo_unmap(surface->bo);
1453             }
1454             else if (surface->pShadowBuffer != nullptr)
1455             {
1456                 SwizzleSurfaceByHW(surface, true);
1457 
1458                 mos_bo_unmap(surface->pShadowBuffer->bo);
1459                 FreeBuffer(surface->pShadowBuffer);
1460                 MOS_Delete(surface->pShadowBuffer);
1461                 surface->pShadowBuffer = nullptr;
1462 
1463                 mos_bo_unmap(surface->bo);
1464             }
1465             else if (surface->pSystemShadow)
1466             {
1467                 SwizzleSurface(surface->pMediaCtx,
1468                                surface->pGmmResourceInfo,
1469                                surface->bo->virt,
1470                                (MOS_TILE_TYPE)surface->TileType,
1471                                (uint8_t *)surface->pSystemShadow,
1472                                true);
1473 
1474                 MOS_DeleteArray(surface->pSystemShadow);
1475                 surface->pSystemShadow = nullptr;
1476 
1477                 mos_bo_unmap(surface->bo);
1478             }
1479             else if(surface->uiMapFlag & MOS_LOCKFLAG_NO_SWIZZLE)
1480             {
1481                 mos_bo_unmap(surface->bo);
1482             }
1483             else
1484             {
1485                mos_bo_unmap_gtt(surface->bo);
1486             }
1487         }
1488         surface->pData       = nullptr;
1489         surface->bo->virt    = nullptr;
1490         surface->bMapped     = false;
1491     }
1492     else
1493     {
1494         // do nothing here
1495     }
1496 
1497     surface->iRefCount--;
1498 
1499     return;
1500 }
1501 
CreateShadowResource(DDI_MEDIA_SURFACE * surface)1502 VAStatus MediaLibvaUtilNext::CreateShadowResource(DDI_MEDIA_SURFACE *surface)
1503 {
1504     VAStatus vaStatus = VA_STATUS_SUCCESS;
1505     DDI_FUNC_ENTER;
1506     DDI_CHK_NULL(surface, "nullptr surface", VA_STATUS_ERROR_INVALID_SURFACE);
1507     DDI_CHK_NULL(surface->pGmmResourceInfo, "nullptr surface->pGmmResourceInfo", VA_STATUS_ERROR_INVALID_SURFACE);
1508     if (surface->pGmmResourceInfo->GetSetCpSurfTag(0, 0) != 0)
1509     {
1510         return VA_STATUS_ERROR_INVALID_SURFACE;
1511     }
1512 
1513     if (surface->iWidth < 64 || surface->iRealHeight < 64 || (surface->iPitch % 64 != 0) || surface->format == Media_Format_P016)
1514     {
1515         return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
1516     }
1517 
1518     surface->pShadowBuffer = MOS_New(DDI_MEDIA_BUFFER);
1519     DDI_CHK_NULL(surface->pShadowBuffer, "Failed to allocate shadow buffer", VA_STATUS_ERROR_INVALID_BUFFER);
1520     surface->pShadowBuffer->pMediaCtx = surface->pMediaCtx;
1521     surface->pShadowBuffer->bUseSysGfxMem = true;
1522     surface->pShadowBuffer->iSize = surface->pGmmResourceInfo->GetSizeSurface();
1523 
1524     vaStatus = AllocateBuffer(Media_Format_Buffer, surface->pShadowBuffer->iSize, surface->pShadowBuffer, surface->pMediaCtx->pDrmBufMgr, true);
1525 
1526     if (vaStatus != VA_STATUS_SUCCESS)
1527     {
1528         MOS_Delete(surface->pShadowBuffer);
1529         surface->pShadowBuffer = nullptr;
1530     }
1531 
1532     return vaStatus;
1533 }
1534 
LockBuffer(DDI_MEDIA_BUFFER * buf,uint32_t flag)1535 void* MediaLibvaUtilNext::LockBuffer(DDI_MEDIA_BUFFER *buf, uint32_t flag)
1536 {
1537     DDI_FUNC_ENTER;
1538     DDI_CHK_NULL(buf, "nullptr buf", nullptr);
1539     if((Media_Format_CPU != buf->format) && (false == buf->bMapped))
1540     {
1541         if (nullptr != buf->pSurface)
1542         {
1543             LockSurface(buf->pSurface, flag);
1544             buf->pData = buf->pSurface->pData;
1545         }
1546         else
1547         {
1548             if (buf->pMediaCtx->bIsAtomSOC)
1549             {
1550                 mos_bo_map_gtt(buf->bo);
1551             }
1552             else
1553             {
1554                 if (buf->TileType == TILING_NONE)
1555                 {
1556                     mos_bo_map(buf->bo, ((MOS_LOCKFLAG_READONLY | MOS_LOCKFLAG_WRITEONLY) & flag));
1557                 }
1558                 else
1559                 {
1560                     mos_bo_map_gtt(buf->bo);
1561                 }
1562              }
1563 
1564             buf->pData = (uint8_t*)(buf->bo->virt);
1565         }
1566 
1567         buf->bMapped = true;
1568         buf->iRefCount++;
1569     }
1570     else if ((Media_Format_CPU == buf->format) && (false == buf->bMapped))
1571     {
1572         buf->bMapped = true;
1573         buf->iRefCount++;
1574     }
1575     else
1576     {
1577         buf->iRefCount++;
1578     }
1579 
1580     return buf->pData;
1581 }
1582 
UnlockBuffer(DDI_MEDIA_BUFFER * buf)1583 void MediaLibvaUtilNext::UnlockBuffer(DDI_MEDIA_BUFFER *buf)
1584 {
1585     DDI_FUNC_ENTER;
1586     DDI_CHK_NULL(buf, "nullptr buf", );
1587     if (0 == buf->iRefCount)
1588     {
1589         return;
1590     }
1591     if((true == buf->bMapped) && (Media_Format_CPU != buf->format) && (1 == buf->iRefCount))
1592     {
1593         if (nullptr != buf->pSurface)
1594         {
1595             UnlockSurface(buf->pSurface);
1596         }
1597         else
1598         {
1599              if (buf->pMediaCtx->bIsAtomSOC)
1600              {
1601                  mos_bo_unmap_gtt(buf->bo);
1602              }
1603              else
1604              {
1605                  if (buf->TileType == TILING_NONE)
1606                  {
1607                      mos_bo_unmap(buf->bo);
1608                  }
1609                  else
1610                  {
1611                      mos_bo_unmap_gtt(buf->bo);
1612                  }
1613             }
1614             buf->bo->virt = nullptr;
1615         }
1616 
1617         buf->pData       = nullptr;
1618 
1619         buf->bMapped     = false;
1620     }
1621     else if ((true == buf->bMapped) && (Media_Format_CPU == buf->format) && (1 == buf->iRefCount))
1622     {
1623         buf->bMapped     = false;
1624     }
1625     else
1626     {
1627         // do nothing here
1628     }
1629     buf->iRefCount--;
1630     return;
1631 }
1632 
SwizzleSurface(PDDI_MEDIA_CONTEXT mediaCtx,PGMM_RESOURCE_INFO pGmmResInfo,void * pLockedAddr,uint32_t TileType,uint8_t * pResourceBase,bool bUpload)1633 VAStatus MediaLibvaUtilNext::SwizzleSurface(
1634     PDDI_MEDIA_CONTEXT         mediaCtx,
1635     PGMM_RESOURCE_INFO         pGmmResInfo,
1636     void                       *pLockedAddr,
1637     uint32_t                   TileType,
1638     uint8_t                    *pResourceBase,
1639     bool                       bUpload)
1640 {
1641     uint32_t            uiSize         = 0, uiPitch = 0;
1642     GMM_RES_COPY_BLT    gmmResCopyBlt  = {0};
1643     uint32_t            uiPicHeight    = 0;
1644     uint32_t            ulSwizzledSize = 0;
1645     VAStatus            vaStatus       = VA_STATUS_SUCCESS;
1646     DDI_FUNC_ENTER;
1647 
1648     DDI_CHK_NULL(pGmmResInfo,   "pGmmResInfo is NULL",   VA_STATUS_ERROR_OPERATION_FAILED);
1649     DDI_CHK_NULL(pLockedAddr,   "pLockedAddr is NULL",   VA_STATUS_ERROR_OPERATION_FAILED);
1650     DDI_CHK_NULL(pResourceBase, "pResourceBase is NULL", VA_STATUS_ERROR_ALLOCATION_FAILED);
1651 
1652     uiPicHeight = pGmmResInfo->GetBaseHeight();
1653     uiSize      = pGmmResInfo->GetSizeSurface();
1654     uiPitch     = pGmmResInfo->GetRenderPitch();
1655     gmmResCopyBlt.Gpu.pData      = pLockedAddr;
1656     gmmResCopyBlt.Sys.pData      = pResourceBase;
1657     gmmResCopyBlt.Sys.RowPitch   = uiPitch;
1658     gmmResCopyBlt.Sys.BufferSize = uiSize;
1659     gmmResCopyBlt.Sys.SlicePitch = uiSize;
1660     gmmResCopyBlt.Blt.Slices     = 1;
1661     gmmResCopyBlt.Blt.Upload     = bUpload;
1662 
1663     if(mediaCtx->pGmmClientContext->IsPlanar(pGmmResInfo->GetResourceFormat()) == true)
1664     {
1665         gmmResCopyBlt.Blt.Width  = pGmmResInfo->GetBaseWidth();
1666         gmmResCopyBlt.Blt.Height = uiSize/uiPitch;
1667     }
1668 
1669     pGmmResInfo->CpuBlt(&gmmResCopyBlt);
1670 
1671     return vaStatus;
1672 }
1673 
ReleasePMediaBufferFromHeap(PDDI_MEDIA_HEAP bufferHeap,uint32_t vaBufferID)1674 void MediaLibvaUtilNext::ReleasePMediaBufferFromHeap(
1675     PDDI_MEDIA_HEAP  bufferHeap,
1676     uint32_t         vaBufferID)
1677 {
1678     DDI_FUNC_ENTER;
1679     DDI_CHK_NULL(bufferHeap, "nullptr bufferHeap", );
1680 
1681     DDI_CHK_LESS(vaBufferID, bufferHeap->uiAllocatedHeapElements, "invalid buffer id", );
1682     PDDI_MEDIA_BUFFER_HEAP_ELEMENT mediaBufferHeapBase  =  (PDDI_MEDIA_BUFFER_HEAP_ELEMENT)bufferHeap->pHeapBase;
1683     PDDI_MEDIA_BUFFER_HEAP_ELEMENT mediaBufferHeapElmt  =  &mediaBufferHeapBase[vaBufferID];
1684     DDI_CHK_NULL(mediaBufferHeapElmt->pBuffer, "buffer is already released", );
1685     void *firstFree                        = bufferHeap->pFirstFreeHeapElement;
1686     bufferHeap->pFirstFreeHeapElement      = (void*)mediaBufferHeapElmt;
1687     mediaBufferHeapElmt->pNextFree         = (PDDI_MEDIA_BUFFER_HEAP_ELEMENT)firstFree;
1688     mediaBufferHeapElmt->pBuffer           = nullptr;
1689     return;
1690 }
1691 
SwizzleSurfaceByHW(DDI_MEDIA_SURFACE * surface,bool isDeSwizzle)1692 VAStatus MediaLibvaUtilNext::SwizzleSurfaceByHW(DDI_MEDIA_SURFACE *surface, bool isDeSwizzle)
1693 {
1694     DDI_FUNC_ENTER;
1695     DDI_CHK_NULL(surface, "nullptr surface", VA_STATUS_ERROR_INVALID_SURFACE);
1696     DDI_CHK_NULL(surface->pMediaCtx, "nullptr media context", VA_STATUS_ERROR_INVALID_CONTEXT);
1697 
1698     MOS_CONTEXT mosCtx = {};
1699     PERF_DATA perfData = {};
1700     PDDI_MEDIA_CONTEXT mediaDrvCtx = surface->pMediaCtx;
1701 
1702     // Get the buf manager for codechal create
1703     mosCtx.bufmgr          = mediaDrvCtx->pDrmBufMgr;
1704     mosCtx.fd              = mediaDrvCtx->fd;
1705     mosCtx.iDeviceId       = mediaDrvCtx->iDeviceId;
1706     mosCtx.m_skuTable        = mediaDrvCtx->SkuTable;
1707     mosCtx.m_waTable         = mediaDrvCtx->WaTable;
1708     mosCtx.m_gtSystemInfo    = *mediaDrvCtx->pGtSystemInfo;
1709     mosCtx.m_platform        = mediaDrvCtx->platform;
1710 
1711     mosCtx.ppMediaMemDecompState = &mediaDrvCtx->pMediaMemDecompState;
1712     mosCtx.pfnMemoryDecompress   = mediaDrvCtx->pfnMemoryDecompress;
1713     mosCtx.pfnMediaMemoryCopy    = mediaDrvCtx->pfnMediaMemoryCopy;
1714     mosCtx.pfnMediaMemoryCopy2D  = mediaDrvCtx->pfnMediaMemoryCopy2D;
1715     mosCtx.pPerfData             = &perfData;
1716     mosCtx.m_gtSystemInfo        = *mediaDrvCtx->pGtSystemInfo;
1717     mosCtx.m_auxTableMgr         = mediaDrvCtx->m_auxTableMgr;
1718     mosCtx.pGmmClientContext     = mediaDrvCtx->pGmmClientContext;
1719 
1720     mosCtx.m_osDeviceContext     = mediaDrvCtx->m_osDeviceContext;
1721     mosCtx.m_userSettingPtr      = mediaDrvCtx->m_userSettingPtr;
1722 
1723     MOS_RESOURCE source = {};
1724     MOS_RESOURCE target = {};
1725 
1726     if (isDeSwizzle)
1727     {
1728         MediaLibvaCommonNext::MediaBufferToMosResource(surface->pShadowBuffer, &source);
1729         MediaLibvaCommonNext::MediaSurfaceToMosResource(surface, &target);
1730     }
1731     else
1732     {
1733         MediaLibvaCommonNext::MediaSurfaceToMosResource(surface, &source);
1734         MediaLibvaCommonNext::MediaBufferToMosResource(surface->pShadowBuffer, &target);
1735     }
1736 
1737     DDI_NORMALMESSAGE("If mmd device isn't registered, use media blt copy.");
1738     MediaCopyBaseState *mediaCopyState = static_cast<MediaCopyBaseState*>(mediaDrvCtx->pMediaCopyState);
1739     if (!mediaCopyState)
1740     {
1741         mediaCopyState = static_cast<MediaCopyBaseState*>(McpyDeviceNext::CreateFactory(&mosCtx));
1742         if (!mediaCopyState)
1743         {
1744             return VA_STATUS_ERROR_UNKNOWN;
1745         }
1746         mediaDrvCtx->pMediaCopyState = mediaCopyState;
1747     }
1748 
1749 #if (_DEBUG || _RELEASE_INTERNAL)
1750     // disable reg key report to avoid conflict with media copy cases.
1751     mediaCopyState->SetRegkeyReport(false);
1752 #endif
1753 
1754     auto format = surface->pGmmResourceInfo->GetResourceFormat();
1755     auto width  = surface->pGmmResourceInfo->GetBaseWidth();
1756     auto height = surface->pGmmResourceInfo->GetBaseHeight();
1757     auto pitch  = surface->pGmmResourceInfo->GetRenderPitch();
1758 
1759     auto uOffsetX = surface->pGmmResourceInfo->GetPlanarXOffset(GMM_PLANE_U);
1760     auto uOffsetY = surface->pGmmResourceInfo->GetPlanarYOffset(GMM_PLANE_U);
1761     auto vOffsetX = surface->pGmmResourceInfo->GetPlanarXOffset(GMM_PLANE_V);
1762     auto vOffsetY = surface->pGmmResourceInfo->GetPlanarYOffset(GMM_PLANE_V);
1763 
1764     DDI_NORMALMESSAGE("Override param: format %d, width %d, height %d, pitch %d", format, width, height, pitch);
1765 
1766     DDI_CHK_NULL(source.pGmmResInfo, "nullptr surface", VA_STATUS_ERROR_INVALID_SURFACE);
1767     DDI_CHK_NULL(target.pGmmResInfo, "nullptr surface", VA_STATUS_ERROR_INVALID_SURFACE);
1768 
1769     if (isDeSwizzle)
1770     {
1771         source.pGmmResInfo->OverrideSurfaceFormat(format);
1772         source.pGmmResInfo->OverrideSurfaceType(RESOURCE_2D);
1773         source.pGmmResInfo->OverrideBaseWidth(width);
1774         source.pGmmResInfo->OverrideBaseHeight(height);
1775         source.pGmmResInfo->OverridePitch(pitch);
1776 
1777         source.pGmmResInfo->OverridePlanarXOffset(GMM_PLANE_U, uOffsetX);
1778         source.pGmmResInfo->OverridePlanarYOffset(GMM_PLANE_U, uOffsetY);
1779         source.pGmmResInfo->OverridePlanarXOffset(GMM_PLANE_V, vOffsetX);
1780         source.pGmmResInfo->OverridePlanarYOffset(GMM_PLANE_V, vOffsetY);
1781 
1782         source.Format = target.Format;
1783     }
1784     else
1785     {
1786         target.pGmmResInfo->OverrideSurfaceFormat(format);
1787         target.pGmmResInfo->OverrideSurfaceType(RESOURCE_2D);
1788         target.pGmmResInfo->OverrideBaseWidth(width);
1789         target.pGmmResInfo->OverrideBaseHeight(height);
1790         target.pGmmResInfo->OverridePitch(pitch);
1791 
1792         target.pGmmResInfo->OverridePlanarXOffset(GMM_PLANE_U, uOffsetX);
1793         target.pGmmResInfo->OverridePlanarYOffset(GMM_PLANE_U, uOffsetY);
1794         target.pGmmResInfo->OverridePlanarXOffset(GMM_PLANE_V, vOffsetX);
1795         target.pGmmResInfo->OverridePlanarYOffset(GMM_PLANE_V, vOffsetY);
1796 
1797         target.Format = source.Format;
1798     }
1799 
1800     MOS_STATUS mosSts = mediaCopyState->SurfaceCopy(&source, &target, MCPY_METHOD_BALANCE);
1801 
1802     if (mosSts == MOS_STATUS_SUCCESS)
1803     {
1804         return VA_STATUS_SUCCESS;
1805     }
1806     else
1807     {
1808         return VA_STATUS_ERROR_UNKNOWN;
1809     }
1810 }
1811 
CreateBuffer(DDI_MEDIA_BUFFER * buffer,MOS_BUFMGR * bufmgr)1812 VAStatus MediaLibvaUtilNext::CreateBuffer(
1813     DDI_MEDIA_BUFFER *buffer,
1814     MOS_BUFMGR       *bufmgr)
1815 {
1816     VAStatus status = VA_STATUS_SUCCESS;
1817     DDI_FUNC_ENTER;
1818     DDI_CHK_NULL(buffer,                             "nullptr buffer",         VA_STATUS_ERROR_INVALID_BUFFER);
1819     DDI_CHK_LESS(buffer->format, Media_Format_Count, "Invalid buffer->format", VA_STATUS_ERROR_INVALID_PARAMETER);
1820 
1821     if (buffer->format == Media_Format_CPU)
1822     {
1823         buffer->pData= (uint8_t*)MOS_AllocAndZeroMemory(buffer->iSize);
1824         if (nullptr == buffer->pData)
1825         {
1826             status = VA_STATUS_ERROR_ALLOCATION_FAILED;
1827         }
1828     }
1829     else
1830     {
1831         if (Media_Format_2DBuffer == buffer->format)
1832         {
1833             status = Allocate2DBuffer(buffer->uiHeight, buffer->uiWidth, buffer, bufmgr);
1834         }
1835         else
1836         {
1837             status = AllocateBuffer(buffer->format, buffer->iSize, buffer, bufmgr);
1838         }
1839     }
1840 
1841     buffer->uiLockedBufID   = VA_INVALID_ID;
1842     buffer->uiLockedImageID = VA_INVALID_ID;
1843     buffer->iRefCount       = 0;
1844 
1845     return status;
1846 }
1847 
Allocate2DBuffer(uint32_t height,uint32_t width,PDDI_MEDIA_BUFFER mediaBuffer,MOS_BUFMGR * bufmgr)1848 VAStatus MediaLibvaUtilNext::Allocate2DBuffer(
1849     uint32_t             height,
1850     uint32_t             width,
1851     PDDI_MEDIA_BUFFER    mediaBuffer,
1852     MOS_BUFMGR           *bufmgr)
1853 {
1854     DDI_CHK_NULL(mediaBuffer,                               "mediaBuffer is nullptr",                               VA_STATUS_ERROR_INVALID_BUFFER);
1855     DDI_CHK_NULL(mediaBuffer->pMediaCtx,                    "mediaBuffer->pMediaCtx is nullptr",                    VA_STATUS_ERROR_INVALID_BUFFER);
1856     DDI_CHK_NULL(mediaBuffer->pMediaCtx->pGmmClientContext, "mediaBuffer->pMediaCtx->pGmmClientContext is nullptr", VA_STATUS_ERROR_INVALID_BUFFER);
1857 
1858     int32_t  size           = 0;
1859     uint32_t tileformat     = TILING_NONE;
1860     VAStatus hRes           = VA_STATUS_SUCCESS;
1861     int32_t  mem_type       = MOS_MEMPOOL_VIDEOMEMORY;
1862 
1863     // Create GmmResourceInfo
1864     GMM_RESCREATE_PARAMS        gmmParams;
1865     MOS_ZeroMemory(&gmmParams, sizeof(gmmParams));
1866     gmmParams.BaseWidth             = width;
1867     gmmParams.BaseHeight            = height;
1868     gmmParams.ArraySize             = 1;
1869     gmmParams.Type                  = RESOURCE_2D;
1870     gmmParams.Format                = GMM_FORMAT_GENERIC_8BIT;
1871 
1872     DDI_CHK_CONDITION(gmmParams.Format == GMM_FORMAT_INVALID,
1873                          "Unsupported format",
1874                          VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT);
1875 
1876     gmmParams.Flags.Info.Linear = true;
1877     gmmParams.Flags.Gpu.Video   = true;
1878     gmmParams.Flags.Info.LocalOnly = MEDIA_IS_SKU(&mediaBuffer->pMediaCtx->SkuTable, FtrLocalMemory);
1879     GMM_RESOURCE_INFO  *gmmResourceInfo;
1880     mediaBuffer->pGmmResourceInfo = gmmResourceInfo = mediaBuffer->pMediaCtx->pGmmClientContext->CreateResInfoObject(&gmmParams);
1881 
1882     if(nullptr == gmmResourceInfo)
1883     {
1884         DDI_VERBOSEMESSAGE("Gmm Create Resource Failed.");
1885         hRes = VA_STATUS_ERROR_ALLOCATION_FAILED;
1886         return hRes;
1887     }
1888     uint32_t    gmmPitch;
1889     uint32_t    gmmSize;
1890     uint32_t    gmmHeight;
1891     gmmPitch    = (uint32_t)gmmResourceInfo->GetRenderPitch();
1892     gmmSize     = (uint32_t)gmmResourceInfo->GetSizeSurface();
1893     gmmHeight   = gmmResourceInfo->GetBaseHeight();
1894 
1895     MemoryPolicyParameter memPolicyPar = { 0 };
1896     memPolicyPar.skuTable = &mediaBuffer->pMediaCtx->SkuTable;
1897     memPolicyPar.waTable  = &mediaBuffer->pMediaCtx->WaTable;
1898     memPolicyPar.resInfo  = mediaBuffer->pGmmResourceInfo;
1899     memPolicyPar.resName  = "Media 2D Buffer";
1900     memPolicyPar.uiType   = mediaBuffer->uiType;
1901     memPolicyPar.preferredMemType = mediaBuffer->bUseSysGfxMem ? MOS_MEMPOOL_SYSTEMMEMORY : 0;
1902 
1903     mem_type = MemoryPolicyManager::UpdateMemoryPolicy(&memPolicyPar);
1904 
1905     unsigned int patIndex = MosInterface::GetPATIndexFromGmm(mediaBuffer->pMediaCtx->pGmmClientContext, gmmResourceInfo);
1906     bool isCpuCacheable   = gmmResourceInfo->GetResFlags().Info.Cacheable;
1907 
1908     MOS_LINUX_BO  *bo;
1909     struct mos_drm_bo_alloc alloc;
1910     alloc.name = "Media 2D Buffer";
1911     alloc.size = gmmSize;
1912     alloc.alignment = 4096;
1913     alloc.ext.tiling_mode = TILING_NONE;
1914     alloc.ext.mem_type = mem_type;
1915     alloc.ext.pat_index = patIndex;
1916     alloc.ext.cpu_cacheable = isCpuCacheable;
1917 
1918     bo = mos_bo_alloc(bufmgr, &alloc);
1919 
1920     mediaBuffer->bMapped = false;
1921     if (bo)
1922     {
1923         mediaBuffer->format     = Media_Format_2DBuffer;
1924         mediaBuffer->uiWidth    = width;
1925         mediaBuffer->uiHeight   = gmmHeight;
1926         mediaBuffer->uiPitch    = gmmPitch;
1927         mediaBuffer->iSize      = gmmSize;
1928         mediaBuffer->iRefCount  = 0;
1929         mediaBuffer->bo         = bo;
1930         mediaBuffer->TileType   = tileformat;
1931         mediaBuffer->pData      = (uint8_t*) bo->virt;
1932         DDI_VERBOSEMESSAGE("Alloc %7d bytes (%d x %d resource)\n", size, width, height);
1933         uint32_t event[] = {bo->handle, mediaBuffer->format, width, height, gmmPitch, bo->size, tileformat, 0};
1934         MOS_TraceEventExt(EVENT_VA_BUFFER, EVENT_TYPE_INFO, event, sizeof(event), &gmmResourceInfo->GetResFlags(), sizeof(GMM_RESOURCE_FLAG));
1935     }
1936     else
1937     {
1938         DDI_VERBOSEMESSAGE("Fail to Alloc %7d bytes (%d x %d resource)\n", size, width, height);
1939         hRes = VA_STATUS_ERROR_ALLOCATION_FAILED;
1940     }
1941 
1942     return hRes;
1943 }
1944 
AllocateBuffer(DDI_MEDIA_FORMAT format,int32_t size,PDDI_MEDIA_BUFFER mediaBuffer,MOS_BUFMGR * bufmgr,bool isShadowBuffer)1945 VAStatus MediaLibvaUtilNext::AllocateBuffer(
1946     DDI_MEDIA_FORMAT     format,
1947     int32_t              size,
1948     PDDI_MEDIA_BUFFER    mediaBuffer,
1949     MOS_BUFMGR           *bufmgr,
1950     bool                 isShadowBuffer)
1951 {
1952     DDI_FUNC_ENTER;
1953     DDI_CHK_NULL(mediaBuffer,                               "mediaBuffer is nullptr",                               VA_STATUS_ERROR_INVALID_BUFFER);
1954     DDI_CHK_NULL(mediaBuffer->pMediaCtx,                    "mediaBuffer->pMediaCtx is nullptr",                    VA_STATUS_ERROR_INVALID_BUFFER);
1955     DDI_CHK_NULL(mediaBuffer->pMediaCtx->pGmmClientContext, "mediaBuffer->pMediaCtx->pGmmClientContext is nullptr", VA_STATUS_ERROR_INVALID_BUFFER);
1956     if(format >= Media_Format_Count)
1957     {
1958        return VA_STATUS_ERROR_INVALID_PARAMETER;
1959     }
1960 
1961     VAStatus     hRes = VA_STATUS_SUCCESS;
1962     int32_t      mem_type = MOS_MEMPOOL_VIDEOMEMORY;
1963 
1964     // create fake GmmResourceInfo
1965     GMM_RESCREATE_PARAMS gmmParams;
1966     MOS_ZeroMemory(&gmmParams, sizeof(gmmParams));
1967     gmmParams.BaseWidth             = 1;
1968     gmmParams.BaseHeight            = 1;
1969     gmmParams.ArraySize             = 0;
1970     gmmParams.Type                  = RESOURCE_1D;
1971     gmmParams.Format                = GMM_FORMAT_GENERIC_8BIT;
1972     gmmParams.Flags.Gpu.Video       = true;
1973     gmmParams.Flags.Info.Linear     = true;
1974     gmmParams.Flags.Info.LocalOnly  = MEDIA_IS_SKU(&mediaBuffer->pMediaCtx->SkuTable, FtrLocalMemory);
1975 
1976     if (isShadowBuffer)
1977     {
1978         gmmParams.Flags.Info.Cacheable = true;
1979         gmmParams.Usage = GMM_RESOURCE_USAGE_STAGING;
1980     }
1981 
1982     mediaBuffer->pGmmResourceInfo = mediaBuffer->pMediaCtx->pGmmClientContext->CreateResInfoObject(&gmmParams);
1983     DDI_CHK_NULL(mediaBuffer->pGmmResourceInfo, "pGmmResourceInfo is nullptr", VA_STATUS_ERROR_INVALID_BUFFER);
1984     mediaBuffer->pGmmResourceInfo->OverrideSize(mediaBuffer->iSize);
1985     mediaBuffer->pGmmResourceInfo->OverrideBaseWidth(mediaBuffer->iSize);
1986     mediaBuffer->pGmmResourceInfo->OverridePitch(mediaBuffer->iSize);
1987 
1988     MemoryPolicyParameter memPolicyPar = { 0 };
1989     memPolicyPar.skuTable = &mediaBuffer->pMediaCtx->SkuTable;
1990     memPolicyPar.waTable  = &mediaBuffer->pMediaCtx->WaTable;
1991     memPolicyPar.resInfo  = mediaBuffer->pGmmResourceInfo;
1992     memPolicyPar.resName  = "Media Buffer";
1993     memPolicyPar.uiType   = mediaBuffer->uiType;
1994     memPolicyPar.preferredMemType = mediaBuffer->bUseSysGfxMem ? MOS_MEMPOOL_SYSTEMMEMORY : 0;
1995 
1996     mem_type = MemoryPolicyManager::UpdateMemoryPolicy(&memPolicyPar);
1997 
1998     unsigned int patIndex = MosInterface::GetPATIndexFromGmm(mediaBuffer->pMediaCtx->pGmmClientContext, mediaBuffer->pGmmResourceInfo);
1999     bool isCpuCacheable   = mediaBuffer->pGmmResourceInfo->GetResFlags().Info.Cacheable;
2000 
2001     struct mos_drm_bo_alloc alloc;
2002     alloc.name = "Media Buffer";
2003     alloc.size = size;
2004     alloc.alignment = 4096;
2005     alloc.ext.tiling_mode = TILING_NONE;
2006     alloc.ext.mem_type = mem_type;
2007     alloc.ext.pat_index = patIndex;
2008     alloc.ext.cpu_cacheable = isCpuCacheable;
2009 
2010     MOS_LINUX_BO *bo  = mos_bo_alloc(bufmgr, &alloc);
2011     mediaBuffer->bMapped = false;
2012     if (bo)
2013     {
2014         mediaBuffer->format     = format;
2015         mediaBuffer->iSize      = size;
2016         mediaBuffer->iRefCount  = 0;
2017         mediaBuffer->bo         = bo;
2018         mediaBuffer->pData      = (uint8_t*) bo->virt;
2019 
2020         DDI_VERBOSEMESSAGE("Alloc %8d bytes resource.",size);
2021         uint32_t event[] = {bo->handle, format, size, 1, size, bo->size, 0, 0};
2022         MOS_TraceEventExt(EVENT_VA_BUFFER, EVENT_TYPE_INFO, event, sizeof(event), &mediaBuffer->pGmmResourceInfo->GetResFlags(), sizeof(GMM_RESOURCE_FLAG));
2023     }
2024     else
2025     {
2026         DDI_ASSERTMESSAGE("Fail to Alloc %8d bytes resource.",size);
2027         hRes = VA_STATUS_ERROR_ALLOCATION_FAILED;
2028     }
2029 
2030     return hRes;
2031 }
2032 
AllocPMediaBufferFromHeap(PDDI_MEDIA_HEAP bufferHeap)2033 PDDI_MEDIA_BUFFER_HEAP_ELEMENT MediaLibvaUtilNext::AllocPMediaBufferFromHeap(PDDI_MEDIA_HEAP bufferHeap)
2034 {
2035     DDI_FUNC_ENTER;
2036     DDI_CHK_NULL(bufferHeap, "nullptr bufferHeap", nullptr);
2037 
2038     PDDI_MEDIA_BUFFER_HEAP_ELEMENT  mediaBufferHeapElmt = nullptr;
2039     if (nullptr == bufferHeap->pFirstFreeHeapElement)
2040     {
2041         void *newHeapBase = MOS_ReallocMemory(bufferHeap->pHeapBase, (bufferHeap->uiAllocatedHeapElements + DDI_MEDIA_HEAP_INCREMENTAL_SIZE) * sizeof(DDI_MEDIA_BUFFER_HEAP_ELEMENT));
2042         if (nullptr == newHeapBase)
2043         {
2044             DDI_ASSERTMESSAGE("DDI: realloc failed.");
2045             return nullptr;
2046         }
2047         bufferHeap->pHeapBase                                 = newHeapBase;
2048         PDDI_MEDIA_BUFFER_HEAP_ELEMENT mediaBufferHeapBase    = (PDDI_MEDIA_BUFFER_HEAP_ELEMENT)bufferHeap->pHeapBase;
2049         bufferHeap->pFirstFreeHeapElement     = (void*)(&mediaBufferHeapBase[bufferHeap->uiAllocatedHeapElements]);
2050         for (int32_t i = 0; i < (DDI_MEDIA_HEAP_INCREMENTAL_SIZE); i++)
2051         {
2052             mediaBufferHeapElmt               = &mediaBufferHeapBase[bufferHeap->uiAllocatedHeapElements + i];
2053             mediaBufferHeapElmt->pNextFree    = (i == (DDI_MEDIA_HEAP_INCREMENTAL_SIZE - 1))? nullptr : &mediaBufferHeapBase[bufferHeap->uiAllocatedHeapElements + i + 1];
2054             mediaBufferHeapElmt->uiVaBufferID = bufferHeap->uiAllocatedHeapElements + i;
2055         }
2056         bufferHeap->uiAllocatedHeapElements  += DDI_MEDIA_HEAP_INCREMENTAL_SIZE;
2057     }
2058 
2059     mediaBufferHeapElmt                       = (PDDI_MEDIA_BUFFER_HEAP_ELEMENT)bufferHeap->pFirstFreeHeapElement;
2060     bufferHeap->pFirstFreeHeapElement         = mediaBufferHeapElmt->pNextFree;
2061     return mediaBufferHeapElmt;
2062 }
2063 
AllocPVAImageFromHeap(PDDI_MEDIA_HEAP imageHeap)2064 PDDI_MEDIA_IMAGE_HEAP_ELEMENT MediaLibvaUtilNext::AllocPVAImageFromHeap(PDDI_MEDIA_HEAP imageHeap)
2065 {
2066     PDDI_MEDIA_IMAGE_HEAP_ELEMENT   vaimageHeapElmt = nullptr;
2067     DDI_FUNC_ENTER;
2068     DDI_CHK_NULL(imageHeap, "nullptr imageHeap", nullptr);
2069 
2070     if (nullptr == imageHeap->pFirstFreeHeapElement)
2071     {
2072         void *newHeapBase = MOS_ReallocMemory(imageHeap->pHeapBase, (imageHeap->uiAllocatedHeapElements + DDI_MEDIA_HEAP_INCREMENTAL_SIZE) * sizeof(DDI_MEDIA_IMAGE_HEAP_ELEMENT));
2073 
2074         if (nullptr == newHeapBase)
2075         {
2076             DDI_ASSERTMESSAGE("DDI: realloc failed.");
2077             return nullptr;
2078         }
2079         imageHeap->pHeapBase                           = newHeapBase;
2080         PDDI_MEDIA_IMAGE_HEAP_ELEMENT vaimageHeapBase  = (PDDI_MEDIA_IMAGE_HEAP_ELEMENT)imageHeap->pHeapBase;
2081         imageHeap->pFirstFreeHeapElement               = (void*)(&vaimageHeapBase[imageHeap->uiAllocatedHeapElements]);
2082         for (int32_t i = 0; i < (DDI_MEDIA_HEAP_INCREMENTAL_SIZE); i++)
2083         {
2084             vaimageHeapElmt                   = &vaimageHeapBase[imageHeap->uiAllocatedHeapElements + i];
2085             vaimageHeapElmt->pNextFree        = (i == (DDI_MEDIA_HEAP_INCREMENTAL_SIZE - 1))? nullptr : &vaimageHeapBase[imageHeap->uiAllocatedHeapElements + i + 1];
2086             vaimageHeapElmt->uiVaImageID      = imageHeap->uiAllocatedHeapElements + i;
2087         }
2088         imageHeap->uiAllocatedHeapElements   += DDI_MEDIA_HEAP_INCREMENTAL_SIZE;
2089 
2090     }
2091 
2092     vaimageHeapElmt                           = (PDDI_MEDIA_IMAGE_HEAP_ELEMENT)imageHeap->pFirstFreeHeapElement;
2093     imageHeap->pFirstFreeHeapElement          = vaimageHeapElmt->pNextFree;
2094     return vaimageHeapElmt;
2095 }
2096 
ConvertFourccToGmmFmt(uint32_t fourcc)2097 GMM_RESOURCE_FORMAT MediaLibvaUtilNext::ConvertFourccToGmmFmt(uint32_t fourcc)
2098 {
2099     DDI_FUNC_ENTER;
2100     switch (fourcc)
2101     {
2102         case VA_FOURCC_BGRA   : return GMM_FORMAT_B8G8R8A8_UNORM_TYPE;
2103         case VA_FOURCC_ARGB   : return GMM_FORMAT_B8G8R8A8_UNORM_TYPE;
2104         case VA_FOURCC_RGBA   : return GMM_FORMAT_R8G8B8A8_UNORM_TYPE;
2105         case VA_FOURCC_ABGR   : return GMM_FORMAT_R8G8B8A8_UNORM_TYPE;
2106         case VA_FOURCC_BGRX   : return GMM_FORMAT_B8G8R8X8_UNORM_TYPE;
2107         case VA_FOURCC_XRGB   : return GMM_FORMAT_B8G8R8X8_UNORM_TYPE;
2108         case VA_FOURCC_RGBX   : return GMM_FORMAT_R8G8B8X8_UNORM_TYPE;
2109         case VA_FOURCC_XBGR   : return GMM_FORMAT_R8G8B8X8_UNORM_TYPE;
2110         case VA_FOURCC_R8G8B8 : return GMM_FORMAT_R8G8B8_UNORM;
2111         case VA_FOURCC_RGBP   : return GMM_FORMAT_RGBP;
2112         case VA_FOURCC_BGRP   : return GMM_FORMAT_BGRP;
2113         case VA_FOURCC_RGB565 : return GMM_FORMAT_B5G6R5_UNORM_TYPE;
2114         case VA_FOURCC_AYUV   : return GMM_FORMAT_AYUV_TYPE;
2115 #if VA_CHECK_VERSION(1, 13, 0)
2116         case VA_FOURCC_XYUV   : return GMM_FORMAT_AYUV_TYPE;
2117 #endif
2118         case VA_FOURCC_NV12   : return GMM_FORMAT_NV12_TYPE;
2119         case VA_FOURCC_NV21   : return GMM_FORMAT_NV21_TYPE;
2120         case VA_FOURCC_YUY2   : return GMM_FORMAT_YUY2;
2121         case VA_FOURCC_UYVY   : return GMM_FORMAT_UYVY;
2122         case VA_FOURCC_YV12   : return GMM_FORMAT_YV12_TYPE;
2123         case VA_FOURCC_I420   : return GMM_FORMAT_I420_TYPE;
2124         case VA_FOURCC_IYUV   : return GMM_FORMAT_IYUV_TYPE;
2125         case VA_FOURCC_411P   : return GMM_FORMAT_MFX_JPEG_YUV411_TYPE;
2126         case VA_FOURCC_422H   : return GMM_FORMAT_MFX_JPEG_YUV422H_TYPE;
2127         case VA_FOURCC_422V   : return GMM_FORMAT_MFX_JPEG_YUV422V_TYPE;
2128         case VA_FOURCC_444P   : return GMM_FORMAT_MFX_JPEG_YUV444_TYPE;
2129         case VA_FOURCC_IMC3   : return GMM_FORMAT_IMC3_TYPE;
2130         case VA_FOURCC_P208   : return GMM_FORMAT_P208_TYPE;
2131         case VA_FOURCC_P010   : return GMM_FORMAT_P010_TYPE;
2132         case VA_FOURCC_P012   : return GMM_FORMAT_P016_TYPE;
2133         case VA_FOURCC_P016   : return GMM_FORMAT_P016_TYPE;
2134         case VA_FOURCC_Y210   : return GMM_FORMAT_Y210_TYPE;
2135         case VA_FOURCC_Y410   : return GMM_FORMAT_Y410_TYPE;
2136 #if VA_CHECK_VERSION(1, 9, 0)
2137         case VA_FOURCC_Y212   : return GMM_FORMAT_Y212_TYPE;
2138 #endif
2139         case VA_FOURCC_Y216   : return GMM_FORMAT_Y216_TYPE;
2140 #if VA_CHECK_VERSION(1, 9, 0)
2141         case VA_FOURCC_Y412   : return GMM_FORMAT_Y412_TYPE;
2142 #endif
2143         case VA_FOURCC_Y416   : return GMM_FORMAT_Y416_TYPE;
2144         case VA_FOURCC_Y800   : return GMM_FORMAT_GENERIC_8BIT;
2145         case VA_FOURCC_A2R10G10B10   : return GMM_FORMAT_R10G10B10A2_UNORM_TYPE;
2146         case VA_FOURCC_A2B10G10R10   : return GMM_FORMAT_B10G10R10A2_UNORM_TYPE;
2147         case VA_FOURCC_X2R10G10B10   : return GMM_FORMAT_R10G10B10A2_UNORM_TYPE;
2148         case VA_FOURCC_X2B10G10R10   : return GMM_FORMAT_B10G10R10A2_UNORM_TYPE;
2149         default               : return GMM_FORMAT_INVALID;
2150     }
2151 }
2152 
InitMutex(PMEDIA_MUTEX_T mutex)2153 void MediaLibvaUtilNext::InitMutex(PMEDIA_MUTEX_T mutex)
2154 {
2155     pthread_mutex_init(mutex, nullptr);
2156 }
2157 
DestroyMutex(PMEDIA_MUTEX_T mutex)2158 void MediaLibvaUtilNext::DestroyMutex(PMEDIA_MUTEX_T mutex)
2159 {
2160     int32_t ret = pthread_mutex_destroy(mutex);
2161     if(ret != 0)
2162     {
2163         DDI_NORMALMESSAGE("can't destroy the mutex!\n");
2164     }
2165 }
2166 
SetMediaResetEnableFlag(PDDI_MEDIA_CONTEXT mediaCtx)2167 VAStatus MediaLibvaUtilNext::SetMediaResetEnableFlag(PDDI_MEDIA_CONTEXT mediaCtx)
2168 {
2169     bool enableReset = false;
2170     mediaCtx->bMediaResetEnable = false;
2171 
2172     DDI_CHK_NULL(mediaCtx,"nullptr mediaCtx!", VA_STATUS_ERROR_INVALID_CONTEXT);
2173 
2174     if(!MEDIA_IS_SKU(&mediaCtx->SkuTable, FtrSWMediaReset))
2175     {
2176         mediaCtx->bMediaResetEnable = false;
2177         return VA_STATUS_SUCCESS;
2178     }
2179 
2180     mediaCtx->bMediaResetEnable = true;
2181 
2182 #if (_DEBUG || _RELEASE_INTERNAL)
2183     ReadUserSettingForDebug(
2184         mediaCtx->m_userSettingPtr,
2185         enableReset,
2186         __MEDIA_USER_FEATURE_VALUE_MEDIA_RESET_ENABLE,
2187         MediaUserSetting::Group::Device);
2188     mediaCtx->bMediaResetEnable = enableReset;
2189 #endif
2190     if(!mediaCtx->bMediaResetEnable)
2191     {
2192         return VA_STATUS_SUCCESS;
2193     }
2194 
2195     char* mediaResetEnv = getenv("INTEL_MEDIA_RESET_WATCHDOG");
2196     if(mediaResetEnv)
2197     {
2198         mediaCtx->bMediaResetEnable = strcmp(mediaResetEnv, "1") ? false : true;
2199         return VA_STATUS_SUCCESS;
2200     }
2201 
2202     return VA_STATUS_SUCCESS;
2203 }
2204 
GetSurfaceModifier(DDI_MEDIA_CONTEXT * mediaCtx,DDI_MEDIA_SURFACE * mediaSurface,uint64_t & modifier)2205 VAStatus MediaLibvaUtilNext::GetSurfaceModifier(
2206     DDI_MEDIA_CONTEXT  *mediaCtx,
2207     DDI_MEDIA_SURFACE  *mediaSurface,
2208     uint64_t           &modifier)
2209 {
2210     DDI_CHK_NULL(mediaCtx,                       "nullptr media context",                  VA_STATUS_ERROR_INVALID_CONTEXT);
2211     DDI_CHK_NULL(mediaSurface,                   "nullptr mediaSurface",                   VA_STATUS_ERROR_INVALID_SURFACE);
2212     DDI_CHK_NULL(mediaSurface->bo,               "nullptr mediaSurface->bo",               VA_STATUS_ERROR_INVALID_SURFACE);
2213     DDI_CHK_NULL(mediaSurface->pGmmResourceInfo, "nullptr mediaSurface->pGmmResourceInfo", VA_STATUS_ERROR_INVALID_SURFACE);
2214     GMM_TILE_TYPE  gmmTileType = mediaSurface->pGmmResourceInfo->GetTileType();
2215     GMM_RESOURCE_FLAG       gmmFlags    = {0};
2216     gmmFlags = mediaSurface->pGmmResourceInfo->GetResFlags();
2217 
2218     if(MEDIA_IS_SKU(&mediaCtx->SkuTable, FtrXe2Compression))
2219     {
2220         // Update Xe2Compression Modifier
2221         uint64_t compressedModifier = I915_FORMAT_MOD_4_TILED_LNL_CCS;
2222 
2223         if (MEDIA_IS_SKU(&mediaCtx->SkuTable, FtrLocalMemory))
2224         {
2225             // DGfx only support compression on Local memory
2226             compressedModifier = I915_FORMAT_MOD_4_TILED_BMG_CCS;
2227         }
2228         switch(gmmTileType)
2229         {
2230             case GMM_TILED_4:
2231                 modifier = gmmFlags.Info.MediaCompressed ? compressedModifier : I915_FORMAT_MOD_4_TILED;
2232                 break;
2233             case GMM_TILED_Y:
2234                 modifier = I915_FORMAT_MOD_Y_TILED;
2235             break;
2236             case GMM_TILED_X:
2237                 modifier = I915_FORMAT_MOD_X_TILED;
2238                 break;
2239             case GMM_NOT_TILED:
2240                 modifier = DRM_FORMAT_MOD_LINEAR;
2241                 break;
2242             default:
2243                 //handle other possible tile format
2244                 if(TILING_Y == mediaSurface->TileType)
2245                 {
2246                     modifier = gmmFlags.Info.MediaCompressed ? compressedModifier : I915_FORMAT_MOD_4_TILED;
2247                 }
2248                 else
2249                 {
2250                     modifier = DRM_FORMAT_MOD_LINEAR;
2251                 }
2252                 break;
2253         }
2254 
2255         return VA_STATUS_SUCCESS;
2256     }
2257 
2258     bool                    bMmcEnabled = false;
2259     if ((gmmFlags.Gpu.MMC               ||
2260          gmmFlags.Gpu.CCS)              &&
2261         (gmmFlags.Info.MediaCompressed  ||
2262          gmmFlags.Info.RenderCompressed))
2263     {
2264         bMmcEnabled = true;
2265     }
2266     else
2267     {
2268         bMmcEnabled = false;
2269     }
2270 
2271     switch(gmmTileType)
2272     {
2273         case GMM_TILED_4:
2274             if(mediaCtx->m_auxTableMgr && bMmcEnabled)
2275             {
2276                 modifier = gmmFlags.Info.MediaCompressed ? I915_FORMAT_MOD_4_TILED_MTL_MC_CCS :
2277                     (gmmFlags.Info.RenderCompressed ? I915_FORMAT_MOD_4_TILED_MTL_RC_CCS_CC : I915_FORMAT_MOD_4_TILED);
2278             }
2279             else
2280             {
2281                 modifier = I915_FORMAT_MOD_4_TILED;
2282             }
2283             break;
2284         case GMM_TILED_Y:
2285             if (mediaCtx->m_auxTableMgr && bMmcEnabled)
2286             {
2287                 modifier = gmmFlags.Info.MediaCompressed ? I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS :
2288                     (gmmFlags.Info.RenderCompressed ? I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS : I915_FORMAT_MOD_Y_TILED);
2289             }
2290             else
2291             {
2292                 modifier = I915_FORMAT_MOD_Y_TILED;
2293             }
2294             break;
2295         case GMM_TILED_X:
2296             modifier = I915_FORMAT_MOD_X_TILED;
2297             break;
2298         case GMM_NOT_TILED:
2299             modifier = DRM_FORMAT_MOD_LINEAR;
2300             break;
2301         default:
2302             //handle other possible tile format
2303             if(TILING_Y == mediaSurface->TileType)
2304             {
2305                 modifier = gmmFlags.Info.MediaCompressed ? I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS :
2306                     (gmmFlags.Info.RenderCompressed ? I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS : I915_FORMAT_MOD_Y_TILED);
2307             }
2308             else
2309             {
2310                 modifier = DRM_FORMAT_MOD_LINEAR;
2311             }
2312             break;
2313 
2314     }
2315     return VA_STATUS_SUCCESS;
2316 }
2317 
DdiAllocPVAContextFromHeap(PDDI_MEDIA_HEAP vaContextHeap)2318 PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT MediaLibvaUtilNext::DdiAllocPVAContextFromHeap(
2319     PDDI_MEDIA_HEAP vaContextHeap)
2320 {
2321     PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT  vacontextHeapElmt = nullptr;
2322     DDI_FUNCTION_ENTER();
2323     DDI_CHK_NULL(vaContextHeap, "nullptr vaContextHeap", nullptr);
2324 
2325     if (nullptr == vaContextHeap->pFirstFreeHeapElement)
2326     {
2327         void *newHeapBase = MOS_ReallocMemory(vaContextHeap->pHeapBase, (vaContextHeap->uiAllocatedHeapElements + DDI_MEDIA_HEAP_INCREMENTAL_SIZE) * sizeof(DDI_MEDIA_VACONTEXT_HEAP_ELEMENT));
2328         DDI_CHK_NULL(newHeapBase, "DDI: realloc failed.", nullptr);
2329 
2330         vaContextHeap->pHeapBase                            = newHeapBase;
2331         PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT vacontextHeapBase = (PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT)vaContextHeap->pHeapBase;
2332         DDI_CHK_NULL(vacontextHeapBase, "nullptr vacontextHeapBase.", nullptr);
2333         vaContextHeap->pFirstFreeHeapElement        = (void*)(&(vacontextHeapBase[vaContextHeap->uiAllocatedHeapElements]));
2334         for (int32_t i = 0; i < (DDI_MEDIA_HEAP_INCREMENTAL_SIZE); i++)
2335         {
2336             vacontextHeapElmt                       = &vacontextHeapBase[vaContextHeap->uiAllocatedHeapElements + i];
2337             vacontextHeapElmt->pNextFree            = (i == (DDI_MEDIA_HEAP_INCREMENTAL_SIZE - 1))? nullptr : &vacontextHeapBase[vaContextHeap->uiAllocatedHeapElements + i + 1];
2338             vacontextHeapElmt->uiVaContextID        = vaContextHeap->uiAllocatedHeapElements + i;
2339             vacontextHeapElmt->pVaContext           = nullptr;
2340         }
2341         vaContextHeap->uiAllocatedHeapElements     += DDI_MEDIA_HEAP_INCREMENTAL_SIZE;
2342     }
2343 
2344     vacontextHeapElmt                    = (PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT)vaContextHeap->pFirstFreeHeapElement;
2345     vaContextHeap->pFirstFreeHeapElement = vacontextHeapElmt->pNextFree;
2346     return vacontextHeapElmt;
2347 }
2348 
DdiReleasePVAContextFromHeap(PDDI_MEDIA_HEAP vaContextHeap,uint32_t vaContextID)2349 void MediaLibvaUtilNext::DdiReleasePVAContextFromHeap(
2350     PDDI_MEDIA_HEAP vaContextHeap,
2351     uint32_t        vaContextID)
2352 {
2353     DDI_FUNCTION_ENTER();
2354     DDI_CHK_NULL(vaContextHeap, "nullptr vaContextHeap", );
2355     DDI_CHK_LESS(vaContextID, vaContextHeap->uiAllocatedHeapElements, "invalid context id", );
2356 
2357     PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT vaContextHeapBase = (PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT)vaContextHeap->pHeapBase;
2358     PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT vaContextHeapElmt = &vaContextHeapBase[vaContextID];
2359     DDI_CHK_NULL(vaContextHeapElmt->pVaContext, "context is already released", );
2360     void *firstFree                        = vaContextHeap->pFirstFreeHeapElement;
2361 
2362     vaContextHeap->pFirstFreeHeapElement   = (void*)vaContextHeapElmt;
2363     vaContextHeapElmt->pNextFree           = (PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT)firstFree;
2364     vaContextHeapElmt->pVaContext          = nullptr;
2365 
2366     return;
2367 }
2368 
GetFormatFromMediaFormat(DDI_MEDIA_FORMAT mediaFormat)2369 MOS_FORMAT MediaLibvaUtilNext::GetFormatFromMediaFormat(DDI_MEDIA_FORMAT mediaFormat)
2370 {
2371     MOS_FORMAT format = Format_Invalid;
2372     DDI_FUNC_ENTER;
2373     static const std::map<const DDI_MEDIA_FORMAT, const MOS_FORMAT> ddiFormatToMediaFormatMap =
2374     {
2375         {Media_Format_NV12, Format_NV12},
2376         {Media_Format_NV21, Format_NV21},
2377         {Media_Format_X8R8G8B8, Format_X8R8G8B8},
2378         {Media_Format_X8B8G8R8, Format_X8B8G8R8},
2379         {Media_Format_A8R8G8B8, Format_A8R8G8B8},
2380         {Media_Format_A8B8G8R8, Format_A8B8G8R8},
2381         {Media_Format_R8G8B8A8, Format_A8B8G8R8},
2382         {Media_Format_R5G6B5, Format_R5G6B5},
2383         {Media_Format_R8G8B8, Format_R8G8B8},
2384         {Media_Format_YUY2, Format_YUY2},
2385         {Media_Format_UYVY, Format_UYVY},
2386         {Media_Format_YV12, Format_YV12},
2387         {Media_Format_I420, Format_I420},
2388         {Media_Format_IYUV, Format_IYUV},
2389         {Media_Format_422H, Format_422H},
2390         {Media_Format_422V, Format_422V},
2391         {Media_Format_400P, Format_400P},
2392         {Media_Format_411P, Format_411P},
2393         {Media_Format_444P, Format_444P},
2394         {Media_Format_IMC3, Format_IMC3},
2395         {Media_Format_P010, Format_P010},
2396         {Media_Format_P012, Format_P016},
2397         {Media_Format_P016, Format_P016},
2398         {Media_Format_R10G10B10A2, Format_R10G10B10A2},
2399         {Media_Format_R10G10B10X2, Format_R10G10B10A2},
2400         {Media_Format_B10G10R10A2, Format_B10G10R10A2},
2401         {Media_Format_B10G10R10X2, Format_B10G10R10A2},
2402         {Media_Format_RGBP, Format_RGBP},
2403         {Media_Format_BGRP, Format_BGRP},
2404         {Media_Format_Y210, Format_Y210},
2405 #if VA_CHECK_VERSION(1, 9, 0)
2406         {Media_Format_Y212, Format_Y216},
2407         {Media_Format_Y412, Format_Y416},
2408 #endif
2409         {Media_Format_Y216, Format_Y216},
2410         {Media_Format_Y410, Format_Y410},
2411         {Media_Format_Y416, Format_Y416},
2412         {Media_Format_AYUV, Format_AYUV},
2413 #if VA_CHECK_VERSION(1, 13, 0)
2414         {Media_Format_XYUV, Format_AYUV},
2415 #endif
2416         {Media_Format_Y8, Format_Y8},
2417         {Media_Format_Y16S, Format_Y16S},
2418         {Media_Format_Y16U, Format_Y16U},
2419         {Media_Format_VYUY, Format_VYUY},
2420         {Media_Format_YVYU, Format_YVYU},
2421         {Media_Format_A16R16G16B16, Format_A16R16G16B16},
2422         {Media_Format_A16B16G16R16, Format_A16B16G16R16}
2423     };
2424     auto it = ddiFormatToMediaFormatMap.find(mediaFormat);
2425     if(it != ddiFormatToMediaFormatMap.end())
2426     {
2427         return it->second;
2428     }
2429     else
2430     {
2431         DDI_ASSERTMESSAGE("ERROR media format to vphal format.");
2432         return Format_Invalid;
2433     }
2434 }
2435 
GetTileTypeFromMediaTileType(uint32_t mediaTileType)2436 MOS_TILE_TYPE MediaLibvaUtilNext::GetTileTypeFromMediaTileType(uint32_t mediaTileType)
2437 {
2438     MOS_TILE_TYPE tileType = MOS_TILE_INVALID;
2439     DDI_FUNC_ENTER;
2440 
2441     switch(mediaTileType)
2442     {
2443        case TILING_Y:
2444            tileType = MOS_TILE_Y;
2445            break;
2446        case TILING_X:
2447            tileType = MOS_TILE_X;
2448            break;
2449        case TILING_NONE:
2450            tileType = MOS_TILE_LINEAR;
2451            break;
2452         default:
2453            tileType = MOS_TILE_LINEAR;
2454     }
2455 
2456     return tileType;
2457 }
2458 
GetColorSpaceFromMediaFormat(DDI_MEDIA_FORMAT format)2459 VPHAL_CSPACE MediaLibvaUtilNext::GetColorSpaceFromMediaFormat(DDI_MEDIA_FORMAT format)
2460 {
2461     DDI_FUNC_ENTER;
2462     MOS_FORMAT mosFormat = GetFormatFromMediaFormat(format);
2463 
2464     if (IS_RGB_FORMAT(mosFormat))
2465     {
2466         return CSpace_sRGB;
2467     }
2468     else
2469     {
2470         return CSpace_BT601;
2471     }
2472 }
2473 
UnRefBufObjInMediaBuffer(PDDI_MEDIA_BUFFER buf)2474 void MediaLibvaUtilNext::UnRefBufObjInMediaBuffer(PDDI_MEDIA_BUFFER buf)
2475 {
2476     DDI_FUNC_ENTER;
2477     mos_bo_unreference(buf->bo);
2478     return;
2479 }
2480 
ReleasePVAImageFromHeap(PDDI_MEDIA_HEAP imageHeap,uint32_t vaImageID)2481 void MediaLibvaUtilNext::ReleasePVAImageFromHeap(PDDI_MEDIA_HEAP imageHeap, uint32_t vaImageID)
2482 {
2483     PDDI_MEDIA_IMAGE_HEAP_ELEMENT    vaImageHeapBase = nullptr;
2484     PDDI_MEDIA_IMAGE_HEAP_ELEMENT    vaImageHeapElmt = nullptr;
2485     void                             *firstFree      = nullptr;
2486     DDI_FUNC_ENTER;
2487     DDI_CHK_NULL(imageHeap, "nullptr imageHeap", );
2488 
2489     DDI_CHK_LESS(vaImageID, imageHeap->uiAllocatedHeapElements, "invalid image id", );
2490     vaImageHeapBase                    = (PDDI_MEDIA_IMAGE_HEAP_ELEMENT)imageHeap->pHeapBase;
2491     vaImageHeapElmt                    = &vaImageHeapBase[vaImageID];
2492     DDI_CHK_NULL(vaImageHeapElmt->pImage, "image is already released", );
2493     firstFree                          = imageHeap->pFirstFreeHeapElement;
2494     imageHeap->pFirstFreeHeapElement   = (void*)vaImageHeapElmt;
2495     vaImageHeapElmt->pNextFree         = (PDDI_MEDIA_IMAGE_HEAP_ELEMENT)firstFree;
2496     vaImageHeapElmt->pImage            = nullptr;
2497 }
2498 
2499 #ifdef RELEASE
MediaPrintFps()2500 void MediaLibvaUtilNext::MediaPrintFps()
2501 {
2502     return;
2503 }
2504 #else
MediaPrintFps()2505 void MediaLibvaUtilNext::MediaPrintFps()
2506 {
2507     struct timeval tv2 ={};
2508     DDI_FUNC_ENTER;
2509     if (m_isMediaFpsPrintFpsEnabled == false)
2510     {
2511         return;
2512     }
2513     if (0 == m_vaFpsSampleSize)
2514     {
2515         return;
2516     }
2517     gettimeofday(&tv2, 0);
2518 
2519     pthread_mutex_lock(&m_fpsMutex);
2520     if (-1 == m_frameCountFps)
2521     {
2522         gettimeofday(&m_tv1, 0);
2523     }
2524 
2525     if (++m_frameCountFps >= m_vaFpsSampleSize)
2526     {
2527         char   fpsFileName[LENGTH_OF_FPS_FILE_NAME] = {};
2528         FILE   *fp                                  = nullptr;
2529         char   temp[LENGTH_OF_FPS_FILE_NAME]        = {};
2530 
2531         int64_t diff  = (tv2.tv_sec - m_tv1.tv_sec)*1000000 + tv2.tv_usec - m_tv1.tv_usec;
2532         float fps     = m_frameCountFps / (diff / 1000000.0);
2533         DDI_NORMALMESSAGE("FPS:%6.4f, Interval:%11lu.", fps,((uint64_t)tv2.tv_sec)*1000 + (tv2.tv_usec/1000));
2534         sprintf_s(temp, sizeof(temp), "FPS:%6.4f, Interval:%" PRIu64"\n", fps,((uint64_t)tv2.tv_sec)*1000 + (tv2.tv_usec/1000));
2535 
2536         MOS_ZeroMemory(fpsFileName,LENGTH_OF_FPS_FILE_NAME);
2537         sprintf_s(fpsFileName, sizeof(fpsFileName), FPS_FILE_NAME);
2538         if ((fp = fopen(fpsFileName, "wb")) == nullptr)
2539         {
2540             pthread_mutex_unlock(&m_fpsMutex);
2541             DDI_ASSERTMESSAGE("Unable to open fps file.");
2542             return;
2543         }
2544 
2545         fwrite(temp, 1, strlen(temp), fp);
2546         fclose(fp);
2547         m_frameCountFps = -1;
2548     }
2549     pthread_mutex_unlock(&m_fpsMutex);
2550     return;
2551 }
2552 #endif
2553