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