1 /*
2 * Copyright (c) 2020-2021, 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_copy.cpp
24 //! \brief Common interface and structure used in media copy
25 //! \details Common interface and structure used in media copy which are platform independent
26 //!
27
28 #include "media_copy.h"
29 #include "media_copy_common.h"
30 #include "media_debug_dumper.h"
31 #include "mhw_cp_interface.h"
32 #include "mos_utilities.h"
33 #include "mos_util_debug.h"
34
35 #define BLT_MAX_WIDTH (1 << 16) - 1
36 #define BLT_MAX_HEIGHT (1 << 16) - 1
37 #define BLT_MAX_PITCH (1 << 18) - 1
38
39 #define VE_MIN_WIDTH 64
40 #define VE_MIN_HEIGHT 32
41
42 #define RENDER_MIN_WIDTH 16
43 #define RENDER_MIN_HEIGHT 16
44
MediaCopyBaseState()45 MediaCopyBaseState::MediaCopyBaseState():
46 m_osInterface(nullptr)
47 {
48
49 }
50
~MediaCopyBaseState()51 MediaCopyBaseState::~MediaCopyBaseState()
52 {
53 if (m_osInterface)
54 {
55 m_osInterface->pfnDestroy(m_osInterface, false);
56 MOS_FreeMemory(m_osInterface);
57 m_osInterface = nullptr;
58 }
59
60 if (m_inUseGPUMutex)
61 {
62 MosUtilities::MosDestroyMutex(m_inUseGPUMutex);
63 m_inUseGPUMutex = nullptr;
64 }
65
66 #if (_DEBUG || _RELEASE_INTERNAL)
67 if (m_surfaceDumper != nullptr)
68 {
69 MOS_Delete(m_surfaceDumper);
70 m_surfaceDumper = nullptr;
71 }
72 #endif
73 }
74
75 //!
76 //! \brief init Media copy
77 //! \details init func.
78 //! \param none
79 //! \return MOS_STATUS
80 //! Return MOS_STATUS_SUCCESS if success, otherwise return failed.
81 //!
Initialize(PMOS_INTERFACE osInterface)82 MOS_STATUS MediaCopyBaseState::Initialize(PMOS_INTERFACE osInterface)
83 {
84 if (m_inUseGPUMutex == nullptr)
85 {
86 m_inUseGPUMutex = MosUtilities::MosCreateMutex();
87 MCPY_CHK_NULL_RETURN(m_inUseGPUMutex);
88 }
89 MCPY_CHK_NULL_RETURN(m_osInterface);
90 Mos_SetVirtualEngineSupported(m_osInterface, true);
91 m_osInterface->pfnVirtualEngineSupported(m_osInterface, true, true);
92
93 #if (_DEBUG || _RELEASE_INTERNAL)
94 if (m_surfaceDumper == nullptr)
95 {
96 m_surfaceDumper = MOS_New(CommonSurfaceDumper, osInterface);
97 MOS_OS_CHK_NULL_RETURN(m_surfaceDumper);
98 }
99 MediaUserSettingSharedPtr userSettingPtr = nullptr;
100
101 m_surfaceDumper->GetSurfaceDumpLocation(m_dumpLocation_in, mcpy_in);
102 m_surfaceDumper->GetSurfaceDumpLocation(m_dumpLocation_out, mcpy_out);
103 if (m_osInterface)
104 {
105 userSettingPtr = m_osInterface->pfnGetUserSettingInstance(m_osInterface);
106 ReadUserSettingForDebug(
107 userSettingPtr,
108 m_MCPYForceMode,
109 __MEDIA_USER_FEATURE_SET_MCPY_FORCE_MODE,
110 MediaUserSetting::Group::Device);
111
112 ReadUserSettingForDebug(
113 userSettingPtr,
114 m_enableVeCopySmallRes,
115 __MEDIA_USER_FEATURE_ENABLE_VECOPY_SMALL_RESOLUTION,
116 MediaUserSetting::Group::Device);
117 }
118 #endif
119 return MOS_STATUS_SUCCESS;
120 }
121
122 //!
123 //! \brief check copy capability.
124 //! \details to determine surface copy is supported or not.
125 //! \param none
126 //! \return MOS_STATUS
127 //! Return MOS_STATUS_SUCCESS if support, otherwise return unspoort.
128 //!
CapabilityCheck(MOS_FORMAT format,MCPY_STATE_PARAMS & mcpySrc,MCPY_STATE_PARAMS & mcpyDst,MCPY_ENGINE_CAPS & caps,MCPY_METHOD preferMethod)129 MOS_STATUS MediaCopyBaseState::CapabilityCheck(
130 MOS_FORMAT format,
131 MCPY_STATE_PARAMS &mcpySrc,
132 MCPY_STATE_PARAMS &mcpyDst,
133 MCPY_ENGINE_CAPS &caps,
134 MCPY_METHOD preferMethod)
135 {
136 // derivate class specific check. include HW engine avaliable check.
137 MCPY_CHK_STATUS_RETURN(FeatureSupport(mcpySrc.OsRes, mcpyDst.OsRes, mcpySrc, mcpyDst, caps));
138
139 // common policy check
140 // legal check
141 // Blt engine does not support protection, allow the copy if dst is staging buffer in system mem
142 if (preferMethod == MCPY_METHOD_POWERSAVING &&
143 (mcpySrc.CpMode == MCPY_CPMODE_CP || mcpyDst.CpMode == MCPY_CPMODE_CP))
144 {
145 MCPY_ASSERTMESSAGE("illegal usage");
146 return MOS_STATUS_INVALID_PARAMETER;
147 }
148
149 // vebox cap check.
150 if (!IsVeboxCopySupported(mcpySrc.OsRes, mcpyDst.OsRes) || // format check, implemented on Gen derivate class.
151 mcpySrc.bAuxSuface)
152 {
153 caps.engineVebox = false;
154 // temp solution for FP16 enabling on new platform
155 if (format == Format_A16B16G16R16F || format == Format_A16R16G16B16F)
156 {
157 return MOS_STATUS_UNIMPLEMENTED;
158 }
159 }
160
161 // Eu cap check.
162 if (!RenderFormatSupportCheck(mcpySrc.OsRes, mcpyDst.OsRes) || // format check, implemented on Gen derivate class.
163 mcpySrc.bAuxSuface)
164 {
165 caps.engineRender = false;
166 }
167
168 if (!caps.engineVebox && !caps.engineBlt && !caps.engineRender)
169 {
170 return MOS_STATUS_INVALID_PARAMETER; // unsupport copy on each hw engine.
171 }
172
173 return MOS_STATUS_SUCCESS;
174 }
175
176 //!
177 //! \brief surface copy pre process.
178 //! \details pre process before doing surface copy.
179 //! \param none
180 //! \return MOS_STATUS
181 //! Return MOS_STATUS_SUCCESS if support, otherwise return unspoort.
182 //!
PreCheckCpCopy(MCPY_STATE_PARAMS src,MCPY_STATE_PARAMS dest,MCPY_METHOD preferMethod)183 MOS_STATUS MediaCopyBaseState::PreCheckCpCopy(
184 MCPY_STATE_PARAMS src, MCPY_STATE_PARAMS dest, MCPY_METHOD preferMethod)
185 {
186 if (preferMethod == MCPY_METHOD_POWERSAVING &&
187 (src.CpMode == MCPY_CPMODE_CP || dest.CpMode == MCPY_CPMODE_CP))
188 {
189 MCPY_ASSERTMESSAGE("BLT Copy with CP is not supported");
190 return MOS_STATUS_PLATFORM_NOT_SUPPORTED;
191 }
192
193 return MOS_STATUS_SUCCESS;
194 }
195
196 //!
197 //! \brief dispatch copy task if support.
198 //! \details dispatch copy task to HW engine (vebox, EU, Blt) based on customer and default.
199 //! \param src
200 //! [in] Pointer to source surface
201 //! \param dst
202 //! [in] Pointer to destination surface
203 //! \return MOS_STATUS
204 //! Return MOS_STATUS_SUCCESS if support, otherwise return unspoort.
205 //!
CopyEnigneSelect(MCPY_METHOD & preferMethod,MCPY_ENGINE & mcpyEngine,MCPY_ENGINE_CAPS & caps)206 MOS_STATUS MediaCopyBaseState::CopyEnigneSelect(MCPY_METHOD& preferMethod, MCPY_ENGINE& mcpyEngine, MCPY_ENGINE_CAPS& caps)
207 {
208 // driver should make sure there is at least one he can process copy even customer choice doesn't match caps.
209 switch (preferMethod)
210 {
211 case MCPY_METHOD_PERFORMANCE:
212 mcpyEngine = caps.engineRender?MCPY_ENGINE_RENDER:(caps.engineBlt ? MCPY_ENGINE_BLT : MCPY_ENGINE_VEBOX);
213 break;
214 case MCPY_METHOD_BALANCE:
215 mcpyEngine = caps.engineVebox?MCPY_ENGINE_VEBOX:(caps.engineBlt?MCPY_ENGINE_BLT:MCPY_ENGINE_RENDER);
216 break;
217 case MCPY_METHOD_POWERSAVING:
218 case MCPY_METHOD_DEFAULT:
219 mcpyEngine = caps.engineBlt?MCPY_ENGINE_BLT:(caps.engineVebox?MCPY_ENGINE_VEBOX:MCPY_ENGINE_RENDER);
220 break;
221 default:
222 break;
223 }
224 #if (_DEBUG || _RELEASE_INTERNAL)
225 if (MCPY_METHOD_PERFORMANCE == m_MCPYForceMode)
226 {
227 mcpyEngine = MCPY_ENGINE_RENDER;
228 }
229 else if (MCPY_METHOD_POWERSAVING == m_MCPYForceMode)
230 {
231 mcpyEngine = MCPY_ENGINE_BLT;
232 }
233 else if (MCPY_METHOD_BALANCE == m_MCPYForceMode)
234 {
235 mcpyEngine = MCPY_ENGINE_VEBOX;
236 }
237 else if (MCPY_METHOD_DEFAULT != m_MCPYForceMode)
238 {
239 return MOS_STATUS_INVALID_PARAMETER; // bypass copy engine, just let APP handle it.
240 }
241 #endif
242 return MOS_STATUS_SUCCESS;
243 }
244
GetMinRequiredSurfaceSizeInBytes(uint32_t pitch,uint32_t height,MOS_FORMAT format)245 uint32_t GetMinRequiredSurfaceSizeInBytes(uint32_t pitch, uint32_t height, MOS_FORMAT format)
246 {
247 uint32_t nBytes = 0;
248 switch (format)
249 {
250 case Format_NV12:
251 case Format_YV12:
252 case Format_I420:
253 case Format_P010:
254 case Format_P016:
255 nBytes = pitch * height + (pitch >> 1) * (height >> 1) + (pitch >> 1) * (height >> 1);
256 break;
257 case Format_RGBP:
258 case Format_BGRP:
259 nBytes = pitch * height + pitch * height + pitch * height;
260 break;
261 case Format_Y410:
262 case Format_Y416:
263 case Format_Y210:
264 case Format_Y216:
265 case Format_YUY2:
266 case Format_R5G6B5:
267 case Format_R8G8B8:
268 case Format_A8R8G8B8:
269 case Format_A8B8G8R8:
270 case Format_X8R8G8B8:
271 case Format_X8B8G8R8:
272 case Format_AYUV:
273 case Format_R10G10B10A2:
274 case Format_B10G10R10A2:
275 case Format_P8:
276 case Format_L8:
277 case Format_A8:
278 case Format_Y16U:
279 case Format_A16B16G16R16F:
280 case Format_A16R16G16B16F:
281 case Format_A16B16G16R16:
282 case Format_A16R16G16B16:
283 case Format_IRW0:
284 case Format_IRW1:
285 case Format_IRW2:
286 case Format_IRW3:
287 nBytes = pitch * height;
288 break;
289 default:
290 MCPY_ASSERTMESSAGE("Unsupported format!");
291 break;
292 }
293 return nBytes;
294 }
295
CheckResourceSizeValidForCopy(const MOS_SURFACE & res,const MCPY_ENGINE method)296 MOS_STATUS MediaCopyBaseState::CheckResourceSizeValidForCopy(const MOS_SURFACE &res, const MCPY_ENGINE method)
297 {
298 if (res.TileType != MOS_TILE_LINEAR)
299 {
300 return MOS_STATUS_SUCCESS;
301 }
302
303 uint32_t nBytes = GetMinRequiredSurfaceSizeInBytes(res.dwPitch, res.dwHeight, res.Format);
304 if (nBytes == 0)
305 {
306 return MOS_STATUS_INVALID_PARAMETER;
307 }
308 if (res.dwSize < nBytes)
309 {
310 MT_ERR2(MT_MEDIA_COPY,
311 MT_MEDIA_COPY_DATASIZE, nBytes,
312 MT_MEDIA_COPY_DATASIZE, res.dwSize);
313
314 return MOS_STATUS_INVALID_PARAMETER;
315 }
316
317 if (method == MCPY_ENGINE_BLT)
318 {
319 if (res.dwPitch > BLT_MAX_PITCH || res.dwHeight > BLT_MAX_HEIGHT || res.dwWidth > BLT_MAX_WIDTH)
320 {
321 MT_ERR3(MT_MEDIA_COPY,
322 MT_SURF_WIDTH, res.dwWidth,
323 MT_SURF_HEIGHT, res.dwHeight,
324 MT_SURF_PITCH, res.dwPitch);
325 MCPY_ASSERTMESSAGE("Surface size overflow! pitch %d, height %d, width %d", res.dwPitch, res.dwHeight, res.dwWidth);
326 return MOS_STATUS_INVALID_PARAMETER;
327 }
328 }
329
330 if (method == MCPY_ENGINE_RENDER)
331 {
332 if (res.dwHeight < RENDER_MIN_HEIGHT || res.dwWidth < RENDER_MIN_WIDTH)
333 {
334 MT_ERR2(MT_MEDIA_COPY,
335 MT_SURF_WIDTH, res.dwWidth,
336 MT_SURF_HEIGHT, res.dwHeight);
337 MCPY_ASSERTMESSAGE("Surface size not meet min requirement! height %d, width %d", res.dwHeight, res.dwWidth);
338 return MOS_STATUS_INVALID_PARAMETER;
339 }
340 }
341
342 if (method == MCPY_ENGINE_VEBOX)
343 {
344 #if (_DEBUG || _RELEASE_INTERNAL)
345 if (!m_enableVeCopySmallRes)
346 #endif
347 {
348 if (res.dwHeight < VE_MIN_HEIGHT || res.dwWidth < VE_MIN_WIDTH)
349 {
350 MT_ERR2(MT_MEDIA_COPY,
351 MT_SURF_WIDTH, res.dwWidth,
352 MT_SURF_HEIGHT, res.dwHeight);
353 MCPY_ASSERTMESSAGE("Surface size not meet min requirement! height %d, width %d", res.dwHeight, res.dwWidth);
354 return MOS_STATUS_INVALID_PARAMETER;
355 }
356 }
357 }
358
359 return MOS_STATUS_SUCCESS;
360 }
361
ValidateResource(const MOS_SURFACE & src,const MOS_SURFACE & dst,MCPY_ENGINE method)362 MOS_STATUS MediaCopyBaseState::ValidateResource(const MOS_SURFACE &src, const MOS_SURFACE &dst, MCPY_ENGINE method)
363 {
364 // For CP buffer copy, CP will handle the overflown size, skip size check
365 if (src.OsResource.pGmmResInfo->GetResourceType() == RESOURCE_BUFFER &&
366 dst.OsResource.pGmmResInfo->GetResourceType() == RESOURCE_BUFFER &&
367 method == MCPY_ENGINE_BLT)
368 {
369 return MOS_STATUS_SUCCESS;
370 }
371
372 MCPY_CHK_STATUS_RETURN(CheckResourceSizeValidForCopy(src, method));
373 MCPY_CHK_STATUS_RETURN(CheckResourceSizeValidForCopy(dst, method));
374
375 return MOS_STATUS_SUCCESS;
376 }
377
378 //!
379 //! \brief surface copy func.
380 //! \details copy surface.
381 //! \param src
382 //! [in] Pointer to source surface
383 //! \param dst
384 //! [in] Pointer to destination surface
385 //! \return MOS_STATUS
386 //! Return MOS_STATUS_SUCCESS if support, otherwise return unspoort.
387 //!
SurfaceCopy(PMOS_RESOURCE src,PMOS_RESOURCE dst,MCPY_METHOD preferMethod)388 MOS_STATUS MediaCopyBaseState::SurfaceCopy(PMOS_RESOURCE src, PMOS_RESOURCE dst, MCPY_METHOD preferMethod)
389 {
390 MOS_TraceEventExt(EVENT_MEDIA_COPY, EVENT_TYPE_START, nullptr, 0, nullptr, 0);
391 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
392
393 MOS_SURFACE SrcResDetails, DstResDetails;
394 MOS_ZeroMemory(&SrcResDetails, sizeof(MOS_SURFACE));
395 MOS_ZeroMemory(&DstResDetails, sizeof(MOS_SURFACE));
396 SrcResDetails.Format = Format_Invalid;
397 SrcResDetails.OsResource = *src;
398 DstResDetails.Format = Format_Invalid;
399 DstResDetails.OsResource = *dst;
400
401 MCPY_STATE_PARAMS mcpySrc = {nullptr, MOS_MMC_DISABLED, MOS_TILE_LINEAR, MCPY_CPMODE_CLEAR, false};
402 MCPY_STATE_PARAMS mcpyDst = {nullptr, MOS_MMC_DISABLED, MOS_TILE_LINEAR, MCPY_CPMODE_CLEAR, false};
403 MCPY_ENGINE mcpyEngine = MCPY_ENGINE_BLT;
404 MCPY_ENGINE_CAPS mcpyEngineCaps = {1, 1, 1, 1};
405
406 MCPY_CHK_STATUS_RETURN(m_osInterface->pfnGetResourceInfo(m_osInterface, src, &SrcResDetails));
407 MCPY_CHK_STATUS_RETURN(m_osInterface->pfnGetMemoryCompressionMode(m_osInterface, src, (PMOS_MEMCOMP_STATE)&(mcpySrc.CompressionMode)));
408 mcpySrc.CpMode = src->pGmmResInfo->GetSetCpSurfTag(false, 0)?MCPY_CPMODE_CP:MCPY_CPMODE_CLEAR;
409 mcpySrc.TileMode = SrcResDetails.TileType;
410 mcpySrc.OsRes = src;
411 MCPY_NORMALMESSAGE("input surface's format %d, width %d; hight %d, pitch %d, tiledmode %d, mmc mode %d, cp mode %d, ResType %d, preferMethod %d",
412 SrcResDetails.Format,
413 SrcResDetails.dwWidth,
414 SrcResDetails.dwHeight,
415 SrcResDetails.dwPitch,
416 mcpySrc.TileMode,
417 mcpySrc.CompressionMode,
418 mcpySrc.CpMode,
419 src->pGmmResInfo->GetResourceType(),
420 preferMethod);
421 MT_LOG7(MT_MEDIA_COPY, MT_NORMAL,
422 MT_SURF_PITCH, SrcResDetails.dwPitch,
423 MT_SURF_HEIGHT, SrcResDetails.dwHeight,
424 MT_SURF_WIDTH, SrcResDetails.dwWidth,
425 MT_SURF_MOS_FORMAT, SrcResDetails.Format,
426 MT_MEDIA_COPY_DATASIZE, SrcResDetails.dwSize,
427 MT_SURF_TILE_TYPE, SrcResDetails.TileType,
428 MT_SURF_COMP_MODE, mcpySrc.CompressionMode);
429
430 MCPY_CHK_STATUS_RETURN(m_osInterface->pfnGetResourceInfo(m_osInterface, dst, &DstResDetails));
431 MCPY_CHK_STATUS_RETURN(m_osInterface->pfnGetMemoryCompressionMode(m_osInterface,dst, (PMOS_MEMCOMP_STATE) &(mcpyDst.CompressionMode)));
432 mcpyDst.CpMode = dst->pGmmResInfo->GetSetCpSurfTag(false, 0)?MCPY_CPMODE_CP:MCPY_CPMODE_CLEAR;
433 mcpyDst.TileMode = DstResDetails.TileType;
434 mcpyDst.OsRes = dst;
435 MCPY_NORMALMESSAGE("Output surface's format %d, width %d; hight %d, pitch %d, tiledmode %d, mmc mode %d,cp mode %d, ResType %d",
436 DstResDetails.Format,
437 DstResDetails.dwWidth,
438 DstResDetails.dwHeight,
439 DstResDetails.dwPitch,
440 mcpyDst.TileMode,
441 mcpyDst.CompressionMode,
442 mcpyDst.CpMode,
443 dst->pGmmResInfo->GetResourceType());
444 MT_LOG7(MT_MEDIA_COPY, MT_NORMAL,
445 MT_SURF_PITCH, DstResDetails.dwPitch,
446 MT_SURF_HEIGHT, DstResDetails.dwHeight,
447 MT_SURF_WIDTH, DstResDetails.dwWidth,
448 MT_SURF_MOS_FORMAT, DstResDetails.Format,
449 MT_MEDIA_COPY_DATASIZE, DstResDetails.dwSize,
450 MT_SURF_TILE_TYPE, DstResDetails.TileType,
451 MT_SURF_COMP_MODE, mcpyDst.CompressionMode);
452
453 #if (_DEBUG || _RELEASE_INTERNAL) && !defined(LINUX)
454 TRACEDATA_MEDIACOPY eventData = {0};
455 TRACEDATA_MEDIACOPY_INIT(
456 eventData,
457 src->AllocationInfo.m_AllocationHandle,
458 SrcResDetails.dwWidth,
459 SrcResDetails.dwHeight,
460 SrcResDetails.Format,
461 *((int64_t *)&src->pGmmResInfo->GetResFlags().Gpu),
462 *((int64_t *)&src->pGmmResInfo->GetResFlags().Info),
463 src->pGmmResInfo->GetSetCpSurfTag(0, 0),
464 dst->AllocationInfo.m_AllocationHandle,
465 DstResDetails.dwWidth,
466 DstResDetails.dwHeight,
467 DstResDetails.Format,
468 *((int64_t *)&dst->pGmmResInfo->GetResFlags().Gpu),
469 *((int64_t *)&dst->pGmmResInfo->GetResFlags().Info),
470 dst->pGmmResInfo->GetSetCpSurfTag(0, 0)
471 );
472
473 MOS_TraceEventExt(EVENT_MEDIA_COPY, EVENT_TYPE_INFO, &eventData, sizeof(eventData), nullptr, 0);
474 #endif
475
476 MCPY_CHK_STATUS_RETURN(PreCheckCpCopy(mcpySrc, mcpyDst, preferMethod));
477
478 MCPY_CHK_STATUS_RETURN(CapabilityCheck(SrcResDetails.Format,
479 mcpySrc, mcpyDst,
480 mcpyEngineCaps, preferMethod));
481
482 CopyEnigneSelect(preferMethod, mcpyEngine, mcpyEngineCaps);
483
484 MCPY_CHK_STATUS_RETURN(ValidateResource(SrcResDetails, DstResDetails, mcpyEngine));
485
486 MCPY_CHK_STATUS_RETURN(TaskDispatch(mcpySrc, mcpyDst, mcpyEngine));
487
488 MOS_TraceEventExt(EVENT_MEDIA_COPY, EVENT_TYPE_END, nullptr, 0, nullptr, 0);
489 return eStatus;
490 }
491
TaskDispatch(MCPY_STATE_PARAMS mcpySrc,MCPY_STATE_PARAMS mcpyDst,MCPY_ENGINE mcpyEngine)492 MOS_STATUS MediaCopyBaseState::TaskDispatch(MCPY_STATE_PARAMS mcpySrc, MCPY_STATE_PARAMS mcpyDst, MCPY_ENGINE mcpyEngine)
493 {
494 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
495
496
497 #if (_DEBUG || _RELEASE_INTERNAL)
498 MOS_SURFACE sourceSurface = {};
499 MOS_SURFACE targetSurface = {};
500
501 targetSurface.Format = Format_Invalid;
502 targetSurface.OsResource = *mcpyDst.OsRes;
503
504 #if !defined(LINUX) && !defined(ANDROID) && !EMUL
505 MOS_ZeroMemory(&targetSurface.OsResource.AllocationInfo, sizeof(SResidencyInfo));
506 #endif
507
508 sourceSurface.Format = Format_Invalid;
509 sourceSurface.OsResource = *mcpySrc.OsRes;
510
511 m_osInterface->pfnGetResourceInfo(m_osInterface, &sourceSurface.OsResource, &sourceSurface);
512 m_osInterface->pfnGetResourceInfo(m_osInterface, &targetSurface.OsResource, &targetSurface);
513
514 // Set the dump location like "dumpLocation before MCPY=path_to_dump_folder" in user feature configure file
515 // Otherwise, the surface may not be dumped
516 // Only dump linear surface
517 if (m_surfaceDumper && mcpySrc.TileMode == MOS_TILE_LINEAR)
518 {
519 if ((*m_dumpLocation_in == '\0') || (*m_dumpLocation_in == ' '))
520 {
521 MCPY_NORMALMESSAGE("Invalid dump location set, the surface will not be dumped");
522 }
523 else
524 {
525 m_surfaceDumper->DumpSurfaceToFile(m_osInterface, &sourceSurface, m_dumpLocation_in, m_surfaceDumper->m_frameNum, true, false, nullptr);
526 }
527 }
528 #endif
529
530 MosUtilities::MosLockMutex(m_inUseGPUMutex);
531 switch(mcpyEngine)
532 {
533 case MCPY_ENGINE_VEBOX:
534 eStatus = MediaVeboxCopy(mcpySrc.OsRes, mcpyDst.OsRes);
535 break;
536 case MCPY_ENGINE_BLT:
537 if ((mcpyDst.TileMode != MOS_TILE_LINEAR) && (mcpyDst.CompressionMode == MOS_MMC_RC))
538 {
539 MCPY_NORMALMESSAGE("mmc on, mcpyDst.TileMode= %d, mcpyDst.CompressionMode = %d", mcpyDst.TileMode, mcpyDst.CompressionMode);
540 eStatus = m_osInterface->pfnDecompResource(m_osInterface, mcpyDst.OsRes);
541 if (MOS_STATUS_SUCCESS != eStatus)
542 {
543 MosUtilities::MosUnlockMutex(m_inUseGPUMutex);
544 MCPY_CHK_STATUS_RETURN(eStatus);
545 }
546 }
547 eStatus = MediaBltCopy(mcpySrc.OsRes, mcpyDst.OsRes);
548 break;
549 case MCPY_ENGINE_RENDER:
550 eStatus = MediaRenderCopy(mcpySrc.OsRes, mcpyDst.OsRes);
551 break;
552 default:
553 break;
554 }
555 MosUtilities::MosUnlockMutex(m_inUseGPUMutex);
556
557 #if (_DEBUG || _RELEASE_INTERNAL)
558 if (m_bRegReport)
559 {
560 std::string copyEngine = mcpyEngine ?(mcpyEngine == MCPY_ENGINE_BLT?"BLT":"Render"):"VeBox";
561 MediaUserSettingSharedPtr userSettingPtr = m_osInterface->pfnGetUserSettingInstance(m_osInterface);
562 ReportUserSettingForDebug(
563 userSettingPtr,
564 __MEDIA_USER_FEATURE_MCPY_MODE,
565 copyEngine,
566 MediaUserSetting::Group::Device);
567 }
568
569 // Set the dump location like "dumpLocation after MCPY=path_to_dump_folder" in user feature configure file
570 // Otherwise, the surface may not be dumped
571 // Only dump linear surface
572 if (m_surfaceDumper && mcpyDst.TileMode == MOS_TILE_LINEAR)
573 {
574 if ((*m_dumpLocation_out == '\0') || (*m_dumpLocation_out == ' '))
575 {
576 MCPY_NORMALMESSAGE("Invalid dump location set, the surface will not be dumped");
577 }
578 else
579 {
580 m_surfaceDumper->DumpSurfaceToFile(m_osInterface, &targetSurface, m_dumpLocation_out, m_surfaceDumper->m_frameNum, true, false, nullptr);
581 }
582 m_surfaceDumper->m_frameNum++;
583 }
584 #endif
585 MCPY_NORMALMESSAGE("Media Copy works on %s Engine", mcpyEngine ?(mcpyEngine == MCPY_ENGINE_BLT?"BLT":"Render"):"VeBox");
586
587 return eStatus;
588 }
589
590 //!
591 //! \brief aux surface copy.
592 //! \details copy surface.
593 //! \param src
594 //! [in] Pointer to source surface
595 //! \param dst
596 //! [in] Pointer to destination surface
597 //! \return MOS_STATUS
598 //! Return MOS_STATUS_SUCCESS if support, otherwise return unspoort.
599 //!
AuxCopy(PMOS_RESOURCE src,PMOS_RESOURCE dst)600 MOS_STATUS MediaCopyBaseState::AuxCopy(PMOS_RESOURCE src, PMOS_RESOURCE dst)
601 {
602 // only support form Gen12+, will implement on deriavete class.
603 MCPY_ASSERTMESSAGE("doesn't support");
604 return MOS_STATUS_INVALID_HANDLE;
605 }
606
GetMosInterface()607 PMOS_INTERFACE MediaCopyBaseState::GetMosInterface()
608 {
609 return m_osInterface;
610 }