1 /*
2 * Copyright (c) 2019-2022, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 //!
23 //! \file vphal_render_vebox_memdecomp.cpp
24 //! \brief Defines data structures and interfaces for media memory decompression.
25 //! \details
26 //!
27 #include "vphal_render_vebox_memdecomp.h"
28 #include "mos_os_cp_interface_specific.h"
29 #include "vphal_debug.h"
30 #include "vp_utils.h"
31
32 #define DECOMPRESSION_WIDTH_ALIGNMENT_IN_BYTE 32
33
MediaVeboxDecompState()34 MediaVeboxDecompState::MediaVeboxDecompState():
35 MediaMemDecompBaseState(),
36 m_osInterface(nullptr),
37 m_veboxInterface(nullptr),
38 m_mhwMiInterface(nullptr),
39 m_cpInterface(nullptr)
40 {
41 m_veboxMMCResolveEnabled = false;
42 }
43
~MediaVeboxDecompState()44 MediaVeboxDecompState::~MediaVeboxDecompState()
45 {
46 MOS_STATUS eStatus;
47
48 if (m_cpInterface)
49 {
50 if(m_osInterface)
51 {
52 m_osInterface->pfnDeleteMhwCpInterface(m_cpInterface);
53 m_cpInterface = nullptr;
54 }
55 else
56 {
57 VPHAL_MEMORY_DECOMP_ASSERTMESSAGE("Failed to destroy cpInterface.");
58 }
59 }
60
61 if (m_veboxInterface)
62 {
63 #if (_DEBUG || _RELEASE_INTERNAL)
64 if (m_surfaceDumper)
65 {
66 MOS_Delete(m_surfaceDumper);
67 m_surfaceDumper = nullptr;
68 }
69 #endif
70 eStatus = m_veboxInterface->DestroyHeap();
71 MOS_Delete(m_veboxInterface);
72 m_veboxInterface = nullptr;
73 if (eStatus != MOS_STATUS_SUCCESS)
74 {
75 VPHAL_MEMORY_DECOMP_ASSERTMESSAGE("Failed to destroy Vebox Interface, eStatus:%d.\n", eStatus);
76 }
77 }
78
79 if (m_mhwMiInterface)
80 {
81 MOS_Delete(m_mhwMiInterface);
82 m_mhwMiInterface = nullptr;
83 }
84
85 if (m_osInterface)
86 {
87 m_osInterface->pfnDestroy(m_osInterface, false);
88 MOS_FreeMemory(m_osInterface);
89 m_osInterface = nullptr;
90 }
91 }
92
93 #if (_DEBUG || _RELEASE_INTERNAL)
CloneResourceInfo(PVPHAL_SURFACE pVphalSurface,PMOS_SURFACE pMosSurface)94 MOS_STATUS CloneResourceInfo(PVPHAL_SURFACE pVphalSurface, PMOS_SURFACE pMosSurface)
95 {
96 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
97
98 VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(pVphalSurface);
99 VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(pMosSurface);
100
101 pVphalSurface->SurfType = SURF_NONE;
102
103 pVphalSurface->OsResource = pMosSurface->OsResource;
104 pVphalSurface->dwWidth = pMosSurface->dwWidth;
105 pVphalSurface->dwHeight = pMosSurface->dwHeight;
106 pVphalSurface->dwPitch = pMosSurface->dwPitch;
107 pVphalSurface->Format = pMosSurface->Format;
108 pVphalSurface->TileType = pMosSurface->TileType;
109 pVphalSurface->TileModeGMM = pMosSurface->TileModeGMM;
110 pVphalSurface->bGMMTileEnabled = pMosSurface->bGMMTileEnabled;
111 pVphalSurface->dwDepth = pMosSurface->dwDepth;
112 pVphalSurface->dwSlicePitch = pMosSurface->dwSlicePitch;
113 pVphalSurface->dwOffset = pMosSurface->dwOffset;
114 pVphalSurface->bCompressible = pMosSurface->bCompressible;
115 pVphalSurface->bIsCompressed = pMosSurface->bIsCompressed;
116 pVphalSurface->CompressionMode = pMosSurface->CompressionMode;
117 pVphalSurface->CompressionFormat = pMosSurface->CompressionFormat;
118
119 pVphalSurface->YPlaneOffset.iLockSurfaceOffset = pMosSurface->YPlaneOffset.iLockSurfaceOffset;
120 pVphalSurface->YPlaneOffset.iSurfaceOffset = pMosSurface->YPlaneOffset.iSurfaceOffset;
121 pVphalSurface->YPlaneOffset.iXOffset = pMosSurface->YPlaneOffset.iXOffset;
122 pVphalSurface->YPlaneOffset.iYOffset = pMosSurface->YPlaneOffset.iYOffset;
123
124 pVphalSurface->UPlaneOffset.iLockSurfaceOffset = pMosSurface->UPlaneOffset.iLockSurfaceOffset;
125 pVphalSurface->UPlaneOffset.iSurfaceOffset = pMosSurface->UPlaneOffset.iSurfaceOffset;
126 pVphalSurface->UPlaneOffset.iXOffset = pMosSurface->UPlaneOffset.iXOffset;
127 pVphalSurface->UPlaneOffset.iYOffset = pMosSurface->UPlaneOffset.iYOffset;
128
129 pVphalSurface->VPlaneOffset.iLockSurfaceOffset = pMosSurface->VPlaneOffset.iLockSurfaceOffset;
130 pVphalSurface->VPlaneOffset.iSurfaceOffset = pMosSurface->VPlaneOffset.iSurfaceOffset;
131 pVphalSurface->VPlaneOffset.iXOffset = pMosSurface->VPlaneOffset.iXOffset;
132 pVphalSurface->VPlaneOffset.iYOffset = pMosSurface->VPlaneOffset.iYOffset;
133
134 return eStatus;
135 }
136
137 #define DumpSurfaceMemDecomp(MosSurface, SurfaceCounter, BufferCopy, Location) \
138 { \
139 VPHAL_SURFACE VphalSurface = {}; \
140 CloneResourceInfo(&VphalSurface, &MosSurface); \
141 if (m_surfaceDumper) \
142 { \
143 m_surfaceDumper->DumpSurface(&VphalSurface, SurfaceCounter, BufferCopy, Location); \
144 } \
145 }
146 #else
147 #define DumpSurfaceMemDecomp(MosSurface, surfaceCounter, DoubleCopy, Locationlocation) {}
148 #endif
149
MemoryDecompress(PMOS_RESOURCE targetResource)150 MOS_STATUS MediaVeboxDecompState::MemoryDecompress(PMOS_RESOURCE targetResource)
151 {
152 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
153 MOS_SURFACE TargetSurface;
154
155 MHW_FUNCTION_ENTER;
156
157 VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(targetResource);
158 MOS_TraceEventExt(EVENT_MEDIA_COPY, EVENT_TYPE_START, nullptr, 0, nullptr, 0);
159 #if MOS_MEDIASOLO_SUPPORTED
160 if (m_osInterface->bSoloInUse)
161 {
162 // Bypass
163 }
164 else
165 #endif
166 {
167 if (m_veboxMMCResolveEnabled)
168 {
169 MOS_ZeroMemory(&TargetSurface, sizeof(MOS_SURFACE));
170
171 TargetSurface.Format = Format_Invalid;
172 TargetSurface.OsResource = *targetResource;
173 VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(GetResourceInfo(&TargetSurface));
174
175 //Get context before proceeding
176 auto gpuContext = m_osInterface->CurrentGpuContextOrdinal;
177
178 if (TargetSurface.bCompressible)
179 {
180 DumpSurfaceMemDecomp(TargetSurface, m_surfaceDumpCounter, 0, VPHAL_DBG_DUMP_TYPE_PRE_MEMDECOMP);
181
182 VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(RenderDecompCMD(&TargetSurface));
183
184 DumpSurfaceMemDecomp(TargetSurface, m_surfaceDumpCounter++, 0, VPHAL_DBG_DUMP_TYPE_POST_MEMDECOMP);
185 }
186 }
187 }
188 MOS_TraceEventExt(EVENT_MEDIA_COPY, EVENT_TYPE_END, nullptr, 0, nullptr, 0);
189 return eStatus;
190 }
191
MediaMemoryCopy(PMOS_RESOURCE inputResource,PMOS_RESOURCE outputResource,bool outputCompressed)192 MOS_STATUS MediaVeboxDecompState::MediaMemoryCopy(
193 PMOS_RESOURCE inputResource,
194 PMOS_RESOURCE outputResource,
195 bool outputCompressed)
196 {
197 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
198 bool bValidInputSurface = false;
199 bool bValidOutputSurface = false;
200
201 MHW_FUNCTION_ENTER;
202
203 VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(inputResource);
204 VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(outputResource);
205 MOS_TraceEventExt(EVENT_MEDIA_COPY, EVENT_TYPE_START, nullptr, 0, nullptr, 0);
206
207 MOS_SURFACE sourceSurface;
208 MOS_SURFACE targetSurface;
209
210 MOS_ZeroMemory(&targetSurface, sizeof(MOS_SURFACE));
211 MOS_ZeroMemory(&sourceSurface, sizeof(MOS_SURFACE));
212
213 targetSurface.Format = Format_Invalid;
214 targetSurface.OsResource = *outputResource;
215
216 #if !defined(LINUX) && !defined(ANDROID) && !EMUL && !_VULKAN
217 // for Double Buffer copy, clear the allocationInfo temply
218 MOS_ZeroMemory(&targetSurface.OsResource.AllocationInfo, sizeof(SResidencyInfo));
219 #endif
220
221 sourceSurface.Format = Format_Invalid;
222 sourceSurface.OsResource = *inputResource;
223 VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(GetResourceInfo(&targetSurface));
224 VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(GetResourceInfo(&sourceSurface));
225
226 #if (_DEBUG || _RELEASE_INTERNAL)
227 {
228 // Read user feature key to force outputCompressed
229 ReadUserSettingForDebug(
230 m_userSettingPtr,
231 outputCompressed,
232 __VPHAL_VEBOX_FORCE_VP_MEMCOPY_OUTPUTCOMPRESSED,
233 MediaUserSetting::Group::Sequence);
234 }
235 #endif
236
237 if (!outputCompressed && targetSurface.CompressionMode != MOS_MMC_DISABLED)
238 {
239 targetSurface.CompressionMode = MOS_MMC_RC;
240 }
241
242 //if surface is linear buffer, use mos copy
243 if (sourceSurface.TileType == MOS_TILE_LINEAR &&
244 targetSurface.TileType == MOS_TILE_LINEAR &&
245 sourceSurface.Type == MOS_GFXRES_BUFFER &&
246 targetSurface.Type == MOS_GFXRES_BUFFER )
247 {
248 DumpSurfaceMemDecomp(sourceSurface, m_surfaceDumpCounter, 1, VPHAL_DBG_DUMP_TYPE_PRE_MEMDECOMP);
249 do
250 {
251 MOS_LOCK_PARAMS lockSourceFlags;
252 MOS_ZeroMemory(&lockSourceFlags, sizeof(MOS_LOCK_PARAMS));
253 lockSourceFlags.ReadOnly = 1;
254 lockSourceFlags.WriteOnly = 0;
255
256 MOS_LOCK_PARAMS lockTargetFlags;
257 MOS_ZeroMemory(&lockTargetFlags, sizeof(MOS_LOCK_PARAMS));
258 lockTargetFlags.ReadOnly = 0;
259 lockTargetFlags.WriteOnly = 1;
260
261 uint8_t *lockedSrcAddr = (uint8_t *)m_osInterface->pfnLockResource(m_osInterface, &sourceSurface.OsResource, &lockSourceFlags);
262
263 if (lockedSrcAddr == nullptr)
264 {
265 //non lockable resource enabled, we can't lock source surface
266 eStatus = MOS_STATUS_NULL_POINTER;
267 VPHAL_MEMORY_DECOMP_ASSERTMESSAGE("Failed to lock non-lockable input resource, buffer copy failed, eStatus:%d.\n", eStatus);
268 MT_ERR2(MT_VE_DECOMP_COPY, MT_SURF_IS_INPUT, 1, MT_VE_DECOMP_COPY_SURF_LOCK_STATUS, eStatus);
269 break;
270 }
271
272 uint8_t *lockedTarAddr = (uint8_t *)m_osInterface->pfnLockResource(m_osInterface, &targetSurface.OsResource, &lockTargetFlags);
273
274 if (lockedTarAddr == nullptr)
275 {
276 eStatus = MOS_STATUS_NULL_POINTER;
277 m_osInterface->pfnUnlockResource(m_osInterface, &sourceSurface.OsResource);
278 VPHAL_MEMORY_DECOMP_ASSERTMESSAGE("Failed to lock non-lockable output resource, buffer copy failed, eStatus:%d.\n", eStatus);
279 MT_ERR2(MT_VE_DECOMP_COPY, MT_SURF_IS_OUTPUT, 1, MT_VE_DECOMP_COPY_SURF_LOCK_STATUS, eStatus);
280 break;
281 }
282 // This resource is a series of bytes. Is not 2 dimensional.
283 uint32_t sizeSrcMain = sourceSurface.dwWidth;
284 uint32_t sizeTargetMain = targetSurface.dwWidth;
285 eStatus = MOS_SecureMemcpy(lockedTarAddr, sizeTargetMain, lockedSrcAddr, sizeSrcMain);
286 m_osInterface->pfnUnlockResource(m_osInterface, &sourceSurface.OsResource);
287 m_osInterface->pfnUnlockResource(m_osInterface, &targetSurface.OsResource);
288
289 if (eStatus != MOS_STATUS_SUCCESS)
290 {
291 VPHAL_MEMORY_DECOMP_ASSERTMESSAGE("Failed to copy linear buffer from source to target, eStatus:%d.\n", eStatus);
292 MT_ERR1(MT_VE_DECOMP_COPY, MT_MOS_STATUS, eStatus);
293 break;
294 }
295 } while (false);
296
297 DumpSurfaceMemDecomp(targetSurface, m_surfaceDumpCounter++, 1, VPHAL_DBG_DUMP_TYPE_POST_MEMDECOMP);
298 MOS_TraceEventExt(EVENT_MEDIA_COPY, EVENT_TYPE_END, nullptr, 0, nullptr, 0);
299 return eStatus;
300 }
301
302 // if source surface or target surface is non-64align linear, return error here
303 if((sourceSurface.dwPitch%64 != 0 && sourceSurface.TileType == MOS_TILE_LINEAR) ||
304 (targetSurface.dwPitch%64 != 0 && targetSurface.TileType == MOS_TILE_LINEAR))
305 {
306 eStatus = MOS_STATUS_INVALID_PARAMETER;
307 VPHAL_MEMORY_DECOMP_ASSERTMESSAGE("VEBOX does not support non-64align pitch linear surface, eStatus:%d.\n", eStatus);
308 MT_ERR2(MT_VE_DECOMP_COPY, MT_SURF_PITCH, sourceSurface.dwPitch, MT_SURF_PITCH, targetSurface.dwPitch);
309 MOS_TraceEventExt(EVENT_MEDIA_COPY, EVENT_TYPE_END, nullptr, 0, nullptr, 0);
310 return eStatus;
311 }
312
313 //Get context before proceeding
314 auto gpuContext = m_osInterface->CurrentGpuContextOrdinal;
315
316 //Check whether surface is valid, or it will cause page fault
317 m_osInterface->pfnVerifyMosSurface(&sourceSurface, bValidInputSurface);
318 m_osInterface->pfnVerifyMosSurface(&targetSurface, bValidOutputSurface);
319 if (!bValidInputSurface || !bValidOutputSurface)
320 {
321 VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(MOS_STATUS_INVALID_PARAMETER);
322 }
323
324 // Sync for Vebox read
325 m_osInterface->pfnSyncOnResource(
326 m_osInterface,
327 &sourceSurface.OsResource,
328 MOS_GPU_CONTEXT_VEBOX,
329 false);
330
331 // Sync for Vebox write
332 m_osInterface->pfnSyncOnResource(
333 m_osInterface,
334 &targetSurface.OsResource,
335 MOS_GPU_CONTEXT_VEBOX,
336 false);
337
338 DumpSurfaceMemDecomp(sourceSurface, m_surfaceDumpCounter, 1, VPHAL_DBG_DUMP_TYPE_PRE_MEMDECOMP);
339
340 VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(RenderDoubleBufferDecompCMD(&sourceSurface, &targetSurface));
341
342 DumpSurfaceMemDecomp(targetSurface, m_surfaceDumpCounter++, 1, VPHAL_DBG_DUMP_TYPE_POST_MEMDECOMP);
343 MOS_TraceEventExt(EVENT_MEDIA_COPY, EVENT_TYPE_END, nullptr, 0, nullptr, 0);
344 return eStatus;
345 }
346
MediaMemoryCopy2D(PMOS_RESOURCE inputResource,PMOS_RESOURCE outputResource,uint32_t copyWidth,uint32_t copyHeight,uint32_t copyInputOffset,uint32_t copyOutputOffset,uint32_t bpp,bool outputCompressed)347 MOS_STATUS MediaVeboxDecompState::MediaMemoryCopy2D(
348 PMOS_RESOURCE inputResource,
349 PMOS_RESOURCE outputResource,
350 uint32_t copyWidth,
351 uint32_t copyHeight,
352 uint32_t copyInputOffset,
353 uint32_t copyOutputOffset,
354 uint32_t bpp,
355 bool outputCompressed)
356 {
357 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
358 bool bValidInputSurface = false;
359 bool bValidOutputSurface = false;
360
361 MHW_FUNCTION_ENTER;
362
363 VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(inputResource);
364 VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(outputResource);
365 MOS_TraceEventExt(EVENT_MEDIA_COPY, EVENT_TYPE_START, nullptr, 0, nullptr, 0);
366
367 MOS_SURFACE sourceSurface;
368 MOS_SURFACE targetSurface;
369
370 MOS_ZeroMemory(&targetSurface, sizeof(MOS_SURFACE));
371 MOS_ZeroMemory(&sourceSurface, sizeof(MOS_SURFACE));
372
373 targetSurface.Format = Format_Invalid;
374 targetSurface.OsResource = *outputResource;
375
376 #if !defined(LINUX) && !defined(ANDROID) && !EMUL && !_VULKAN
377 // for Double Buffer copy, clear the allocationInfo temply
378 MOS_ZeroMemory(&targetSurface.OsResource.AllocationInfo, sizeof(SResidencyInfo));
379 #endif
380
381 sourceSurface.Format = Format_Invalid;
382 sourceSurface.OsResource = *inputResource;
383 VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(GetResourceInfo(&targetSurface));
384 VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(GetResourceInfo(&sourceSurface));
385
386 #if (_DEBUG || _RELEASE_INTERNAL)
387 {
388 // Read user feature key to Force outputCompressed
389 ReadUserSettingForDebug(
390 m_userSettingPtr,
391 outputCompressed,
392 __VPHAL_VEBOX_FORCE_VP_MEMCOPY_OUTPUTCOMPRESSED,
393 MediaUserSetting::Group::Sequence);
394 }
395 #endif
396
397 if (!outputCompressed && targetSurface.CompressionMode != MOS_MMC_DISABLED)
398 {
399 targetSurface.CompressionMode = MOS_MMC_RC;
400 }
401
402 //Get context before proceeding
403 auto gpuContext = m_osInterface->CurrentGpuContextOrdinal;
404 uint32_t pixelInByte = 1;
405
406 switch (bpp)
407 {
408 case 8:
409 targetSurface.Format = Format_Y8;
410 sourceSurface.Format = Format_Y8;
411 pixelInByte = 1;
412 break;
413 case 16:
414 targetSurface.Format = Format_Y16U;
415 sourceSurface.Format = Format_Y16U;
416 pixelInByte = 2;
417 break;
418 case 32:
419 targetSurface.Format = Format_AYUV;
420 sourceSurface.Format = Format_AYUV;
421 pixelInByte = 4;
422 break;
423 case 64:
424 targetSurface.Format = Format_Y416;
425 sourceSurface.Format = Format_Y416;
426 pixelInByte = 8;
427 break;
428 default:
429 targetSurface.Format = Format_Y8;
430 sourceSurface.Format = Format_Y8;
431 pixelInByte = 1;
432 break;
433 }
434
435
436 sourceSurface.dwOffset = copyInputOffset;
437 targetSurface.dwOffset = copyOutputOffset;
438
439 sourceSurface.dwWidth = copyWidth / pixelInByte;
440 sourceSurface.dwHeight = copyHeight;
441 targetSurface.dwWidth = copyWidth / pixelInByte;
442 targetSurface.dwHeight = copyHeight;
443
444 //Check whether surface is valid, or it will cause page fault
445 m_osInterface->pfnVerifyMosSurface(&sourceSurface, bValidInputSurface);
446 m_osInterface->pfnVerifyMosSurface(&targetSurface, bValidOutputSurface);
447 if (!bValidInputSurface || !bValidOutputSurface)
448 {
449 VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(MOS_STATUS_INVALID_PARAMETER);
450 }
451
452 // Sync for Vebox write
453 m_osInterface->pfnSyncOnResource(
454 m_osInterface,
455 &sourceSurface.OsResource,
456 MOS_GPU_CONTEXT_VEBOX,
457 false);
458
459 DumpSurfaceMemDecomp(sourceSurface, m_surfaceDumpCounter, 1, VPHAL_DBG_DUMP_TYPE_PRE_MEMDECOMP);
460
461 VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(RenderDoubleBufferDecompCMD(&sourceSurface, &targetSurface));
462
463 DumpSurfaceMemDecomp(targetSurface, m_surfaceDumpCounter++, 1, VPHAL_DBG_DUMP_TYPE_POST_MEMDECOMP);
464 MOS_TraceEventExt(EVENT_MEDIA_COPY, EVENT_TYPE_END, nullptr, 0, nullptr, 0);
465 return eStatus;
466 }
467
MediaMemoryTileConvert(PMOS_RESOURCE inputResource,PMOS_RESOURCE outputResource,uint32_t copyWidth,uint32_t copyHeight,uint32_t copyInputOffset,uint32_t copyOutputOffset,bool isTileToLinear,bool outputCompressed)468 MOS_STATUS MediaVeboxDecompState::MediaMemoryTileConvert(
469 PMOS_RESOURCE inputResource,
470 PMOS_RESOURCE outputResource,
471 uint32_t copyWidth,
472 uint32_t copyHeight,
473 uint32_t copyInputOffset,
474 uint32_t copyOutputOffset,
475 bool isTileToLinear,
476 bool outputCompressed)
477 {
478 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
479
480 MHW_FUNCTION_ENTER;
481
482 VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(inputResource);
483 VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(outputResource);
484 MOS_TraceEventExt(EVENT_MEDIA_COPY, EVENT_TYPE_START, nullptr, 0, nullptr, 0);
485
486 MOS_SURFACE sourceSurface;
487 MOS_SURFACE targetSurface;
488
489 MOS_ZeroMemory(&targetSurface, sizeof(MOS_SURFACE));
490 MOS_ZeroMemory(&sourceSurface, sizeof(MOS_SURFACE));
491
492 targetSurface.Format = Format_Invalid;
493 targetSurface.OsResource = *outputResource;
494
495 #if !defined(LINUX) && !defined(ANDROID) && !EMUL && !_VULKAN
496 // for Double Buffer copy, clear the allocationInfo temply
497 MOS_ZeroMemory(&targetSurface.OsResource.AllocationInfo, sizeof(SResidencyInfo));
498 #endif
499
500 sourceSurface.Format = Format_Invalid;
501 sourceSurface.OsResource = *inputResource;
502 VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(GetResourceInfo(&targetSurface));
503 VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(GetResourceInfo(&sourceSurface));
504
505 if (targetSurface.TileType == MOS_TILE_LINEAR &&
506 sourceSurface.TileType == MOS_TILE_LINEAR)
507 {
508 VPHAL_MEMORY_DECOMP_NORMALMESSAGE("unsupport linear to linear convert, return unsupport feature");
509 MT_ERR2(MT_VE_DECOMP_COPY, MT_SURF_TILE_TYPE, MOS_TILE_LINEAR, MT_SURF_TILE_TYPE, MOS_TILE_LINEAR);
510 return MOS_STATUS_PLATFORM_NOT_SUPPORTED;
511 }
512
513 MOS_FORMAT format = Format_Any;
514 if (isTileToLinear)
515 {
516 if (!IsFormatSupported(&sourceSurface))
517 {
518 VPHAL_MEMORY_DECOMP_NORMALMESSAGE("unsupport processing format, return unsupport feature");
519 MT_ERR2(MT_VE_DECOMP_COPY, MT_SURF_MOS_FORMAT, sourceSurface.Format, MT_SURF_IS_INPUT, 1);
520 return MOS_STATUS_PLATFORM_NOT_SUPPORTED;
521 }
522
523 format = sourceSurface.Format;
524 copyHeight = sourceSurface.dwHeight;
525 }
526 else
527 {
528 if (!IsFormatSupported(&targetSurface))
529 {
530 VPHAL_MEMORY_DECOMP_NORMALMESSAGE("unsupport processing format, return unsupport feature");
531 MT_ERR2(MT_VE_DECOMP_COPY, MT_SURF_MOS_FORMAT, targetSurface.Format, MT_SURF_IS_OUTPUT, 1);
532 return MOS_STATUS_PLATFORM_NOT_SUPPORTED;
533 }
534
535 format = targetSurface.Format;
536 copyHeight = targetSurface.dwHeight;
537 }
538
539 if (!outputCompressed && targetSurface.CompressionMode != MOS_MMC_DISABLED)
540 {
541 targetSurface.CompressionMode = MOS_MMC_RC;
542 }
543
544 //Get context before proceeding
545 auto gpuContext = m_osInterface->CurrentGpuContextOrdinal;
546
547 targetSurface.Format = format;
548 sourceSurface.Format = format;
549
550 sourceSurface.dwOffset = copyInputOffset;
551 targetSurface.dwOffset = copyOutputOffset;
552
553 sourceSurface.dwWidth = copyWidth;
554 sourceSurface.dwHeight = copyHeight;
555 targetSurface.dwWidth = copyWidth;
556 targetSurface.dwHeight = copyHeight;
557
558 // Sync for Vebox write
559 m_osInterface->pfnSyncOnResource(
560 m_osInterface,
561 &targetSurface.OsResource,
562 MOS_GPU_CONTEXT_VEBOX,
563 false);
564
565 DumpSurfaceMemDecomp(sourceSurface, m_surfaceDumpCounter, 1, VPHAL_DBG_DUMP_TYPE_PRE_MEMDECOMP);
566
567 VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(RenderDoubleBufferDecompCMD(&sourceSurface, &targetSurface));
568
569 DumpSurfaceMemDecomp(targetSurface, m_surfaceDumpCounter++, 1, VPHAL_DBG_DUMP_TYPE_POST_MEMDECOMP);
570 MOS_TraceEventExt(EVENT_MEDIA_COPY, EVENT_TYPE_END, nullptr, 0, nullptr, 0);
571 return eStatus;
572 }
573
Initialize(PMOS_INTERFACE osInterface,MhwCpInterface * cpInterface,PMHW_MI_INTERFACE mhwMiInterface,PMHW_VEBOX_INTERFACE veboxInterface)574 MOS_STATUS MediaVeboxDecompState::Initialize(
575 PMOS_INTERFACE osInterface,
576 MhwCpInterface *cpInterface,
577 PMHW_MI_INTERFACE mhwMiInterface,
578 PMHW_VEBOX_INTERFACE veboxInterface)
579 {
580 MOS_STATUS eStatus;
581 MHW_VEBOX_GPUNODE_LIMIT GpuNodeLimit;
582 MOS_GPU_NODE VeboxGpuNode;
583 MOS_GPU_CONTEXT VeboxGpuContext;
584 RENDERHAL_SETTINGS_LEGACY RenderHalSettings;
585
586 eStatus = MOS_STATUS_SUCCESS;
587
588 VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(osInterface);
589 VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(cpInterface);
590 VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(mhwMiInterface);
591 VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(veboxInterface);
592
593 m_osInterface = osInterface;
594 m_cpInterface = cpInterface;
595 m_mhwMiInterface = mhwMiInterface;
596 m_veboxInterface = veboxInterface;
597
598 m_userSettingPtr = m_osInterface->pfnGetUserSettingInstance(m_osInterface);
599
600 // Set-Up Vebox decompression enable or not
601 IsVeboxDecompressionEnabled();
602
603 if (m_veboxInterface)
604 {
605 GpuNodeLimit.bCpEnabled = (m_osInterface->osCpInterface->IsCpEnabled())? true : false;
606
607 // Check GPU Node decide logic together in this function
608 VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(m_veboxInterface->FindVeboxGpuNodeToUse(&GpuNodeLimit));
609
610 VeboxGpuNode = (MOS_GPU_NODE)(GpuNodeLimit.dwGpuNodeToUse);
611 VeboxGpuContext = (VeboxGpuNode == MOS_GPU_NODE_VE) ? MOS_GPU_CONTEXT_VEBOX : MOS_GPU_CONTEXT_VEBOX2;
612
613 // Create VEBOX/VEBOX2 Context
614 VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(m_veboxInterface->CreateGpuContext(
615 m_osInterface,
616 VeboxGpuContext,
617 VeboxGpuNode));
618
619 // Register Vebox GPU context with the Batch Buffer completion event
620 VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(m_osInterface->pfnRegisterBBCompleteNotifyEvent(
621 m_osInterface,
622 MOS_GPU_CONTEXT_VEBOX));
623
624 if (m_veboxInterface->m_veboxHeap == nullptr)
625 {
626 VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(m_veboxInterface->CreateHeap());
627 }
628
629 #if (_DEBUG || _RELEASE_INTERNAL)
630 CreateSurfaceDumper();
631 if (m_surfaceDumper)
632 {
633 m_surfaceDumper->GetSurfaceDumpSpec();
634 }
635 else
636 {
637 VPHAL_MEMORY_DECOMP_ASSERTMESSAGE("surface dumpper creation failed.");
638 }
639 #endif
640 }
641
642 return eStatus;
643 }
644 #if (_DEBUG || _RELEASE_INTERNAL)
CreateSurfaceDumper()645 void MediaVeboxDecompState::CreateSurfaceDumper()
646 {
647 m_surfaceDumper = MOS_New(VphalSurfaceDumper, m_osInterface);
648 }
649 #endif
650
GetResourceInfo(PMOS_SURFACE surface)651 MOS_STATUS MediaVeboxDecompState::GetResourceInfo(PMOS_SURFACE surface)
652 {
653 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
654
655 VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(m_osInterface);
656 VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(surface);
657
658 MOS_SURFACE resDetails;
659 MOS_ZeroMemory(&resDetails, sizeof(resDetails));
660 resDetails.Format = Format_Invalid;
661
662 VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(m_osInterface->pfnGetResourceInfo(
663 m_osInterface,
664 &surface->OsResource,
665 &resDetails));
666
667 surface->Format = resDetails.Format;
668 #if defined(LINUX) && !defined(WDDM_LINUX)
669 if ((surface->Format == Format_NV12 || surface->Format == Format_P010) && surface->OsResource.iWidth & 1 != 0)
670 {
671 uint32_t bitsPerPixel = 8;
672 if (surface->Format == Format_P010)
673 {
674 bitsPerPixel = 16;
675 }
676
677 uint32_t alignWidth = MOS_ALIGN_CEIL(resDetails.dwWidth, DECOMPRESSION_WIDTH_ALIGNMENT_IN_BYTE*8/bitsPerPixel);
678 if (alignWidth <= resDetails.dwPitch*8/bitsPerPixel)
679 {
680 surface->dwWidth = alignWidth;
681 }
682 else
683 {
684 VPHAL_MEMORY_DECOMP_ASSERTMESSAGE("May got green line corruption.");
685 surface->dwWidth = resDetails.dwWidth;
686 }
687 }
688 else
689 {
690 surface->dwWidth = resDetails.dwWidth;
691 }
692 #else
693 surface->dwWidth = resDetails.dwWidth;
694 #endif
695 surface->dwHeight = resDetails.dwHeight;
696 surface->dwPitch = resDetails.dwPitch;
697 surface->dwDepth = resDetails.dwDepth;
698 surface->bArraySpacing = resDetails.bArraySpacing;
699 surface->TileType = resDetails.TileType;
700 surface->TileModeGMM = resDetails.TileModeGMM;
701 surface->bGMMTileEnabled = resDetails.bGMMTileEnabled;
702 surface->bCompressible = resDetails.bCompressible;
703 surface->bIsCompressed = resDetails.bIsCompressed;
704 surface->dwOffset = resDetails.RenderOffset.YUV.Y.BaseOffset;
705 surface->YPlaneOffset.iSurfaceOffset = resDetails.RenderOffset.YUV.Y.BaseOffset;
706 surface->YPlaneOffset.iXOffset = resDetails.RenderOffset.YUV.Y.XOffset;
707 surface->YPlaneOffset.iYOffset = resDetails.RenderOffset.YUV.Y.YOffset;
708 surface->UPlaneOffset.iSurfaceOffset = resDetails.RenderOffset.YUV.U.BaseOffset;
709 surface->UPlaneOffset.iXOffset = resDetails.RenderOffset.YUV.U.XOffset;
710 surface->UPlaneOffset.iYOffset = resDetails.RenderOffset.YUV.U.YOffset;
711 surface->VPlaneOffset.iSurfaceOffset = resDetails.RenderOffset.YUV.V.BaseOffset;
712 surface->VPlaneOffset.iXOffset = resDetails.RenderOffset.YUV.V.XOffset;
713 surface->VPlaneOffset.iYOffset = resDetails.RenderOffset.YUV.V.YOffset;
714 surface->dwSize = (uint32_t)surface->OsResource.pGmmResInfo->GetSizeMainSurface();
715
716 MOS_MEMCOMP_STATE mmcMode;
717
718 MOS_ZeroMemory(&mmcMode, sizeof(mmcMode));
719 m_osInterface->pfnGetMemoryCompressionMode(m_osInterface, &surface->OsResource, &mmcMode);
720 surface->CompressionMode = (MOS_RESOURCE_MMC_MODE)mmcMode;
721
722 if (mmcMode)
723 {
724 m_osInterface->pfnGetMemoryCompressionFormat(m_osInterface, &surface->OsResource, &surface->CompressionFormat);
725 if ((surface->TileType == MOS_TILE_Y ||
726 surface->TileType == MOS_TILE_YS))
727 {
728 surface->bCompressible = true;
729 surface->bIsCompressed = true;
730 surface->CompressionMode = (MOS_RESOURCE_MMC_MODE)mmcMode;
731 }
732 }
733
734 return eStatus;
735 }
736
737 #define SURFACE_DW_UY_OFFSET(pSurface) \
738 ((pSurface) != nullptr ? ((pSurface)->UPlaneOffset.iSurfaceOffset - (pSurface)->dwOffset) / (pSurface)->dwPitch + (pSurface)->UPlaneOffset.iYOffset : 0)
739
740 #define SURFACE_DW_VY_OFFSET(pSurface) \
741 ((pSurface) != nullptr ? ((pSurface)->VPlaneOffset.iSurfaceOffset - (pSurface)->dwOffset) / (pSurface)->dwPitch + (pSurface)->VPlaneOffset.iYOffset : 0)
742
SetupVeboxSurfaceState(PMHW_VEBOX_SURFACE_STATE_CMD_PARAMS mhwVeboxSurfaceStateCmdParams,PMOS_SURFACE inputSurface,PMOS_SURFACE outputSurface)743 MOS_STATUS MediaVeboxDecompState::SetupVeboxSurfaceState(
744 PMHW_VEBOX_SURFACE_STATE_CMD_PARAMS mhwVeboxSurfaceStateCmdParams,
745 PMOS_SURFACE inputSurface,
746 PMOS_SURFACE outputSurface)
747 {
748 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
749 bool inputIsLinearBuffer = false;
750 bool outputIsLinearBuffer = false;
751 uint32_t bpp = 1;
752 uint32_t inputWidth = 0;
753 uint32_t outputWidth = 0;
754
755 VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(inputSurface);
756 VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(mhwVeboxSurfaceStateCmdParams);
757
758 MOS_ZeroMemory(mhwVeboxSurfaceStateCmdParams, sizeof(*mhwVeboxSurfaceStateCmdParams));
759
760 mhwVeboxSurfaceStateCmdParams->SurfInput.bActive = mhwVeboxSurfaceStateCmdParams->SurfOutput.bActive = true;
761 mhwVeboxSurfaceStateCmdParams->SurfInput.dwBitDepth = mhwVeboxSurfaceStateCmdParams->SurfOutput.dwBitDepth = inputSurface->dwDepth;
762 mhwVeboxSurfaceStateCmdParams->SurfInput.dwHeight = mhwVeboxSurfaceStateCmdParams->SurfOutput.dwHeight =
763 MOS_MIN(inputSurface->dwHeight, ((outputSurface!= nullptr) ? outputSurface->dwHeight : inputSurface->dwHeight));
764 mhwVeboxSurfaceStateCmdParams->SurfInput.dwWidth = mhwVeboxSurfaceStateCmdParams->SurfOutput.dwWidth =
765 MOS_MIN(inputSurface->dwWidth, ((outputSurface != nullptr) ? outputSurface->dwWidth : inputSurface->dwWidth));
766 mhwVeboxSurfaceStateCmdParams->SurfInput.Format = mhwVeboxSurfaceStateCmdParams->SurfOutput.Format = inputSurface->Format;
767
768 MOS_SURFACE inputDetails, outputDetails;
769 MOS_ZeroMemory(&inputDetails, sizeof(inputDetails));
770 MOS_ZeroMemory(&outputDetails, sizeof(outputDetails));
771 inputDetails.Format = Format_Invalid;
772 outputDetails.Format = Format_Invalid;
773
774 if (inputSurface)
775 {
776 VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(m_osInterface->pfnGetResourceInfo(
777 m_osInterface,
778 &inputSurface->OsResource,
779 &inputDetails));
780 }
781
782 if (outputSurface)
783 {
784 VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(m_osInterface->pfnGetResourceInfo(
785 m_osInterface,
786 &outputSurface->OsResource,
787 &outputDetails));
788
789 // Following settings are enabled only when outputSurface is availble
790 inputIsLinearBuffer = (inputDetails.dwHeight == 1) ? true : false;
791 outputIsLinearBuffer = (outputDetails.dwHeight == 1) ? true : false;
792
793 inputWidth = inputSurface->dwWidth;
794 outputWidth = outputSurface->dwWidth;
795
796 if (inputIsLinearBuffer)
797 {
798 bpp = outputDetails.dwPitch / outputDetails.dwWidth;
799 if (outputDetails.dwPitch % outputDetails.dwWidth != 0)
800 {
801 inputWidth = outputDetails.dwPitch / bpp;
802 }
803 }
804 else if (outputIsLinearBuffer)
805 {
806 bpp = inputDetails.dwPitch / inputDetails.dwWidth;
807 if (inputDetails.dwPitch % inputDetails.dwWidth != 0)
808 {
809 outputWidth = inputDetails.dwPitch / bpp;
810 }
811 }
812 else
813 {
814 VPHAL_MEMORY_DECOMP_NORMALMESSAGE("2D to 2D, no need for bpp setting.");
815 }
816 }
817
818
819 if (inputSurface->dwPitch > 0 &&
820 (inputSurface->Format == Format_P010 ||
821 inputSurface->Format == Format_P016 ||
822 inputSurface->Format == Format_NV12))
823 {
824 mhwVeboxSurfaceStateCmdParams->SurfInput.dwUYoffset = (!inputIsLinearBuffer) ? SURFACE_DW_UY_OFFSET(inputSurface) :
825 inputSurface->dwHeight;
826
827 if (outputSurface)
828 {
829 mhwVeboxSurfaceStateCmdParams->SurfOutput.dwUYoffset = (!outputIsLinearBuffer) ? SURFACE_DW_UY_OFFSET(outputSurface) :
830 outputSurface->dwHeight;
831 }
832 else
833 {
834 mhwVeboxSurfaceStateCmdParams->SurfOutput.dwUYoffset = mhwVeboxSurfaceStateCmdParams->SurfInput.dwUYoffset;
835 }
836 }
837
838 mhwVeboxSurfaceStateCmdParams->SurfInput.rcMaxSrc.left = mhwVeboxSurfaceStateCmdParams->SurfOutput.rcMaxSrc.left = 0;
839 mhwVeboxSurfaceStateCmdParams->SurfInput.rcMaxSrc.right = mhwVeboxSurfaceStateCmdParams->SurfOutput.rcMaxSrc.right = (long)(mhwVeboxSurfaceStateCmdParams->SurfInput.dwWidth);
840 mhwVeboxSurfaceStateCmdParams->SurfInput.rcMaxSrc.top = mhwVeboxSurfaceStateCmdParams->SurfOutput.rcMaxSrc.top = 0;
841 mhwVeboxSurfaceStateCmdParams->SurfInput.rcMaxSrc.bottom = mhwVeboxSurfaceStateCmdParams->SurfOutput.rcMaxSrc.bottom = (long)(mhwVeboxSurfaceStateCmdParams->SurfInput.dwHeight);
842 mhwVeboxSurfaceStateCmdParams->bOutputValid = true;
843
844 // if output surface is null, then Inplace resolve happens
845 if (!outputSurface)
846 {
847 mhwVeboxSurfaceStateCmdParams->SurfInput.TileType = mhwVeboxSurfaceStateCmdParams->SurfOutput.TileType = inputSurface->TileType;
848 mhwVeboxSurfaceStateCmdParams->SurfInput.TileModeGMM = mhwVeboxSurfaceStateCmdParams->SurfOutput.TileModeGMM = inputSurface->TileModeGMM;
849 mhwVeboxSurfaceStateCmdParams->SurfInput.bGMMTileEnabled = mhwVeboxSurfaceStateCmdParams->SurfOutput.bGMMTileEnabled = inputSurface->bGMMTileEnabled;
850 mhwVeboxSurfaceStateCmdParams->SurfOutput.dwPitch = mhwVeboxSurfaceStateCmdParams->SurfInput.dwPitch = inputSurface->dwPitch;
851 mhwVeboxSurfaceStateCmdParams->SurfInput.pOsResource = mhwVeboxSurfaceStateCmdParams->SurfOutput.pOsResource = &(inputSurface->OsResource);
852 mhwVeboxSurfaceStateCmdParams->SurfInput.dwYoffset = mhwVeboxSurfaceStateCmdParams->SurfOutput.dwYoffset = inputSurface->YPlaneOffset.iYOffset;
853
854 mhwVeboxSurfaceStateCmdParams->SurfInput.dwCompressionFormat = mhwVeboxSurfaceStateCmdParams->SurfOutput.dwCompressionFormat =
855 inputSurface->CompressionFormat;
856 }
857 else
858 // double buffer resolve
859 {
860 mhwVeboxSurfaceStateCmdParams->SurfInput.TileType = inputSurface->TileType;
861 mhwVeboxSurfaceStateCmdParams->SurfInput.TileModeGMM = inputSurface->TileModeGMM;
862 mhwVeboxSurfaceStateCmdParams->SurfInput.bGMMTileEnabled = inputSurface->bGMMTileEnabled;
863 mhwVeboxSurfaceStateCmdParams->SurfOutput.TileType = outputSurface->TileType;
864 mhwVeboxSurfaceStateCmdParams->SurfOutput.TileModeGMM = outputSurface->TileModeGMM;
865 mhwVeboxSurfaceStateCmdParams->SurfOutput.bGMMTileEnabled = outputSurface->bGMMTileEnabled;
866
867 // When surface is 1D but processed as 2D, fake a min(pitch, width) is needed as the pitch API passed may less surface width in 1D surface
868 mhwVeboxSurfaceStateCmdParams->SurfInput.dwPitch = (inputIsLinearBuffer) ?
869 MOS_MIN(inputWidth * bpp, inputSurface->dwPitch) : inputSurface->dwPitch;
870 mhwVeboxSurfaceStateCmdParams->SurfOutput.dwPitch = (outputIsLinearBuffer) ?
871 MOS_MIN(outputWidth * bpp, outputSurface->dwPitch) : outputSurface->dwPitch;
872 mhwVeboxSurfaceStateCmdParams->SurfInput.pOsResource = &(inputSurface->OsResource);
873 mhwVeboxSurfaceStateCmdParams->SurfOutput.pOsResource = &(outputSurface->OsResource);
874 mhwVeboxSurfaceStateCmdParams->SurfInput.dwYoffset = inputSurface->YPlaneOffset.iYOffset;
875 mhwVeboxSurfaceStateCmdParams->SurfOutput.dwYoffset = outputSurface->YPlaneOffset.iYOffset;
876 mhwVeboxSurfaceStateCmdParams->SurfInput.dwCompressionFormat = inputSurface->CompressionFormat;
877 mhwVeboxSurfaceStateCmdParams->SurfOutput.dwCompressionFormat = outputSurface->CompressionFormat;
878 }
879
880 return eStatus;
881 }
882
InitCommandBuffer(PMOS_COMMAND_BUFFER cmdBuffer)883 MOS_STATUS MediaVeboxDecompState::InitCommandBuffer(
884 PMOS_COMMAND_BUFFER cmdBuffer)
885 {
886 PMOS_INTERFACE pOsInterface;
887 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
888 uint32_t iRemaining;
889 RENDERHAL_GENERIC_PROLOG_PARAMS GenericPrologParams = {};
890 PMOS_RESOURCE gpuStatusBuffer = nullptr;
891
892 //---------------------------------------------
893 VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(cmdBuffer);
894 VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(m_osInterface);
895 VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(m_mhwMiInterface);
896 //---------------------------------------------
897
898 eStatus = MOS_STATUS_SUCCESS;
899 pOsInterface = m_osInterface;
900
901 MOS_GPU_CONTEXT gpuContext = m_osInterface->pfnGetGpuContext(m_osInterface);
902
903 #ifndef EMUL
904 if (pOsInterface->bEnableKmdMediaFrameTracking)
905 {
906 // Get GPU Status buffer
907 VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(pOsInterface->pfnGetGpuStatusBufferResource(pOsInterface, gpuStatusBuffer));
908 VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(gpuStatusBuffer);
909 // Register the buffer
910 VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(pOsInterface->pfnRegisterResource(pOsInterface, gpuStatusBuffer, true, true));
911
912 GenericPrologParams.bEnableMediaFrameTracking = true;
913 GenericPrologParams.presMediaFrameTrackingSurface = gpuStatusBuffer;
914 GenericPrologParams.dwMediaFrameTrackingTag = pOsInterface->pfnGetGpuStatusTag(pOsInterface, pOsInterface->CurrentGpuContextOrdinal);
915 GenericPrologParams.dwMediaFrameTrackingAddrOffset = pOsInterface->pfnGetGpuStatusTagOffset(pOsInterface, pOsInterface->CurrentGpuContextOrdinal);
916
917 // Increment GPU Status Tag
918 pOsInterface->pfnIncrementGpuStatusTag(pOsInterface, pOsInterface->CurrentGpuContextOrdinal);
919 }
920 #endif
921
922 if (GenericPrologParams.bEnableMediaFrameTracking)
923 {
924 VPHAL_MEMORY_DECOMP_CHK_NULL_RETURN(GenericPrologParams.presMediaFrameTrackingSurface);
925 cmdBuffer->Attributes.bEnableMediaFrameTracking = GenericPrologParams.bEnableMediaFrameTracking;
926 cmdBuffer->Attributes.dwMediaFrameTrackingTag = GenericPrologParams.dwMediaFrameTrackingTag;
927 cmdBuffer->Attributes.dwMediaFrameTrackingAddrOffset = GenericPrologParams.dwMediaFrameTrackingAddrOffset;
928 cmdBuffer->Attributes.resMediaFrameTrackingSurface = GenericPrologParams.presMediaFrameTrackingSurface;
929 }
930
931 // initialize command buffer attributes
932 cmdBuffer->Attributes.bTurboMode = false;
933 cmdBuffer->Attributes.bMediaPreemptionEnabled = false;
934 cmdBuffer->Attributes.dwMediaFrameTrackingAddrOffset = 0;
935
936 MHW_GENERIC_PROLOG_PARAMS genericPrologParams;
937 MOS_ZeroMemory(&genericPrologParams, sizeof(genericPrologParams));
938 genericPrologParams.pOsInterface = m_osInterface;
939 genericPrologParams.pvMiInterface = m_mhwMiInterface;
940 genericPrologParams.bMmcEnabled = true;
941
942 VPHAL_MEMORY_DECOMP_CHK_STATUS_RETURN(Mhw_SendGenericPrologCmd(
943 cmdBuffer,
944 &genericPrologParams));
945
946 return eStatus;
947 }
948
IsFormatSupported(PMOS_SURFACE surface)949 bool MediaVeboxDecompState::IsFormatSupported(PMOS_SURFACE surface)
950 {
951 bool bRet = false;
952
953 if (surface->Format == Format_R10G10B10A2 ||
954 surface->Format == Format_B10G10R10A2 ||
955 surface->Format == Format_Y410 ||
956 surface->Format == Format_Y210)
957 {
958 // Re-map RGB10/RGB10/Y410/Y210 as AYUV
959 surface->Format = Format_AYUV;
960 }
961
962 if (surface->Format == Format_A8 ||
963 surface->Format == Format_Y8 ||
964 surface->Format == Format_L8 ||
965 surface->Format == Format_P8 ||
966 surface->Format == Format_STMM)
967 {
968 surface->Format = Format_P8;
969 }
970
971 if (surface->Format == Format_IMC3 ||
972 surface->Format == Format_444P ||
973 surface->Format == Format_422H ||
974 surface->Format == Format_422V ||
975 surface->Format == Format_411P ||
976 surface->Format == Format_411R ||
977 surface->Format == Format_444P ||
978 surface->Format == Format_RGBP ||
979 surface->Format == Format_BGRP ||
980 surface->Format == Format_400P ||
981 surface->Format == Format_420O )
982 {
983 surface->Format = Format_P8;
984 surface->dwHeight = surface->dwSize / surface->dwPitch;
985 }
986
987 if (IS_RGB64_FLOAT_FORMAT(surface->Format) ||
988 IS_RGB64_FORMAT(surface->Format) ||
989 surface->Format == Format_G32R32F)
990 {
991 surface->Format = Format_Y416;
992 }
993
994 // Check if Sample Format is supported for decompression
995 if (surface->Format != Format_NV12 &&
996 surface->Format != Format_AYUV &&
997 surface->Format != Format_Y416 &&
998 surface->Format != Format_P010 &&
999 surface->Format != Format_P016 &&
1000 !IS_PA_FORMAT(surface->Format) &&
1001 surface->Format != Format_A8R8G8B8 &&
1002 surface->Format != Format_A8B8G8R8 &&
1003 surface->Format != Format_X8R8G8B8 &&
1004 surface->Format != Format_X8B8G8R8 &&
1005 surface->Format != Format_P8 &&
1006 surface->Format != Format_Y16U)
1007 {
1008 VPHAL_MEMORY_DECOMP_NORMALMESSAGE("Unsupported Source Format '0x%08x' for VEBOX Decompression.", surface->Format);
1009 goto finish;
1010 }
1011
1012 bRet = true;
1013
1014 finish:
1015 return bRet;
1016 }
1017