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