xref: /aosp_15_r20/external/intel-media-driver/media_driver/agnostic/common/cm/cm_event_rt.cpp (revision ba62d9d3abf0e404f2022b4cd7a85e107f48596f)
1 /*
2 * Copyright (c) 2007-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_event_rt.cpp
24 //! \brief     Contains OS-agnostic CmEventRT member functions.
25 //!
26 
27 #include "cm_event_rt.h"
28 
29 #include "cm_device_rt.h"
30 #include "cm_queue_rt.h"
31 #include "cm_mem.h"
32 #include "cm_task_rt.h"
33 #include "cm_kernel_rt.h"
34 #include "cm_thread_space_rt.h"
35 #include "cm_group_space.h"
36 #include "cm_surface_manager.h"
37 #include "cm_task_internal.h"
38 
39 namespace CMRT_UMD
40 {
41 //*-----------------------------------------------------------------------------
42 //| Purpose:    Create Cm Event
43 //| Returns:    Result of the operation.
44 //*-----------------------------------------------------------------------------
Create(uint32_t index,CmQueueRT * queue,CmTaskInternal * task,int32_t taskDriverId,CmDeviceRT * device,bool isVisible,CmEventRT * & event)45 int32_t CmEventRT::Create(uint32_t index, CmQueueRT *queue, CmTaskInternal *task, int32_t taskDriverId, CmDeviceRT *device, bool isVisible, CmEventRT *&event)
46 {
47     int32_t result = CM_SUCCESS;
48     event = new (std::nothrow) CmEventRT( index, queue, task, taskDriverId, device, isVisible );
49     if( event )
50     {
51         event->m_device->m_memObjectCount.eventCount++;
52         if(isVisible)
53         {   // Increase the refcount when the Event is visiable
54             event->Acquire();
55         }
56         result = event->Initialize();
57         if( result != CM_SUCCESS )
58         {
59             CmEventRT::Destroy( event );
60         }
61     }
62     else
63     {
64         CM_ASSERTMESSAGE("Error: Failed to create CmEvent due to out of system memory.");
65         result = CM_OUT_OF_HOST_MEMORY;
66     }
67     return result;
68 }
69 
70 //*-----------------------------------------------------------------------------
71 //| Purpose:    Destroy Cm Event
72 //| Returns:    Result of the operation.
73 //*-----------------------------------------------------------------------------
Destroy(CmEventRT * & event)74 int32_t CmEventRT::Destroy( CmEventRT* &event )
75 {
76     CM_OBJECT_COUNT* memObjectCount = &event->m_device->m_memObjectCount;
77     long refCount = event->SafeRelease();
78     if (refCount == 0)
79     {
80         memObjectCount->eventCount--;
81         event = nullptr;
82     }
83     return CM_SUCCESS;
84 }
85 
86 
87 //*-----------------------------------------------------------------------------
88 //| Purpose:    Constructor of Cm Event
89 //| Returns:    Result of the operation.
90 //*-----------------------------------------------------------------------------
CmEventRT(uint32_t index,CmQueueRT * queue,CmTaskInternal * task,int32_t taskDriverId,CmDeviceRT * device,bool isVisible)91 CmEventRT::CmEventRT(uint32_t index, CmQueueRT *queue, CmTaskInternal *task, int32_t taskDriverId, CmDeviceRT *device, bool isVisible):
92     m_index( index ),
93     m_taskDriverId( taskDriverId ),
94     m_osData(nullptr),
95     m_status( CM_STATUS_QUEUED ),
96     m_time( 0 ),
97     m_ticks(0),
98     m_hwStartTimeStampInTicks( 0 ),
99     m_hwEndTimeStampInTicks( 0 ),
100     m_device( device ),
101     m_queue (queue),
102     m_refCount(0),
103     m_isVisible(isVisible),
104     m_task(task),
105     m_callbackFunction(nullptr),
106     m_callbackUserData(nullptr),
107     m_osSignalTriggered(false)
108 {
109     m_globalSubmitTimeCpu.QuadPart = 0;
110     m_submitTimeGpu.QuadPart = 0;
111     m_hwStartTimeStamp.QuadPart = 0;
112     m_hwEndTimeStamp.QuadPart = 0;
113     m_completeTime.QuadPart = 0;
114     m_enqueueTime.QuadPart = 0;
115 
116     m_kernelNames          = nullptr ;
117     m_threadSpace          = nullptr ;
118     m_kernelCount          = 0 ;
119 
120     MOS_ZeroMemory(&m_surEntryInfoArrays, sizeof(m_surEntryInfoArrays));
121 }
122 
123 //*-----------------------------------------------------------------------------
124 //| Purpose:    Increase Reference count
125 //| Returns:    Result of the operation.
126 //*-----------------------------------------------------------------------------
Acquire(void)127 int32_t CmEventRT::Acquire( void )
128 {
129     ++m_refCount;
130     return m_refCount;
131 }
132 
133 //*-----------------------------------------------------------------------------
134 //| Purpose:    De of Cm Event
135 //| Returns:    Result of the operation.
136 //*-----------------------------------------------------------------------------
SafeRelease(void)137 int32_t CmEventRT::SafeRelease( void )
138 {
139     --m_refCount;
140     if(m_refCount == 0 )
141     {
142         delete this;
143         return 0;
144     }
145     else
146     {
147         return m_refCount;
148     }
149 }
150 
151 //*-----------------------------------------------------------------------------
152 //| Purpose:    Destructor of Cm Event
153 //| Returns:    Result of the operation.
154 //*-----------------------------------------------------------------------------
~CmEventRT(void)155 CmEventRT::~CmEventRT( void )
156 {
157     // call callback registered by Vtune
158     if(m_callbackFunction)
159     {
160         m_callbackFunction(this, m_callbackUserData);
161     }
162 
163     if (m_surEntryInfoArrays.surfEntryInfosArray!= nullptr)
164     {
165 
166         for( uint32_t i = 0; i < m_surEntryInfoArrays.kernelNum; i ++ )
167         {
168             MosSafeDelete(m_surEntryInfoArrays.surfEntryInfosArray[i].surfEntryInfos);
169             MosSafeDelete(m_surEntryInfoArrays.surfEntryInfosArray[i].globalSurfInfos);
170         }
171         MosSafeDelete(m_surEntryInfoArrays.surfEntryInfosArray);
172     }
173 
174     if (m_kernelNames != nullptr)
175     {
176         for ( uint32_t i = 0; i < m_kernelCount; i++)
177         {
178             MosSafeDeleteArray(m_kernelNames[i]);
179         }
180         MosSafeDeleteArray( m_kernelNames );
181         MosSafeDeleteArray( m_threadSpace );
182     }
183 }
184 
185 //*-----------------------------------------------------------------------------
186 //| Purpose:    Initialize Cm Event
187 //| Returns:    Result of the operation.
188 //*-----------------------------------------------------------------------------
Initialize(void)189 int32_t CmEventRT::Initialize(void)
190 {
191     if( m_taskDriverId == -1 )
192         // -1 is an invalid task id in driver, i.e. the task has NOT been passed down to driver yet
193         // event is created at the enqueue time, so initial value is CM_STATUS_QUEUED
194     {
195         m_status = CM_STATUS_QUEUED;
196     }
197     else
198     {
199         CM_ASSERTMESSAGE("Error: Failed to initialize CmEvent.");
200         return CM_FAILURE;
201     }
202 
203     m_kernelNames = nullptr;
204     m_kernelCount = 0;
205 
206     return CM_SUCCESS;
207 }
208 
GetStatusNoFlush(CM_STATUS & status)209 int32_t CmEventRT::GetStatusNoFlush(CM_STATUS& status)
210 {
211     if ((m_status == CM_STATUS_FLUSHED) || (m_status == CM_STATUS_STARTED))
212     {
213         Query();
214     }
215     else if (m_status == CM_STATUS_QUEUED)
216     {
217         // the task hasn't beeen flushed yet
218         // if the task correspoonding to this event can be flushed, m_status will change to CM_STATUS_FLUSHED
219         m_queue->FlushTaskWithoutSync();
220 
221     }
222     else if (m_status == CM_STATUS_FINISHED)
223     {
224         //Do nothing
225     }
226     else
227     {
228         CM_ASSERTMESSAGE("Error: Failed to get status.");
229     }
230 
231     status = m_status;
232     return CM_SUCCESS;
233 }
234 
ModifyStatus(CM_STATUS status,uint64_t elapsedTime)235 int32_t CmEventRT::ModifyStatus(CM_STATUS status, uint64_t elapsedTime)
236 {
237     if (m_ticks == 0)
238     {
239         m_time = elapsedTime;
240     }
241     m_status = status;
242     return CM_SUCCESS;
243 }
244 
GetQueue(CmQueueRT * & queue)245 int32_t CmEventRT::GetQueue(CmQueueRT *& queue)
246 {
247     queue = m_queue;
248     return CM_SUCCESS;
249 }
250 
251 //*-----------------------------------------------------------------------------
252 //! Query the execution time of a task( one kernel or multiples kernels running concurrently )
253 //! in the unit of nanoseconds.
254 //! The execution time is from the time when the task starts to execution in GPU to the time
255 //! when the task finished execution
256 //! This is a non-blocking call.
257 //! INPUT:
258 //!     Reference to time
259 //! OUTPUT:
260 //!     CM_SUCCESS if the execution time is successfully returned
261 //!     CM_FAILURE if not, e.g. the task hasn't finished
262 //*-----------------------------------------------------------------------------
GetExecutionTime(uint64_t & time)263 CM_RT_API int32_t CmEventRT::GetExecutionTime(uint64_t& time)
264 {
265     CM_STATUS eventStatus = CM_STATUS_QUEUED;
266 
267     GetStatusNoFlush(eventStatus);
268 
269     if( eventStatus == CM_STATUS_FINISHED )
270     {
271         time = m_time;
272         return CM_SUCCESS;
273     }
274     else
275     {
276         return CM_FAILURE;
277     }
278 }
279 
GetExecutionTickTime(uint64_t & ticks)280 CM_RT_API int32_t CmEventRT::GetExecutionTickTime(uint64_t& ticks)
281 {
282     CM_STATUS eventStatus = CM_STATUS_QUEUED;
283 
284     GetStatusNoFlush(eventStatus);
285 
286     if (eventStatus == CM_STATUS_FINISHED)
287     {
288         ticks = m_ticks;
289         return CM_SUCCESS;
290     }
291     else
292     {
293         return CM_FAILURE;
294     }
295 }
296 
GetSubmitTime(LARGE_INTEGER * time)297 int32_t CmEventRT::GetSubmitTime(LARGE_INTEGER* time)
298 {
299 
300     CM_STATUS eventStatus = CM_STATUS_QUEUED;
301 
302     GetStatusNoFlush(eventStatus);
303 
304     if( eventStatus == CM_STATUS_FINISHED )
305     {
306         *time = m_globalSubmitTimeCpu;
307         return CM_SUCCESS;
308     }
309     else
310     {
311         CM_ASSERTMESSAGE("Error: Failed to get task submit time.");
312         return CM_FAILURE;
313     }
314 }
315 
GetHWStartTime(LARGE_INTEGER * time)316 int32_t CmEventRT::GetHWStartTime(LARGE_INTEGER* time)
317 {
318     CM_STATUS eventStatus = CM_STATUS_QUEUED;
319 
320     GetStatusNoFlush(eventStatus);
321 
322     if( eventStatus == CM_STATUS_FINISHED )
323     {
324         time->QuadPart = m_globalSubmitTimeCpu.QuadPart + m_hwStartTimeStamp.QuadPart - m_submitTimeGpu.QuadPart;
325         return CM_SUCCESS;
326     }
327     else
328     {
329         return CM_FAILURE;
330     }
331 
332 }
333 
GetKernelCount()334 uint32_t CmEventRT::GetKernelCount()
335 {
336     return m_kernelCount;
337 }
338 
GetHWEndTime(LARGE_INTEGER * time)339 int32_t CmEventRT::GetHWEndTime(LARGE_INTEGER* time)
340 {
341 
342     CM_STATUS eventStatus = CM_STATUS_QUEUED;
343 
344     GetStatusNoFlush(eventStatus);
345 
346     if( eventStatus == CM_STATUS_FINISHED )
347     {
348         time->QuadPart = m_globalSubmitTimeCpu.QuadPart + m_hwEndTimeStamp.QuadPart - m_submitTimeGpu.QuadPart;
349         return CM_SUCCESS;
350     }
351     else
352     {
353         return CM_FAILURE;
354     }
355 }
356 
GetCompleteTime(LARGE_INTEGER * time)357 int32_t CmEventRT::GetCompleteTime(LARGE_INTEGER* time)
358 {
359 
360     CM_STATUS eventStatus = CM_STATUS_QUEUED;
361 
362     GetStatusNoFlush(eventStatus);
363 
364     if( eventStatus == CM_STATUS_FINISHED )
365     {
366         *time = m_completeTime;
367         return CM_SUCCESS;
368     }
369     else
370     {
371         return CM_FAILURE;
372     }
373 
374 }
375 
GetEnqueueTime(LARGE_INTEGER * time)376 int32_t CmEventRT::GetEnqueueTime(LARGE_INTEGER* time)
377 {
378     CM_STATUS eventStatus = CM_STATUS_QUEUED;
379 
380     GetStatusNoFlush( eventStatus );
381 
382     if ( eventStatus == CM_STATUS_FINISHED )
383     {
384         *time = m_enqueueTime;
385         return CM_SUCCESS;
386     }
387     else
388     {
389         return CM_FAILURE;
390     }
391 
392 }
393 
SetKernelNames(CmTaskRT * task,CmThreadSpaceRT * threadSpace,CmThreadGroupSpace * threadGroupSpace)394 int32_t CmEventRT::SetKernelNames(CmTaskRT* task, CmThreadSpaceRT* threadSpace, CmThreadGroupSpace* threadGroupSpace)
395 {
396     uint32_t i = 0;
397     int32_t hr = CM_SUCCESS;
398     uint32_t threadCount;
399     m_kernelCount = task->GetKernelCount();
400 
401     // Alloc memory for kernel names
402     m_kernelNames = MOS_NewArray(char*, m_kernelCount);
403     m_threadSpace = MOS_NewArray(uint32_t, (4*m_kernelCount));
404     CM_CHK_NULL_GOTOFINISH(m_kernelNames, CM_OUT_OF_HOST_MEMORY);
405     CmSafeMemSet(m_kernelNames, 0, m_kernelCount*sizeof(char*) );
406     CM_CHK_NULL_GOTOFINISH(m_threadSpace, CM_OUT_OF_HOST_MEMORY);
407 
408     for (i = 0; i < m_kernelCount; i++)
409     {
410         m_kernelNames[i] = MOS_NewArray(char, CM_MAX_KERNEL_NAME_SIZE_IN_BYTE);
411         CM_CHK_NULL_GOTOFINISH(m_kernelNames[i], CM_OUT_OF_HOST_MEMORY);
412         CmKernelRT* kernel = task->GetKernelPointer(i);
413         MOS_SecureStrcpy(m_kernelNames[i], CM_MAX_KERNEL_NAME_SIZE_IN_BYTE, kernel->GetName());
414 
415         kernel->GetThreadCount(threadCount);
416         m_threadSpace[4 * i] = threadCount;
417         m_threadSpace[4 * i + 1] = 1;
418         m_threadSpace[4 * i + 2] = threadCount;
419         m_threadSpace[4 * i + 3] = 1;
420     }
421 
422     if (threadSpace)
423     {
424         uint32_t threadWidth, threadHeight;
425         threadSpace->GetThreadSpaceSize(threadWidth, threadHeight);
426         m_threadSpace[0] = threadWidth;
427         m_threadSpace[1] = threadHeight;
428         m_threadSpace[2] = threadWidth;
429         m_threadSpace[3] = threadHeight;
430     }
431     else if (threadGroupSpace)
432     {
433         uint32_t threadWidth, threadHeight, threadDepth, groupWidth, groupHeight, groupDepth;
434         threadGroupSpace->GetThreadGroupSpaceSize(threadWidth, threadHeight, threadDepth, groupWidth, groupHeight, groupDepth);
435         m_threadSpace[0] = threadWidth;
436         m_threadSpace[1] = threadHeight;
437         m_threadSpace[2] = threadWidth * groupWidth;
438         m_threadSpace[3] = threadHeight * groupHeight * groupDepth;
439     }
440 
441 finish:
442     if(hr == CM_OUT_OF_HOST_MEMORY)
443     {
444         if(m_kernelNames != nullptr)
445         {
446             for (uint32_t j = 0; j < m_kernelCount; j++)
447             {
448                 MosSafeDeleteArray(m_kernelNames[j]);
449             }
450         }
451         MosSafeDeleteArray(m_kernelNames);
452         MosSafeDeleteArray(m_threadSpace);
453     }
454     return hr;
455 }
456 
SetEnqueueTime(LARGE_INTEGER time)457 int32_t CmEventRT::SetEnqueueTime( LARGE_INTEGER time )
458 {
459     m_enqueueTime = time;
460     return CM_SUCCESS;
461 }
462 
SetCompleteTime(LARGE_INTEGER time)463 int32_t CmEventRT::SetCompleteTime( LARGE_INTEGER time )
464 {
465     m_completeTime = time;
466     return CM_SUCCESS;
467 }
468 
GetIndex(uint32_t & index)469 int32_t CmEventRT::GetIndex( uint32_t & index )
470 {
471     index = m_index;
472     return CM_SUCCESS;
473 }
474 
475 //*-----------------------------------------------------------------------------
476 //| Purpose:    Set Task ID
477 //| Returns:    Result of the operation.
478 //*-----------------------------------------------------------------------------
SetTaskDriverId(int32_t id)479 int32_t CmEventRT::SetTaskDriverId( int32_t id )
480 {
481     m_taskDriverId = id;
482     if( m_taskDriverId > -1 )
483         // Valid task id in driver, i.e. the task has been passed down to driver
484     {
485         m_status = CM_STATUS_FLUSHED;
486     }
487     else if( m_taskDriverId == -1 )
488         // -1 is an invalid task id in driver, i.e. the task has NOT been passed down to driver yet
489         // event is created at the enqueue time, so initial value is CM_STATUS_QUEUED
490     {
491         m_status = CM_STATUS_QUEUED;
492     }
493     else
494     {
495         CM_ASSERTMESSAGE("Error: Failed to set task driver ID.");
496         return CM_FAILURE;
497     }
498 
499     return CM_SUCCESS;
500 }
501 
502 //*-----------------------------------------------------------------------------
503 //| Purpose:    Set OS data
504 //| Returns:    Result of the operation.
505 //*-----------------------------------------------------------------------------
SetTaskOsData(void * data)506 int32_t CmEventRT::SetTaskOsData( void  *data )
507 {
508     m_osData = data;
509     return CM_SUCCESS;
510 }
511 
512 //*-----------------------------------------------------------------------------
513 //| Purpose:    Get Task ID
514 //| Returns:    Result of the operation.
515 //*-----------------------------------------------------------------------------
GetTaskDriverId(int32_t & id)516 int32_t CmEventRT::GetTaskDriverId( int32_t & id )
517 {
518     id = m_taskDriverId;
519     return CM_SUCCESS;
520 }
521 
522 //*-----------------------------------------------------------------------------
523 //| Purpose:    Query status of a task.
524 //| Returns:    Result of the operation.
525 //*-----------------------------------------------------------------------------
Query(void)526 int32_t CmEventRT::Query( void )
527 {
528     CM_RETURN_CODE  hr = CM_SUCCESS;
529 
530     CLock Lock(m_criticalSectionQuery);
531 
532     if( ( m_status != CM_STATUS_FLUSHED ) && ( m_status != CM_STATUS_STARTED ) )
533     {
534         return CM_FAILURE;
535     }
536 
537     CM_ASSERT( m_taskDriverId > -1 );
538     CM_HAL_QUERY_TASK_PARAM param;
539     CmSafeMemSet(&param, 0, sizeof(CM_HAL_QUERY_TASK_PARAM));
540     param.taskId = m_taskDriverId;
541     m_task->GetTaskType(param.taskType);
542     param.queueOption = m_queue->GetQueueOption();
543 
544     PCM_CONTEXT_DATA cmData = (PCM_CONTEXT_DATA)m_device->GetAccelData();
545 
546     CM_CHK_MOSSTATUS_GOTOFINISH_CMERROR(cmData->cmHalState->pfnQueryTask(cmData->cmHalState, &param));
547 
548     if( param.status == CM_TASK_FINISHED )
549     {
550         std::vector<CmQueueRT *> &queue = m_device->GetQueue();
551 
552         m_time = param.taskDurationNs;
553         m_ticks = param.taskDurationTicks;
554         m_hwStartTimeStampInTicks = param.taskHWStartTimeStampInTicks;
555         m_hwEndTimeStampInTicks = param.taskHWEndTimeStampInTicks;
556         m_status = CM_STATUS_FINISHED;
557 
558         //Update the state tracking array when a task is finished
559 
560         if (queue.size() == 0)
561         {
562             CM_ASSERTMESSAGE("Error: Invalid CmQueue.");
563             return CM_NULL_POINTER;
564         }
565 
566         UnreferenceIfNeeded(m_osData);
567 
568         CmNotifierGroup *notifiers = m_device->GetNotifiers();
569         if (notifiers != nullptr)
570         {
571             notifiers->NotifyTaskCompleted(m_task);
572         }
573 
574         m_globalSubmitTimeCpu = param.taskGlobalSubmitTimeCpu;
575         m_submitTimeGpu = param.taskSubmitTimeGpu;
576         m_hwStartTimeStamp = param.taskHWStartTimeStamp;
577         m_hwEndTimeStamp = param.taskHWEndTimeStamp;
578 
579         EVENT_LOG(this);
580     }
581     else if( param.status == CM_TASK_IN_PROGRESS )
582     {
583         m_status = CM_STATUS_STARTED;
584     }
585     else if (param.status == CM_TASK_RESET)
586     {
587         m_status = CM_STATUS_RESET;
588     }
589 
590 finish:
591     return hr;
592 }
593 
594 //*-----------------------------------------------------------------------------
595 //| Purpose:    Get m_status.
596 //| Returns:    return m_status.
597 //*-----------------------------------------------------------------------------
GetStatusWithoutFlush()598 CM_STATUS CmEventRT::GetStatusWithoutFlush()
599 {
600     return m_status;
601 }
602 
603 //*-----------------------------------------------------------------------------
604 //| Purpose:    GT-PIN : Get Surface Details
605 //| Returns:    result of operation
606 //*-----------------------------------------------------------------------------
GetSurfaceDetails(uint32_t kernIndex,uint32_t surfBTI,CM_SURFACE_DETAILS & outDetails)607 CM_RT_API  int32_t CmEventRT::GetSurfaceDetails(uint32_t kernIndex, uint32_t surfBTI,CM_SURFACE_DETAILS & outDetails )
608 {
609     CM_SURFACE_DETAILS *tempSurfInfo;
610     CmSurfaceManager *surfaceMgr;
611     m_device->GetSurfaceManager( surfaceMgr);
612 
613     if(!m_device->CheckGTPinEnabled())
614     {
615         CM_ASSERTMESSAGE("Error: Need to enable GT-Pin to call this function.");
616         return CM_NOT_IMPLEMENTED;
617     }
618 
619     if(kernIndex+1>m_surEntryInfoArrays.kernelNum)
620     {
621         CM_ASSERTMESSAGE("Error: Incorrect kernel Index.");
622         return CM_INVALID_ARG_VALUE;
623     }
624     uint32_t tempIndex=0;
625 
626     if (surfaceMgr->IsCmReservedSurfaceIndex(surfBTI))
627     {
628         tempIndex=surfBTI-CM_GLOBAL_SURFACE_INDEX_START;
629         if(tempIndex+1>m_surEntryInfoArrays.surfEntryInfosArray[kernIndex].globalSurfNum)
630         {
631             CM_ASSERTMESSAGE("Error: Incorrect surface Binding table Index.");
632             return CM_INVALID_ARG_VALUE;
633         }
634         tempSurfInfo = tempIndex +
635                         m_surEntryInfoArrays.surfEntryInfosArray[kernIndex].globalSurfInfos;
636 
637     }
638     else if (surfaceMgr->IsValidSurfaceIndex(surfBTI)) //not static buffer
639     {
640         if((surfBTI-surfaceMgr->ValidSurfaceIndexStart() +1)>m_surEntryInfoArrays.surfEntryInfosArray[kernIndex].usedIndex)
641         {
642             CM_ASSERTMESSAGE("Error: Incorrect surface Binding table Index.");
643             return CM_INVALID_ARG_VALUE;
644         }
645         else
646         {
647             tempIndex = surfBTI - surfaceMgr->ValidSurfaceIndexStart();
648         }
649         tempSurfInfo = tempIndex +
650                     m_surEntryInfoArrays.surfEntryInfosArray[kernIndex].surfEntryInfos;
651 
652     }
653     else
654     {//error
655         CM_ASSERTMESSAGE("Error: Incorrect surface Binding table Index.");
656         return CM_INVALID_ARG_VALUE;
657     }
658 
659     CmSafeMemCopy(&outDetails,tempSurfInfo,sizeof(CM_SURFACE_DETAILS));
660     return CM_SUCCESS;
661 }
662 
663 //*-----------------------------------------------------------------------------
664 //| Purpose:    GT-PIN : Set Surface Details
665 //| Returns:    Result of the operation.
666 //*-----------------------------------------------------------------------------
SetSurfaceDetails(CM_HAL_SURFACE_ENTRY_INFO_ARRAYS surfaceInfo)667 int32_t CmEventRT::SetSurfaceDetails(CM_HAL_SURFACE_ENTRY_INFO_ARRAYS surfaceInfo)
668 {
669     m_surEntryInfoArrays.kernelNum = surfaceInfo.kernelNum;
670     m_surEntryInfoArrays.surfEntryInfosArray = (CM_HAL_SURFACE_ENTRY_INFO_ARRAY*)MOS_AllocAndZeroMemory(
671                                                                    surfaceInfo.kernelNum *
672                                                                    sizeof(CM_HAL_SURFACE_ENTRY_INFO_ARRAY));
673 
674     if(m_surEntryInfoArrays.surfEntryInfosArray == nullptr)
675     {
676         CM_ASSERTMESSAGE("Error: Mem allocation fail.");
677         return CM_OUT_OF_HOST_MEMORY;
678     }
679 
680     for( uint32_t i = 0; i < surfaceInfo.kernelNum; i ++ )
681     {
682         //non static buffers
683         uint32_t surfEntryMax = surfaceInfo.surfEntryInfosArray[i].maxEntryNum;
684         uint32_t surfEntryNum = surfaceInfo.surfEntryInfosArray[i].usedIndex;
685 
686         m_surEntryInfoArrays.surfEntryInfosArray[i].usedIndex = surfEntryNum;
687         m_surEntryInfoArrays.surfEntryInfosArray[i].maxEntryNum = surfEntryMax;
688         CM_SURFACE_DETAILS* temp = (CM_SURFACE_DETAILS*)MOS_AllocAndZeroMemory(
689                                             surfEntryNum*
690                                             sizeof(CM_SURFACE_DETAILS));
691         if(temp == nullptr)
692         {
693             return CM_OUT_OF_HOST_MEMORY;
694          }
695         else
696         {
697             m_surEntryInfoArrays.surfEntryInfosArray[i].surfEntryInfos=temp;
698             CmSafeMemCopy(m_surEntryInfoArrays.surfEntryInfosArray[i].surfEntryInfos,
699                                          surfaceInfo.surfEntryInfosArray[i].surfEntryInfos,
700                                          surfEntryNum*sizeof(CM_SURFACE_DETAILS));
701          }
702 
703         //static buffers
704         uint32_t globalSurfNum = surfaceInfo.surfEntryInfosArray[i].globalSurfNum;
705         if(globalSurfNum>0)
706         {
707             m_surEntryInfoArrays.surfEntryInfosArray[i].globalSurfNum = globalSurfNum;
708             temp=(CM_SURFACE_DETAILS*)MOS_AllocAndZeroMemory(
709                   globalSurfNum*sizeof(CM_SURFACE_DETAILS));
710             if(temp == nullptr)
711             {
712                 return CM_OUT_OF_HOST_MEMORY;
713              }
714             else
715             {
716                 m_surEntryInfoArrays.surfEntryInfosArray[i].globalSurfInfos=temp;
717                 CmSafeMemCopy(m_surEntryInfoArrays.surfEntryInfosArray[i].globalSurfInfos,
718                                              surfaceInfo.surfEntryInfosArray[i].globalSurfInfos,
719                                              globalSurfNum*sizeof(CM_SURFACE_DETAILS));
720              }
721         }//(globalSurfNum>0)
722     }//for
723     return CM_SUCCESS;
724 }
725 
GetProfilingInfo(CM_EVENT_PROFILING_INFO infoType,size_t paramSize,void * inputValue,void * value)726 CM_RT_API  int32_t CmEventRT::GetProfilingInfo(CM_EVENT_PROFILING_INFO infoType, size_t paramSize, void  *inputValue, void  *value)
727 {
728     int32_t hr = CM_SUCCESS;
729 
730     CM_CHK_NULL_GOTOFINISH_CMERROR(value);
731 
732     switch(infoType)
733     {
734         case CM_EVENT_PROFILING_HWSTART:
735              CM_CHK_COND_RETURN((paramSize < sizeof(LARGE_INTEGER)), CM_INVALID_PARAM_SIZE, "Invalid parameter size.");
736              CM_CHK_CMSTATUS_GOTOFINISH(GetHWStartTime((LARGE_INTEGER *)value));
737              break;
738 
739         case CM_EVENT_PROFILING_HWEND:
740              CM_CHK_COND_RETURN((paramSize < sizeof(LARGE_INTEGER)), CM_INVALID_PARAM_SIZE, "Invalid parameter size.");
741              CM_CHK_CMSTATUS_GOTOFINISH(GetHWEndTime((LARGE_INTEGER *)value));
742              break;
743 
744         case CM_EVENT_PROFILING_SUBMIT:
745              CM_CHK_COND_RETURN((paramSize < sizeof(LARGE_INTEGER)), CM_INVALID_PARAM_SIZE, "Invalid parameter size.");
746              CM_CHK_CMSTATUS_GOTOFINISH(GetSubmitTime((LARGE_INTEGER *)value));
747              break;
748 
749         case CM_EVENT_PROFILING_COMPLETE:
750             CM_CHK_COND_RETURN((paramSize < sizeof(LARGE_INTEGER)), CM_INVALID_PARAM_SIZE, "Invalid parameter size.");
751              CM_CHK_CMSTATUS_GOTOFINISH(GetCompleteTime((LARGE_INTEGER *)value));
752              break;
753 
754         case CM_EVENT_PROFILING_ENQUEUE:
755             CM_CHK_COND_RETURN((paramSize < sizeof(LARGE_INTEGER)), CM_INVALID_PARAM_SIZE, "Invalid parameter size.");
756              CM_CHK_CMSTATUS_GOTOFINISH(GetEnqueueTime((LARGE_INTEGER *)value));
757              break;
758 
759         case CM_EVENT_PROFILING_KERNELCOUNT:
760              CM_CHK_COND_RETURN((paramSize < sizeof(uint32_t)), CM_INVALID_PARAM_SIZE, "Invalid parameter size.");
761              *(uint32_t *)value =  GetKernelCount();
762              break;
763 
764         case CM_EVENT_PROFILING_KERNELNAMES:
765              {
766                  CM_CHK_NULL_GOTOFINISH_CMERROR(inputValue);
767                  uint32_t kernelIndex = *(uint32_t *)inputValue;
768                  if( kernelIndex >= m_kernelCount)
769                  {
770                     hr = CM_INVALID_PARAM_SIZE;
771                     goto finish;
772                  }
773                  *((char **)value) = m_kernelNames[kernelIndex];
774              }
775              break;
776 
777         case CM_EVENT_PROFILING_THREADSPACE:
778              {
779                  CM_CHK_NULL_GOTOFINISH_CMERROR(inputValue);
780                  uint32_t kernelIndex = *(uint32_t *)inputValue;
781                  if( kernelIndex >= m_kernelCount)
782                  {
783                     hr = CM_INVALID_PARAM_SIZE;
784                     goto finish;
785                  }
786                  // 4 elements, global/local, width/height,
787                  CmSafeMemCopy(value, m_threadSpace + kernelIndex*4 , sizeof(uint32_t)*4);
788              }
789             break;
790 
791         case CM_EVENT_PROFILING_CALLBACK:
792             {
793                  CM_CHK_NULL_GOTOFINISH_CMERROR(inputValue);
794                  CM_CHK_NULL_GOTOFINISH_CMERROR(value);
795                  CM_CHK_CMSTATUS_GOTOFINISH(SetCallBack((EventCallBackFunction)inputValue, value));
796             }
797             break;
798 
799         default:
800             hr = CM_FAILURE;
801     }
802 
803 finish:
804     return hr;
805 }
806 
SetCallBack(EventCallBackFunction function,void * userData)807 int32_t CmEventRT:: SetCallBack(EventCallBackFunction function, void  *userData)
808 {
809     m_callbackFunction = function;
810     m_callbackUserData = userData;
811     return CM_SUCCESS;
812 }
813 
814 #if CM_LOG_ON
Log(const char * callerFuncName)815 std::string CmEventRT::Log(const char *callerFuncName)
816 {
817     static const char *statusStrings[] = {
818 #define ENUM_STRING(e)  #e
819             ENUM_STRING(CM_STATUS_QUEUED),
820             ENUM_STRING(CM_STATUS_FLUSHED),
821             ENUM_STRING(CM_STATUS_FINISHED),
822             ENUM_STRING(CM_STATUS_STARTED),
823             ENUM_STRING(CM_STATUS_RESET),
824 #undef ENUM_STRING
825     };
826 
827     std::ostringstream  oss;
828     oss << callerFuncName << "():\n"
829         << "<CmEvent>:" << reinterpret_cast<uint64_t>(this) << "\n"
830         << " Status: " << statusStrings[m_status] << "\n"
831         << " Duration:" << m_time << "ns\n"
832         << " DurationInTick:" << m_ticks << "\n"
833         << " StartTimeInTick:" << m_hwStartTimeStampInTicks << "\n"
834         << " EndTimeInTick:"<< m_hwEndTimeStampInTicks << "\n"
835         << " Kernel Cnt:"<< m_kernelCount << std::endl;
836 
837     return oss.str();
838 }
839 
GetHalState()840 CM_HAL_STATE* CmEventRT::GetHalState() { return m_device->GetHalState(); }
841 
842 #endif  // #if CM_LOG_ON
843 }  // namespace
844