xref: /aosp_15_r20/external/intel-media-driver/media_softlet/agnostic/common/shared/media_debug_dumper.cpp (revision ba62d9d3abf0e404f2022b4cd7a85e107f48596f)
1 /*
2 * Copyright (c) 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_debug_dumper.cpp
24 //! \brief    Implementation of functions for debugging
25 //! \details  This file contains the implementation of functions for
26 //!           surface dumper
27 //!
28 
29 #if (_DEBUG || _RELEASE_INTERNAL)
30 
31 #include <stdio.h>
32 #include "mos_os.h"
33 #include "mos_context_next.h"
34 #include "media_debug_dumper.h"
35 
36 #define COMMON_SURF_DUMP_OUTFILE_KEY_NAME        "outfileLocation"
37 #define COMMON_SURF_DUMP_LOCATION_KEY_NAME       "dumpLocations"
38 #define COMMON_SURF_DUMP_START_FRAME_KEY_NAME    "startFrame"
39 #define COMMON_SURF_DUMP_END_FRAME_KEY_NAME      "endFrame"
40 #define COMMON_SURF_DUMP_MAX_DATA_LEN            200
41 #define COMMON_SURF_DUMP_TYPE_BACKGROUND         "background"
42 #define COMMON_SURF_DUMP_TYPE_PRIMARY            "primary"
43 #define COMMON_SURF_DUMP_TYPE_SUBSTREAM          "substream"
44 #define COMMON_SURF_DUMP_TYPE_REFERENCE          "reference"
45 #define COMMON_SURF_DUMP_TYPE_RENDERTARGET       "rendertarget"
46 #define COMMON_SURF_DUMP_LOC_PREALL              "preall"
47 #define COMMON_SURF_DUMP_LOC_PREDNDI             "predndi"
48 #define COMMON_SURF_DUMP_LOC_POSTDNDI            "postdndi"
49 #define COMMON_SURF_DUMP_LOC_PRECOMP             "precomp"
50 #define COMMON_SURF_DUMP_LOC_POSTCOMP            "postcomp"
51 #define COMMON_SURF_DUMP_LOC_PREMEMDECOMP        "prememdecomp"
52 #define COMMON_SURF_DUMP_LOC_POSTMEMDECOMP       "postmemdecomp"
53 #define COMMON_SURF_DUMP_LOC_VEBOX_DRIVERHEAP    "veboxdriverheap"
54 #define COMMON_SURF_DUMP_LOC_VEBOX_KERNELHEAP    "veboxkernelheap"
55 #define COMMON_SURF_DUMP_LOC_POSTALL             "postall"
56 
CommonSurfaceDumper(PMOS_INTERFACE pOsInterface)57 CommonSurfaceDumper::CommonSurfaceDumper(PMOS_INTERFACE pOsInterface) :
58     m_osInterface(pOsInterface),
59     m_dumpSpec()
60 {
61     if (m_osInterface)
62     {
63         m_userSettingPtr = m_osInterface->pfnGetUserSettingInstance(m_osInterface);
64     }
65 }
66 
~CommonSurfaceDumper()67 CommonSurfaceDumper::~CommonSurfaceDumper()
68 {
69 }
70 
HasAuxSurf(PMOS_RESOURCE osResource)71 bool CommonSurfaceDumper::HasAuxSurf(
72     PMOS_RESOURCE    osResource)
73 {
74     MEDIA_DEBUG_FUNCTION_ENTER;
75 
76     bool    hasAuxSurf = false;
77 #if !EMUL
78     GMM_RESOURCE_FLAG                   gmmFlags;
79     MOS_ZeroMemory(&gmmFlags, sizeof(gmmFlags));
80     gmmFlags    = osResource->pGmmResInfo->GetResFlags();
81     hasAuxSurf  = (gmmFlags.Gpu.MMC && gmmFlags.Gpu.UnifiedAuxSurface) ||
82                   (gmmFlags.Gpu.CCS && gmmFlags.Gpu.UnifiedAuxSurface && gmmFlags.Info.MediaCompressed);
83 #endif
84     return hasAuxSurf;
85 }
86 
GetPlaneDefs(PMOS_SURFACE pSurface,COMMON_SURF_DUMP_SURFACE_DEF * pPlanes,uint32_t * pdwNumPlanes,uint32_t * pdwSize,bool auxEnable,bool isDeswizzled)87 MOS_STATUS CommonSurfaceDumper::GetPlaneDefs(
88     PMOS_SURFACE                  pSurface,
89     COMMON_SURF_DUMP_SURFACE_DEF* pPlanes,
90     uint32_t*                     pdwNumPlanes,
91     uint32_t*                     pdwSize,
92     bool                          auxEnable,
93     bool                          isDeswizzled)
94 {
95     MEDIA_DEBUG_FUNCTION_ENTER;
96 
97     MOS_STATUS      eStatus;
98     uint32_t        i;
99     bool            PaddingEnable = false;
100 
101     eStatus = MOS_STATUS_SUCCESS;
102 
103     // Caller should supply this much!
104     MOS_ZeroMemory(pPlanes, sizeof(COMMON_SURF_DUMP_SURFACE_DEF) * 3);
105 
106     switch (pSurface->Format)
107     {
108     case Format_AI44:
109     case Format_IA44:
110     case Format_A4L4:
111     case Format_P8:
112     case Format_L8:
113     case Format_A8:
114     case Format_Buffer:
115     case Format_STMM:
116     case Format_IRW4:
117     case Format_IRW5:
118     case Format_IRW6:
119     case Format_IRW7:
120     case Format_RAW:
121     case Format_Y8:
122         *pdwNumPlanes = 1;
123 
124         pPlanes[0].dwWidth = pSurface->dwWidth;
125         pPlanes[0].dwHeight = pSurface->dwHeight;
126         pPlanes[0].dwPitch = pSurface->dwPitch;
127         break;
128 
129     case Format_R5G6B5:
130     case Format_A8P8:
131     case Format_A8L8:
132     case Format_YUY2:
133     case Format_YUYV:
134     case Format_YVYU:
135     case Format_UYVY:
136     case Format_VYUY:
137     case Format_IRW0:
138     case Format_IRW1:
139     case Format_IRW2:
140     case Format_IRW3:
141     case Format_V8U8:
142     case Format_R16F:
143     case Format_Y16S:
144     case Format_Y16U:
145         *pdwNumPlanes = 1;
146 
147         pPlanes[0].dwWidth = pSurface->dwWidth * 2;
148         pPlanes[0].dwHeight = pSurface->dwHeight;
149         pPlanes[0].dwPitch = pSurface->dwPitch;
150         break;
151 
152     case Format_R32U:
153     case Format_R32F:
154     case Format_A8R8G8B8:
155     case Format_X8R8G8B8:
156     case Format_A8B8G8R8:
157     case Format_X8B8G8R8:
158     case Format_R8G8B8:
159     case Format_AYUV:
160     case Format_AUYV:
161     case Format_R10G10B10A2:
162     case Format_B10G10R10A2:
163     case Format_Y410:
164         *pdwNumPlanes = 1;
165 
166         pPlanes[0].dwWidth = pSurface->dwWidth * 4;
167         pPlanes[0].dwHeight = pSurface->dwHeight;
168         pPlanes[0].dwPitch = pSurface->dwPitch;
169         break;
170 
171     case Format_Y416:
172     case Format_A16B16G16R16:
173     case Format_A16R16G16B16:
174     case Format_A16B16G16R16F:
175     case Format_A16R16G16B16F:
176         *pdwNumPlanes = 1;
177 
178         pPlanes[0].dwWidth = pSurface->dwWidth * 8;
179         pPlanes[0].dwHeight = pSurface->dwHeight;
180         pPlanes[0].dwPitch = pSurface->dwPitch;
181         break;
182 
183     case Format_NV12:
184         *pdwNumPlanes = 2;
185 
186         pPlanes[0].dwWidth = pSurface->dwWidth;
187         pPlanes[0].dwHeight = pSurface->dwHeight;
188         pPlanes[0].dwPitch = pSurface->dwPitch;
189 
190         pPlanes[1].dwWidth = pPlanes[0].dwWidth;
191         pPlanes[1].dwHeight = pPlanes[0].dwHeight / 2;
192         pPlanes[1].dwPitch = pSurface->dwPitch;
193         break;
194 
195     case Format_P010:
196     case Format_P016:
197         *pdwNumPlanes = 2;
198 
199         pPlanes[0].dwWidth = pSurface->dwWidth * 2;
200         pPlanes[0].dwHeight = pSurface->dwHeight;
201         pPlanes[0].dwPitch = pSurface->dwPitch;
202 
203         pPlanes[1].dwWidth = pPlanes[0].dwWidth;
204         pPlanes[1].dwHeight = pPlanes[0].dwHeight / 2;
205         pPlanes[1].dwPitch = pSurface->dwPitch;
206         break;
207 
208     case Format_IMC2:
209     case Format_IMC4:
210         *pdwNumPlanes = 2;
211 
212         pPlanes[0].dwWidth = pSurface->dwWidth;
213         pPlanes[0].dwHeight = pSurface->dwHeight;
214         pPlanes[0].dwPitch = pSurface->dwPitch;
215 
216         pPlanes[1].dwWidth = pPlanes[0].dwWidth;
217         pPlanes[1].dwHeight = pPlanes[0].dwHeight / 2;
218         pPlanes[1].dwPitch = pPlanes[0].dwPitch;
219         break;
220 
221     case Format_YVU9:
222         *pdwNumPlanes = 3;
223 
224         pPlanes[0].dwWidth = pSurface->dwWidth;
225         pPlanes[0].dwHeight = pSurface->dwHeight;
226         pPlanes[0].dwPitch = pSurface->dwPitch;
227 
228         pPlanes[1].dwWidth = pPlanes[0].dwWidth / 4;
229         pPlanes[1].dwHeight = pPlanes[0].dwHeight / 4;
230         pPlanes[1].dwPitch = pPlanes[0].dwPitch;
231 
232         pPlanes[2].dwWidth = pPlanes[0].dwWidth / 4;
233         pPlanes[2].dwHeight = pPlanes[0].dwHeight / 4;
234         pPlanes[2].dwPitch = pPlanes[0].dwPitch;
235         break;
236 
237     case Format_IMC1:
238     case Format_IMC3:
239         *pdwNumPlanes = 3;
240 
241         pPlanes[0].dwWidth = pSurface->dwWidth;
242         pPlanes[0].dwHeight = pSurface->dwHeight;
243         pPlanes[0].dwPitch = pSurface->dwPitch;
244 
245         pPlanes[1].dwWidth = pPlanes[0].dwWidth / 2;
246         pPlanes[1].dwHeight = pPlanes[0].dwHeight / 2;
247         pPlanes[1].dwPitch = pPlanes[0].dwPitch;
248 
249         pPlanes[2].dwWidth = pPlanes[0].dwWidth / 2;
250         pPlanes[2].dwHeight = pPlanes[0].dwHeight / 2;
251         pPlanes[2].dwPitch = pPlanes[0].dwPitch;
252         break;
253 
254     case Format_I420:
255     case Format_IYUV:
256     case Format_YV12:
257         *pdwNumPlanes = 3;
258 
259         pPlanes[0].dwWidth = pSurface->dwWidth;
260         pPlanes[0].dwHeight = pSurface->dwHeight;
261         pPlanes[0].dwPitch = pSurface->dwPitch;
262 
263         pPlanes[1].dwWidth = pPlanes[0].dwWidth / 2;
264         pPlanes[1].dwHeight = pPlanes[0].dwHeight / 2;
265         pPlanes[1].dwPitch = pPlanes[0].dwPitch / 2;
266 
267         pPlanes[2].dwWidth = pPlanes[0].dwWidth / 2;
268         pPlanes[2].dwHeight = pPlanes[0].dwHeight / 2;
269         pPlanes[2].dwPitch = pPlanes[0].dwPitch / 2;
270         break;
271     case Format_400P:
272         *pdwNumPlanes = 1;
273 
274         pPlanes[0].dwWidth = pSurface->dwWidth;
275         pPlanes[0].dwHeight = pSurface->dwHeight;
276         pPlanes[0].dwPitch = pSurface->dwPitch;
277         break;
278 
279     case Format_411P:
280         *pdwNumPlanes = 3;
281 
282         pPlanes[0].dwWidth = pSurface->dwWidth;
283         pPlanes[0].dwHeight = pSurface->dwHeight;
284         pPlanes[0].dwPitch = pSurface->dwPitch;
285 
286         pPlanes[1].dwWidth = pPlanes[0].dwWidth / 4;
287         pPlanes[1].dwHeight = pPlanes[0].dwHeight;
288         pPlanes[1].dwPitch = pPlanes[0].dwPitch;
289 
290         pPlanes[2].dwWidth = pPlanes[0].dwWidth / 4;
291         pPlanes[2].dwHeight = pPlanes[0].dwHeight;
292         pPlanes[2].dwPitch = pPlanes[0].dwPitch;
293         break;
294 
295     case Format_411R:
296         *pdwNumPlanes = 3;
297 
298         pPlanes[0].dwWidth = pSurface->dwWidth;
299         pPlanes[0].dwHeight = pSurface->dwHeight;
300         pPlanes[0].dwPitch = pSurface->dwPitch;
301 
302         pPlanes[1].dwWidth = pPlanes[0].dwWidth;
303         pPlanes[1].dwHeight = pPlanes[0].dwHeight / 4;
304         pPlanes[1].dwPitch = pPlanes[0].dwPitch;
305 
306         pPlanes[2].dwWidth = pPlanes[0].dwWidth;
307         pPlanes[2].dwHeight = pPlanes[0].dwHeight / 4;
308         pPlanes[2].dwPitch = pPlanes[0].dwPitch;
309         break;
310 
311     case Format_422H:
312         *pdwNumPlanes = 3;
313 
314         pPlanes[0].dwWidth = pSurface->dwWidth;
315         pPlanes[0].dwHeight = pSurface->dwHeight;
316         pPlanes[0].dwPitch = pSurface->dwPitch;
317 
318         pPlanes[1].dwWidth = pPlanes[0].dwWidth / 2;
319         pPlanes[1].dwHeight = pPlanes[0].dwHeight;
320         pPlanes[1].dwPitch = pPlanes[0].dwPitch;
321 
322         pPlanes[2].dwWidth = pPlanes[0].dwWidth / 2;
323         pPlanes[2].dwHeight = pPlanes[0].dwHeight;
324         pPlanes[2].dwPitch = pPlanes[0].dwPitch;
325         break;
326 
327     case Format_422V:
328         *pdwNumPlanes = 3;
329 
330         pPlanes[0].dwWidth = pSurface->dwWidth;
331         pPlanes[0].dwHeight = pSurface->dwHeight;
332         pPlanes[0].dwPitch = pSurface->dwPitch;
333 
334         pPlanes[1].dwWidth = pPlanes[0].dwWidth;
335         pPlanes[1].dwHeight = pPlanes[0].dwHeight / 2;
336         pPlanes[1].dwPitch = pPlanes[0].dwPitch;
337 
338         pPlanes[2].dwWidth = pPlanes[0].dwWidth;
339         pPlanes[2].dwHeight = pPlanes[0].dwHeight / 2;
340         pPlanes[2].dwPitch = pPlanes[0].dwPitch;
341         break;
342 
343     case Format_444P:
344     case Format_RGBP:
345     case Format_BGRP:
346         *pdwNumPlanes = 3;
347 
348         pPlanes[0].dwWidth = pSurface->dwWidth;
349         pPlanes[0].dwHeight = pSurface->dwHeight;
350         pPlanes[0].dwPitch = pSurface->dwPitch;
351 
352         pPlanes[1].dwWidth = pPlanes[0].dwWidth;
353         pPlanes[1].dwHeight = pPlanes[0].dwHeight;
354         pPlanes[1].dwPitch = pPlanes[0].dwPitch;
355 
356         pPlanes[2].dwWidth = pPlanes[0].dwWidth;
357         pPlanes[2].dwHeight = pPlanes[0].dwHeight;
358         pPlanes[2].dwPitch = pPlanes[0].dwPitch;
359         break;
360 
361     case Format_Y210:
362     case Format_Y216:
363         *pdwNumPlanes = 1;
364 
365         pPlanes[0].dwWidth = pSurface->dwWidth * 4;
366         pPlanes[0].dwHeight = pSurface->dwHeight;
367         pPlanes[0].dwPitch = pSurface->dwPitch;
368         break;
369 
370     case Format_P210:
371     case Format_P216:
372         *pdwNumPlanes = 2;
373 
374         pPlanes[0].dwWidth = pSurface->dwWidth * 2;
375         pPlanes[0].dwHeight = pSurface->dwHeight;
376         pPlanes[0].dwPitch = pSurface->dwPitch;
377 
378         pPlanes[1].dwWidth = pSurface->dwWidth * 2;
379         pPlanes[1].dwHeight = pSurface->dwHeight;
380         pPlanes[1].dwPitch = pSurface->dwPitch;
381         break;
382 
383     default:
384         MEDIA_DEBUG_NORMALMESSAGE("Format '%d' not supported in current driver, using default 1 plane for dump", pSurface->Format);
385         *pdwNumPlanes = 1;
386 
387         pPlanes[0].dwWidth = pSurface->dwWidth;
388         pPlanes[0].dwHeight = pSurface->dwHeight;
389         pPlanes[0].dwPitch = pSurface->dwPitch;
390         break;
391     }
392 
393     // For Deswizzled surfaces, Mos_Specific_LockResource() already do the de-padding between Y and UV surf.
394     // so, don't use the info of U/V PlaneOffset, as the padding is already removed.
395     for (i = 0; i < *pdwNumPlanes; i++)
396     {
397         switch (i)
398         {
399         case 0:
400             pPlanes[i].dwOffset = pSurface->YPlaneOffset.iSurfaceOffset +
401                                   (pSurface->YPlaneOffset.iYOffset * pSurface->dwPitch) +
402                                   pSurface->YPlaneOffset.iXOffset;
403             break;
404         case 1:
405             if (pSurface->Format == Format_YV12)
406             {
407                 pPlanes[i].dwOffset = (isDeswizzled ? pPlanes[0].dwPitch * pPlanes[0].dwHeight + pPlanes[0].dwOffset : pSurface->VPlaneOffset.iSurfaceOffset) +
408                                       (pSurface->VPlaneOffset.iYOffset * pSurface->dwPitch) +
409                                       pSurface->VPlaneOffset.iXOffset;
410             }
411             else
412             {
413                 pPlanes[i].dwOffset = (isDeswizzled ? pPlanes[0].dwPitch * pPlanes[0].dwHeight + pPlanes[0].dwOffset : pSurface->UPlaneOffset.iSurfaceOffset) +
414                                       (pSurface->UPlaneOffset.iYOffset * pSurface->dwPitch) +
415                                       pSurface->UPlaneOffset.iXOffset;
416             }
417             break;
418         case 2:
419             if (pSurface->Format == Format_YV12)
420             {
421                 pPlanes[i].dwOffset = (isDeswizzled ? pPlanes[1].dwOffset + pPlanes[1].dwPitch * pPlanes[1].dwHeight : pSurface->UPlaneOffset.iSurfaceOffset) +
422                                       (pSurface->UPlaneOffset.iYOffset * pSurface->dwPitch) +
423                                       pSurface->UPlaneOffset.iXOffset;
424             }
425             else
426             {
427                 pPlanes[i].dwOffset = (isDeswizzled ? pPlanes[1].dwOffset + pPlanes[1].dwPitch * pPlanes[1].dwHeight : pSurface->VPlaneOffset.iSurfaceOffset) +
428                                       (pSurface->VPlaneOffset.iYOffset * pSurface->dwPitch) +
429                                       pSurface->VPlaneOffset.iXOffset;
430             }
431             break;
432         default:
433             MEDIA_DEBUG_ASSERTMESSAGE("More than 3 planes not supported.");
434             break;
435         }
436     }
437 
438     //compressed surface need 32 align on height
439     if (auxEnable && !isDeswizzled)
440     {
441         for (i = 0; i < *pdwNumPlanes; i++)
442         {
443             pPlanes[i].dwHeight = MOS_ALIGN_CEIL(pPlanes[i].dwHeight, 32);
444         }
445     }
446 
447     // For uncompressed surface, padding data is not needed. For compressed surface, padding data is needed for offline check
448     if (auxEnable)
449     {
450         *pdwSize = (pPlanes[0].dwPitch * pPlanes[0].dwHeight) +
451             (pPlanes[1].dwPitch * pPlanes[1].dwHeight) +
452             (pPlanes[2].dwPitch * pPlanes[2].dwHeight);
453     }
454     else
455     {
456         *pdwSize = (pPlanes[0].dwWidth * pPlanes[0].dwHeight) +
457             (pPlanes[1].dwWidth * pPlanes[1].dwHeight) +
458             (pPlanes[2].dwWidth * pPlanes[2].dwHeight);
459     }
460 
461     return eStatus;
462 }
463 
WhitespaceTrim(char * ptr)464 char* CommonSurfaceDumper::WhitespaceTrim(
465     char*   ptr)
466 {
467     MEDIA_DEBUG_FUNCTION_ENTER;
468 
469     char*    pcTemp;                             // pointer to temp string to remove spces
470 
471     if (ptr == nullptr)
472     {
473         MEDIA_DEBUG_ASSERTMESSAGE("ptr value = \"%s\".", ptr);
474         return nullptr;
475     }
476 
477     if ((strlen(ptr) == 1) && (*ptr != '\0'))
478     {
479         MEDIA_DEBUG_ASSERTMESSAGE("Single character is not supported.");
480         *ptr = '\0';
481     }
482 
483     if (strlen(ptr) == 0)
484     {
485         return ptr;
486     }
487 
488     // Remove left spaces
489     while (*ptr == ' ' || *ptr == '\t')
490     {
491         ptr++;
492     }
493 
494     // Remove right spaces
495     pcTemp = ptr + strlen(ptr)-1;
496     while (*pcTemp == ' ' || *pcTemp == '\t')
497     {
498         pcTemp--;
499     }
500     *(++pcTemp) = '\0';
501 
502     return ptr;
503 }
504 
SurfTypeStringToEnum(char * pcSurfType,COMMON_SURFACE_TYPE * pSurfType)505 MOS_STATUS CommonSurfaceDumper::SurfTypeStringToEnum(
506     char*                         pcSurfType,
507     COMMON_SURFACE_TYPE            *pSurfType)
508 {
509     MEDIA_DEBUG_FUNCTION_ENTER;
510 
511     MOS_STATUS eStatus;
512 
513     eStatus = MOS_STATUS_SUCCESS;
514 
515     CommonDumperTool::StringToLower(pcSurfType);
516     if (strcmp(pcSurfType,      COMMON_SURF_DUMP_TYPE_BACKGROUND)   == 0)
517     {
518         *pSurfType = COMMON_SURF_IN_BACKGROUND;
519     }
520     else if (strcmp(pcSurfType, COMMON_SURF_DUMP_TYPE_PRIMARY)      == 0)
521     {
522         *pSurfType = COMMON_SURF_IN_PRIMARY;
523     }
524     else if (strcmp(pcSurfType, COMMON_SURF_DUMP_TYPE_SUBSTREAM)    == 0)
525     {
526         *pSurfType = COMMON_SURF_IN_SUBSTREAM;
527     }
528     else if (strcmp(pcSurfType, COMMON_SURF_DUMP_TYPE_REFERENCE)    == 0)
529     {
530         *pSurfType = COMMON_SURF_IN_REFERENCE;
531     }
532     else if (strcmp(pcSurfType, COMMON_SURF_DUMP_TYPE_RENDERTARGET) == 0)
533     {
534         *pSurfType = COMMON_SURF_OUT_RENDERTARGET;
535     }
536     else
537     {
538         MEDIA_DEBUG_ASSERTMESSAGE("Unknown surface type \"%s\".", pcSurfType);
539         eStatus = MOS_STATUS_UNKNOWN;
540         return eStatus;
541     }
542 
543     return eStatus;
544 }
545 
LocStringToEnum(char * pcLocString,uint32_t * pLocation)546 MOS_STATUS CommonSurfaceDumper::LocStringToEnum(
547     char*                           pcLocString,
548     uint32_t                        *pLocation)
549 {
550     MEDIA_DEBUG_FUNCTION_ENTER;
551 
552     MOS_STATUS eStatus;
553 
554     eStatus = MOS_STATUS_SUCCESS;
555 
556     CommonDumperTool::StringToLower(pcLocString);
557     if (strcmp(pcLocString,      COMMON_SURF_DUMP_LOC_PREALL)   == 0)
558     {
559         *pLocation = COMMON_DUMP_TYPE_PRE_ALL;
560     }
561     else if (strcmp(pcLocString, COMMON_SURF_DUMP_LOC_PREDNDI)  == 0)
562     {
563         *pLocation = COMMON_DUMP_TYPE_PRE_DNDI;
564     }
565     else if (strcmp(pcLocString, COMMON_SURF_DUMP_LOC_POSTDNDI) == 0)
566     {
567         *pLocation = COMMON_DUMP_TYPE_POST_DNDI;
568     }
569     else if (strcmp(pcLocString, COMMON_SURF_DUMP_LOC_PRECOMP)  == 0)
570     {
571         *pLocation = COMMON_DUMP_TYPE_PRE_COMP;
572     }
573     else if (strcmp(pcLocString, COMMON_SURF_DUMP_LOC_POSTCOMP) == 0)
574     {
575         *pLocation = COMMON_DUMP_TYPE_POST_COMP;
576     }
577     else if (strcmp(pcLocString, COMMON_SURF_DUMP_LOC_PREMEMDECOMP) == 0)
578     {
579         *pLocation = COMMON_DUMP_TYPE_PRE_MEMDECOMP;
580     }
581     else if (strcmp(pcLocString, COMMON_SURF_DUMP_LOC_POSTMEMDECOMP) == 0)
582     {
583         *pLocation = COMMON_DUMP_TYPE_POST_MEMDECOMP;
584     }
585     else if (strcmp(pcLocString, COMMON_SURF_DUMP_LOC_POSTALL)  == 0)
586     {
587         *pLocation = COMMON_DUMP_TYPE_POST_ALL;
588     }
589     else if (strcmp(pcLocString, COMMON_SURF_DUMP_LOC_VEBOX_DRIVERHEAP) == 0)
590     {
591         *pLocation = COMMON_DUMP_TYPE_VEBOX_DRIVERHEAP;
592     }
593     else if (strcmp(pcLocString, COMMON_SURF_DUMP_LOC_VEBOX_KERNELHEAP) == 0)
594     {
595         *pLocation = COMMON_DUMP_TYPE_VEBOX_KERNELHEAP;
596     }
597     else
598     {
599         MEDIA_DEBUG_NORMALMESSAGE("Unknown dump location \"%s\".", pcLocString);
600         eStatus = MOS_STATUS_UNKNOWN;
601         return eStatus;
602     }
603 
604     return eStatus;
605 }
606 
ProcessDumpLocations(char * pcDumpLocData)607 MOS_STATUS CommonSurfaceDumper::ProcessDumpLocations(
608     char*                      pcDumpLocData)
609 {
610     MEDIA_DEBUG_FUNCTION_ENTER;
611 
612     MOS_STATUS  eStatus;
613     char*       pcCommaLoc;                                                        // pointer to next comma in dump location string
614     char*       pcCurrToken;                                                       // pointer to current token in a string
615     char*       pcColonLoc;                                                        // pointer to next colon in location string
616     int32_t     iNumStrings;                                                       // number of dump locations
617     int32_t     i;                                                                 // loop iteration counter
618     COMMON_SURF_DUMP_SPEC    *pDumpSpec = &m_dumpSpec;
619 
620     eStatus      = MOS_STATUS_SUCCESS;
621     iNumStrings  = 0;
622 
623     if (strlen(pcDumpLocData) > 0)
624     {
625         // Count number of strings in key data
626         // If non empty string, there is at least one value
627         iNumStrings++;
628         // Count the rest
629         pcCommaLoc = pcDumpLocData;
630         while ((pcCommaLoc = strchr(pcCommaLoc + 1, ',')) != nullptr)
631         {
632             iNumStrings++;
633         }
634 
635         // Set number of strings and allocate space for them
636         pDumpSpec->iNumDumpLocs = iNumStrings;
637         pDumpSpec->pDumpLocations = (COMMON_SURF_DUMP_LOC*)MOS_AllocAndZeroMemory(
638                     sizeof(COMMON_SURF_DUMP_LOC) * pDumpSpec->iNumDumpLocs);
639         pcCurrToken = pcDumpLocData;
640 
641         // Determine each part of the string
642         for (i = 0; i < pDumpSpec->iNumDumpLocs; i++)
643         {
644             pcCommaLoc = strchr(pcCurrToken, ',');
645             if (pcCommaLoc != nullptr)
646             {
647                 *pcCommaLoc = '\0';
648             }
649 
650             // Handle surface type
651             pcColonLoc = strchr(pcCurrToken, ':');
652             if (pcColonLoc == nullptr)
653             {
654                 // Dump all
655                 pDumpSpec->pDumpLocations[i].SurfType = COMMON_SURF_NONE;
656             }
657             else
658             {
659                 // Remove surface type from dump location
660                 *pcColonLoc = '\0';
661                 // Set surface type
662                 pcColonLoc++;
663 
664                 pcColonLoc = WhitespaceTrim(pcColonLoc);
665             }
666 
667             //trim the whitespaces from dump location
668             pcCurrToken = WhitespaceTrim(pcCurrToken);
669         } // end for each part of the string
670     } // if data length > 0
671 
672     return eStatus;
673 }
674 
675 // Get dump location
GetSurfaceDumpLocation(char * dumpLoc,MCPY_DIRECTION mcpyDirection)676 MOS_STATUS CommonSurfaceDumper::GetSurfaceDumpLocation(
677     char* dumpLoc,
678     MCPY_DIRECTION mcpyDirection)
679 {
680     MediaUserSetting::Value        outValue;
681 
682     MEDIA_DEBUG_FUNCTION_ENTER;
683 
684     // Get dump location
685     outValue = "";
686 
687     if (mcpyDirection == mcpy_in)
688     {
689         ReadUserSettingForDebug(
690             m_userSettingPtr,
691             outValue,
692             __COMMON_DBG_SURF_DUMP_LOCATION_KEY_NAME_IN,
693             MediaUserSetting::Group::Device);
694     }
695     else
696     {
697         ReadUserSettingForDebug(
698             m_userSettingPtr,
699             outValue,
700             __COMMON_DBG_SURF_DUMP_LOCATION_KEY_NAME_OUT,
701             MediaUserSetting::Group::Device);
702     }
703 
704 #if !defined(LINUX) && !defined(ANDROID)
705     strcpy_s(dumpLoc, MAX_PATH, outValue.ConstString().c_str());
706 #else
707     strcpy(dumpLoc, outValue.ConstString().c_str());
708 #endif
709 
710     return MOS_STATUS_SUCCESS;
711 }
712 
ReAllocateSurface(PMOS_INTERFACE pOsInterface,PMOS_SURFACE pSurface,PMOS_SURFACE pSrcSurf,PCCHAR pSurfaceName,MOS_GFXRES_TYPE defaultResType,bool useLinearResource)713 MOS_STATUS CommonSurfaceDumper::ReAllocateSurface(
714     PMOS_INTERFACE  pOsInterface,
715     PMOS_SURFACE    pSurface,
716     PMOS_SURFACE    pSrcSurf,
717     PCCHAR          pSurfaceName,
718     MOS_GFXRES_TYPE defaultResType,
719     bool            useLinearResource)
720 {
721     MOS_ALLOC_GFXRES_PARAMS allocParams;
722 
723     MEDIA_DEBUG_CHK_NULL(pOsInterface);
724     MEDIA_DEBUG_CHK_NULL(pSrcSurf);
725     MEDIA_DEBUG_CHK_NULL(pSurface);
726     MEDIA_DEBUG_CHK_NULL(&pSurface->OsResource);
727 
728     // bCompressible should be compared with bCompressible since it is inited by bCompressible in previous call
729     // TileType of surface should be compared since we need to reallocate surface if TileType changes
730     if (!Mos_ResourceIsNull(&pSurface->OsResource) &&
731         (pSurface->dwWidth == pSrcSurf->dwWidth) &&
732         (pSurface->dwHeight == pSrcSurf->dwHeight) &&
733         (pSurface->Format == pSrcSurf->Format) &&
734         ((pSurface->bCompressible == pSrcSurf->bCompressible) || useLinearResource) && // omit this check as linear surface is uncompressible
735         (pSurface->CompressionMode == pSrcSurf->CompressionMode) &&
736         ((pSurface->TileType == pSrcSurf->TileType) ||
737          (pSurface->TileType == MOS_TILE_LINEAR && useLinearResource))) // when useLinearResource no reallocation needed
738     {
739         MEDIA_DEBUG_NORMALMESSAGE("Skip to reallocate temp surface.");
740         return MOS_STATUS_SUCCESS;
741     }
742     MOS_ZeroMemory(&allocParams, sizeof(MOS_ALLOC_GFXRES_PARAMS));
743 
744 #if !EMUL
745     //  Need to reallocate surface according to expected tiletype instead of tiletype of the surface what we have
746     if ((pSurface->OsResource.pGmmResInfo != nullptr) &&
747         (pSurface->TileType == pSrcSurf->TileType))
748     {
749         // Reallocate but use same tile type and resource type as current
750         allocParams.TileType = pSurface->OsResource.TileType;
751         allocParams.Type     = defaultResType;
752     }
753     else
754 #endif
755     {
756         // First time allocation. Caller must specify default params
757         allocParams.TileType = pSrcSurf->TileType;
758         allocParams.Type     = defaultResType;
759     }
760 
761     // Force to use tile linear for reallocated resource
762     if (useLinearResource)
763     {
764         allocParams.TileType = MOS_TILE_LINEAR;
765         allocParams.Type = MOS_GFXRES_2D;
766     }
767 
768     allocParams.dwWidth         = pSrcSurf->dwWidth;
769     allocParams.dwHeight        = pSrcSurf->dwHeight;
770     allocParams.Format          = pSrcSurf->Format;
771     allocParams.bIsCompressible = pSrcSurf->bCompressible;
772     allocParams.CompressionMode = pSrcSurf->CompressionMode;
773     allocParams.pBufName        = pSurfaceName;
774     allocParams.dwArraySize     = 1;
775 
776     // Delete resource if already allocated
777     pOsInterface->pfnFreeResource(pOsInterface, &(pSurface->OsResource));
778 
779     // Allocate surface
780     MEDIA_DEBUG_CHK_STATUS(pOsInterface->pfnAllocateResource(
781         pOsInterface,
782         &allocParams,
783         &pSurface->OsResource));
784 
785     pSurface->dwWidth         = pSrcSurf->dwWidth;
786     pSurface->dwHeight        = pSrcSurf->dwHeight;
787     pSurface->dwPitch         = pSrcSurf->dwPitch;
788     pSurface->dwDepth         = pSrcSurf->dwDepth;
789     pSurface->dwQPitch        = pSrcSurf->dwQPitch;
790     pSurface->bArraySpacing   = pSrcSurf->bArraySpacing;
791     pSurface->bCompressible   = pSrcSurf->bCompressible;
792     pSurface->CompressionMode = pSrcSurf->CompressionMode;
793     pSurface->bIsCompressed   = pSrcSurf->bIsCompressed;
794 
795     if (!pOsInterface->apoMosEnabled && !pOsInterface->apoMosForLegacyRuntime)
796     {
797         MOS_SURFACE details;
798         MOS_ZeroMemory(&details, sizeof(details));
799         details.Format = Format_Invalid;
800 
801         MEDIA_DEBUG_CHK_STATUS(pOsInterface->pfnGetResourceInfo(pOsInterface, &pSurface->OsResource, &details));
802 
803         pSurface->Format                      = details.Format;
804         pSurface->TileType                    = details.TileType;
805         pSurface->dwOffset                    = details.RenderOffset.YUV.Y.BaseOffset;
806         pSurface->YPlaneOffset.iSurfaceOffset = details.RenderOffset.YUV.Y.BaseOffset;
807         pSurface->YPlaneOffset.iXOffset       = details.RenderOffset.YUV.Y.XOffset;
808         pSurface->YPlaneOffset.iYOffset =
809             (pSurface->YPlaneOffset.iSurfaceOffset - pSurface->dwOffset) / pSurface->dwPitch +
810             details.RenderOffset.YUV.Y.YOffset;
811         pSurface->UPlaneOffset.iSurfaceOffset = details.RenderOffset.YUV.U.BaseOffset;
812         pSurface->UPlaneOffset.iXOffset       = details.RenderOffset.YUV.U.XOffset;
813         pSurface->UPlaneOffset.iYOffset =
814             (pSurface->UPlaneOffset.iSurfaceOffset - pSurface->dwOffset) / pSurface->dwPitch +
815             details.RenderOffset.YUV.U.YOffset;
816         pSurface->UPlaneOffset.iLockSurfaceOffset = details.LockOffset.YUV.U;
817         pSurface->VPlaneOffset.iSurfaceOffset     = details.RenderOffset.YUV.V.BaseOffset;
818         pSurface->VPlaneOffset.iXOffset           = details.RenderOffset.YUV.V.XOffset;
819         pSurface->VPlaneOffset.iYOffset =
820             (pSurface->VPlaneOffset.iSurfaceOffset - pSurface->dwOffset) / pSurface->dwPitch +
821             details.RenderOffset.YUV.V.YOffset;
822         pSurface->VPlaneOffset.iLockSurfaceOffset = details.LockOffset.YUV.V;
823     }
824     else
825     {
826         pSurface->Format = Format_Invalid;
827         MEDIA_DEBUG_CHK_STATUS(pOsInterface->pfnGetResourceInfo(pOsInterface, &pSurface->OsResource, pSurface));
828     }
829 
830     return MOS_STATUS_SUCCESS;
831 }
832 
IsSyncFreeNeededForMMCSurface(PMOS_INTERFACE osInterface,PMOS_SURFACE surface)833 bool CommonSurfaceDumper::IsSyncFreeNeededForMMCSurface(
834     PMOS_INTERFACE  osInterface,
835     PMOS_SURFACE    surface)
836 {
837     if (nullptr == osInterface || nullptr == surface)
838     {
839         return false;
840     }
841 
842     //Compressed surface aux table update is after resource dealloction, aux table update need wait the WLs complete
843     //the sync deallocation flag will make sure deallocation API return after all surface related WL been completed and resource been destroyed by OS
844     auto *pSkuTable = osInterface->pfnGetSkuTable(osInterface);
845     if (pSkuTable &&
846         MEDIA_IS_SKU(pSkuTable, FtrE2ECompression) &&                                    //Compression enabled platform
847         !MEDIA_IS_SKU(pSkuTable, FtrFlatPhysCCS) &&                                      //NOT DGPU compression
848         ((surface->bCompressible) && (surface->CompressionMode != MOS_MMC_DISABLED)))  //Compressed enabled surface
849     {
850         return true;
851     }
852 
853     return false;
854 }
855 
DumpSurfaceToFileEnd(PMOS_INTERFACE pOsInterface,uint8_t * pDst,bool isSurfaceLocked,PMOS_RESOURCE pLockedResource,PMOS_SURFACE pSurface)856 MOS_STATUS CommonSurfaceDumper::DumpSurfaceToFileEnd(
857     PMOS_INTERFACE  pOsInterface,
858     uint8_t        *pDst,
859     bool            isSurfaceLocked,
860     PMOS_RESOURCE   pLockedResource,
861     PMOS_SURFACE    pSurface)
862 {
863     MOS_STATUS eStatus;
864     eStatus = MOS_STATUS_SUCCESS;
865 
866     MOS_SafeFreeMemory(pDst);
867 
868     if (isSurfaceLocked && pLockedResource != nullptr)
869     {
870         eStatus = (MOS_STATUS)pOsInterface->pfnUnlockResource(pOsInterface, pLockedResource);
871         if (eStatus != MOS_STATUS_SUCCESS)
872         {
873             return eStatus;
874         }
875     }
876 
877     if (pSurface)
878     {
879         MOS_GFXRES_FREE_FLAGS resFreeFlags = {0};
880         if (IsSyncFreeNeededForMMCSurface(pOsInterface, pSurface))
881         {
882             resFreeFlags.SynchronousDestroy = 1;
883         }
884         pOsInterface->pfnFreeResourceWithFlag(pOsInterface, &(pSurface->OsResource), resFreeFlags.Value);
885     }
886     MOS_SafeFreeMemory(pSurface);
887 
888     return eStatus;
889 }
890 
DumpSurfaceToFile(PMOS_INTERFACE pOsInterface,PMOS_SURFACE pSurface,char * psPathPrefix,uint64_t iCounter,bool bLockSurface,bool bNoDecompWhenLock,uint8_t * pData)891 MOS_STATUS CommonSurfaceDumper::DumpSurfaceToFile(
892     PMOS_INTERFACE              pOsInterface,
893     PMOS_SURFACE                pSurface,
894     char                       *psPathPrefix,
895     uint64_t                    iCounter,
896     bool                        bLockSurface,
897     bool                        bNoDecompWhenLock,
898     uint8_t*                    pData)
899 {
900     MEDIA_DEBUG_FUNCTION_ENTER;
901 
902     MOS_STATUS                          eStatus;
903     bool                                isSurfaceLocked;
904     char                                sPath[MAX_PATH], sOsPath[MAX_PATH];
905     uint8_t                            *pDst, *pTmpSrc, *pTmpDst;
906     uint32_t                            dwNumPlanes, dwSize, j, i;
907     COMMON_SURF_DUMP_SURFACE_DEF        planes[3];
908     uint32_t                            dstPlaneOffset[3] = {0};
909     MOS_LOCK_PARAMS                     LockFlags;
910     MOS_USER_FEATURE_VALUE_WRITE_DATA   UserFeatureWriteData;
911     bool                                hasAuxSurf;
912     bool                                enableAuxDump;
913     bool                                enablePlaneDump   = false;
914     PMOS_RESOURCE                       pLockedResource   = nullptr;
915     PMOS_SURFACE                        temp2DSurfForCopy = nullptr;
916 
917     MEDIA_DEBUG_CHK_NULL(pSurface);
918     MEDIA_DEBUG_CHK_NULL(pOsInterface);
919     MEDIA_DEBUG_CHK_NULL(psPathPrefix);
920 
921     eStatus         = MOS_STATUS_SUCCESS;
922     isSurfaceLocked = false;
923     hasAuxSurf      = false;
924     pDst            = nullptr;
925     enableAuxDump   = m_dumpSpec.enableAuxDump;
926     MOS_ZeroMemory(sPath,   MAX_PATH);
927     MOS_ZeroMemory(sOsPath, MAX_PATH);
928     dwNumPlanes     = 0;
929     enablePlaneDump = m_dumpSpec.enablePlaneDump;
930 
931     if (pSurface->dwDepth == 0)
932     {
933         pSurface->dwDepth = 1;
934     }
935 
936     hasAuxSurf = HasAuxSurf(&pSurface->OsResource);
937 
938     // get plane definitions
939     MEDIA_DEBUG_CHK_STATUS(GetPlaneDefs(
940         pSurface,
941         planes,
942         &dwNumPlanes,
943         &dwSize,
944         hasAuxSurf, //(hasAuxSurf && enableAuxDump),
945         !enableAuxDump));// !(hasAuxSurf && enableAuxDump)));
946 
947     if (bLockSurface)
948     {
949         // Caller should not give pData when it expect the function to lock surf
950         pData = nullptr;
951 
952         LockFlags.Value     = 0;
953         LockFlags.ReadOnly  = 1;
954 
955         // If aux data exist and enable aux dump, no swizzle and no decompress
956         if (hasAuxSurf && enableAuxDump)
957         {
958             LockFlags.TiledAsTiled = 1;
959             LockFlags.NoDecompress = 1;
960         }
961 
962         if (bNoDecompWhenLock)
963         {
964             LockFlags.NoDecompress = 1;
965         }
966 
967         bool isPlanar = false;
968         isPlanar      = (pSurface->Format == Format_NV12) || (pSurface->Format == Format_P010) || (pSurface->Format == Format_P016);
969         if (isPlanar && pSurface->TileType != MOS_TILE_LINEAR)
970         {
971             temp2DSurfForCopy = (PMOS_SURFACE)MOS_AllocAndZeroMemory(sizeof(MOS_SURFACE));
972             MEDIA_DEBUG_CHK_NULL(temp2DSurfForCopy);
973 
974             MEDIA_DEBUG_CHK_STATUS(ReAllocateSurface(
975                 m_osInterface,
976                 temp2DSurfForCopy,
977                 pSurface,
978                 "Temp2DSurfForSurfDumper",
979                 MOS_GFXRES_2D,
980                 1));
981 
982             m_osInterface->pfnDoubleBufferCopyResource(
983                 m_osInterface,
984                 &pSurface->OsResource,
985                 &temp2DSurfForCopy->OsResource,
986                 false);
987 
988             pData = (uint8_t *)pOsInterface->pfnLockResource(
989                 pOsInterface,
990                 &temp2DSurfForCopy->OsResource,
991                 &LockFlags);
992 
993             pLockedResource = &temp2DSurfForCopy->OsResource;
994 
995             // get plane definitions
996             eStatus = GetPlaneDefs(
997                 temp2DSurfForCopy,
998                 planes,
999                 &dwNumPlanes,
1000                 &dwSize,
1001                 hasAuxSurf,        //(hasAuxSurf && enableAuxDump),
1002                 !enableAuxDump);   // !(hasAuxSurf && enableAuxDump)));
1003             if (eStatus != MOS_STATUS_SUCCESS)
1004             {
1005                 return(DumpSurfaceToFileEnd(
1006                     pOsInterface,
1007                     pDst,
1008                     isSurfaceLocked,
1009                     pLockedResource,
1010                     temp2DSurfForCopy));
1011             }
1012         }
1013         else
1014         {
1015             pData = (uint8_t *)pOsInterface->pfnLockResource(
1016                 pOsInterface,
1017                 &pSurface->OsResource,
1018                 &LockFlags);
1019             pLockedResource = &pSurface->OsResource;
1020         }
1021 
1022         if (nullptr == pData)
1023         {
1024             return(DumpSurfaceToFileEnd(
1025                 pOsInterface,
1026                 pDst,
1027                 isSurfaceLocked,
1028                 pLockedResource,
1029                 temp2DSurfForCopy));
1030         }
1031 
1032         isSurfaceLocked = true;
1033 
1034         // Write error to user feauture key
1035         eStatus = ReportUserSettingForDebug(
1036             m_userSettingPtr,
1037             __COMMON_DBG_SURF_DUMPER_RESOURCE_LOCK,
1038             1,
1039             MediaUserSetting::Group::Device);
1040 
1041         if (eStatus != MOS_STATUS_SUCCESS)
1042         {
1043             return(DumpSurfaceToFileEnd(
1044                 pOsInterface,
1045                 pDst,
1046                 isSurfaceLocked,
1047                 pLockedResource,
1048                 temp2DSurfForCopy));
1049         }
1050     }
1051 
1052     MOS_SecureStringPrint(
1053         sPath,
1054         MAX_PATH,
1055         sizeof(sPath),
1056         "%s_f[%04lld]_w[%d]_h[%d]_p[%d].%s",
1057         psPathPrefix,
1058         iCounter,
1059         pSurface->dwWidth,
1060         pSurface->dwHeight,
1061         pSurface->dwPitch,
1062         CommonDumperTool::GetFormatStr(pSurface->Format));
1063 
1064     CommonDumperTool::GetOsFilePath(sPath, sOsPath);
1065 
1066     pDst = (uint8_t*)MOS_AllocAndZeroMemory(dwSize);
1067 
1068     if ((nullptr == pDst) || (nullptr == pData))
1069     {
1070         return(DumpSurfaceToFileEnd(
1071             pOsInterface,
1072             pDst,
1073             isSurfaceLocked,
1074             pLockedResource,
1075             temp2DSurfForCopy));
1076     }
1077     pTmpSrc = pData;
1078     pTmpDst = pDst;
1079 
1080     for (j = 0; j < dwNumPlanes; j++)
1081     {
1082         for (i = 0; i < planes[j].dwHeight; i++)
1083         {
1084             if (hasAuxSurf && enableAuxDump)
1085             {
1086                 MOS_SecureMemcpy(
1087                     pTmpDst,
1088                     planes[j].dwPitch,
1089                     pTmpSrc,
1090                     planes[j].dwPitch);
1091 
1092                 pTmpSrc += planes[j].dwPitch;
1093                 pTmpDst += planes[j].dwPitch;
1094 
1095                 dstPlaneOffset[j+1] += planes[j].dwPitch;
1096             }
1097             else
1098             {
1099                 MOS_SecureMemcpy(
1100                     pTmpDst,
1101                     planes[j].dwWidth,
1102                     pTmpSrc,
1103                     planes[j].dwWidth);
1104 
1105                 pTmpSrc += planes[j].dwPitch;
1106                 pTmpDst += planes[j].dwWidth;
1107 
1108                 dstPlaneOffset[j+1] += planes[j].dwWidth;
1109             }
1110         }
1111 
1112         //if more than 1 plane, dump each plane's surface for offline analysis
1113         if (enablePlaneDump)
1114         {
1115             if ((dwNumPlanes > 1) && (dwNumPlanes <= 3))
1116             {
1117                 char sPlanePath[MAX_PATH], sPlaneOsPath[MAX_PATH];
1118                 MOS_ZeroMemory(sPlanePath, MAX_PATH);
1119                 MOS_ZeroMemory(sPlaneOsPath, MAX_PATH);
1120 
1121                 MOS_SecureStringPrint(
1122                     sPlanePath,
1123                     MAX_PATH,
1124                     sizeof(sPlanePath),
1125                     "%s_f[%04lld]_w[%d]_h[%d]_p[%d].%s",
1126                     psPathPrefix,
1127                     iCounter,
1128                     planes[j].dwWidth,
1129                     planes[j].dwHeight,
1130                     planes[j].dwPitch,
1131                     (j == 0 ? "Y" : ((dwNumPlanes == 2) ? "UV" : ((j == 1) ? "U" : "V"))));
1132 
1133                 CommonDumperTool::GetOsFilePath(sPlanePath, sPlaneOsPath);
1134 
1135                 eStatus = MosUtilities::MosWriteFileFromPtr(sPlaneOsPath, pDst + dstPlaneOffset[j], dstPlaneOffset[j + 1]);
1136                 if (eStatus != MOS_STATUS_SUCCESS)
1137                 {
1138                     return(DumpSurfaceToFileEnd(
1139                     pOsInterface,
1140                     pDst,
1141                     isSurfaceLocked,
1142                     pLockedResource,
1143                     temp2DSurfForCopy));
1144                 }
1145             }
1146             else
1147             {
1148                 MEDIA_DEBUG_ASSERTMESSAGE("More than 3 planes not supported during plane dump.");
1149             }
1150         }
1151     }
1152 
1153     MosUtilities::MosWriteFileFromPtr(sOsPath, pDst, dwSize);
1154 
1155     return(DumpSurfaceToFileEnd(
1156         pOsInterface,
1157         pDst,
1158         isSurfaceLocked,
1159         pLockedResource,
1160         temp2DSurfForCopy));
1161 }
1162 
GetFormatStr(MOS_FORMAT format)1163 const char * CommonDumperTool::GetFormatStr(MOS_FORMAT format)
1164 {
1165     MEDIA_DEBUG_FUNCTION_ENTER;
1166 
1167     switch (format)
1168     {
1169         case Format_A8R8G8B8    : return _T("argb");
1170         case Format_X8R8G8B8    : return _T("xrgb");
1171         case Format_A8B8G8R8    : return _T("abgr");
1172         case Format_X8B8G8R8    : return _T("xbgr");
1173         case Format_A16R16G16B16: return _T("argb16");
1174         case Format_A16B16G16R16: return _T("abgr16");
1175         case Format_R5G6B5      : return _T("rgb16");
1176         case Format_R8G8B8      : return _T("rgb");
1177         case Format_R32U        : return _T("r32u");
1178         case Format_RGBP        : return _T("rgbp");
1179         case Format_BGRP        : return _T("bgrp");
1180         case Format_R32F        : return _T("r32f");
1181         case Format_YUY2        : return _T("yuy2");
1182         case Format_YUYV        : return _T("yuyv");
1183         case Format_YVYU        : return _T("yvyu");
1184         case Format_UYVY        : return _T("uyvy");
1185         case Format_VYUY        : return _T("vyuy");
1186         case Format_Y416        : return _T("y416");
1187         case Format_AYUV        : return _T("ayuv");
1188         case Format_AUYV        : return _T("auyv");
1189         case Format_NV12        : return _T("nv12");
1190         case Format_NV11        : return _T("nv11");
1191         case Format_P208        : return _T("p208");
1192         case Format_IMC1        : return _T("imc1");
1193         case Format_IMC2        : return _T("imc2");
1194         case Format_IMC3        : return _T("imc3");
1195         case Format_IMC4        : return _T("imc4");
1196         case Format_422H        : return _T("422h");
1197         case Format_422V        : return _T("422v");
1198         case Format_444P        : return _T("444p");
1199         case Format_411P        : return _T("411p");
1200         case Format_411R        : return _T("411r");
1201         case Format_400P        : return _T("400p");
1202         case Format_I420        : return _T("i420");
1203         case Format_IYUV        : return _T("iyuv");
1204         case Format_YV12        : return _T("yv12");
1205         case Format_YVU9        : return _T("yvu9");
1206         case Format_AI44        : return _T("ai44");
1207         case Format_IA44        : return _T("ia44");
1208         case Format_P8          : return _T("P8");
1209         case Format_STMM        : return _T("stmm");
1210         case Format_Buffer      : return _T("buff");
1211         case Format_RAW         : return _T("buff");
1212         case Format_PAL         : return _T("pal");
1213         case Format_A8P8        : return _T("a8p8");
1214         case Format_A8          : return _T("a8");
1215         case Format_L8          : return _T("l8");
1216         case Format_A4L4        : return _T("a4l4");
1217         case Format_A8L8        : return _T("a8l8");
1218         case Format_V8U8        : return _T("v8u8");
1219         case Format_IRW0        : return _T("irw0");
1220         case Format_IRW1        : return _T("irw1");
1221         case Format_IRW2        : return _T("irw2");
1222         case Format_IRW3        : return _T("irw3");
1223         case Format_R10G10B10A2 : return _T("r10g10b10a2");
1224         case Format_B10G10R10A2 : return _T("b10g10r10a2");
1225         case Format_P010        : return _T("p010");
1226         case Format_P016        : return _T("p016");
1227         case Format_R16F        : return _T("r16f");
1228         case Format_Y210        : return _T("y210");
1229         case Format_Y216        : return _T("y216");
1230         case Format_Y410        : return _T("y410");
1231         case Format_P210        : return _T("p210");
1232         case Format_P216        : return _T("p216");
1233         default                 : return _T("Err");
1234     }
1235 
1236     return nullptr;
1237 }
1238 
StringToLower(char * pcString)1239 void CommonDumperTool::StringToLower(
1240     char* pcString)
1241 {
1242     MEDIA_DEBUG_FUNCTION_ENTER;
1243 
1244     size_t stStrLen;                                                           // length of string
1245     size_t i;                                                                  // loop iterator
1246 
1247     stStrLen = strlen(pcString);
1248     for (i = 0; i < stStrLen; i++)
1249     {
1250         if (isupper(pcString[i]))
1251         {
1252             pcString[i] = (char)tolower(pcString[i]);
1253         }
1254     }
1255 }
1256 
GetOsFilePath(const char * pcFilePath,char * pOsFilePath)1257 void CommonDumperTool::GetOsFilePath(
1258     const char* pcFilePath,
1259     char*       pOsFilePath)
1260 {
1261     MEDIA_DEBUG_FUNCTION_ENTER;
1262 
1263     MOS_SecureMemcpy(pOsFilePath, MAX_PATH, (void*)pcFilePath, strlen(pcFilePath));
1264 }
1265 
1266 #endif // (_DEBUG || _RELEASE_INTERNAL)
1267