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(¶m, 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, ¶m));
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