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 ¶ms
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 ¶ms,
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 ¶ms,
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 ¶ms,
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 ¶ms,
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 ¶ms,
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 ¶ms,
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 ¶ms,
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