1 /*
2 * Copyright (c) 2017, 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      cm_hal_dump.cpp
24 //! \brief     Functions related to dump generated hw commands/curbe data
25 //!
26 
27 #include "cm_hal.h"
28 #include "renderhal_platform_interface.h"
29 
30 #if (MDF_COMMAND_BUFFER_DUMP || MDF_CURBE_DATA_DUMP || MDF_SURFACE_STATE_DUMP)
31 #if defined(ANDROID) || defined(LINUX)
32 #define PlatformSNPrintf snprintf
33 #define PLATFORM_DIR_SEPERATOR   "/"
34 #else
35 #define PlatformSNPrintf sprintf_s
36 #define PLATFORM_DIR_SEPERATOR   "\\"
37 #endif
38 
39 #define SIZE_OF_DWORD_PLUS_ONE                  (2*sizeof(uint32_t) +1)
40 //!
41 //! \brief    Dump Hex Dword to dest buffer
42 //! \param    [in] destBuf
43 //!           dest buffer
44 //! \param    [in] buflen
45 //!           length of buffer
46 //! \param    [in] srcBuf
47 //!           pointer to surface of buffer
48 //! \param    [in] uNum
49 //!           number of dword to dump
50 //! \return   number of bytes written
51 //!
HalCm_CopyHexDwordLine(char * destBuf,size_t buflen,uint32_t * srcBuf,uint32_t uNum)52 static uint32_t HalCm_CopyHexDwordLine(char  *destBuf, size_t buflen, uint32_t *srcBuf, uint32_t uNum)
53 {
54     uint32_t bytesWritten = 0;
55     for (uint32_t i = 0; i < uNum; ++i) {
56         bytesWritten += PlatformSNPrintf(destBuf + bytesWritten, buflen - bytesWritten, "%08x ", srcBuf[i]);
57     }
58     bytesWritten += PlatformSNPrintf(destBuf + bytesWritten, buflen - bytesWritten, "\n");
59 
60     return bytesWritten;
61 }
62 
63 //!
64 //! \brief    Get dump file name and counter
65 //! \param    [in] fileNamePrefix[]
66 //!           dump file name
67 //! \param    [in] timeStampFlag
68 //!           flag to control if need time stamp
69 //! \param    [in] counter
70 //!           dump file counter
71 //! \param    [in] outputDir
72 //!           pointer to output dir
73 //! \param    [in] outputFile
74 //!           pointer output file prefix
75 //! \return   number of bytes written
76 //!
GetFileNameAndCounter(char fileNamePrefix[],bool timeStampFlag,int32_t counter,const char * outputDir,const char * outputFile)77 int32_t GetFileNameAndCounter(char fileNamePrefix[], bool timeStampFlag, int32_t counter,
78                               const char *outputDir,const char *outputFile)
79 {
80     GetLogFileLocation(outputDir, fileNamePrefix);
81     PlatformSNPrintf(fileNamePrefix + strlen(fileNamePrefix),
82                      MOS_MAX_HLT_FILENAME_LEN - strlen(fileNamePrefix), PLATFORM_DIR_SEPERATOR);
83 
84     if (timeStampFlag)
85     {
86         SYSTEMTIME systime;
87         GetLocalTime(&systime);
88         PlatformSNPrintf(fileNamePrefix + strlen(fileNamePrefix),
89                         MOS_MAX_HLT_FILENAME_LEN - strlen(fileNamePrefix), "%s_%d_%d_%d_%d_%d_%d_%d.txt",
90                         outputFile, systime.wMonth, systime.wDay, systime.wHour,
91                         systime.wMinute, systime.wSecond, systime.wMilliseconds, counter);
92     }
93     else
94     {
95         //check if command buffer or surface state counter, and get it
96         if (!strcmp(outputFile,"Command_Buffer"))
97         {
98             counter = GetCommandBufferDumpCounter(__MEDIA_USER_FEATURE_VALUE_MDF_CMD_DUMP_COUNTER_ID);
99         }
100         else if (!strcmp(outputFile,"Surface_State_Dump"))
101         {
102             counter = GetSurfaceStateDumpCounter(__MEDIA_USER_FEATURE_VALUE_MDF_SURFACE_STATE_DUMP_COUNTER_ID);
103         }
104         else if (!strcmp(outputFile, "Interface_Descriptor_Data_Dump"))
105         {
106             counter = GetInterfaceDescriptorDataDumpCounter(__MEDIA_USER_FEATURE_VALUE_MDF_INTERFACE_DESCRIPTOR_DATA_COUNTER_ID);
107         }
108 
109         PlatformSNPrintf(fileNamePrefix + strlen(fileNamePrefix),
110                          MOS_MAX_HLT_FILENAME_LEN - strlen(fileNamePrefix), "%s_%d.txt", outputFile, counter);
111     }
112     return counter;
113 
114 }
115 
116 #endif
117 
118 #if MDF_COMMAND_BUFFER_DUMP
119 
120 #define HALCM_COMMAND_BUFFER_OUTPUT_DIR         "HALCM_Command_Buffer_Dumps"
121 #define HALCM_COMMAND_BUFFER_OUTPUT_FILE        "Command_Buffer"
122 
123 //!
124 //! \brief    Read Register key to check if dump flag enabled
125 //! \param    [in] state
126 //!           Pointer to cm hal state
127 //! \return   CM_SUCCESS if success, else fail reason
128 //!
HalCm_InitDumpCommandBuffer(PCM_HAL_STATE state)129 int32_t HalCm_InitDumpCommandBuffer(PCM_HAL_STATE state)
130 {
131     char                            fileName[MOS_MAX_HLT_FILENAME_LEN];
132     MOS_STATUS                      eStatus;
133     MOS_USER_FEATURE_VALUE_DATA     userFeatureValueData;
134     int32_t                         hr = CM_FAILURE;
135 
136     MOS_OS_ASSERT(state);
137 
138     MOS_ZeroMemory(&userFeatureValueData, sizeof(userFeatureValueData));
139 
140     // Check if command buffer dump was enabled in user feature settings.
141     GetLogFileLocation(HALCM_COMMAND_BUFFER_OUTPUT_DIR, fileName);
142 
143     eStatus = MOS_UserFeature_ReadValue_ID(
144         nullptr,
145         __MEDIA_USER_FEATURE_VALUE_MDF_CMD_DUMP_ENABLE_ID,
146         &userFeatureValueData);
147     if (eStatus != MOS_STATUS_SUCCESS)
148     {
149         MOS_OS_NORMALMESSAGE("Unable to read command buffer user feature key. Status = %d", eStatus);
150         goto finish;
151     }
152     if (userFeatureValueData.bData)
153     {
154         eStatus = MOS_CreateDirectory(fileName);
155         if (eStatus != MOS_STATUS_SUCCESS)
156         {
157             MOS_OS_NORMALMESSAGE("Failed to create output directory. Status = %d", eStatus);
158             goto finish;
159         }
160         // Setup member function and variable.
161         state->dumpCommandBuffer = userFeatureValueData.bData ? true : false;
162         if (userFeatureValueData.bData == 17)
163         {
164             state->enableCMDDumpTimeStamp = true;
165         }
166         else
167         {
168             state->enableCMDDumpTimeStamp = false;
169         }
170     }
171     hr = CM_SUCCESS;
172 finish:
173     return hr;
174 }
175 
176 //!
177 //! \brief    Dump command buffer to file
178 //! \param    [in] state
179 //!           pointer to cm hal state
180 //! \param    [in] cmdBuffer
181 //!           pointer to command buffer
182 //! \param    [in] offsetSurfaceState
183 //!           offset to surface state
184 //! \param    [in] sizeOfSurfaceState
185 //!           size of surface state
186 //! \return   int32_t
187 //!           CM_SUCCESS if success, else fail reason
188 //!
HalCm_DumpCommadBuffer(PCM_HAL_STATE state,PMOS_COMMAND_BUFFER cmdBuffer,int offsetSurfaceState,size_t sizeOfSurfaceState)189 int32_t HalCm_DumpCommadBuffer(PCM_HAL_STATE state, PMOS_COMMAND_BUFFER cmdBuffer, int offsetSurfaceState, size_t sizeOfSurfaceState)
190 {
191 
192     int32_t        commandBufferNumber = 0;
193     int32_t         hr = CM_FAILURE;
194     MOS_STATUS      eStatus = MOS_STATUS_UNKNOWN;
195     char            *outputBuffer = nullptr;
196     // Each hex value should have 9 chars.
197     uint32_t        bytesWritten = 0;
198     uint32_t        numberOfDwords = 0;
199     uint32_t        sizeToAllocate = 0;
200     char            fileName[MOS_MAX_HLT_FILENAME_LEN];
201     uint32_t        offset = 0;
202 
203     PMOS_INTERFACE osInterface = state->osInterface;
204     PRENDERHAL_STATE_HEAP stateHeap   = state->renderHal->pStateHeap;
205 
206     MOS_OS_ASSERT(state);
207     MOS_OS_ASSERT(cmdBuffer);
208 
209    //Check if use timestamp in cmd buffer dump file
210     commandBufferNumber = GetFileNameAndCounter(fileName, state->enableCMDDumpTimeStamp,
211                           commandBufferNumber,
212                           HALCM_COMMAND_BUFFER_OUTPUT_DIR,
213                           HALCM_COMMAND_BUFFER_OUTPUT_FILE);
214 
215     //get the command buffer header size
216     offset = GetCommandBufferHeaderDWords(osInterface);
217 
218     numberOfDwords = cmdBuffer->iOffset / sizeof(uint32_t) - offset;
219     sizeToAllocate = numberOfDwords * (SIZE_OF_DWORD_PLUS_ONE)+2 +   //length of command buffer line
220         stateHeap->iCurrentSurfaceState *
221         (SIZE_OF_DWORD_PLUS_ONE *
222         state->renderHal->pRenderHalPltInterface->GetSurfaceStateCmdSize() / sizeof(uint32_t) + 2); //length of surface state lines
223                                                                                                                           // Alloc output buffer.
224     outputBuffer = (char *)MOS_AllocAndZeroMemory(sizeToAllocate);
225     if (!outputBuffer) {
226         MOS_OS_NORMALMESSAGE("Failed to allocate memory for command buffer dump");
227         return MOS_STATUS_NO_SPACE;
228     }
229 
230     // write command buffer dwords.
231     bytesWritten += HalCm_CopyHexDwordLine(outputBuffer, sizeToAllocate - bytesWritten,
232                                           (uint32_t *)cmdBuffer->pCmdBase + offset, numberOfDwords);
233     MOS_OS_CHK_STATUS(MOS_WriteFileFromPtr((const char *)fileName, outputBuffer, bytesWritten));
234     commandBufferNumber++;
235 
236     //Record command buffer dump counter
237     if (!state->enableCMDDumpTimeStamp)
238     {
239         RecordCommandBufferDumpCounter(commandBufferNumber,
240                                        __MEDIA_USER_FEATURE_VALUE_MDF_CMD_DUMP_COUNTER_ID);
241     }
242     hr = CM_SUCCESS;
243 finish:
244     // Free the memory.
245     if (outputBuffer)
246     {
247         MOS_FreeMemAndSetNull(outputBuffer);
248     }
249     return hr;
250 }
251 
252 #endif
253 
254 #if MDF_CURBE_DATA_DUMP
255 
256 #define HALCM_CURBE_DATA_OUTPUT_DIR         "HALCM_Curbe_Data_Dumps"
257 #define HALCM_CURBE_DATA_OUTPUT_FILE        "Curbe_Data"
258 
259 //!
260 //! \brief    Read Register key to check if Curbe Data dump flag enabled
261 //! \param    [in] state
262 //!           Pointer to cm hal state
263 //! \return   CM_SUCCESS if success, else fail reason
264 //!
HalCm_InitDumpCurbeData(PCM_HAL_STATE state)265 int32_t HalCm_InitDumpCurbeData(PCM_HAL_STATE state)
266 {
267     MOS_USER_FEATURE_VALUE_DATA userFeatureValueData;
268     char                        fileName[MOS_MAX_HLT_FILENAME_LEN];
269     MOS_STATUS                  eStatus;
270     int32_t                     hr = CM_FAILURE;
271 
272     MOS_OS_ASSERT(state);
273 
274     MOS_ZeroMemory(&userFeatureValueData, sizeof(userFeatureValueData));
275 
276     // Check if curbe data dump was enabled in user feature settings.
277     eStatus = MOS_UserFeature_ReadValue_ID(
278         nullptr,
279         __MEDIA_USER_FEATURE_VALUE_MDF_CURBE_DUMP_ENABLE_ID,
280         &userFeatureValueData);
281     if (eStatus != MOS_STATUS_SUCCESS)
282     {
283         MOS_OS_NORMALMESSAGE("Unable to read curbe data dump user feature key. Status = %d", eStatus);
284         goto finish;
285     }
286     if (userFeatureValueData.bData)
287     {
288         GetLogFileLocation(HALCM_CURBE_DATA_OUTPUT_DIR, fileName);
289         eStatus = MOS_CreateDirectory(fileName);
290         if (eStatus != MOS_STATUS_SUCCESS)
291         {
292             MOS_OS_NORMALMESSAGE("Failed to create curbe data output directory. Status = %d", eStatus);
293             goto finish;
294         }
295         // Setup member function and variable.
296         state->dumpCurbeData = userFeatureValueData.bData ? true : false;
297     }
298     hr = CM_SUCCESS;
299 finish:
300     return hr;
301 }
302 
303 //!
304 //! \brief    Dump Curbe Data to file
305 //! \param    [in] state
306 //!           pointer to cm hal state
307 //! \return   int32_t
308 //!           CM_SUCCESS if success, else fail reason
309 //!
HalCm_DumpCurbeData(PCM_HAL_STATE state)310 int32_t HalCm_DumpCurbeData(PCM_HAL_STATE state)
311 {
312     static uint32_t curbeDataNumber = 0;
313     int32_t         hr = CM_FAILURE;
314     MOS_STATUS      eStatus = MOS_STATUS_UNKNOWN;
315     char            *outputBuffer = nullptr;
316     uint32_t        bytesWritten = 0;
317     char            fileName[MOS_MAX_HLT_FILENAME_LEN];
318     uint32_t        numberOfDwords = 0;
319     uint32_t        sizeToAllocate = 0;
320     PMOS_INTERFACE osInterface = state->osInterface;
321     uint32_t        *curbeData = nullptr;
322     PRENDERHAL_STATE_HEAP stateHeap = state->renderHal->pStateHeap;
323 
324     MOS_OS_ASSERT(state);
325 
326     // Set the file name.
327     GetLogFileLocation(HALCM_CURBE_DATA_OUTPUT_DIR, fileName);
328 
329     PlatformSNPrintf(fileName + strlen(fileName), MOS_MAX_HLT_FILENAME_LEN - strlen(fileName),
330                      PLATFORM_DIR_SEPERATOR);
331     PlatformSNPrintf(fileName + strlen(fileName), MOS_MAX_HLT_FILENAME_LEN - strlen(fileName),
332                      "%s_%d.txt", HALCM_CURBE_DATA_OUTPUT_FILE, (int)curbeDataNumber);
333 
334     // write curbe data dwords.
335     if (state->dshEnabled)
336     {
337         numberOfDwords = stateHeap->pCurMediaState->pDynamicState->Curbe.dwSize / sizeof(uint32_t);
338         sizeToAllocate = numberOfDwords*SIZE_OF_DWORD_PLUS_ONE+2;
339         outputBuffer = (char *)MOS_AllocAndZeroMemory(sizeToAllocate);
340         curbeData = (uint32_t *)MOS_AllocAndZeroMemory(stateHeap->pCurMediaState->pDynamicState->Curbe.dwSize);
341         stateHeap->pCurMediaState->pDynamicState->memoryBlock.ReadData(curbeData,
342             stateHeap->pCurMediaState->pDynamicState->Curbe.dwOffset,
343             stateHeap->pCurMediaState->pDynamicState->Curbe.dwSize);
344 
345         bytesWritten += HalCm_CopyHexDwordLine(outputBuffer,
346                           sizeToAllocate - bytesWritten,
347                           curbeData,
348                           numberOfDwords);
349     }
350     else
351     {
352         numberOfDwords = stateHeap->pCurMediaState->iCurbeOffset / sizeof(uint32_t);
353         sizeToAllocate = numberOfDwords*SIZE_OF_DWORD_PLUS_ONE+2;
354         outputBuffer = (char *)MOS_AllocAndZeroMemory(sizeToAllocate);
355         bytesWritten += HalCm_CopyHexDwordLine(outputBuffer,
356                           sizeToAllocate - bytesWritten,
357                           (uint32_t*)(stateHeap->pGshBuffer + stateHeap->pCurMediaState->dwOffset + stateHeap->dwOffsetCurbe),
358                           numberOfDwords);
359     }
360 
361     MOS_OS_CHK_STATUS(MOS_WriteFileFromPtr((const char *)fileName, outputBuffer, bytesWritten));
362 
363     curbeDataNumber++;
364 
365     hr = CM_SUCCESS;
366 
367 finish:
368     // Free the memory.
369     if (outputBuffer)
370     {
371         MOS_FreeMemAndSetNull(outputBuffer);
372     }
373 
374     if (curbeData)
375     {
376         MOS_FreeMemAndSetNull(curbeData);
377     }
378 
379     return hr;
380 
381 }
382 
383 #endif
384 
385 #if MDF_SURFACE_CONTENT_DUMP
386 
387 //!
388 //! \brief    Read Register key to check if Surface content flag enabled
389 //! \param    [in] state
390 //!           Pointer to cm hal state
391 //! \return   CM_SUCCESS if success, else fail reason
392 //!
HalCm_InitSurfaceDump(PCM_HAL_STATE state)393 int32_t HalCm_InitSurfaceDump(PCM_HAL_STATE state)
394 {
395     MOS_USER_FEATURE_VALUE_DATA userFeatureValueData;
396     MOS_STATUS                  eStatus;
397     int32_t                     hr = CM_FAILURE;
398 
399     MOS_OS_ASSERT(state);
400 
401     MOS_ZeroMemory(&userFeatureValueData, sizeof(userFeatureValueData));
402 
403     // Check if surface content dump was enabled in user feature settings.
404     eStatus = MOS_UserFeature_ReadValue_ID(
405         nullptr,
406         __MEDIA_USER_FEATURE_VALUE_MDF_SURFACE_DUMP_ENABLE_ID,
407         &userFeatureValueData);
408     if (eStatus != MOS_STATUS_SUCCESS)
409     {
410         MOS_OS_NORMALMESSAGE("Unable to read surface content dump user feature key. Status = %d", eStatus);
411         goto finish;
412     }
413     if (userFeatureValueData.bData)
414     {
415         // Setup member function and variable.
416         state->dumpSurfaceContent = userFeatureValueData.bData ? true : false;
417     }
418     hr = CM_SUCCESS;
419 finish:
420     return hr;
421 }
422 
423 #endif
424 
425 
426 #if MDF_SURFACE_STATE_DUMP
427 #define HALCM_SURFACE_STATE_OUTPUT_DIR         "HALCM_Surface_State_Dumps"
428 #define HALCM_SURFACE_STATE_OUTPUT_FILE        "Surface_State_Dump"
429 
HalCm_InitDumpSurfaceState(PCM_HAL_STATE state)430 int32_t HalCm_InitDumpSurfaceState(PCM_HAL_STATE state)
431 {
432     MOS_USER_FEATURE_VALUE_DATA userFeatureValueData;
433     char                        fileName[MOS_MAX_HLT_FILENAME_LEN];
434     MOS_STATUS                  eStatus;
435     int32_t                     hr = CM_FAILURE;
436 
437     MOS_OS_ASSERT(state);
438 
439     MOS_ZeroMemory(&userFeatureValueData, sizeof(userFeatureValueData));
440 
441     // Check if command buffer dump was enabled in user feature settings.
442     GetLogFileLocation(HALCM_SURFACE_STATE_OUTPUT_DIR, fileName);
443 
444     eStatus = MOS_UserFeature_ReadValue_ID(
445         nullptr,
446         __MEDIA_USER_FEATURE_VALUE_MDF_SURFACE_STATE_DUMP_ENABLE_ID,
447         &userFeatureValueData);
448     if (eStatus != MOS_STATUS_SUCCESS)
449     {
450         MOS_OS_NORMALMESSAGE("Unable to read surface state user feature key. Status = %d", eStatus);
451         goto finish;
452     }
453     if (userFeatureValueData.bData)
454     {
455         eStatus = MOS_CreateDirectory(fileName);
456         if (eStatus != MOS_STATUS_SUCCESS)
457         {
458             MOS_OS_NORMALMESSAGE("Failed to create output directory. Status = %d", eStatus);
459             goto finish;
460         }
461         // Setup member function and variable.
462         state->dumpSurfaceState = userFeatureValueData.bData ? true : false;
463 
464         if (userFeatureValueData.bData == 17)
465         {
466             state->enableSurfaceStateDumpTimeStamp = true;
467         }
468         else
469         {
470             state->enableSurfaceStateDumpTimeStamp = false;
471         }
472     }
473     hr = CM_SUCCESS;
474 finish:
475     return hr;
476 }
477 
478 //!
479 //! \brief    Dump surface state to file
480 //! \param    [in] state
481 //!           pointer to cm hal state
482 //! \param    [in] offsetSurfaceState
483 //!           offset to surface state
484 //! \param    [in] sizeOfSurfaceState
485 //!           size of surface state
486 //! \return   int32_t
487 //!           CM_SUCCESS if success, else fail reason
488 //!
HalCm_DumpSurfaceState(PCM_HAL_STATE state,int offsetSurfaceState,size_t sizeOfSurfaceState)489 int32_t HalCm_DumpSurfaceState(PCM_HAL_STATE state,  int offsetSurfaceState, size_t sizeOfSurfaceState)
490 {
491     int32_t         hr = CM_FAILURE;
492     MOS_STATUS      eStatus = MOS_STATUS_UNKNOWN;
493 
494     PMOS_INTERFACE osInterface = state->osInterface;
495     PRENDERHAL_STATE_HEAP stateHeap = state->renderHal->pStateHeap;
496 
497     char            filename[MOS_MAX_HLT_FILENAME_LEN];
498     int32_t         surfacestatedumpNumber = 0;
499     uint32_t        surfacebytesWritten = 0;
500     char            *surfaceoutputBuffer = nullptr;
501     uint32_t        surfacesizeToAllocate = 0;
502 
503    //Check if use timestamp in cmd buffer dump file
504     surfacestatedumpNumber = GetFileNameAndCounter(filename, state->enableSurfaceStateDumpTimeStamp,
505         surfacestatedumpNumber,
506         HALCM_SURFACE_STATE_OUTPUT_DIR,
507         HALCM_SURFACE_STATE_OUTPUT_FILE);
508 
509     //calculate surface state dump allocation size
510     surfacesizeToAllocate = stateHeap->iCurrentSurfaceState *
511         (SIZE_OF_DWORD_PLUS_ONE *
512         state->renderHal->pRenderHalPltInterface->GetSurfaceStateCmdSize() / sizeof(uint32_t) + 2);
513 
514     //allocate surface output buffer
515     surfaceoutputBuffer = (char *)MOS_AllocAndZeroMemory(surfacesizeToAllocate);
516     if (!surfaceoutputBuffer) {
517         MOS_OS_NORMALMESSAGE("Failed to allocate memory for surface state dump");
518         return MOS_STATUS_NO_SPACE;
519     }
520 
521     //write all surface states
522     for (int32_t index = 0; index < stateHeap->iCurrentSurfaceState; ++index) {
523         PRENDERHAL_SURFACE_STATE_ENTRY entry = stateHeap->pSurfaceEntry + index;
524         void *surfaceState = (char*)entry->pSurfaceState;
525         //the address of surface states are 32bit or uint32_t aligned.
526         surfacebytesWritten += HalCm_CopyHexDwordLine(surfaceoutputBuffer + surfacebytesWritten,
527                                surfacesizeToAllocate - surfacebytesWritten, (uint32_t*)surfaceState,
528                                sizeOfSurfaceState / sizeof(uint32_t));
529     }
530 
531     //Write to file
532     MOS_OS_CHK_STATUS(MOS_WriteFileFromPtr((const char *)filename, surfaceoutputBuffer,
533                       surfacebytesWritten));
534 
535     surfacestatedumpNumber++;
536 
537     if (!state->enableSurfaceStateDumpTimeStamp)
538     {
539         RecordSurfaceStateDumpCounter(surfacestatedumpNumber,
540                                       __MEDIA_USER_FEATURE_VALUE_MDF_SURFACE_STATE_DUMP_COUNTER_ID);
541     }
542 
543     hr = CM_SUCCESS;
544 
545 finish:
546     // Free the memory.
547     if (surfaceoutputBuffer)
548     {
549         MOS_FreeMemAndSetNull(surfaceoutputBuffer);
550     }
551 
552     return hr;
553 
554 }
555 #endif
556 
557 #if MDF_INTERFACE_DESCRIPTOR_DATA_DUMP
558 #define HALCM_INTERFACE_DESCRIPTOR_DATA_OUTPUT_DIR         "HALCM_Interface_Descriptor_Data_Dumps"
559 #define HALCM_INTERFACE_DESCRIPTOR_DATA_OUTPUT_FILE        "Interface_Descriptor_Data_Dump"
560 
HalCm_InitDumpInterfaceDescriporData(PCM_HAL_STATE state)561 int32_t HalCm_InitDumpInterfaceDescriporData(PCM_HAL_STATE state)
562 {
563     MOS_USER_FEATURE_VALUE_DATA userFeatureValueData;
564     char                        fileName[MOS_MAX_HLT_FILENAME_LEN];
565     MOS_STATUS                  eStatus;
566     int32_t                     hr = CM_FAILURE;
567 
568     MOS_OS_ASSERT(state);
569 
570     MOS_ZeroMemory(&userFeatureValueData, sizeof(userFeatureValueData));
571 
572     // Check if command buffer dump was enabled in user feature settings.
573     GetLogFileLocation(HALCM_INTERFACE_DESCRIPTOR_DATA_OUTPUT_DIR, fileName);
574 
575     eStatus = MOS_UserFeature_ReadValue_ID(
576         nullptr,
577         __MEDIA_USER_FEATURE_VALUE_MDF_INTERFACE_DESCRIPTOR_DATA_DUMP_ID,
578         &userFeatureValueData);
579     if (eStatus != MOS_STATUS_SUCCESS)
580     {
581         MOS_OS_NORMALMESSAGE("Unable to read interface descriptor data dump user feature key. Status = %d", eStatus);
582         goto finish;
583     }
584     if (userFeatureValueData.bData)
585     {
586         eStatus = MOS_CreateDirectory(fileName);
587         if (eStatus != MOS_STATUS_SUCCESS)
588         {
589             MOS_OS_NORMALMESSAGE("Failed to create output directory. Status = %d", eStatus);
590             goto finish;
591         }
592         // Setup member function and variable.
593         state->dumpIDData = userFeatureValueData.bData ? true : false;
594         if (userFeatureValueData.bData == 17)
595         {
596             state->enableIDDumpTimeStamp = true;
597         }
598         else
599         {
600             state->enableIDDumpTimeStamp = false;
601         }
602 
603     }
604     hr = CM_SUCCESS;
605 finish:
606     return hr;
607 }
608 
609 //!
610 //! \brief    Dump interface descriptor data to file
611 //! \param    [in] state
612 //!           pointer to cm hal state
613 //! \return   int32_t
614 //!           CM_SUCCESS if success, else fail reason
615 //!
HalCm_DumpInterfaceDescriptorData(PCM_HAL_STATE state)616 int32_t HalCm_DumpInterfaceDescriptorData(PCM_HAL_STATE state)
617 {
618     uint32_t        IDDNumber = 0;
619     int32_t         hr = CM_FAILURE;
620     MOS_STATUS      eStatus = MOS_STATUS_UNKNOWN;
621     char            *outputBuffer = nullptr;
622     uint32_t        bytesWritten = 0;
623     char            fileName[MOS_MAX_HLT_FILENAME_LEN];
624     uint32_t        numberOfDwords = 0;
625     uint32_t        sizeToAllocate = 0;
626     PMOS_INTERFACE osInterface = state->osInterface;
627     uint32_t        *InterfaceDescriptorData = nullptr;
628     PRENDERHAL_STATE_HEAP stateHeap = state->renderHal->pStateHeap;
629 
630     MOS_OS_ASSERT(state);
631 
632     // Set the file name.
633     GetLogFileLocation(HALCM_INTERFACE_DESCRIPTOR_DATA_OUTPUT_DIR, fileName);
634 
635     //Check if use timestamp in cmd buffer dump file
636     IDDNumber = GetFileNameAndCounter(fileName, state->enableIDDumpTimeStamp,
637         IDDNumber,
638         HALCM_INTERFACE_DESCRIPTOR_DATA_OUTPUT_DIR,
639         HALCM_INTERFACE_DESCRIPTOR_DATA_OUTPUT_FILE);
640 
641     // write interface descriptor data dwords.
642     if (state->dshEnabled)
643     {
644         numberOfDwords = stateHeap->pCurMediaState->pDynamicState->MediaID.dwSize / sizeof(uint32_t);
645         sizeToAllocate = numberOfDwords * SIZE_OF_DWORD_PLUS_ONE + 2;
646         outputBuffer = (char *)MOS_AllocAndZeroMemory(sizeToAllocate);
647         InterfaceDescriptorData = (uint32_t *)MOS_AllocAndZeroMemory(stateHeap->pCurMediaState->pDynamicState->MediaID.dwSize);
648         stateHeap->pCurMediaState->pDynamicState->memoryBlock.ReadData(InterfaceDescriptorData,
649             stateHeap->pCurMediaState->pDynamicState->MediaID.dwOffset,
650             stateHeap->pCurMediaState->pDynamicState->MediaID.dwSize);
651 
652         bytesWritten += HalCm_CopyHexDwordLine(outputBuffer,
653             sizeToAllocate - bytesWritten,
654             InterfaceDescriptorData,
655             numberOfDwords);
656     }
657     else
658     {
659         numberOfDwords = stateHeap->dwSizeMediaID / sizeof(uint32_t);
660         sizeToAllocate = numberOfDwords * SIZE_OF_DWORD_PLUS_ONE + 2;
661         outputBuffer = (char *)MOS_AllocAndZeroMemory(sizeToAllocate);
662         bytesWritten += HalCm_CopyHexDwordLine(outputBuffer,
663             sizeToAllocate - bytesWritten,
664             (uint32_t*)(stateHeap->pGshBuffer + stateHeap->pCurMediaState->dwOffset + stateHeap->dwOffsetMediaID),
665             numberOfDwords);
666     }
667 
668     MOS_OS_CHK_STATUS(MOS_WriteFileFromPtr((const char *)fileName, outputBuffer, bytesWritten));
669 
670     IDDNumber++;
671     if (!state->enableIDDumpTimeStamp)
672     {
673         RecordInterfaceDescriptorDataDumpCounter(IDDNumber,
674             __MEDIA_USER_FEATURE_VALUE_MDF_INTERFACE_DESCRIPTOR_DATA_COUNTER_ID);
675     }
676 
677     hr = CM_SUCCESS;
678 
679 finish:
680     // Free the memory.
681     if (outputBuffer)
682     {
683         MOS_FreeMemAndSetNull(outputBuffer);
684     }
685 
686     if (InterfaceDescriptorData)
687     {
688         MOS_FreeMemAndSetNull(InterfaceDescriptorData);
689     }
690 
691     return hr;
692 
693 }
694 #endif