1 /*
2 * Copyright (c) 2017-2021, 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_device_rt.cpp
24 //! \brief Contains OS-agnostic CmDevice member functions.
25 //!
26
27 #include "cm_device_rt.h"
28
29 #include "cm_queue_rt.h"
30 #include "cm_surface_manager.h"
31 #include "cm_program.h"
32 #include "cm_kernel_rt.h"
33 #include "cm_task_rt.h"
34 #include "cm_buffer_rt.h"
35 #include "cm_thread_space_rt.h"
36 #include "cm_debug.h"
37 #include "cm_mem.h"
38 #include "cm_surface_vme.h"
39 #include "cm_sampler8x8_state_rt.h"
40 #include "cm_sampler_rt.h"
41 #include "cm_group_space.h"
42 #include "cm_surface_2d_rt.h"
43 #include "cm_surface_2d_up_rt.h"
44 #include "cm_surface_3d_rt.h"
45 #include "cm_vebox_rt.h"
46 #include "cm_printf_host.h"
47 #include "cm_execution_adv.h"
48 #include "cm_log.h"
49
50 struct CM_SET_CAPS
51 {
52 CM_SET_TYPE type;
53 union
54 {
55 uint32_t maxValue;
56 struct
57 {
58 uint32_t configRegsiter0;
59 uint32_t configRegsiter1;
60 uint32_t configRegsiter2;
61 uint32_t configRegsiter3;
62 };
63 };
64 };
65
66 namespace CMRT_UMD
67 {
68 const uint32_t CmDeviceRTBase::m_maxPrintBuffer = 16;
69
70 //*-----------------------------------------------------------------------------
71 //| Purpose: Cm Device Acquire: Increae the m_cmDeviceRefCount
72 //| Returns: CM_SUCCESS
73 //*-----------------------------------------------------------------------------
Acquire()74 int32_t CmDeviceRTBase::Acquire()
75 {
76 // Enter critical section
77 CLock locker(m_criticalSectionDeviceRefCount);
78
79 m_cmDeviceRefCount ++;
80 return CM_SUCCESS;
81 }
82
83 //*-----------------------------------------------------------------------------
84 //| Purpose: Cm Device Relase: Decrease the m_cmDeviceRefCount
85 //| Returns: Reference count of Cm Device
86 //*-----------------------------------------------------------------------------
Release()87 int32_t CmDeviceRTBase::Release()
88 {
89 // Enter critical section
90 CLock locker(m_criticalSectionDeviceRefCount);
91
92 m_cmDeviceRefCount --;
93
94 return m_cmDeviceRefCount;
95 }
96
97 //*-----------------------------------------------------------------------------
98 //| Purpose: Constructor of CmDevice
99 //| Returns: None.
100 //*-----------------------------------------------------------------------------
CmDeviceRTBase(uint32_t options)101 CmDeviceRTBase::CmDeviceRTBase(uint32_t options):
102 m_memObjectCount({ 0 }),
103 m_mosContext (nullptr),
104 m_accelData (nullptr),
105 m_accelSize (0),
106 m_surfaceMgr( nullptr ),
107 m_programArray( CM_INIT_PROGRAM_COUNT ),
108 m_programCount( 0 ),
109 m_kernelArray( CM_INIT_KERNEL_COUNT ),
110 m_kernelCount( 0 ),
111 m_sampler8x8Array( CM_INIT_SAMPLER_COUNT ),
112 m_samplerArray( CM_INIT_SAMPLER_COUNT ),
113 m_threadSpaceArray( CM_INIT_THREADSPACE_COUNT ),
114 m_threadSpaceCount( 0 ),
115 m_veboxArray(CM_INIT_VEBOX_COUNT),
116 m_veboxCount(0),
117 m_hJITDll(nullptr),
118 m_fJITCompile(nullptr),
119 m_fJITCompile_v2(nullptr),
120 m_fFreeBlock(nullptr),
121 m_fJITVersion(nullptr),
122 m_ddiVersion( 0 ),
123 m_platform(IGFX_UNKNOWN_CORE),
124 m_cmDeviceRefCount(0),
125 m_gpuCopyKernelProgram(nullptr),
126 m_surfInitKernelProgram(nullptr),
127 m_InitCmQueue(nullptr),
128 m_kernel0(nullptr),
129 m_kernel1(nullptr),
130 m_gpuInitTask0(nullptr),
131 m_gpuInitTask1(nullptr),
132 #if USE_EXTENSION_CODE
133 m_gtpin(nullptr),
134 #endif
135 m_isPrintEnabled(false),
136 m_printBufferSize(0),
137 m_threadGroupSpaceArray(CM_INIT_THREADGROUPSPACE_COUNT),
138 m_threadGroupSpaceCount(0),
139 m_taskArray(CM_INIT_TASK_COUNT),
140 m_taskCount(0),
141 m_nGPUFreqOriginal(0),
142 m_nGPUFreqMin(0),
143 m_nGPUFreqMax(0),
144 m_vtuneOn(false),
145 m_isDriverStoreEnabled(0),
146 m_notifierGroup(nullptr),
147 m_hasGpuCopyKernel(false),
148 m_hasGpuInitKernel(false),
149 m_kernelsLoaded(0),
150 m_preloadKernelEnabled(true),
151 m_queuePriority(CM_DEVICE_CREATE_PRIORITY_DEFAULT)
152 {
153 //Initialize the structures in the class
154 MOS_ZeroMemory(&m_halMaxValues, sizeof(m_halMaxValues));
155 MOS_ZeroMemory(&m_halMaxValuesEx, sizeof(m_halMaxValuesEx));
156 MOS_ZeroMemory(&m_cmHalCreateOption, sizeof(m_cmHalCreateOption));
157
158 //Initialize Dev Create Param
159 InitDevCreateOption( m_cmHalCreateOption, options );
160
161 // Create the notifers
162 m_notifierGroup = MOS_New(CmNotifierGroup);
163 }
164
165 //*-----------------------------------------------------------------------------
166 //| Purpose: The common part of destructor of CmDevice, that is OS independent
167 //| Returns: None.
168 //*-----------------------------------------------------------------------------
DestructCommon()169 void CmDeviceRTBase::DestructCommon()
170 {
171 // Delete Predefined Program
172 if(m_gpuCopyKernelProgram)
173 {
174 DestroyProgram(m_gpuCopyKernelProgram);
175 }
176
177 if(m_surfInitKernelProgram)
178 {
179 DestroyProgram(m_surfInitKernelProgram);
180 }
181
182 //Free the surface/memory for print buffer
183 while(!m_printBufferMems.empty())
184 {
185 uint8_t *mem = m_printBufferMems.front();
186 m_printBufferMems.pop_front();
187 MOS_AlignedFreeMemory(mem);
188 }
189
190 while(!m_printBufferUPs.empty())
191 {
192 CmBufferUP *buffer = m_printBufferUPs.front();
193 m_printBufferUPs.pop_front();
194 DestroyBufferUP(buffer);
195 }
196
197 #if USE_EXTENSION_CODE
198 // Free CmGTPin
199 MOS_Delete(m_gtpin);
200 #endif
201
202 // Solve resource release dependency issue
203 // Flush Queue to make sure no task internal and connected resources left.
204 m_criticalSectionQueue.Acquire();
205 for (auto iter = m_queue.begin(); iter != m_queue.end(); iter++)
206 {
207 (*iter)->CleanQueue();
208 }
209 m_criticalSectionQueue.Release();
210 PCM_CONTEXT_DATA pCmData = (PCM_CONTEXT_DATA)m_accelData;
211 if (pCmData && pCmData->cmHalState && pCmData->cmHalState->advExecutor)
212 {
213 pCmData->cmHalState->advExecutor->WaitForAllTasksFinished();
214 }
215
216 for( uint32_t i = 0; i < m_kernelCount; i ++ )
217 {
218 CmKernelRT* kernel = (CmKernelRT*)m_kernelArray.GetElement( i );
219 if( kernel )
220 {
221 CmProgramRT* program = nullptr;
222 kernel->GetCmProgram(program);
223 uint32_t indexInProgramArray;
224 for (indexInProgramArray = 0; indexInProgramArray < m_programArray.GetSize(); indexInProgramArray++)
225 {
226 if (program == m_programArray.GetElement( indexInProgramArray ))
227 {
228 break;
229 }
230 }
231 CmKernelRT::Destroy( kernel, program );
232 if ((program == nullptr) && (indexInProgramArray < m_programArray.GetSize()))
233 {
234 m_programArray.SetElement(indexInProgramArray, nullptr);
235 }
236 }
237 }
238 m_kernelArray.Delete();
239
240 for( uint32_t i = 0; i < m_programArray.GetSize(); i ++ )
241 {
242 CmProgramRT* program = (CmProgramRT*)m_programArray.GetElement( i );
243 while( program ) // Program can be acquired more than once
244 {
245 CmProgramRT::Destroy( program );
246 }
247 }
248 m_programArray.Delete();
249
250 for( uint32_t i = 0; i < m_samplerArray.GetSize(); i ++ )
251 {
252 CmSamplerRT* sampler = (CmSamplerRT *)m_samplerArray.GetElement( i );
253
254 if(sampler)
255 {
256 SamplerIndex* index = nullptr;
257 sampler->GetIndex( index );
258 CM_ASSERT( index );
259 uint32_t indexValue = index->get_data();
260
261 CmSamplerRT::Destroy( sampler );
262 UnregisterSamplerState( indexValue );
263 }
264 }
265 m_samplerArray.Delete();
266
267 for(uint32_t i = 0; i < m_sampler8x8Array.GetSize(); i ++ )
268 {
269 CmSampler8x8State_RT* sampler8x8 = (CmSampler8x8State_RT* )m_sampler8x8Array.GetElement( i );
270 if(sampler8x8)
271 {
272 SamplerIndex* index = nullptr;
273 sampler8x8->GetIndex( index );
274 CM_ASSERT( index );
275 uint32_t indexValue = index->get_data();
276 CmSampler8x8State_RT::Destroy( sampler8x8 );
277 UnregisterSampler8x8State( indexValue );
278 }
279 }
280 m_sampler8x8Array.Delete();
281
282 uint32_t threadSpaceArrayUsedSize = m_threadSpaceArray.GetSize();
283 for( uint32_t i = 0; i < threadSpaceArrayUsedSize; i ++ )
284 {
285 CmThreadSpaceRT* threadSpaceRT = (CmThreadSpaceRT*)m_threadSpaceArray.GetElement( i );
286 if( threadSpaceRT )
287 {
288 CmThreadSpaceRT::Destroy( threadSpaceRT );
289 }
290 }
291 m_threadSpaceArray.Delete();
292
293 for( uint32_t i = 0; i < m_threadGroupSpaceCount; i ++ ) // Destroy thread group space array
294 {
295 CmThreadGroupSpace* threadGroupSpace = (CmThreadGroupSpace*)m_threadGroupSpaceArray.GetElement( i );
296 if( threadGroupSpace )
297 {
298 CmThreadGroupSpace::Destroy( threadGroupSpace );
299 }
300 }
301 m_threadGroupSpaceArray.Delete();
302
303 uint32_t taskArrayUsedSize = m_taskArray.GetSize();
304 for( uint32_t i = 0; i < taskArrayUsedSize; i ++ ) // Destroy task array
305 {
306 CmTaskRT* task = (CmTaskRT*)m_taskArray.GetElement( i );
307 if( task )
308 {
309 CmTaskRT::Destroy( task );
310 }
311 }
312 m_taskArray.Delete();
313
314 for( uint32_t i = 0; i < m_veboxCount; i ++ ) // Destroy Vebox array
315 {
316 CmVeboxRT* vebox = (CmVeboxRT*)m_veboxArray.GetElement(i);
317 if (vebox)
318 {
319 CmVeboxRT::Destroy(vebox);
320 }
321 }
322 m_veboxArray.Delete();
323
324 //Destroy Surface Manager
325 CmSurfaceManager::Destroy( m_surfaceMgr );
326
327 //Destroy Queue: Queue must be released after surface manager
328 m_criticalSectionQueue.Acquire();
329 for (auto iter = m_queue.begin(); iter != m_queue.end();)
330 {
331 DestroyQueue(*iter);
332 iter = m_queue.erase(iter);
333 }
334 m_criticalSectionQueue.Release();
335
336 // Notify the listeners
337 if (m_notifierGroup != nullptr)
338 {
339 m_notifierGroup->NotifyDeviceDestroyed(this);
340 }
341
342 //Free the notifiers
343 if (m_notifierGroup != nullptr)
344 {
345 MOS_Delete(m_notifierGroup);
346 }
347
348 //Free DLL handle if it is there
349 if (m_hJITDll)
350 {
351 MosUtilities::MosFreeLibrary(m_hJITDll);
352 }
353 }
354
355
356 //*-----------------------------------------------------------------------------
357 //| Purpose: Create Aux Device and Initialize it
358 //| Returns: Result of the operation.
359 //*-----------------------------------------------------------------------------
Initialize(MOS_CONTEXT * mosContext)360 int32_t CmDeviceRTBase::Initialize(MOS_CONTEXT *mosContext)
361 {
362 int32_t result = InitializeOSSpecific(mosContext);
363
364 if( result != CM_SUCCESS )
365 {
366 CM_ASSERTMESSAGE("Error: Initialize OS specific failure.");
367 return result;
368 }
369
370 m_surfaceMgr = nullptr;
371 CmDeviceRT *cmDevice = static_cast<CmDeviceRT*>(this);
372 CM_CHK_NULL_RETURN_CMERROR(cmDevice);
373
374 result = CmSurfaceManager::Create(
375 cmDevice,
376 m_halMaxValues,
377 m_halMaxValuesEx,
378 m_surfaceMgr );
379
380 if( result != CM_SUCCESS )
381 {
382 CM_ASSERTMESSAGE("Error: Create CmSurfaceManager failure.");
383 return result;
384 }
385
386 result = SetSurfaceArraySizeForAlias();
387 if (result != CM_SUCCESS)
388 {
389 CM_ASSERTMESSAGE("Error: Set surface array size failure.");
390 return result;
391 }
392
393 ReadVtuneProfilingFlag();
394
395 // Load Predefined Kernels
396 if (m_preloadKernelEnabled)
397 {
398 CmProgram* tmpProgram = nullptr;
399 int32_t ret = LoadPredefinedCopyKernel(tmpProgram);
400 if (ret == CM_SUCCESS)
401 {
402 m_hasGpuCopyKernel = true;
403 }
404 ret = LoadPredefinedInitKernel(tmpProgram);
405 if (ret == CM_SUCCESS)
406 {
407 m_hasGpuInitKernel = true;
408 }
409 }
410
411 // prepare GPU predefined queue/kernel/task for surface init
412 #if !defined(_FULL_OPEN_SOURCE)
413 result = PrepareGPUinitSurface();
414 #endif
415 // get the last tracker
416 PCM_HAL_STATE state = (( PCM_CONTEXT_DATA )m_accelData)->cmHalState;
417 m_surfaceMgr->SetLatestVeboxTrackerAddr(state->renderHal->veBoxTrackerRes.data);
418
419 if (m_notifierGroup != nullptr)
420 {
421 m_notifierGroup->NotifyDeviceCreated(this);
422 }
423
424 DEVICE_LOG(this);
425
426 return result;
427 }
428
429 //*-----------------------------------------------------------------------------
430 //| Purpose: Create Buffer
431 //| Arguments : size [in] Size of the Buffer
432 //| surface [in/out] Reference to Pointer to CmBuffer
433 //| Returns: Result of the operation.
434 //*-----------------------------------------------------------------------------
CreateBuffer(uint32_t size,CmBuffer * & surface)435 CM_RT_API int32_t CmDeviceRTBase::CreateBuffer(uint32_t size, CmBuffer* & surface)
436 {
437 INSERT_API_CALL_LOG(GetHalState());
438
439 if( ( size < CM_MIN_SURF_WIDTH ) || ( size > CM_MAX_1D_SURF_WIDTH ) )
440 {
441 CM_ASSERTMESSAGE("Error: Invalid buffer size.");
442 return CM_INVALID_WIDTH;
443 }
444
445 CLock locker(m_criticalSectionSurface);
446
447 CmBuffer_RT* bufferRT = nullptr;
448 void *sysMem = nullptr;
449 int result = m_surfaceMgr->CreateBuffer(size, CM_BUFFER_N, false, bufferRT, nullptr, sysMem, false, CM_DEFAULT_COMPARISON_VALUE);
450 surface = static_cast< CmBuffer* >(bufferRT);
451
452 return result;
453 }
454
455 //!
456 //! \brief Create a CmBuffer from an existing MOS Resource.
457 //! \details CmBuffer is a wrapper of that MOS resource. This Mos resource is
458 //! owned by caller.
459 //! \param [in] mosResource
460 //! pointer to MOS resource.
461 //! \param [in,out] surface
462 //! reference to pointer of surface to be created.
463 //! \retval CM_SUCCESS if the CmBuffer is successfully created.
464 //! \retval CM_INVALID_MOS_RESOURCE_HANDLE if mosResource is nullptr.
465 //! \retval CM_OUT_OF_HOST_MEMORY if out of system memory
466 //! \retval CM_EXCEED_SURFACE_AMOUNT if maximum amount of 1D surfaces is exceeded.
467 //! \retval CM_FAILURE otherwise
468 //!
CreateBuffer(PMOS_RESOURCE mosResource,CmBuffer * & surface)469 CM_RT_API int32_t CmDeviceRTBase::CreateBuffer(PMOS_RESOURCE mosResource,
470 CmBuffer* & surface)
471 {
472 INSERT_API_CALL_LOG(GetHalState());
473
474 if(mosResource == nullptr)
475 {
476 return CM_INVALID_MOS_RESOURCE_HANDLE;
477 }
478
479 PCM_CONTEXT_DATA cmData = (PCM_CONTEXT_DATA)GetAccelData();
480 PCM_HAL_STATE state = cmData->cmHalState;
481
482 MOS_SURFACE mosSurfDetails;
483 MOS_ZeroMemory(&mosSurfDetails, sizeof(mosSurfDetails));
484 int hr = state->osInterface->pfnGetResourceInfo(state->osInterface, mosResource, &mosSurfDetails);
485 if(hr != MOS_STATUS_SUCCESS)
486 {
487 CM_ASSERTMESSAGE("Error: Get resource info failure.");
488 return hr;
489 }
490
491 if( (mosSurfDetails.dwWidth < CM_MIN_SURF_WIDTH ) || (mosSurfDetails.dwWidth > CM_MAX_1D_SURF_WIDTH ) )
492 {
493 CM_ASSERTMESSAGE("Error: Invalid buffer size.");
494 return CM_INVALID_WIDTH;
495 }
496
497 CLock locker(m_criticalSectionSurface);
498 CmBuffer_RT* buffer = nullptr;
499 void* sysMem = nullptr;
500 int ret = m_surfaceMgr->CreateBuffer(mosSurfDetails.dwWidth, CM_BUFFER_N, false,
501 buffer, mosResource, sysMem, false, CM_DEFAULT_COMPARISON_VALUE);
502 surface = static_cast< CmBuffer* >(buffer);
503
504 return ret;
505 }
506
507 //*--------------------------------------------------------------------------------------------
508 //| Purpose: Create BufferUp
509 //| Arguments : size [in] Size of the Buffer, should be uint32_t-aligned
510 //| sysMem [in] Pointer to host memory, must be page(4K bytes)-aligned.
511 //| surface [in/out] Reference to Pointer to CmBufferUP
512 //| Returns: Result of the operation.
513 //*-----------------------------------------------------------------------------
CreateBufferUP(uint32_t size,void * sysMem,CmBufferUP * & surface)514 CM_RT_API int32_t CmDeviceRTBase::CreateBufferUP(uint32_t size,
515 void* sysMem,
516 CmBufferUP* & surface)
517 {
518 INSERT_API_CALL_LOG(GetHalState());
519
520 // size should be in the valid range and be aligned in uint32_t
521 if( ( size < CM_MIN_SURF_WIDTH ) || ( size > CM_MAX_1D_SURF_WIDTH ) || (size % sizeof(uint32_t)))
522 {
523 CM_ASSERTMESSAGE("Error: Invalid buffer size.\n");
524 return CM_INVALID_WIDTH;
525 }
526
527 if (nullptr == sysMem)
528 {
529 CM_ASSERTMESSAGE("Error: Pointer to host memory is null.\n");
530 return CM_INVALID_ARG_VALUE;
531 }
532 auto uintPtr = reinterpret_cast<uintptr_t>(sysMem);
533 if (uintPtr & (0x1000 - 1))
534 {
535 CM_ASSERTMESSAGE("Error: Pointer to host memory isn't 4K-aligned.\n");
536 return CM_INVALID_ARG_VALUE;
537 }
538
539 CLock locker(m_criticalSectionSurface);
540
541 CmBuffer_RT* bufferRT = nullptr;
542 int result = m_surfaceMgr->CreateBuffer( size, CM_BUFFER_UP, false, bufferRT, nullptr, sysMem, false, CM_DEFAULT_COMPARISON_VALUE );
543 surface = static_cast< CmBufferUP* >(bufferRT);
544
545 return result;
546 }
547
548 //*----------------------------------------------------------------------------
549 //| Purpose: Destroy BufferUp
550 //| Arguments : surface [in] Reference to Pointer to CmBuffer
551 //| Returns: Result of the operation.
552 //*-----------------------------------------------------------------------------
DestroyBufferUP(CmBufferUP * & surface)553 CM_RT_API int32_t CmDeviceRTBase::DestroyBufferUP(CmBufferUP* & surface)
554 {
555 INSERT_API_CALL_LOG(GetHalState());
556
557 CmBuffer_RT* temp = static_cast< CmBuffer_RT* >(surface);
558 if (nullptr == temp)
559 {
560 return CM_NULL_POINTER;
561 }
562
563 CLock locker(m_criticalSectionSurface);
564
565 int32_t status = m_surfaceMgr->DestroySurface(temp, APP_DESTROY);
566
567 if (status != CM_FAILURE) //CM_SURFACE_IN_USE may be returned, which should be treated as SUCCESS.
568 {
569 surface = nullptr;
570 return CM_SUCCESS;
571 }
572 else
573 {
574 return CM_FAILURE;
575 }
576 return status;
577 }
578
579 //*----------------------------------------------------------------------------
580 //| Purpose: Forces the BufferUP to be destroyed
581 //| Arguments : surface [in] Reference to Pointer to CmBuffer
582 //| Returns: Result of the operation.
583 //*-----------------------------------------------------------------------------
ForceDestroyBufferUP(CmBufferUP * & surface)584 CM_RT_API int32_t CmDeviceRTBase::ForceDestroyBufferUP(CmBufferUP* & surface)
585 {
586 INSERT_API_CALL_LOG(GetHalState());
587
588 CmBuffer_RT* temp = static_cast< CmBuffer_RT* >(surface);
589 if (nullptr == temp)
590 {
591 return CM_NULL_POINTER;
592 }
593
594 CLock locker(m_criticalSectionSurface);
595
596 int32_t status = m_surfaceMgr->DestroySurface(temp, FORCE_DESTROY);
597
598 if(status == CM_SUCCESS)
599 {
600 surface = nullptr;
601 }
602 return status;
603 }
604
605 //*--------------------------------------------------------------------------------------------
606 //| Purpose: Create Surface 2D UP
607 //| Arguments : width [in] width of the CmSurface2DUP
608 //| height [in] height of the CmSurface2DUP
609 //| format [in] format of the CmSurface2DUP
610 //|
611 //| sysMem [in] Pointer to host memory, must be page(4K bytes)-aligned.
612 //| surface [in/out] Reference to Pointer to CmSurface2DUP
613 //| Returns: Result of the operation.
614 //*-----------------------------------------------------------------------------
CreateSurface2DUP(uint32_t width,uint32_t height,CM_SURFACE_FORMAT format,void * sysMem,CmSurface2DUP * & surface)615 CM_RT_API int32_t CmDeviceRTBase::CreateSurface2DUP(uint32_t width,
616 uint32_t height,
617 CM_SURFACE_FORMAT format,
618 void* sysMem,
619 CmSurface2DUP* & surface )
620 {
621 INSERT_API_CALL_LOG(GetHalState());
622
623 int32_t result = m_surfaceMgr->Surface2DSanityCheck(width, height, format);
624 if (result != CM_SUCCESS)
625 {
626 CM_ASSERTMESSAGE("Error: Surface2D sanity check failure.\n");
627 return result;
628 }
629
630 if (sysMem == nullptr)
631 {
632 CM_ASSERTMESSAGE("Error: Pointer to host memory is null.\n");
633 return CM_INVALID_ARG_VALUE;
634 }
635 auto uintPtr = reinterpret_cast<uintptr_t>(sysMem);
636 if (uintPtr & (0x1000 - 1))
637 {
638 CM_ASSERTMESSAGE("Error: Pointer to host memory isn't 4K-aligned.\n");
639 return CM_INVALID_ARG_VALUE;
640 }
641
642 CmSurface2DUPRT *surfaceRT = nullptr;
643 CLock locker(m_criticalSectionSurface);
644 result = m_surfaceMgr->CreateSurface2DUP( width, height, format, sysMem, surfaceRT );
645 surface = surfaceRT;
646 return result;
647 }
648
649 //*-----------------------------------------------------------------------------
650 //| Purpose: Create Surface 3D
651 //| Arguments :
652 //| width [in] width of the CmSurface3D
653 //| height [in] height of the CmSurface3D
654 //| format [in] format of the CmSurface3D
655 //| depth [in] depth of the CmSurface3D
656 //| surface [out] Reference to Pointer to CmSurface3D
657 //| Returns: Result of the operation.
658 //*-----------------------------------------------------------------------------
CreateSurface3D(uint32_t width,uint32_t height,uint32_t depth,CM_SURFACE_FORMAT format,CmSurface3D * & surface)659 CM_RT_API int32_t CmDeviceRTBase::CreateSurface3D(uint32_t width,
660 uint32_t height,
661 uint32_t depth,
662 CM_SURFACE_FORMAT format,
663 CmSurface3D* & surface )
664 {
665 INSERT_API_CALL_LOG(GetHalState());
666
667 if( ( width < CM_MIN_SURF_WIDTH ) || ( width > CM_MAX_3D_SURF_WIDTH ) )
668 {
669 CM_ASSERTMESSAGE("Error: Invalid surface 3D width.");
670 return CM_INVALID_WIDTH;
671
672 }
673 if( ( height < CM_MIN_SURF_HEIGHT ) || ( height > CM_MAX_3D_SURF_HEIGHT ) )
674 {
675 CM_ASSERTMESSAGE("Error: Invalid surface 3D height.");
676 return CM_INVALID_HEIGHT;
677 }
678
679 if( ( depth < CM_MIN_SURF_DEPTH ) || ( depth > CM_MAX_3D_SURF_DEPTH ) )
680 {
681 CM_ASSERTMESSAGE("Error: Invalid surface 3D depth.");
682 return CM_INVALID_DEPTH;
683 }
684
685 CLock locker(m_criticalSectionSurface);
686 CmSurface3DRT *surfaceRT = nullptr;
687 int ret = m_surfaceMgr->CreateSurface3D( width, height, depth, format, surfaceRT );
688 surface = surfaceRT;
689 return ret;
690 }
691
DestroySurface(CmBuffer * & surface)692 CM_RT_API int32_t CmDeviceRTBase::DestroySurface( CmBuffer* & surface)
693 {
694 CmBuffer_RT* temp = static_cast< CmBuffer_RT* >(surface);
695 if (nullptr == temp)
696 {
697 return CM_NULL_POINTER;
698 }
699
700 CLock locker(m_criticalSectionSurface);
701
702 int32_t status = m_surfaceMgr->DestroySurface( temp, APP_DESTROY);
703
704 if (status != CM_FAILURE) //CM_SURFACE_IN_USE, or CM_SURFACE_CACHED may be returned, which should be treated as SUCCESS.
705 {
706 surface = nullptr;
707 return CM_SUCCESS;
708 }
709 else
710 {
711 return CM_FAILURE;
712 }
713 }
714
715 //*----------------------------------------------------------------------------
716 //| Purpose: Destroy CmSurface2DUP
717 //| Returns: Result of the operation.
718 //*-----------------------------------------------------------------------------
DestroySurface2DUP(CmSurface2DUP * & surface)719 CM_RT_API int32_t CmDeviceRTBase::DestroySurface2DUP( CmSurface2DUP* & surface)
720 {
721 INSERT_API_CALL_LOG(GetHalState());
722
723 CLock locker(m_criticalSectionSurface);
724
725 CmSurface2DUPRT *surfaceRT = static_cast<CmSurface2DUPRT *>(surface);
726 if (nullptr == surfaceRT)
727 {
728 return CM_NULL_POINTER;
729 }
730
731 int32_t status = m_surfaceMgr->DestroySurface( surfaceRT, APP_DESTROY );
732
733 if (status != CM_FAILURE) //CM_SURFACE_IN_USE, or CM_SURFACE_CACHED may be returned, which should be treated as SUCCESS.
734 {
735 surface = nullptr;
736 return CM_SUCCESS;
737 }
738 else
739 {
740 return CM_FAILURE;
741 }
742 }
743
744 //*----------------------------------------------------------------
745 //| Purpose: Destroys a CmSurface2D object and returns the status.
746 //*----------------------------------------------------------------
DestroySurface(CmSurface2D * & surface)747 CM_RT_API int32_t CmDeviceRTBase::DestroySurface(CmSurface2D* &surface)
748 {
749 INSERT_API_CALL_LOG(GetHalState());
750 CLock locker(m_criticalSectionSurface);
751
752 CmSurface2DRT *surfaceRT = static_cast<CmSurface2DRT*>(surface);
753 if (nullptr == surfaceRT)
754 {
755 return CM_NULL_POINTER;
756 }
757 int32_t status = m_surfaceMgr->DestroySurface(surfaceRT, APP_DESTROY);
758
759 if (status != CM_FAILURE) // CM_SURFACE_IN_USE may be returned, which should be treated as SUCCESS.
760 {
761 surface = nullptr;
762 return CM_SUCCESS;
763 }
764 else
765 {
766 return CM_FAILURE;
767 }
768 }
769
770 //*------------------------------------------------------------------
771 //| Purpose: Destroys a CmSurface3D object and returns the status.
772 //*------------------------------------------------------------------
DestroySurface(CmSurface3D * & surface)773 CM_RT_API int32_t CmDeviceRTBase::DestroySurface( CmSurface3D* & surface)
774 {
775 INSERT_API_CALL_LOG(GetHalState());
776
777 CLock locker(m_criticalSectionSurface);
778
779 CmSurface3DRT *surfaceRT = static_cast<CmSurface3DRT *>(surface);
780 if (nullptr == surfaceRT)
781 {
782 return CM_NULL_POINTER;
783 }
784
785 int32_t status = m_surfaceMgr->DestroySurface( surfaceRT, APP_DESTROY);
786
787 if (status != CM_FAILURE) //CM_SURFACE_IN_USE, or CM_SURFACE_CACHED may be returned, which should be treated as SUCCESS.
788 {
789 surface = nullptr;
790 return CM_SUCCESS;
791 }
792 else
793 {
794 return CM_FAILURE;
795 }
796 }
797
798 //*----------------------------------------------------------------------------
799 //| Purpose: Get Current platform information
800 //|
801 //| Returns: Result of the operation.
802 //*-----------------------------------------------------------------------------
GetGenPlatform(uint32_t & platform)803 CM_RT_API int32_t CmDeviceRTBase::GetGenPlatform( uint32_t &platform )
804 {
805 if( m_platform != IGFX_UNKNOWN_CORE)
806 {
807 platform = m_platform;
808 return CM_SUCCESS;
809 }
810
811 platform = IGFX_UNKNOWN_CORE;
812
813 int32_t hr = 0;
814 CM_QUERY_CAPS queryCaps;
815 uint32_t querySize = sizeof( CM_QUERY_CAPS );
816
817 CmSafeMemSet( &queryCaps, 0, sizeof( queryCaps ) );
818 queryCaps.type = CM_QUERY_GPU;
819
820 hr = GetCapsInternal( &queryCaps, &querySize);
821 if( FAILED(hr) )
822 {
823 CM_ASSERTMESSAGE("Error: Failed to get current GPU platform information.");
824 return CM_FAILURE;
825 }
826 if (queryCaps.version)
827 {
828 platform = queryCaps.version;
829 }
830
831 return CM_SUCCESS;
832 }
833
834 //*----------------------------------------------------------------------------
835 //| Purpose: Get Surface2D information: pitch and physical size in Video memory
836 //|
837 //| Returns: Result of the operation.
838 //*-----------------------------------------------------------------------------
GetSurface2DInfo(uint32_t width,uint32_t height,CM_SURFACE_FORMAT format,uint32_t & pitch,uint32_t & physicalSize)839 CM_RT_API int32_t CmDeviceRTBase::GetSurface2DInfo(uint32_t width,
840 uint32_t height,
841 CM_SURFACE_FORMAT format,
842 uint32_t & pitch,
843 uint32_t & physicalSize)
844 {
845 INSERT_API_CALL_LOG(GetHalState());
846
847 CM_RETURN_CODE hr = CM_SUCCESS;
848 CM_HAL_SURFACE2D_UP_PARAM inParam;
849 PCM_CONTEXT_DATA cmData;
850 PCM_HAL_STATE cmHalState;
851
852 CM_CHK_CMSTATUS_GOTOFINISH(m_surfaceMgr->Surface2DSanityCheck(width, height, format));
853
854 CmSafeMemSet( &inParam, 0, sizeof( CM_HAL_SURFACE2D_UP_PARAM ) );
855 inParam.width = width;
856 inParam.height = height;
857 inParam.format = format;
858
859 cmData = (PCM_CONTEXT_DATA)GetAccelData();
860 cmHalState = cmData->cmHalState;
861 CM_CHK_MOSSTATUS_GOTOFINISH_CMERROR(cmHalState->pfnGetSurface2DPitchAndSize(cmHalState, &inParam));
862
863 pitch = inParam.pitch;
864 physicalSize = inParam.physicalSize;
865
866 finish:
867 return hr;
868 }
869
GetSurfaceManager(CmSurfaceManager * & surfaceMgr)870 int32_t CmDeviceRTBase::GetSurfaceManager( CmSurfaceManager* & surfaceMgr )
871 {
872 surfaceMgr = m_surfaceMgr;
873 return CM_SUCCESS;
874 }
875
GetSurfaceLock()876 CSync* CmDeviceRTBase::GetSurfaceLock()
877 {
878 return &m_criticalSectionReadWriteSurface2D;
879 }
880
GetSurfaceCreationLock()881 CSync* CmDeviceRTBase::GetSurfaceCreationLock()
882 {
883 return &m_criticalSectionSurface;
884 }
885
GetProgramKernelLock()886 CSync* CmDeviceRTBase::GetProgramKernelLock()
887 {
888 return &m_criticalSectionProgramKernel;
889 }
890
GetQueue()891 std::vector<CmQueueRT *> &CmDeviceRTBase::GetQueue()
892 {
893 return m_queue;
894 }
895
GetQueueLock()896 CSync* CmDeviceRTBase::GetQueueLock()
897 {
898 return &m_criticalSectionQueue;
899 }
900
901 //*-----------------------------------------------------------------------------
902 //| Purpose: Get Max values from Device
903 //| Returns: Result of the operation.
904 //*-----------------------------------------------------------------------------
GetHalMaxValues(CM_HAL_MAX_VALUES * & halMaxValues,CM_HAL_MAX_VALUES_EX * & halMaxValuesEx)905 int32_t CmDeviceRTBase::GetHalMaxValues(CM_HAL_MAX_VALUES* & halMaxValues,
906 CM_HAL_MAX_VALUES_EX* & halMaxValuesEx)
907 {
908 halMaxValues = &m_halMaxValues;
909 halMaxValuesEx = &m_halMaxValuesEx;
910
911 return CM_SUCCESS;
912 }
913
914 //*-----------------------------------------------------------------------------
915 //| Purpose: Get Max values by Caps
916 //| Returns: Result of the operation.
917 //*-----------------------------------------------------------------------------
GetMaxValueFromCaps(CM_HAL_MAX_VALUES & maxValues,CM_HAL_MAX_VALUES_EX & maxValuesEx)918 int32_t CmDeviceRTBase::GetMaxValueFromCaps(CM_HAL_MAX_VALUES &maxValues,
919 CM_HAL_MAX_VALUES_EX &maxValuesEx)
920 {
921 CM_QUERY_CAPS queryCaps;
922 uint32_t querySize = sizeof( CM_QUERY_CAPS );
923 CmSafeMemSet( &queryCaps, 0, sizeof( CM_QUERY_CAPS ) );
924 queryCaps.type = CM_QUERY_MAX_VALUES;
925
926 int32_t hr = GetCapsInternal(&queryCaps, &querySize);
927 if( FAILED(hr) )
928 {
929 CM_ASSERTMESSAGE("Error: Failed to get max values by GetCaps.");
930 return CM_FAILURE;
931 }
932
933 maxValues = queryCaps.maxValues;
934 maxValues.maxArgsPerKernel = (queryCaps.maxValues.maxArgsPerKernel > CM_MAX_ARGS_PER_KERNEL)?(CM_MAX_ARGS_PER_KERNEL):queryCaps.maxValues.maxArgsPerKernel;
935
936 CmSafeMemSet( &queryCaps, 0, sizeof( CM_QUERY_CAPS ) );
937 queryCaps.type = CM_QUERY_MAX_VALUES_EX;
938
939 hr = GetCapsInternal(&queryCaps, &querySize);
940 if( FAILED(hr) )
941 {
942 CM_ASSERTMESSAGE("Error: Failed to get max values by GetCaps.");
943 return CM_FAILURE;
944 }
945 maxValuesEx = queryCaps.maxValuesEx;
946
947 return CM_SUCCESS;
948 }
949
950 //*-----------------------------------------------------------------------------
951 //| Purpose: Get Caps from Internal
952 //| Returns: Result of the operation.
953 //*-----------------------------------------------------------------------------
GetCapsInternal(void * caps,uint32_t * size)954 int32_t CmDeviceRTBase::GetCapsInternal(void *caps, uint32_t *size)
955 {
956 PCM_QUERY_CAPS queryCaps;
957 PCM_CONTEXT_DATA cmData;
958 PCM_HAL_STATE cmHalState;
959
960 CM_RETURN_CODE hr = CM_SUCCESS;
961
962 if ((!size) || (!caps) || (*size < sizeof(CM_QUERY_CAPS)))
963 {
964 CM_ASSERTMESSAGE("Error: Invalid arguments.");
965 hr = CM_FAILURE;
966 goto finish;
967 }
968
969 queryCaps = (PCM_QUERY_CAPS)caps;
970 *size = sizeof(CM_QUERY_CAPS);
971
972 if (queryCaps->type == CM_QUERY_VERSION)
973 {
974 queryCaps->version = CM_VERSION;
975 hr = CM_SUCCESS;
976 goto finish;
977 }
978
979 cmData = (PCM_CONTEXT_DATA)GetAccelData();
980 CM_CHK_NULL_GOTOFINISH_CMERROR(cmData);
981
982 cmHalState = cmData->cmHalState;
983 CM_CHK_NULL_GOTOFINISH_CMERROR(cmHalState);
984
985 switch (queryCaps->type)
986 {
987 case CM_QUERY_REG_HANDLE:
988 queryCaps->hRegistration = QueryRegHandleInternal(cmHalState);
989 break;
990 case CM_QUERY_MAX_VALUES:
991 CM_CHK_MOSSTATUS_GOTOFINISH_CMERROR(cmHalState->pfnGetMaxValues(cmHalState, &queryCaps->maxValues));
992 break;
993
994 case CM_QUERY_MAX_VALUES_EX:
995 CM_CHK_MOSSTATUS_GOTOFINISH_CMERROR(cmHalState->pfnGetMaxValuesEx(cmHalState, &queryCaps->maxValuesEx));
996 break;
997
998 case CM_QUERY_GPU:
999 case CM_QUERY_GT:
1000 case CM_QUERY_MIN_RENDER_FREQ:
1001 case CM_QUERY_MAX_RENDER_FREQ:
1002 case CM_QUERY_STEP:
1003 case CM_QUERY_GPU_FREQ:
1004 hr = QueryGPUInfoInternal(queryCaps);
1005 if (hr != CM_SUCCESS)
1006 goto finish;
1007 break;
1008
1009 case CM_QUERY_SURFACE2D_FORMAT_COUNT:
1010 queryCaps->surface2DCount = CM_MAX_SURFACE2D_FORMAT_COUNT_INTERNAL;
1011 break;
1012
1013 case CM_QUERY_SURFACE2D_FORMATS:
1014 hr = QuerySurface2DFormatsInternal(queryCaps);
1015 if (hr != CM_SUCCESS)
1016 goto finish;
1017 break;
1018
1019 case CM_QUERY_PLATFORM_INFO:
1020 CM_CHK_MOSSTATUS_GOTOFINISH_CMERROR(cmHalState->pfnGetPlatformInfo(cmHalState, &queryCaps->platformInfo, false));
1021 break;
1022 default:
1023 hr = CM_FAILURE;
1024 goto finish;
1025 }
1026
1027 finish:
1028 return hr;
1029 }
1030
1031 //*-----------------------------------------------------------------------------
1032 //! Get HW capability.
1033 //! Input :
1034 //! 1) Name of cap to query, only CAP_HW_THREAD_COUNT is supported now.
1035 //! 2) size of memory where the cap value should return to.
1036 //! User should make sure the size is larger than the size of cap value which is really returned.
1037 //! 3) Pointer pointing to memory where the cap value should return to
1038 //! Output:
1039 //! 1) size of cap value which is really returned.
1040 //! 2) CM_SUCCESS if cap value is successfully returned.
1041 //! CM_FAILURE otherwise;
1042 //*-----------------------------------------------------------------------------
GetCaps(CM_DEVICE_CAP_NAME capName,uint32_t & capValueSize,void * capValue)1043 int32_t CmDeviceRTBase::GetCaps(CM_DEVICE_CAP_NAME capName,
1044 uint32_t & capValueSize,
1045 void* capValue )
1046 {
1047 PCM_CONTEXT_DATA cmData;
1048 PCM_HAL_STATE cmHalState;
1049 CM_RETURN_CODE hr = CM_SUCCESS;
1050
1051 if (capValue == nullptr)
1052 {
1053 CM_ASSERTMESSAGE("Error: Pointer to cap value is null.");
1054 return CM_NULL_POINTER;
1055 }
1056
1057 cmData = (PCM_CONTEXT_DATA)GetAccelData();
1058 if(cmData == nullptr)
1059 {
1060 CM_ASSERTMESSAGE("Error: Pointer to CM context data is null.");
1061 return CM_NULL_POINTER;
1062 }
1063
1064 cmHalState = cmData->cmHalState;
1065 if(cmHalState == nullptr)
1066 {
1067 CM_ASSERTMESSAGE("Error: Pointer to CM hal state is null.");
1068 return CM_NULL_POINTER;
1069 }
1070
1071 switch( capName )
1072 {
1073 case CAP_KERNEL_COUNT_PER_TASK:
1074 if( capValueSize >= sizeof( m_halMaxValues.maxKernelsPerTask ) )
1075 {
1076 capValueSize = sizeof( m_halMaxValues.maxKernelsPerTask );
1077 CmSafeMemCopy( capValue, &m_halMaxValues.maxKernelsPerTask, capValueSize );
1078 return CM_SUCCESS;
1079 }
1080 else
1081 {
1082 return CM_FAILURE;
1083 }
1084
1085 case CAP_KERNEL_BINARY_SIZE:
1086 if( capValueSize >= sizeof( m_halMaxValues.maxKernelBinarySize ) )
1087 {
1088 capValueSize = sizeof( m_halMaxValues.maxKernelBinarySize );
1089 CmSafeMemCopy( capValue, &m_halMaxValues.maxKernelBinarySize, capValueSize );
1090 return CM_SUCCESS;
1091 }
1092 else
1093 {
1094 return CM_FAILURE;
1095 }
1096
1097 case CAP_SAMPLER_COUNT:
1098 if( capValueSize >= sizeof( m_halMaxValues.maxSamplerTableSize ) )
1099 {
1100 capValueSize = sizeof( m_halMaxValues.maxSamplerTableSize );
1101 CmSafeMemCopy( capValue, &m_halMaxValues.maxSamplerTableSize, capValueSize );
1102 return CM_SUCCESS;
1103 }
1104 else
1105 {
1106 return CM_FAILURE;
1107 }
1108
1109 case CAP_SAMPLER_COUNT_PER_KERNEL:
1110 if( capValueSize >= sizeof( m_halMaxValues.maxSamplersPerKernel ) )
1111 {
1112 capValueSize = sizeof( m_halMaxValues.maxSamplersPerKernel );
1113 CmSafeMemCopy( capValue, &m_halMaxValues.maxSamplersPerKernel, capValueSize );
1114 return CM_SUCCESS;
1115 }
1116 else
1117 {
1118 return CM_FAILURE;
1119 }
1120
1121 case CAP_BUFFER_COUNT:
1122 if( capValueSize >= sizeof( m_halMaxValues.maxBufferTableSize ) )
1123 {
1124 capValueSize = sizeof( m_halMaxValues.maxBufferTableSize );
1125 CmSafeMemCopy( capValue, &m_halMaxValues.maxBufferTableSize, capValueSize );
1126 return CM_SUCCESS;
1127 }
1128 else
1129 {
1130 return CM_FAILURE;
1131 }
1132
1133 case CAP_SURFACE2D_COUNT:
1134 if( capValueSize >= sizeof( m_halMaxValues.max2DSurfaceTableSize ) )
1135 {
1136 capValueSize = sizeof( m_halMaxValues.max2DSurfaceTableSize );
1137 CmSafeMemCopy( capValue, &m_halMaxValues.max2DSurfaceTableSize, capValueSize );
1138 return CM_SUCCESS;
1139 }
1140 else
1141 {
1142 return CM_FAILURE;
1143 }
1144
1145 case CAP_SURFACE3D_COUNT:
1146 if( capValueSize >= sizeof( m_halMaxValues.max3DSurfaceTableSize ) )
1147 {
1148 capValueSize = sizeof( m_halMaxValues.max3DSurfaceTableSize );
1149 CmSafeMemCopy( capValue, &m_halMaxValues.max3DSurfaceTableSize, capValueSize );
1150 return CM_SUCCESS;
1151 }
1152 else
1153 {
1154 return CM_FAILURE;
1155 }
1156
1157 case CAP_SURFACE2DUP_COUNT:
1158 if( capValueSize >= sizeof( m_halMaxValuesEx.max2DUPSurfaceTableSize ) )
1159 {
1160 capValueSize = sizeof( m_halMaxValuesEx.max2DUPSurfaceTableSize );
1161 CmSafeMemCopy( capValue, &m_halMaxValuesEx.max2DUPSurfaceTableSize, capValueSize );
1162 return CM_SUCCESS;
1163 }
1164 else
1165 {
1166 return CM_FAILURE;
1167 }
1168
1169 case CAP_SURFACE_COUNT_PER_KERNEL:
1170 if( capValueSize >= sizeof( m_halMaxValues.maxSurfacesPerKernel ) )
1171 {
1172 capValueSize = sizeof( m_halMaxValues.maxSurfacesPerKernel );
1173 CmSafeMemCopy( capValue, &m_halMaxValues.maxSurfacesPerKernel, capValueSize );
1174 return CM_SUCCESS;
1175 }
1176 else
1177 {
1178 return CM_FAILURE;
1179 }
1180
1181 case CAP_ARG_COUNT_PER_KERNEL:
1182 if( capValueSize >= sizeof( m_halMaxValues.maxArgsPerKernel ) )
1183 {
1184 capValueSize = sizeof( m_halMaxValues.maxArgsPerKernel );
1185 CmSafeMemCopy( capValue, &m_halMaxValues.maxArgsPerKernel, capValueSize );
1186 return CM_SUCCESS;
1187 }
1188 else
1189 {
1190 return CM_FAILURE;
1191 }
1192
1193 case CAP_ARG_SIZE_PER_KERNEL:
1194 if( capValueSize >= sizeof( m_halMaxValues.maxArgByteSizePerKernel ) )
1195 {
1196 capValueSize = sizeof( m_halMaxValues.maxArgByteSizePerKernel );
1197 CmSafeMemCopy( capValue, &m_halMaxValues.maxArgByteSizePerKernel, capValueSize );
1198 return CM_SUCCESS;
1199 }
1200 else
1201 {
1202 return CM_FAILURE;
1203 }
1204
1205 case CAP_USER_DEFINED_THREAD_COUNT_PER_TASK:
1206 if( capValueSize >= sizeof( m_halMaxValues.maxUserThreadsPerTask ) )
1207 {
1208 capValueSize = sizeof( m_halMaxValues.maxUserThreadsPerTask );
1209 CmSafeMemCopy( capValue, &m_halMaxValues.maxUserThreadsPerTask, capValueSize );
1210 return CM_SUCCESS;
1211 }
1212 else
1213 {
1214 return CM_FAILURE;
1215 }
1216
1217 case CAP_USER_DEFINED_THREAD_COUNT_PER_MEDIA_WALKER:
1218 if( capValueSize >= sizeof( m_halMaxValuesEx.maxUserThreadsPerMediaWalker ) )
1219 {
1220 capValueSize = sizeof( m_halMaxValuesEx.maxUserThreadsPerMediaWalker );
1221 CmSafeMemCopy( capValue, &m_halMaxValuesEx.maxUserThreadsPerMediaWalker, capValueSize );
1222 return CM_SUCCESS;
1223 }
1224 else
1225 {
1226 return CM_FAILURE;
1227 }
1228
1229 case CAP_USER_DEFINED_THREAD_COUNT_PER_THREAD_GROUP:
1230 if( capValueSize >= sizeof( m_halMaxValuesEx.maxUserThreadsPerThreadGroup ) )
1231 {
1232 capValueSize = sizeof( m_halMaxValuesEx.maxUserThreadsPerThreadGroup );
1233 CmSafeMemCopy( capValue, &m_halMaxValuesEx.maxUserThreadsPerThreadGroup, capValueSize );
1234 return CM_SUCCESS;
1235 }
1236 else
1237 {
1238 return CM_FAILURE;
1239 }
1240
1241 case CAP_USER_DEFINED_THREAD_COUNT_PER_TASK_NO_THREAD_ARG:
1242 if( capValueSize >= sizeof( m_halMaxValues.maxUserThreadsPerTaskNoThreadArg ) )
1243 {
1244 capValueSize = sizeof( m_halMaxValues.maxUserThreadsPerTaskNoThreadArg );
1245 CmSafeMemCopy( capValue, &m_halMaxValues.maxUserThreadsPerTaskNoThreadArg, capValueSize );
1246 return CM_SUCCESS;
1247 }
1248 else
1249 {
1250 return CM_FAILURE;
1251 }
1252
1253 case CAP_HW_THREAD_COUNT:
1254 if( capValueSize >= sizeof( m_halMaxValues.maxHwThreads ) )
1255 {
1256 capValueSize = sizeof( m_halMaxValues.maxHwThreads );
1257 CmSafeMemCopy( capValue, &m_halMaxValues.maxHwThreads, capValueSize );
1258 return CM_SUCCESS;
1259 }
1260 else
1261 {
1262 return CM_FAILURE;
1263 }
1264
1265 case CAP_SURFACE2D_FORMAT_COUNT:
1266 if( capValueSize >= sizeof( uint32_t ) )
1267 {
1268 capValueSize = sizeof( uint32_t );
1269 uint32_t formatCount = CM_MAX_SURFACE2D_FORMAT_COUNT;
1270 CmSafeMemCopy( capValue, &formatCount, capValueSize );
1271 return CM_SUCCESS;
1272 }
1273 else
1274 {
1275 return CM_FAILURE;
1276 }
1277
1278 case CAP_SURFACE2D_FORMATS:
1279 return QuerySurface2DFormats(capValue, capValueSize);
1280 case CAP_SURFACE3D_FORMAT_COUNT:
1281 if( capValueSize >= sizeof( uint32_t ) )
1282 {
1283 capValueSize = sizeof( uint32_t );
1284 uint32_t formatCount = CM_MAX_SURFACE3D_FORMAT_COUNT;
1285 CmSafeMemCopy( capValue, &formatCount, capValueSize );
1286 return CM_SUCCESS;
1287 }
1288 else
1289 {
1290 return CM_FAILURE;
1291 }
1292
1293 case CAP_SURFACE3D_FORMATS:
1294 if( capValueSize >= CM_MAX_SURFACE3D_FORMAT_COUNT * sizeof(CM_SURFACE_FORMAT) )
1295 {
1296 capValueSize = CM_MAX_SURFACE3D_FORMAT_COUNT * sizeof(CM_SURFACE_FORMAT) ;
1297 CM_SURFACE_FORMAT formats[ CM_MAX_SURFACE3D_FORMAT_COUNT ] =
1298 {
1299 CM_SURFACE_FORMAT_X8R8G8B8,
1300 CM_SURFACE_FORMAT_A8R8G8B8,
1301 CM_SURFACE_FORMAT_A16B16G16R16
1302 };
1303 CmSafeMemCopy( capValue, formats, capValueSize );
1304 return CM_SUCCESS;
1305 }
1306 else
1307 {
1308 return CM_FAILURE;
1309 }
1310
1311 case CAP_GPU_PLATFORM:
1312 if( capValueSize >= sizeof( uint32_t ) )
1313 {
1314 uint32_t platform = PLATFORM_INTEL_UNKNOWN;
1315 capValueSize = sizeof( uint32_t );
1316 cmHalState->cmHalInterface->GetGenPlatformInfo(&platform, nullptr, nullptr);
1317 CmSafeMemCopy( capValue, &platform, capValueSize );
1318 return CM_SUCCESS;
1319 }
1320 else
1321 {
1322 return CM_FAILURE;
1323 }
1324
1325 case CAP_GT_PLATFORM:
1326 if( capValueSize >= sizeof( uint32_t ) )
1327 {
1328 CM_QUERY_CAPS queryCaps;
1329 queryCaps.type = CM_QUERY_GT;
1330 uint32_t queryCapsSize = sizeof( CM_QUERY_CAPS );
1331 hr = (CM_RETURN_CODE)GetCapsInternal(&queryCaps, &queryCapsSize);
1332 if ( hr != CM_SUCCESS)
1333 {
1334 return hr;
1335 }
1336 capValueSize = sizeof( uint32_t );
1337 uint32_t gtPlatform = queryCaps.genGT;
1338 CmSafeMemCopy( capValue, >Platform, capValueSize );
1339 return hr;
1340 }
1341 else
1342 {
1343 return CM_FAILURE;
1344 }
1345
1346 case CAP_MIN_FREQUENCY:
1347 if( capValueSize >= sizeof( uint32_t ) )
1348 {
1349 CM_QUERY_CAPS queryCaps;
1350 queryCaps.type = CM_QUERY_MIN_RENDER_FREQ;
1351 uint32_t queryCapsSize = sizeof( CM_QUERY_CAPS );
1352 hr = (CM_RETURN_CODE)GetCapsInternal(&queryCaps, &queryCapsSize);
1353 if (hr != CM_SUCCESS)
1354 {
1355 return hr;
1356 }
1357 uint32_t frequency = queryCaps.minRenderFreq;
1358 capValueSize = sizeof( uint32_t );
1359 CmSafeMemCopy( capValue, &frequency, capValueSize );
1360 return hr;
1361 }
1362 else
1363 {
1364 return CM_FAILURE;
1365 }
1366
1367 case CAP_MAX_FREQUENCY:
1368 if( capValueSize >= sizeof( uint32_t ) )
1369 {
1370 CM_QUERY_CAPS queryCaps;
1371 queryCaps.type = CM_QUERY_MAX_RENDER_FREQ;
1372 uint32_t queryCapsSize = sizeof( CM_QUERY_CAPS );
1373 hr = (CM_RETURN_CODE)GetCapsInternal(&queryCaps, &queryCapsSize);
1374 if (hr != CM_SUCCESS)
1375 {
1376 return hr;
1377 }
1378 uint32_t frequency = queryCaps.maxRenderFreq;
1379 capValueSize = sizeof( uint32_t );
1380 CmSafeMemCopy( capValue, &frequency, capValueSize );
1381 return hr;
1382 }
1383 else
1384 {
1385 return CM_FAILURE;
1386 }
1387
1388 case CAP_GPU_CURRENT_FREQUENCY:
1389 if( (m_ddiVersion >= CM_DDI_3_0) && (capValueSize >= sizeof( uint32_t )) )
1390 {
1391 CM_QUERY_CAPS queryCaps;
1392 queryCaps.type = CM_QUERY_GPU_FREQ;
1393 uint32_t queryCapsSize = sizeof( CM_QUERY_CAPS );
1394 hr = (CM_RETURN_CODE)GetCapsInternal(&queryCaps, &queryCapsSize);
1395 if (hr != CM_SUCCESS)
1396 {
1397 return hr;
1398 }
1399 uint32_t frequency = queryCaps.gpuCurrentFreq;
1400 capValueSize = sizeof( uint32_t );
1401 CmSafeMemCopy( capValue, &frequency, capValueSize );
1402 return hr;
1403 }
1404 else
1405 {
1406 return CM_FAILURE;
1407 }
1408
1409 case CAP_PLATFORM_INFO:
1410 if (capValueSize >= sizeof(CM_PLATFORM_INFO))
1411 {
1412 CM_QUERY_CAPS queryCaps;
1413 queryCaps.type = CM_QUERY_PLATFORM_INFO;
1414 uint32_t queryCapsSize = sizeof(CM_QUERY_CAPS);
1415 hr = (CM_RETURN_CODE)GetCapsInternal(&queryCaps, &queryCapsSize);
1416 if (hr != CM_SUCCESS)
1417 {
1418 return hr;
1419 }
1420 capValueSize = sizeof(CM_PLATFORM_INFO);
1421 PCM_PLATFORM_INFO platformInfo = &(queryCaps.platformInfo);
1422 CmSafeMemCopy(capValue, platformInfo, capValueSize);
1423 return hr;
1424 }
1425 else
1426 {
1427 return CM_FAILURE;
1428 }
1429 case CAP_MAX_BUFFER_SIZE:
1430 if (capValueSize >= sizeof(unsigned int))
1431 {
1432 capValueSize = sizeof(unsigned int);
1433 unsigned int maxBufferSize = CM_MAX_1D_SURF_WIDTH;
1434 CmSafeMemCopy(capValue, &maxBufferSize, capValueSize);
1435 return CM_SUCCESS;
1436 }
1437 else
1438 {
1439 return CM_FAILURE;
1440 }
1441 default:
1442 return CM_FAILURE;
1443 }
1444 }
1445
1446 //*-----------------------------------------------------------------------------
1447 //| Purpose: Load program from memory
1448 //| Arguments :
1449 //| commonISACode [in] pointer to memory where common isa locates
1450 //| size [in] size of common isa
1451 //| program [in/out] Pointer to CmProgram
1452 //| options [in] options : non-jitter,jitter
1453 //|
1454 //| Returns: Result of the operation.
1455 //*-----------------------------------------------------------------------------
LoadProgram(void * commonISACode,const uint32_t size,CmProgram * & program,const char * options)1456 CM_RT_API int32_t CmDeviceRTBase::LoadProgram(void* commonISACode,
1457 const uint32_t size,
1458 CmProgram*& program,
1459 const char* options )
1460 {
1461 INSERT_API_CALL_LOG(GetHalState());
1462
1463 int32_t result;
1464
1465 if ((commonISACode == nullptr) || (size == 0))
1466 {
1467 CM_ASSERTMESSAGE("Error: Invalid common isa code.");
1468 return CM_INVALID_COMMON_ISA;
1469 }
1470
1471 CLock locker(m_criticalSectionProgramKernel);
1472
1473 uint32_t firstfreeslot = m_programArray.GetFirstFreeIndex();
1474
1475 CmProgramRT *programRT = static_cast<CmProgramRT *>(program);
1476 CmDeviceRT *cmDevice = static_cast<CmDeviceRT*>(this);
1477 result = CmProgramRT::Create(cmDevice, commonISACode, size, programRT, options, firstfreeslot );
1478 if( result == CM_SUCCESS )
1479 {
1480 m_programArray.SetElement( firstfreeslot, programRT );
1481 m_programCount++;
1482 }
1483 program = programRT;
1484
1485 return result;
1486 }
1487
1488 //*-----------------------------------------------------------------------------
1489 //| Purpose: Destroy Program
1490 //| Returns: Result of the operation.
1491 //*-----------------------------------------------------------------------------
DestroyProgram(CmProgram * & program)1492 CM_RT_API int32_t CmDeviceRTBase::DestroyProgram(CmProgram* & program)
1493 {
1494 INSERT_API_CALL_LOG(GetHalState());
1495
1496 if( program == nullptr )
1497 {
1498 return CM_FAILURE;
1499 }
1500
1501 CLock locker(m_criticalSectionProgramKernel);
1502
1503 CmProgramRT *programRT = static_cast<CmProgramRT *>(program);
1504 uint32_t indexInProgramArrary = programRT->GetProgramIndex();
1505 if( programRT == m_programArray.GetElement( indexInProgramArrary ) )
1506 {
1507 CmProgramRT::Destroy( programRT );
1508 if( programRT == nullptr )
1509 {
1510 m_programArray.SetElement( indexInProgramArrary, nullptr );
1511 m_programCount--;
1512 program = programRT;
1513 }
1514 return CM_SUCCESS;
1515 }
1516 else
1517 {
1518 CM_ASSERTMESSAGE("Error: Failed to destroy CmProgram.");
1519 return CM_FAILURE;
1520 }
1521
1522 }
1523
1524 //*-----------------------------------------------------------------------------
1525 //| Purpose: Create Kernel
1526 //| Arguments :
1527 //| kernel [out] pointer to CmKernel
1528 //| kernelName [in] string of kernel's name
1529 //| program [in/out] Pointer to CmProgram
1530 //| options [in] options : non-jitter,jitter
1531 //|
1532 //| Returns: Result of the operation.
1533 //*-----------------------------------------------------------------------------
CreateKernel(CmProgram * program,const char * kernelName,CmKernel * & kernel,const char * options)1534 CM_RT_API int32_t CmDeviceRTBase::CreateKernel(CmProgram* program,
1535 const char* kernelName,
1536 CmKernel* & kernel,
1537 const char* options )
1538 {
1539 INSERT_API_CALL_LOG(GetHalState());
1540
1541 if(program == nullptr)
1542 {
1543 CM_ASSERTMESSAGE("Error: Pointer to CmProgram is null.");
1544 return CM_NULL_POINTER;
1545 }
1546
1547 CLock locker(m_criticalSectionProgramKernel);
1548
1549 uint32_t freeSlotInKernelArray = m_kernelArray.GetFirstFreeIndex();
1550 CmProgramRT *programRT = static_cast<CmProgramRT *>(program);
1551 CmKernelRT *kernelRT = static_cast<CmKernelRT *>(kernel);
1552 CmDeviceRT *cmDevice = static_cast<CmDeviceRT*>(this);
1553 CM_CHK_NULL_RETURN_CMERROR(cmDevice);
1554
1555 int32_t result = CmKernelRT::Create(cmDevice, programRT, kernelName, freeSlotInKernelArray, m_kernelCount, kernelRT, options );
1556 kernel = kernelRT;
1557 if( result == CM_SUCCESS )
1558 {
1559 m_kernelArray.SetElement( freeSlotInKernelArray, kernel );
1560 m_kernelCount ++;
1561 }
1562
1563 return result;
1564 }
1565
1566 //*-----------------------------------------------------------------------------
1567 //| Purpose: Destroy Kernel
1568 //| Returns: Result of the operation.
1569 //*-----------------------------------------------------------------------------
DestroyKernel(CmKernel * & kernel)1570 CM_RT_API int32_t CmDeviceRTBase::DestroyKernel(CmKernel*& kernel)
1571 {
1572 INSERT_API_CALL_LOG(GetHalState());
1573
1574 if( kernel == nullptr )
1575 {
1576 return CM_NULL_POINTER;
1577 }
1578
1579 CLock locker(m_criticalSectionProgramKernel);
1580
1581 CmKernelRT *kernelRT = static_cast<CmKernelRT *>(kernel);
1582 uint32_t indexInKernelArrary = kernelRT->GetKernelIndex();
1583 if( kernelRT == m_kernelArray.GetElement( indexInKernelArrary ) )
1584 {
1585 CmProgramRT* program = nullptr;
1586 kernelRT->GetCmProgram(program);
1587 if ( program == nullptr)
1588 {
1589 CM_ASSERTMESSAGE("Error: Failed to get valid program.");
1590 return CM_NULL_POINTER;
1591 }
1592
1593 uint32_t indexInProgramArray = program->GetProgramIndex();
1594
1595 if (program == m_programArray.GetElement( indexInProgramArray ))
1596 {
1597 CmKernelRT::Destroy( kernelRT, program );
1598 kernel = kernelRT;
1599
1600 if(kernelRT == nullptr)
1601 {
1602 m_kernelArray.SetElement( indexInKernelArrary, nullptr );
1603 }
1604
1605 if (program == nullptr)
1606 {
1607 m_programArray.SetElement(indexInProgramArray, nullptr);
1608 }
1609
1610 // Note: NOT reduce m_kernelCount here, need to make it to loop mode later
1611 return CM_SUCCESS;
1612 }
1613 else
1614 {
1615 CM_ASSERTMESSAGE("Error: Failed to destroy kernel.");
1616 return CM_FAILURE;
1617 }
1618 }
1619 else
1620 {
1621 CM_ASSERTMESSAGE("Error: Failed to destroy kernel.");
1622 return CM_FAILURE;
1623 }
1624 return CM_SUCCESS;
1625 }
1626
1627
1628 #define PLATFORM_INTEL_TGL 14
CreateQueue(CmQueue * & queue)1629 CM_RT_API int32_t CmDeviceRTBase::CreateQueue(CmQueue* &queue)
1630 {
1631 INSERT_API_CALL_LOG(GetHalState());
1632 CM_QUEUE_CREATE_OPTION queueCreateOption = CM_DEFAULT_QUEUE_CREATE_OPTION;
1633 queueCreateOption.IsRealTimePrioriy = m_queuePriority;
1634
1635 // Check queue type redirect is needed.
1636 PCM_CONTEXT_DATA cmData = (PCM_CONTEXT_DATA)GetAccelData();
1637 CM_CHK_NULL_RETURN_CMERROR(cmData);
1638 CM_CHK_NULL_RETURN_CMERROR(cmData->cmHalState);
1639 CM_CHK_NULL_RETURN_CMERROR(cmData->cmHalState->cmHalInterface);
1640 if (cmData->cmHalState->cmHalInterface->IsRedirectRcsToCcs())
1641 {
1642 queueCreateOption.QueueType = CM_QUEUE_TYPE_COMPUTE;
1643 }
1644 else
1645 {
1646 queueCreateOption.QueueType = CM_QUEUE_TYPE_RENDER;
1647 }
1648
1649 #if (_DEBUG || _RELEASE_INTERNAL)
1650 // Check queue type override for debugging is needed.
1651 MOS_USER_FEATURE_VALUE_DATA UserFeatureData = { 0 };
1652 if (MOS_UserFeature_ReadValue_ID(
1653 nullptr,
1654 __MEDIA_USER_FEATURE_VALUE_MDF_DEFAULT_CM_QUEUE_TYPE_ID,
1655 &UserFeatureData,
1656 cmData->cmHalState->osInterface->pOsContext) == MOS_STATUS_SUCCESS)
1657 {
1658 if (UserFeatureData.u32Data == CM_QUEUE_TYPE_RENDER
1659 || UserFeatureData.u32Data == CM_QUEUE_TYPE_COMPUTE)
1660 {
1661 queueCreateOption.QueueType
1662 = (CM_QUEUE_TYPE)UserFeatureData.u32Data;
1663 }
1664 }
1665 #endif
1666
1667 // override TGL queue type to CM_QUEUE_TYPE_COMPUTE
1668 uint32_t platform = PLATFORM_INTEL_UNKNOWN;
1669 cmData->cmHalState->cmHalInterface->GetGenPlatformInfo(&platform, nullptr, nullptr);
1670 if (PLATFORM_INTEL_TGL == platform)
1671 {
1672 queueCreateOption.QueueType = CM_QUEUE_TYPE_COMPUTE;
1673 }
1674
1675 for (auto iter = m_queue.begin(); iter != m_queue.end(); ++iter)
1676 {
1677 CM_QUEUE_TYPE queueType = (*iter)->GetQueueOption().QueueType;
1678
1679 if (queueType == queueCreateOption.QueueType)
1680 {
1681 queue = (*iter);
1682 return CM_SUCCESS;
1683 }
1684 }
1685
1686 return CreateQueueEx(queue, queueCreateOption);
1687 }
1688
1689
CreateQueueEx(CmQueue * & queue,CM_QUEUE_CREATE_OPTION queueCreateOption)1690 CM_RT_API int32_t CmDeviceRTBase::CreateQueueEx(CmQueue* &queue,
1691 CM_QUEUE_CREATE_OPTION queueCreateOption)
1692 {
1693 INSERT_API_CALL_LOG(GetHalState());
1694 CLock locker(m_criticalSectionQueue);
1695 CmQueueRT *queueRT = nullptr;
1696 PCM_CONTEXT_DATA cmData = (PCM_CONTEXT_DATA)GetAccelData();
1697 CM_CHK_NULL_RETURN_CMERROR(cmData);
1698 CM_CHK_NULL_RETURN_CMERROR(cmData->cmHalState);
1699 CM_CHK_NULL_RETURN_CMERROR(cmData->cmHalState->cmHalInterface);
1700
1701 // override TGL queue type to CM_QUEUE_TYPE_COMPUTE
1702 uint32_t platform = PLATFORM_INTEL_UNKNOWN;
1703 cmData->cmHalState->cmHalInterface->GetGenPlatformInfo(&platform, nullptr, nullptr);
1704 if (PLATFORM_INTEL_TGL == platform)
1705 {
1706 queueCreateOption.QueueType = CM_QUEUE_TYPE_COMPUTE;
1707 }
1708
1709 for (auto iter = m_queue.begin(); iter != m_queue.end(); ++iter)
1710 {
1711 CM_QUEUE_TYPE queueType = (*iter)->GetQueueOption().QueueType;
1712 unsigned int gpuContext = (*iter)->GetQueueOption().GPUContext;
1713
1714 if ((queueType == queueCreateOption.QueueType && gpuContext == queueCreateOption.GPUContext) ||
1715 (queueType == queueCreateOption.QueueType && queueType == CM_QUEUE_TYPE_COMPUTE))
1716 {
1717 queue = (*iter);
1718 return CM_SUCCESS;
1719 }
1720 }
1721
1722 CmDeviceRT *cmDevice = static_cast<CmDeviceRT*>(this);
1723 CM_CHK_NULL_RETURN_CMERROR(cmDevice);
1724 int32_t result = CmQueueRT::Create(cmDevice, queueRT, queueCreateOption);
1725
1726 if (result != CM_SUCCESS)
1727 {
1728 CM_ASSERTMESSAGE("Failed to create the queue.");
1729 return result;
1730 }
1731 m_queue.push_back(queueRT);
1732 queue = queueRT;
1733
1734 return result;
1735 }
1736
1737
DestroyQueue(CmQueueRT * & queue)1738 int32_t CmDeviceRTBase::DestroyQueue(CmQueueRT*& queue)
1739 {
1740 if (queue == nullptr)
1741 {
1742 return CM_NULL_POINTER;
1743 }
1744 return CmQueueRT::Destroy(queue);
1745 }
1746
1747
CreateTask(CmTask * & task)1748 CM_RT_API int32_t CmDeviceRTBase::CreateTask(CmTask *& task)
1749 {
1750 INSERT_API_CALL_LOG(GetHalState());
1751
1752 CLock locker(m_criticalSectionTask);
1753
1754 uint32_t freeSlotInTaskArray = m_taskArray.GetFirstFreeIndex();
1755 CmTaskRT *taskRT = nullptr;
1756 CmDeviceRT *cmDevice = static_cast<CmDeviceRT*>(this);
1757 CM_CHK_NULL_RETURN_CMERROR(cmDevice);
1758 int32_t result = CmTaskRT::Create(cmDevice, freeSlotInTaskArray, m_halMaxValues.maxKernelsPerTask, taskRT);
1759 if (result == CM_SUCCESS)
1760 {
1761 m_taskArray.SetElement( freeSlotInTaskArray, taskRT );
1762 m_taskCount ++;
1763 }
1764 task = taskRT;
1765 return result;
1766 }
1767
1768
DestroyTask(CmTask * & task)1769 CM_RT_API int32_t CmDeviceRTBase::DestroyTask(CmTask*& task)
1770 {
1771 INSERT_API_CALL_LOG(GetHalState());
1772
1773 CLock locker(m_criticalSectionTask);
1774
1775 if( task == nullptr )
1776 {
1777 return CM_FAILURE;
1778 }
1779
1780 CmTaskRT *taskRT = static_cast<CmTaskRT *>(task);
1781 uint32_t index = taskRT->GetIndexInTaskArray();
1782 if(taskRT == (CmTaskRT *)m_taskArray.GetElement( index ))
1783 {
1784 int32_t status = CmTaskRT::Destroy(taskRT);
1785 if(status == CM_SUCCESS)
1786 {
1787 m_taskArray.SetElement( index, nullptr );
1788 task = nullptr;
1789 return CM_SUCCESS;
1790 }
1791 else
1792 {
1793 CM_ASSERTMESSAGE("Error: Failed to destroy task.");
1794 return status;
1795 }
1796 }
1797 else
1798 {
1799 CM_ASSERTMESSAGE("Error: Failed to destroy task.");
1800 return CM_FAILURE;
1801 }
1802 }
1803
1804 //*-----------------------------------------------------------------------------
1805 //! Create a 2-dimensional dependency board. Each board is corrsponding to a task.
1806 //! Each board unit is notated as a pair of X/Y coordinates, which is in the range of [0, width -1] or [0. heigh-1]
1807 //! Each board uint is correspinding to a thread in the task.
1808 //! Input :
1809 //! 1) width and height of the dependency board
1810 //! OUTPUT :
1811 //! CM_SUCCESS if CmThreadSpace is successfully created.
1812 //*-----------------------------------------------------------------------------
CreateThreadSpace(uint32_t width,uint32_t height,CmThreadSpace * & threadSpace)1813 CM_RT_API int32_t CmDeviceRTBase::CreateThreadSpace(uint32_t width,
1814 uint32_t height,
1815 CmThreadSpace* & threadSpace)
1816 {
1817 INSERT_API_CALL_LOG(GetHalState());
1818
1819 CLock locker(m_criticalSectionThreadSpace);
1820
1821 uint32_t freeSlotInThreadSpaceArray = m_threadSpaceArray.GetFirstFreeIndex();
1822 CmThreadSpaceRT *threadSpaceRT = nullptr;
1823 CmDeviceRT *cmDevice = static_cast<CmDeviceRT*>(this);
1824 CM_CHK_NULL_RETURN_CMERROR(cmDevice);
1825 int32_t result = CmThreadSpaceRT::Create(cmDevice, freeSlotInThreadSpaceArray, width, height, threadSpaceRT );
1826 if (result == CM_SUCCESS)
1827 {
1828 m_threadSpaceArray.SetElement( freeSlotInThreadSpaceArray, threadSpaceRT );
1829 m_threadSpaceCount ++;
1830 }
1831 threadSpace = threadSpaceRT;
1832
1833 return result;
1834 }
1835
1836 //*-----------------------------------------------------------------------------
1837 //| Purpose: Destroy Thread Space
1838 //| Returns: Result of the operation.
1839 //*-----------------------------------------------------------------------------
DestroyThreadSpace(CmThreadSpace * & threadSpace)1840 CM_RT_API int32_t CmDeviceRTBase::DestroyThreadSpace(CmThreadSpace* & threadSpace)
1841 {
1842 INSERT_API_CALL_LOG(GetHalState());
1843
1844 if( threadSpace == nullptr )
1845 {
1846 return CM_FAILURE;
1847 }
1848
1849 CmThreadSpaceRT *threadSpaceRT = static_cast<CmThreadSpaceRT *>(threadSpace);
1850 uint32_t indexTs = threadSpaceRT->GetIndexInTsArray();
1851
1852 CLock locker(m_criticalSectionThreadSpace);
1853 if(threadSpace == m_threadSpaceArray.GetElement( indexTs ))
1854 {
1855 int32_t status = CmThreadSpaceRT::Destroy( threadSpaceRT );
1856 if(status == CM_SUCCESS)
1857 {
1858 m_threadSpaceArray.SetElement( indexTs, nullptr );
1859 threadSpace = nullptr;
1860 return CM_SUCCESS;
1861 }
1862 else
1863 {
1864 CM_ASSERTMESSAGE("Error: Failed to destroy thread space.");
1865 return status;
1866 }
1867 }
1868 else
1869 {
1870 CM_ASSERTMESSAGE("Error: Failed to destroy thread space.");
1871 return CM_FAILURE;
1872 }
1873
1874 }
1875
1876 CM_RT_API int32_t
CreateVmeSurfaceG7_5(CmSurface2D * curSurface,CmSurface2D ** forwardSurfaces,CmSurface2D ** backwardSurfaces,const uint32_t forwardSurfaceCount,const uint32_t backwardSurfaceCount,SurfaceIndex * & vmeIndex)1877 CmDeviceRTBase::CreateVmeSurfaceG7_5(CmSurface2D* curSurface,
1878 CmSurface2D** forwardSurfaces,
1879 CmSurface2D** backwardSurfaces,
1880 const uint32_t forwardSurfaceCount,
1881 const uint32_t backwardSurfaceCount,
1882 SurfaceIndex* & vmeIndex)
1883 {
1884 INSERT_API_CALL_LOG(GetHalState());
1885
1886 if(curSurface == nullptr)
1887 {
1888 CM_ASSERTMESSAGE("Error: Pointer to current surface is null.");
1889 return CM_NULL_POINTER;
1890 }
1891
1892 CmSurface2DRT* currentRT = static_cast<CmSurface2DRT *>(curSurface) ;
1893 CmSurface2DRT** forward = nullptr;
1894 CmSurface2DRT** backward = nullptr;
1895
1896 if(forwardSurfaces != nullptr)
1897 {
1898 forward = MOS_NewArray( CmSurface2DRT*, forwardSurfaceCount);
1899 if(forward == nullptr)
1900 {
1901 CM_ASSERTMESSAGE("Error: Out of system memory.");
1902 return CM_OUT_OF_HOST_MEMORY;
1903 }
1904 for(uint32_t i = 0; i< forwardSurfaceCount; i++)
1905 {
1906 forward[i] = static_cast<CmSurface2DRT *>( forwardSurfaces[i] );
1907 if(forward[i] == nullptr)
1908 {
1909 CM_ASSERTMESSAGE("Error: Invalid forward surfaces.");
1910 MosSafeDeleteArray(forward);
1911 return CM_INVALID_ARG_VALUE;
1912 }
1913 }
1914 }
1915
1916 if(backwardSurfaces != nullptr)
1917 {
1918 backward = MOS_NewArray(CmSurface2DRT*,backwardSurfaceCount);
1919 if(backward == nullptr)
1920 {
1921 CM_ASSERTMESSAGE("Error: Out of system memory.");
1922 MosSafeDeleteArray(forward);
1923 return CM_OUT_OF_HOST_MEMORY;
1924 }
1925 for(uint32_t i = 0; i< backwardSurfaceCount; i++)
1926 {
1927 backward[i] = static_cast<CmSurface2DRT *>( backwardSurfaces[i] );
1928 if(backward[i] == nullptr)
1929 {
1930 CM_ASSERTMESSAGE("Error: Invalid backward surfaces.");
1931 MosSafeDeleteArray(forward);
1932 MosSafeDeleteArray(backward);
1933 return CM_INVALID_ARG_VALUE;
1934 }
1935 }
1936 }
1937
1938 CLock locker(m_criticalSectionSurface);
1939
1940 int32_t status = m_surfaceMgr->CreateVmeSurface(currentRT, forward, backward, forwardSurfaceCount, backwardSurfaceCount, vmeIndex);
1941
1942 MosSafeDeleteArray(forward);
1943 MosSafeDeleteArray(backward);
1944
1945 return status;
1946 }
1947
DestroyVmeSurfaceG7_5(SurfaceIndex * & vmeIndex)1948 CM_RT_API int32_t CmDeviceRTBase::DestroyVmeSurfaceG7_5(SurfaceIndex* & vmeIndex)
1949 {
1950 INSERT_API_CALL_LOG(GetHalState());
1951 return DestroyVmeSurface( vmeIndex );
1952 }
1953
SetVmeSurfaceStateParam(SurfaceIndex * vmeIndex,CM_VME_SURFACE_STATE_PARAM * surfStateParam)1954 CM_RT_API int32_t CmDeviceRTBase::SetVmeSurfaceStateParam(SurfaceIndex* vmeIndex,
1955 CM_VME_SURFACE_STATE_PARAM *surfStateParam)
1956 {
1957 INSERT_API_CALL_LOG(GetHalState());
1958
1959 CLock locker(m_criticalSectionSurface);
1960
1961 CM_RETURN_CODE hr = CM_SUCCESS;
1962 CmSurface *cmSurface = nullptr;
1963 CmSurfaceVme *vmeSurface = nullptr;
1964
1965 CM_CHK_NULL_GOTOFINISH_CMERROR(vmeIndex);
1966 CM_CHK_NULL_GOTOFINISH_CMERROR(surfStateParam);
1967
1968 m_surfaceMgr->GetSurface(vmeIndex->get_data(), cmSurface);
1969 CM_CHK_NULL_GOTOFINISH_CMERROR(cmSurface);
1970
1971 // check if it is a vme index
1972 if (cmSurface->Type() != CM_ENUM_CLASS_TYPE_CMSURFACEVME)
1973 {
1974 CM_ASSERTMESSAGE("Error: SetVmeSurfaceStateParam only can config VME surfaces.");
1975 return CM_INVALID_ARG_INDEX;
1976 }
1977
1978 vmeSurface = static_cast<CmSurfaceVme *>(cmSurface);
1979 vmeSurface->SetSurfaceStateResolution(surfStateParam->width, surfStateParam->height);
1980
1981 finish:
1982 return hr;
1983 }
1984
1985 //*-----------------------------------------------------------------------------
1986 //! Create a CmSampler.
1987 //! Input :
1988 //! 1) Const Reference to the sampler state data structure.
1989 //! 2) Reference to the pointer to the CmSampler .
1990 //! Output:
1991 //! CM_SUCCESS if the CmSampler is successfully created;
1992 //! CM_OUT_OF_HOST_MEMORY if out of system memory;
1993 //! CM_FAILURE otherwise;
1994 //*-----------------------------------------------------------------------------
1995 CM_RT_API int32_t
CreateSampler(const CM_SAMPLER_STATE & samplerState,CmSampler * & sampler)1996 CmDeviceRTBase::CreateSampler(const CM_SAMPLER_STATE& samplerState,
1997 CmSampler* & sampler)
1998 {
1999 INSERT_API_CALL_LOG(GetHalState());
2000
2001 CLock locker(m_criticalSectionSampler);
2002
2003 uint32_t index = 0;
2004 int32_t hr= RegisterSamplerState( samplerState, index );
2005 if( FAILED(hr) )
2006 {
2007 CM_ASSERTMESSAGE("Error: Register sampler state failure.");
2008 return CM_EXCEED_SAMPLER_AMOUNT;
2009 }
2010
2011 CmSamplerRT* ptmp = nullptr;
2012 int32_t result = CmSamplerRT::Create( index, ptmp );
2013 if( result == CM_SUCCESS )
2014 {
2015 m_samplerArray.SetElement( index, ptmp );
2016 sampler = static_cast< CmSampler* >(ptmp);
2017 }
2018 else
2019 {
2020 UnregisterSamplerState( index );
2021 }
2022 return result;
2023 }
2024
2025 CM_RT_API int32_t
CreateSamplerEx(const CM_SAMPLER_STATE_EX & samplerState,CmSampler * & sampler)2026 CmDeviceRTBase::CreateSamplerEx(const CM_SAMPLER_STATE_EX& samplerState,
2027 CmSampler* & sampler)
2028 {
2029 INSERT_API_CALL_LOG(GetHalState());
2030
2031 CLock locker(m_criticalSectionSampler);
2032
2033 uint32_t index = 0;
2034 int32_t hr= RegisterSamplerStateEx( samplerState, index );
2035 if( FAILED(hr) )
2036 {
2037 CM_ASSERTMESSAGE("Error: Register sampler state failure.");
2038 return CM_EXCEED_SAMPLER_AMOUNT;
2039 }
2040
2041 CmSamplerRT* ptmp = nullptr;
2042 int32_t result = CmSamplerRT::Create( index, ptmp );
2043 if( result == CM_SUCCESS )
2044 {
2045 m_samplerArray.SetElement( index, ptmp );
2046 sampler = static_cast< CmSampler* >(ptmp);
2047 }
2048 else
2049 {
2050 UnregisterSamplerState( index );
2051 }
2052 return result;
2053 }
2054
2055 //*-----------------------------------------------------------------------------
2056 //| Purpose: Destroy Sampler
2057 //| Returns: Result of the operation.
2058 //*-----------------------------------------------------------------------------
DestroySampler(CmSampler * & sampler)2059 CM_RT_API int32_t CmDeviceRTBase::DestroySampler(CmSampler*& sampler)
2060 {
2061 INSERT_API_CALL_LOG(GetHalState());
2062 CLock locker(m_criticalSectionSampler);
2063
2064 CmSamplerRT* temp = nullptr;
2065 if(sampler != nullptr)
2066 {
2067 temp = static_cast< CmSamplerRT* >(sampler);
2068 }
2069 else
2070 {
2071 return CM_FAILURE;
2072 }
2073
2074 SamplerIndex* index = nullptr;
2075 temp->GetIndex( index );
2076 CM_ASSERT( index );
2077 uint32_t indexValue = index->get_data();
2078
2079 CM_ASSERT( m_samplerArray.GetElement( indexValue ) == (temp) );
2080
2081 int32_t status = CmSamplerRT::Destroy( temp );
2082 if(status == CM_SUCCESS)
2083 {
2084 UnregisterSamplerState( indexValue );
2085 m_samplerArray.SetElement( indexValue, nullptr );
2086 sampler = nullptr;
2087 }
2088
2089 return status;
2090 }
2091
2092 //*-----------------------------------------------------------------------------
2093 //| Purpose: Register Sampler State in CM devie's table
2094 //| Returns: Result of the operation.
2095 //*-----------------------------------------------------------------------------
RegisterSamplerState(const CM_SAMPLER_STATE & samplerState,uint32_t & index)2096 int32_t CmDeviceRTBase::RegisterSamplerState(const CM_SAMPLER_STATE& samplerState,
2097 uint32_t& index)
2098 {
2099 CM_RETURN_CODE hr = CM_SUCCESS;
2100
2101 index = 0;
2102
2103 PCM_CONTEXT_DATA cmData = (PCM_CONTEXT_DATA)GetAccelData();
2104
2105 CM_HAL_SAMPLER_PARAM param;
2106 MOS_ZeroMemory(¶m, sizeof(CM_HAL_SAMPLER_PARAM));
2107 param.addressU = samplerState.addressU;
2108 param.addressV = samplerState.addressV;
2109 param.addressW = samplerState.addressW;
2110 param.magFilter = samplerState.magFilterType;
2111 param.minFilter = samplerState.minFilterType;
2112 param.handle = 0;
2113
2114 CM_CHK_MOSSTATUS_GOTOFINISH_CMERROR(cmData->cmHalState->pfnRegisterSampler(cmData->cmHalState, ¶m));
2115
2116 index = param.handle;
2117
2118 finish:
2119 return hr;
2120 }
2121
2122 int32_t
RegisterSamplerStateEx(const CM_SAMPLER_STATE_EX & samplerState,uint32_t & index)2123 CmDeviceRTBase::RegisterSamplerStateEx(const CM_SAMPLER_STATE_EX& samplerState,
2124 uint32_t& index)
2125 {
2126 CM_RETURN_CODE hr = CM_SUCCESS;
2127
2128 index = 0;
2129
2130 PCM_CONTEXT_DATA cmData = (PCM_CONTEXT_DATA)GetAccelData();
2131
2132 CM_HAL_SAMPLER_PARAM param;
2133 MOS_ZeroMemory(¶m, sizeof(CM_HAL_SAMPLER_PARAM));
2134 param.addressU = samplerState.addressU;
2135 param.addressV = samplerState.addressV;
2136 param.addressW = samplerState.addressW;
2137 param.magFilter = samplerState.magFilterType;
2138 param.minFilter = samplerState.minFilterType;
2139 param.handle = 0;
2140
2141 param.surfaceFormat = (CM_HAL_PIXEL_TYPE)samplerState.SurfaceFormat;
2142 switch (param.surfaceFormat)
2143 {
2144 case CM_HAL_PIXEL_UINT:
2145 param.borderColorRedU = samplerState.BorderColorRedU;
2146 param.borderColorGreenU = samplerState.BorderColorGreenU;
2147 param.borderColorBlueU = samplerState.BorderColorBlueU;
2148 param.borderColorAlphaU = samplerState.BorderColorAlphaU;
2149 break;
2150 case CM_HAL_PIXEL_SINT:
2151 param.borderColorRedS = samplerState.BorderColorRedS;
2152 param.borderColorGreenS = samplerState.BorderColorGreenS;
2153 param.borderColorBlueS = samplerState.BorderColorBlueS;
2154 param.borderColorAlphaS = samplerState.BorderColorAlphaS;
2155 break;
2156 default:
2157 param.borderColorRedF = samplerState.BorderColorRedF;
2158 param.borderColorGreenF = samplerState.BorderColorGreenF;
2159 param.borderColorBlueF = samplerState.BorderColorBlueF;
2160 param.borderColorAlphaF = samplerState.BorderColorAlphaF;
2161 }
2162
2163 CM_CHK_MOSSTATUS_GOTOFINISH_CMERROR(cmData->cmHalState->pfnRegisterSampler(cmData->cmHalState, ¶m));
2164
2165 index = param.handle;
2166
2167 finish:
2168 return hr;
2169 }
2170
2171 //*-----------------------------------------------------------------------------
2172 //| Purpose: Unregister Sampler State in CM devie's table
2173 //| Returns: Result of the operation.
2174 //*-----------------------------------------------------------------------------
UnregisterSamplerState(uint32_t index)2175 int32_t CmDeviceRTBase::UnregisterSamplerState(uint32_t index)
2176 {
2177 CM_RETURN_CODE hr = CM_SUCCESS;
2178
2179 PCM_CONTEXT_DATA cmData = (PCM_CONTEXT_DATA)GetAccelData();
2180
2181 CM_CHK_MOSSTATUS_GOTOFINISH_CMERROR(cmData->cmHalState->pfnUnRegisterSampler(cmData->cmHalState, index));
2182
2183 finish:
2184 return hr;
2185 }
2186
2187 //*-----------------------------------------------------------------------------
2188 //| Purpose: Create Sampler8x8 State
2189 //| Returns: Result of the operation.
2190 //*-----------------------------------------------------------------------------
2191 CM_RT_API int32_t
CreateSampler8x8(const CM_SAMPLER_8X8_DESCR & sampler8x8Descriptor,CmSampler8x8 * & sampler8x8)2192 CmDeviceRTBase::CreateSampler8x8(const CM_SAMPLER_8X8_DESCR & sampler8x8Descriptor,
2193 CmSampler8x8*& sampler8x8)
2194 {
2195 INSERT_API_CALL_LOG(GetHalState());
2196 CLock locker(m_criticalSectionSampler8x8);
2197
2198 int32_t result = CM_FAILURE;
2199
2200 if((sampler8x8Descriptor.stateType == CM_SAMPLER8X8_AVS && sampler8x8Descriptor.avs == nullptr) ||
2201 (sampler8x8Descriptor.stateType == CM_SAMPLER8X8_CONV && sampler8x8Descriptor.conv == nullptr) ||
2202 (sampler8x8Descriptor.stateType == CM_SAMPLER8X8_MISC && sampler8x8Descriptor.misc == nullptr) ||
2203 (sampler8x8Descriptor.stateType == CM_SAMPLER8X8_NONE && sampler8x8Descriptor.conv != nullptr) ||
2204 sampler8x8 != nullptr) {
2205 CM_ASSERTMESSAGE("Error: Invalid arguments.");
2206 return CM_INVALID_ARG_VALUE;
2207 }
2208 CmSampler8x8State_RT* ptmp = nullptr;
2209 uint32_t index = 0;
2210
2211 int32_t hr = RegisterSampler8x8State( sampler8x8Descriptor, index );
2212 if( FAILED(hr) )
2213 {
2214 CM_ASSERTMESSAGE("Error: Register sampler8x8 state failure.");
2215 return CM_EXCEED_SAMPLER_AMOUNT;
2216 }
2217
2218 result = CmSampler8x8State_RT::Create( sampler8x8Descriptor, index, ptmp );
2219 if( result == CM_SUCCESS )
2220 {
2221 m_sampler8x8Array.SetElement( index, ptmp );
2222 sampler8x8 = static_cast< CmSampler8x8* >(ptmp);
2223 }
2224 else
2225 {
2226 UnregisterSampler8x8State( index );
2227 }
2228
2229 return result;
2230 }
2231
2232 //*-----------------------------------------------------------------------------
2233 //| Purpose: Destroy Sampler8x8 State
2234 //| Returns: Result of the operation.
2235 //*-----------------------------------------------------------------------------
DestroySampler8x8(CmSampler8x8 * & sampler8x8)2236 CM_RT_API int32_t CmDeviceRTBase::DestroySampler8x8(CmSampler8x8*& sampler8x8)
2237 {
2238 INSERT_API_CALL_LOG(GetHalState());
2239 CLock locker(m_criticalSectionSampler8x8);
2240
2241 CmSampler8x8State_RT* temp = nullptr;
2242 if(sampler8x8)
2243 {
2244 temp = static_cast< CmSampler8x8State_RT* >(sampler8x8);
2245 }
2246 else
2247 {
2248 return CM_FAILURE;
2249 }
2250
2251 SamplerIndex* index = nullptr;
2252 temp->GetIndex( index );
2253 CM_ASSERT( index );
2254 uint32_t indexValue = index->get_data();
2255
2256 CM_ASSERT( m_sampler8x8Array.GetElement( indexValue ) == (temp) );
2257
2258 int32_t status = CmSampler8x8State_RT::Destroy( temp );
2259 if(status == CM_SUCCESS)
2260 {
2261 UnregisterSampler8x8State( indexValue );
2262 m_sampler8x8Array.SetElement( indexValue, nullptr );
2263 sampler8x8 = nullptr;
2264 }
2265
2266 return status;
2267 }
2268
2269 //*-----------------------------------------------------------------------------
2270 //| Purpose: Create Sampler8x8 Surface
2271 //| Returns: Result of the operation.
2272 //*-----------------------------------------------------------------------------
2273 CM_RT_API int32_t
CreateSampler8x8Surface(CmSurface2D * surface2D,SurfaceIndex * & sampler8x8SurfIndex,CM_SAMPLER8x8_SURFACE sampler8x8Type,CM_SURFACE_ADDRESS_CONTROL_MODE mode)2274 CmDeviceRTBase::CreateSampler8x8Surface(CmSurface2D* surface2D,
2275 SurfaceIndex* & sampler8x8SurfIndex,
2276 CM_SAMPLER8x8_SURFACE sampler8x8Type,
2277 CM_SURFACE_ADDRESS_CONTROL_MODE mode)
2278 {
2279 INSERT_API_CALL_LOG(GetHalState());
2280 uint32_t width = 0;
2281 uint32_t height = 0;
2282 uint32_t sizeperpixel = 0;
2283 uint32_t platform = 0;
2284
2285 GetGenPlatform(platform);
2286
2287 CmSurface2DRT* currentRT = static_cast<CmSurface2DRT *>(surface2D);
2288 if( ! currentRT ) {
2289 CM_ASSERTMESSAGE("Error: Pointer to current surface is null.");
2290 return CM_NULL_POINTER;
2291 }
2292
2293 CM_SURFACE_FORMAT format;
2294 currentRT->GetSurfaceDesc(width, height, format, sizeperpixel);
2295
2296 if (format == CM_SURFACE_FORMAT_NV12)
2297 {
2298 if (platform < IGFX_GEN10_CORE &&
2299 ((width % 4) != 0 || (height % 4) != 0)) { //width or height is not 4 aligned
2300 CM_ASSERTMESSAGE("Error: Width or height is not 4 aligned for nv12 surface.");
2301 return CM_SYSTEM_MEMORY_NOT_4PIXELS_ALIGNED;
2302 }
2303 else if ((width % 2) != 0 || (height % 2) != 0) {
2304 CM_ASSERTMESSAGE("Error: Width or height is not 2 aligned for nv12 surface.");
2305 return CM_SYSTEM_MEMORY_NOT_2PIXELS_ALIGNED;
2306 }
2307 }
2308 CLock locker(m_criticalSectionSurface);
2309
2310 int32_t result = m_surfaceMgr->CreateSampler8x8Surface( currentRT, sampler8x8SurfIndex, sampler8x8Type, mode, nullptr );
2311
2312 return result;
2313 }
2314
2315 //*-----------------------------------------------------------------------------
2316 //| Purpose: Create Sampler8x8 Surface
2317 //| Returns: Result of the operation.
2318 //*-----------------------------------------------------------------------------
2319 CM_RT_API int32_t
CreateSampler8x8SurfaceEx(CmSurface2D * surface2d,SurfaceIndex * & sampler8x8SurfIndex,CM_SAMPLER8x8_SURFACE sampler8x8Type,CM_SURFACE_ADDRESS_CONTROL_MODE mode,CM_FLAG * flag)2320 CmDeviceRTBase::CreateSampler8x8SurfaceEx(CmSurface2D* surface2d,
2321 SurfaceIndex* & sampler8x8SurfIndex,
2322 CM_SAMPLER8x8_SURFACE sampler8x8Type,
2323 CM_SURFACE_ADDRESS_CONTROL_MODE mode,
2324 CM_FLAG* flag)
2325 {
2326 INSERT_API_CALL_LOG(GetHalState());
2327
2328 CmSurface2DRT* currentRT = static_cast<CmSurface2DRT *>(surface2d);
2329 if (!currentRT) {
2330 CM_ASSERTMESSAGE("Error: Pointer to current surface is null.");
2331 return CM_NULL_POINTER;
2332 }
2333 CLock locker(m_criticalSectionSurface);
2334
2335 int32_t result = m_surfaceMgr->CreateSampler8x8Surface(currentRT, sampler8x8SurfIndex, sampler8x8Type, mode, flag);
2336
2337 return result;
2338 }
2339
2340 //*-----------------------------------------------------------------------------
2341 //| Purpose: Create Sampler Surface 2D with Flag
2342 //| Returns: Result of the operation.
2343 //*-----------------------------------------------------------------------------
2344 CM_RT_API int32_t
CreateSamplerSurface2DEx(CmSurface2D * surface2d,SurfaceIndex * & samplerSurfaceIndex,CM_FLAG * flag)2345 CmDeviceRTBase::CreateSamplerSurface2DEx(CmSurface2D* surface2d,
2346 SurfaceIndex* & samplerSurfaceIndex,
2347 CM_FLAG* flag)
2348 {
2349 INSERT_API_CALL_LOG(GetHalState());
2350
2351 if (!surface2d) {
2352 CM_ASSERTMESSAGE("Error: Pointer to sampler surface 2D is null.");
2353 return CM_NULL_POINTER;
2354 }
2355
2356 uint32_t width = 0;
2357 uint32_t height = 0;
2358 uint32_t sizeperpixel = 0;
2359 CM_SURFACE_FORMAT format = CM_SURFACE_FORMAT_INVALID;
2360 CmSurface2DRT* surface2dRT = static_cast<CmSurface2DRT *>(surface2d);
2361 surface2dRT->GetSurfaceDesc(width, height, format, sizeperpixel);
2362 if (!m_surfaceMgr->IsSupportedForSamplerSurface2D(format))
2363 {
2364 return CM_SURFACE_FORMAT_NOT_SUPPORTED;
2365 }
2366
2367 CLock locker(m_criticalSectionSurface);
2368
2369 int32_t result = m_surfaceMgr->CreateSamplerSurface(surface2dRT, samplerSurfaceIndex, flag);
2370
2371 return result;
2372 }
2373
2374 //*-----------------------------------------------------------------------------
2375 //| Purpose: Destroy Sampler8x8 Surface
2376 //| Returns: Result of the operation.
2377 //*-----------------------------------------------------------------------------
2378 CM_RT_API int32_t
DestroySampler8x8Surface(SurfaceIndex * & surfaceIndex)2379 CmDeviceRTBase::DestroySampler8x8Surface(SurfaceIndex* & surfaceIndex)
2380 {
2381 INSERT_API_CALL_LOG(GetHalState());
2382
2383 CLock locker(m_criticalSectionSurface);
2384
2385 int32_t result = m_surfaceMgr->DestroySampler8x8Surface( surfaceIndex );
2386
2387 return result;
2388 }
2389
2390 //*-----------------------------------------------------------------------------
2391 //| Purpose: Coefficient Format Transform
2392 //| Returns: Result of the operation.
2393 //*-----------------------------------------------------------------------------
2394 #define FloatToS1_6(x) (uint8_t)((char)(x * 64))
2395 void
Sampler8x8CoefficientFormatTransform(CM_AVS_INTERNEL_NONPIPLINED_STATE * dstAvsState,CM_AVS_NONPIPLINED_STATE * srcAvsState)2396 CmDeviceRTBase::Sampler8x8CoefficientFormatTransform(
2397 CM_AVS_INTERNEL_NONPIPLINED_STATE* dstAvsState,
2398 CM_AVS_NONPIPLINED_STATE* srcAvsState)
2399 {
2400 int i;
2401
2402 CmSafeMemSet( dstAvsState, 0, sizeof(CM_AVS_INTERNEL_NONPIPLINED_STATE));
2403
2404 dstAvsState->BypassXAF = srcAvsState->BypassXAF;
2405 dstAvsState->BypassYAF = srcAvsState->BypassYAF;
2406 dstAvsState->DefaultSharpLvl = srcAvsState->DefaultSharpLvl;
2407 dstAvsState->bEnableRGBAdaptive = srcAvsState->bEnableRGBAdaptive;
2408 dstAvsState->bAdaptiveFilterAllChannels = srcAvsState->bAdaptiveFilterAllChannels;
2409 if (!srcAvsState->BypassXAF && !srcAvsState->BypassYAF) {
2410 dstAvsState->maxDerivative4Pixels = srcAvsState->maxDerivative4Pixels;
2411 dstAvsState->maxDerivative8Pixels = srcAvsState->maxDerivative8Pixels;
2412 dstAvsState->transitionArea4Pixels = srcAvsState->transitionArea4Pixels;
2413 dstAvsState->transitionArea8Pixels = srcAvsState->transitionArea8Pixels;
2414 }
2415
2416 for (i = 0; i < CM_NUM_COEFF_ROWS_SKL; i++) {
2417 dstAvsState->Tbl0X[i].FilterCoeff_0_0 = FloatToS1_6(srcAvsState->Tbl0X[i].FilterCoeff_0_0);
2418 dstAvsState->Tbl0X[i].FilterCoeff_0_1 = FloatToS1_6(srcAvsState->Tbl0X[i].FilterCoeff_0_1);
2419 dstAvsState->Tbl0X[i].FilterCoeff_0_2 = FloatToS1_6(srcAvsState->Tbl0X[i].FilterCoeff_0_2);
2420 dstAvsState->Tbl0X[i].FilterCoeff_0_3 = FloatToS1_6(srcAvsState->Tbl0X[i].FilterCoeff_0_3);
2421 dstAvsState->Tbl0X[i].FilterCoeff_0_4 = FloatToS1_6(srcAvsState->Tbl0X[i].FilterCoeff_0_4);
2422 dstAvsState->Tbl0X[i].FilterCoeff_0_5 = FloatToS1_6(srcAvsState->Tbl0X[i].FilterCoeff_0_5);
2423 dstAvsState->Tbl0X[i].FilterCoeff_0_6 = FloatToS1_6(srcAvsState->Tbl0X[i].FilterCoeff_0_6);
2424 dstAvsState->Tbl0X[i].FilterCoeff_0_7 = FloatToS1_6(srcAvsState->Tbl0X[i].FilterCoeff_0_7);
2425
2426 dstAvsState->Tbl0Y[i].FilterCoeff_0_0 = FloatToS1_6(srcAvsState->Tbl0Y[i].FilterCoeff_0_0);
2427 dstAvsState->Tbl0Y[i].FilterCoeff_0_1 = FloatToS1_6(srcAvsState->Tbl0Y[i].FilterCoeff_0_1);
2428 dstAvsState->Tbl0Y[i].FilterCoeff_0_2 = FloatToS1_6(srcAvsState->Tbl0Y[i].FilterCoeff_0_2);
2429 dstAvsState->Tbl0Y[i].FilterCoeff_0_3 = FloatToS1_6(srcAvsState->Tbl0Y[i].FilterCoeff_0_3);
2430 dstAvsState->Tbl0Y[i].FilterCoeff_0_4 = FloatToS1_6(srcAvsState->Tbl0Y[i].FilterCoeff_0_4);
2431 dstAvsState->Tbl0Y[i].FilterCoeff_0_5 = FloatToS1_6(srcAvsState->Tbl0Y[i].FilterCoeff_0_5);
2432 dstAvsState->Tbl0Y[i].FilterCoeff_0_6 = FloatToS1_6(srcAvsState->Tbl0Y[i].FilterCoeff_0_6);
2433 dstAvsState->Tbl0Y[i].FilterCoeff_0_7 = FloatToS1_6(srcAvsState->Tbl0Y[i].FilterCoeff_0_7);
2434
2435 dstAvsState->Tbl1X[i].FilterCoeff_0_0 = FloatToS1_6(srcAvsState->Tbl1X[i].FilterCoeff_0_0);
2436 dstAvsState->Tbl1X[i].FilterCoeff_0_1 = FloatToS1_6(srcAvsState->Tbl1X[i].FilterCoeff_0_1);
2437 dstAvsState->Tbl1X[i].FilterCoeff_0_2 = FloatToS1_6(srcAvsState->Tbl1X[i].FilterCoeff_0_2);
2438 dstAvsState->Tbl1X[i].FilterCoeff_0_3 = FloatToS1_6(srcAvsState->Tbl1X[i].FilterCoeff_0_3);
2439 dstAvsState->Tbl1X[i].FilterCoeff_0_4 = FloatToS1_6(srcAvsState->Tbl1X[i].FilterCoeff_0_4);
2440 dstAvsState->Tbl1X[i].FilterCoeff_0_5 = FloatToS1_6(srcAvsState->Tbl1X[i].FilterCoeff_0_5);
2441 dstAvsState->Tbl1X[i].FilterCoeff_0_6 = FloatToS1_6(srcAvsState->Tbl1X[i].FilterCoeff_0_6);
2442 dstAvsState->Tbl1X[i].FilterCoeff_0_7 = FloatToS1_6(srcAvsState->Tbl1X[i].FilterCoeff_0_7);
2443
2444 dstAvsState->Tbl1Y[i].FilterCoeff_0_0 = FloatToS1_6(srcAvsState->Tbl1Y[i].FilterCoeff_0_0);
2445 dstAvsState->Tbl1Y[i].FilterCoeff_0_1 = FloatToS1_6(srcAvsState->Tbl1Y[i].FilterCoeff_0_1);
2446 dstAvsState->Tbl1Y[i].FilterCoeff_0_2 = FloatToS1_6(srcAvsState->Tbl1Y[i].FilterCoeff_0_2);
2447 dstAvsState->Tbl1Y[i].FilterCoeff_0_3 = FloatToS1_6(srcAvsState->Tbl1Y[i].FilterCoeff_0_3);
2448 dstAvsState->Tbl1Y[i].FilterCoeff_0_4 = FloatToS1_6(srcAvsState->Tbl1Y[i].FilterCoeff_0_4);
2449 dstAvsState->Tbl1Y[i].FilterCoeff_0_5 = FloatToS1_6(srcAvsState->Tbl1Y[i].FilterCoeff_0_5);
2450 dstAvsState->Tbl1Y[i].FilterCoeff_0_6 = FloatToS1_6(srcAvsState->Tbl1Y[i].FilterCoeff_0_6);
2451 dstAvsState->Tbl1Y[i].FilterCoeff_0_7 = FloatToS1_6(srcAvsState->Tbl1Y[i].FilterCoeff_0_7);
2452 }
2453
2454 return;
2455 }
2456
2457 //*-----------------------------------------------------------------------------
2458 //| Purpose: Register Sampler8x8 State (Not implemented yet)
2459 //| Returns: Result of the operation.
2460 //*-----------------------------------------------------------------------------
RegisterSampler8x8State(const CM_SAMPLER_8X8_DESCR & sampler8x8State,uint32_t & index)2461 int32_t CmDeviceRTBase::RegisterSampler8x8State(
2462 const CM_SAMPLER_8X8_DESCR & sampler8x8State,
2463 uint32_t& index)
2464 {
2465 CM_RETURN_CODE hr = CM_SUCCESS;
2466
2467 void *dst = nullptr;
2468 void *src = nullptr;
2469
2470 CM_HAL_SAMPLER_8X8_PARAM param;
2471 CM_AVS_STATE_MSG *cmAvs;
2472 PMHW_SAMPLER_STATE_AVS_PARAM mhwAvs;
2473
2474 CmSafeMemSet(¶m, 0, sizeof(CM_HAL_SAMPLER_8X8_PARAM));
2475
2476 index = 0;
2477 param.handle = 0;
2478 param.sampler8x8State.stateType = sampler8x8State.stateType;
2479
2480 //Initialize the input parameters.
2481 switch(sampler8x8State.stateType)
2482 {
2483 case CM_SAMPLER8X8_AVS:
2484 mhwAvs = &(param.sampler8x8State.avsParam.avsState);
2485 cmAvs = sampler8x8State.avs;
2486 mhwAvs->stateID = (int16_t)-1;
2487 mhwAvs->bEnableAVS = true;
2488 mhwAvs->AvsType = cmAvs->AVSTYPE;
2489 mhwAvs->EightTapAFEnable = cmAvs->EightTapAFEnable;
2490 mhwAvs->BypassIEF = cmAvs->BypassIEF;
2491 mhwAvs->GainFactor = cmAvs->GainFactor;
2492 mhwAvs->GlobalNoiseEstm = cmAvs->GlobalNoiseEstm;
2493 mhwAvs->StrongEdgeThr = cmAvs->StrongEdgeThr;
2494 mhwAvs->WeakEdgeThr = cmAvs->WeakEdgeThr;
2495 mhwAvs->StrongEdgeWght = cmAvs->StrongEdgeWght;
2496 mhwAvs->RegularWght = cmAvs->RegularWght;
2497 mhwAvs->NonEdgeWght = cmAvs->NonEdgeWght;
2498
2499 mhwAvs->bEnableSTDE = 0;
2500 mhwAvs->b8TapAdaptiveEnable = 0;
2501 mhwAvs->bSkinDetailFactor = 0;
2502 // current vphal/mhw use HDCDW flag to control shuffleoutputwriteback, we follow them
2503 mhwAvs->bHdcDwEnable = ( cmAvs->HDCDirectWriteEnable || ( !cmAvs->ShuffleOutputWriteback ) );
2504 mhwAvs->bWritebackStandard = !cmAvs->ShuffleOutputWriteback;
2505 mhwAvs->bEnableIEF = 0;
2506 mhwAvs->wIEFFactor = 0;
2507 mhwAvs->wR3xCoefficient = cmAvs->wR3xCoefficient;
2508 mhwAvs->wR3cCoefficient = cmAvs->wR3cCoefficient;
2509 mhwAvs->wR5xCoefficient = cmAvs->wR5xCoefficient;
2510 mhwAvs->wR5cxCoefficient = cmAvs->wR5cxCoefficient;
2511 mhwAvs->wR5cCoefficient = cmAvs->wR5cCoefficient;
2512
2513 Sampler8x8CoefficientFormatTransform((PCM_AVS_INTERNEL_NONPIPLINED_STATE )&(param.sampler8x8State.avsParam.avsTable), sampler8x8State.avs->AvsState);
2514 break;
2515
2516 case CM_SAMPLER8X8_CONV:
2517 dst = (void *)&(param.sampler8x8State.convolveState);
2518 src = (void *)sampler8x8State.conv;
2519 CmSafeMemCopy( dst, src, sizeof( CM_CONVOLVE_STATE_MSG));
2520 break;
2521
2522 case CM_SAMPLER8X8_MISC:
2523 param.sampler8x8State.miscState.DW0.Height = sampler8x8State.misc->DW0.Height;
2524 param.sampler8x8State.miscState.DW0.Width = sampler8x8State.misc->DW0.Width;
2525 param.sampler8x8State.miscState.DW0.Row0 = sampler8x8State.misc->DW0.Row0;
2526 param.sampler8x8State.miscState.DW1.Row1 = sampler8x8State.misc->DW1.Row1;
2527 param.sampler8x8State.miscState.DW1.Row2 = sampler8x8State.misc->DW1.Row2;
2528 param.sampler8x8State.miscState.DW2.Row3 = sampler8x8State.misc->DW2.Row3;
2529 param.sampler8x8State.miscState.DW2.Row4 = sampler8x8State.misc->DW2.Row4;
2530 param.sampler8x8State.miscState.DW3.Row5 = sampler8x8State.misc->DW3.Row5;
2531 param.sampler8x8State.miscState.DW3.Row6 = sampler8x8State.misc->DW3.Row6;
2532 param.sampler8x8State.miscState.DW4.Row7 = sampler8x8State.misc->DW4.Row7;
2533 param.sampler8x8State.miscState.DW4.Row8 = sampler8x8State.misc->DW4.Row8;
2534 param.sampler8x8State.miscState.DW5.Row9 = sampler8x8State.misc->DW5.Row9;
2535 param.sampler8x8State.miscState.DW5.Row10 = sampler8x8State.misc->DW5.Row10;
2536 param.sampler8x8State.miscState.DW6.Row11 = sampler8x8State.misc->DW6.Row11;
2537 param.sampler8x8State.miscState.DW6.Row12 = sampler8x8State.misc->DW6.Row12;
2538 param.sampler8x8State.miscState.DW7.Row13 = sampler8x8State.misc->DW7.Row13;
2539 param.sampler8x8State.miscState.DW7.Row14 = sampler8x8State.misc->DW7.Row14;
2540
2541 break;
2542
2543 default:
2544 CM_ASSERTMESSAGE("Error: Invalid sampler8x8 state descr.");
2545 return hr;
2546 }
2547
2548 PCM_CONTEXT_DATA cmData = (PCM_CONTEXT_DATA)GetAccelData();
2549
2550 CM_CHK_MOSSTATUS_GOTOFINISH_CMERROR(cmData->cmHalState->pfnRegisterSampler8x8(cmData->cmHalState, ¶m));
2551
2552 index = param.handle >> 16;
2553
2554 finish:
2555 return hr;
2556 }
2557
2558 //*-----------------------------------------------------------------------------
2559 //| Purpose: UnRegister Sampler8x8 State (Not implemented yet)
2560 //| Returns: Result of the operation.
2561 //*-----------------------------------------------------------------------------
UnregisterSampler8x8State(uint32_t index)2562 int32_t CmDeviceRTBase::UnregisterSampler8x8State(uint32_t index)
2563 {
2564 CM_RETURN_CODE hr = CM_SUCCESS;
2565
2566 PCM_CONTEXT_DATA cmData = (PCM_CONTEXT_DATA)GetAccelData();
2567
2568 CM_CHK_MOSSTATUS_GOTOFINISH_CMERROR(cmData->cmHalState->pfnUnRegisterSampler8x8(cmData->cmHalState, index));
2569
2570 finish:
2571 return hr;
2572 }
2573
2574 //*-----------------------------------------------------------------------------
2575 //! Function to create a thread group space
2576 //! Arguments:
2577 //! 1. Width/height (in unit of thread ) of each thread group
2578 //! 2. Width/height(in unit of group) of thread group space.
2579 //! 3. Reference to the point to CmThreadGroupSpace object to created.
2580 //! Return Value:
2581 //! CM_SUCCESS if the CmThreadGroupSpace is successfully created
2582 //! Notes:
2583 //! The total thread count is width*height*grpWidth*grpHeight.
2584 //! The thread count will check against the thread count set by CmKernel::SetThreadCount if CmKernel::SetThreadCount is called.
2585 //! CmKernel::SetThreadCount needs to be called if CmKernel::SetThreadArg is to be called.
2586 //*-----------------------------------------------------------------------------
2587 CM_RT_API int32_t
CreateThreadGroupSpaceEx(uint32_t thrdSpaceWidth,uint32_t thrdSpaceHeight,uint32_t thrdSpaceDepth,uint32_t grpSpaceWidth,uint32_t grpSpaceHeight,uint32_t grpSpaceDepth,CmThreadGroupSpace * & threadGroupSpace)2588 CmDeviceRTBase::CreateThreadGroupSpaceEx(uint32_t thrdSpaceWidth,
2589 uint32_t thrdSpaceHeight,
2590 uint32_t thrdSpaceDepth,
2591 uint32_t grpSpaceWidth,
2592 uint32_t grpSpaceHeight,
2593 uint32_t grpSpaceDepth,
2594 CmThreadGroupSpace*& threadGroupSpace)
2595 {
2596 INSERT_API_CALL_LOG(GetHalState());
2597
2598 CLock locker(m_criticalSectionThreadGroupSpace);
2599
2600 uint32_t firstfreeslot = m_threadGroupSpaceArray.GetFirstFreeIndex();
2601 CmDeviceRT *cmDevice = static_cast<CmDeviceRT*>(this);
2602 CM_CHK_NULL_RETURN_CMERROR(cmDevice);
2603 int32_t result = CmThreadGroupSpace::Create(cmDevice, firstfreeslot, thrdSpaceWidth, thrdSpaceHeight, thrdSpaceDepth, grpSpaceWidth, grpSpaceHeight, grpSpaceDepth, threadGroupSpace);
2604 if (result == CM_SUCCESS)
2605 {
2606 m_threadGroupSpaceArray.SetElement( firstfreeslot, threadGroupSpace );
2607 m_threadGroupSpaceCount ++;
2608 }
2609 return result;
2610 }
2611
2612 CM_RT_API int32_t
CreateThreadGroupSpace(uint32_t thrdSpaceWidth,uint32_t thrdSpaceHeight,uint32_t grpSpaceWidth,uint32_t grpSpaceHeight,CmThreadGroupSpace * & threadGroupSpace)2613 CmDeviceRTBase::CreateThreadGroupSpace(uint32_t thrdSpaceWidth,
2614 uint32_t thrdSpaceHeight,
2615 uint32_t grpSpaceWidth,
2616 uint32_t grpSpaceHeight,
2617 CmThreadGroupSpace*& threadGroupSpace)
2618 {
2619 INSERT_API_CALL_LOG(GetHalState());
2620
2621 int32_t result = CreateThreadGroupSpaceEx(thrdSpaceWidth,
2622 thrdSpaceHeight,
2623 1,
2624 grpSpaceWidth,
2625 grpSpaceHeight,
2626 1,
2627 threadGroupSpace);
2628
2629 return result;
2630 }
2631
2632 CM_RT_API int32_t
DestroyThreadGroupSpace(CmThreadGroupSpace * & threadGroupSpace)2633 CmDeviceRTBase::DestroyThreadGroupSpace(CmThreadGroupSpace*& threadGroupSpace)
2634 {
2635 INSERT_API_CALL_LOG(GetHalState());
2636
2637 if( threadGroupSpace == nullptr )
2638 {
2639 return CM_FAILURE;
2640 }
2641
2642 uint32_t indexTGs = threadGroupSpace->GetIndexInTGsArray();
2643
2644 CLock locker(m_criticalSectionThreadGroupSpace);
2645
2646 if(threadGroupSpace == static_cast< CmThreadGroupSpace* >(m_threadGroupSpaceArray.GetElement( indexTGs )))
2647 {
2648 int32_t status = CmThreadGroupSpace::Destroy( threadGroupSpace );
2649 if(status == CM_SUCCESS)
2650 {
2651 m_threadGroupSpaceArray.SetElement( indexTGs, nullptr );
2652 threadGroupSpace = nullptr;
2653 return CM_SUCCESS;
2654 }
2655 }
2656 else
2657 {
2658 CM_ASSERTMESSAGE("Error: Failed to destroy thread group space.");
2659 return CM_FAILURE;
2660 }
2661
2662 return CM_FAILURE;
2663 }
2664
2665 //*-----------------------------------------------------------------------------
2666 //| Purpose: Load Predefined Program, it is used by GPUCopy API
2667 //| Returns: Result of the operation.
2668 //*-----------------------------------------------------------------------------
LoadPredefinedCopyKernel(CmProgram * & program)2669 int32_t CmDeviceRTBase::LoadPredefinedCopyKernel(CmProgram*& program)
2670 {
2671 PCM_HAL_STATE cmHalState;
2672 int32_t hr = CM_SUCCESS;
2673
2674 cmHalState = ((PCM_CONTEXT_DATA)GetAccelData())->cmHalState;
2675
2676 if(m_gpuCopyKernelProgram)
2677 {
2678 program = m_gpuCopyKernelProgram;
2679 return CM_SUCCESS;
2680 }
2681
2682 void * gpucopyKernelIsa;
2683 uint32_t gpucopyKernelIsaSize;
2684
2685 cmHalState->cmHalInterface->GetCopyKernelIsa(gpucopyKernelIsa, gpucopyKernelIsaSize);
2686 if (gpucopyKernelIsa == nullptr || gpucopyKernelIsaSize == 0)
2687 {
2688 return CM_NOT_IMPLEMENTED;
2689 }
2690
2691 hr = LoadProgram((void *)gpucopyKernelIsa, gpucopyKernelIsaSize, program, "PredefinedGPUKernel");
2692 if (hr != CM_SUCCESS)
2693 {
2694 return hr;
2695 }
2696
2697 m_gpuCopyKernelProgram = program;
2698
2699 return hr;
2700 }
2701
2702 //*-----------------------------------------------------------------------------
2703 //| Purpose: Load Predefined surface init Program, it is used by GPU init surface API
2704 //| Returns: Result of the operation.
2705 //*-----------------------------------------------------------------------------
LoadPredefinedInitKernel(CmProgram * & program)2706 int32_t CmDeviceRTBase::LoadPredefinedInitKernel(CmProgram*& program)
2707 {
2708 PCM_HAL_STATE cmHalState;
2709 int32_t hr = CM_SUCCESS;
2710
2711 cmHalState = ((PCM_CONTEXT_DATA)GetAccelData())->cmHalState;
2712
2713 if(m_surfInitKernelProgram)
2714 {
2715 program = m_surfInitKernelProgram;
2716 return CM_SUCCESS;
2717 }
2718
2719 void * gpuinitKernelIsa;
2720 uint32_t gpuinitKernelIsaSize;
2721
2722 cmHalState->cmHalInterface->GetInitKernelIsa(gpuinitKernelIsa, gpuinitKernelIsaSize);
2723 if (gpuinitKernelIsa == nullptr || gpuinitKernelIsaSize == 0)
2724 {
2725 return CM_NOT_IMPLEMENTED;
2726 }
2727
2728 hr = LoadProgram((void *)gpuinitKernelIsa, gpuinitKernelIsaSize, program, "PredefinedGPUKernel");
2729 if (hr != CM_SUCCESS)
2730 {
2731 return hr;
2732 }
2733
2734 m_surfInitKernelProgram = program;
2735
2736 return hr;
2737 }
2738
2739
2740 //*-----------------------------------------------------------------------------
2741 //| Purpose: Prepare program/kernel/task/queue, used by GPU init surface API
2742 //| Returns: Result of the operation.
2743 //*-----------------------------------------------------------------------------
PrepareGPUinitSurface()2744 int32_t CmDeviceRTBase::PrepareGPUinitSurface()
2745 {
2746 PCM_HAL_STATE cmHalState;
2747 int32_t hr = CM_SUCCESS;
2748 if (m_surfInitKernelProgram == nullptr)
2749 {
2750 CmProgram* tmpProgram = nullptr;
2751 CM_CHK_CMSTATUS_GOTOFINISH(LoadPredefinedInitKernel(tmpProgram));
2752 m_hasGpuInitKernel = true;
2753 }
2754
2755 CM_CHK_CMSTATUS_GOTOFINISH(CreateQueue(m_InitCmQueue));
2756
2757 // Single plane surface
2758 CM_CHK_CMSTATUS_GOTOFINISH(CreateKernel(m_surfInitKernelProgram, _NAME(surfaceCopy_set), m_kernel0, "PredefinedGPUInitKernel"));
2759 CM_CHK_CMSTATUS_GOTOFINISH(CreateTask(m_gpuInitTask0));
2760 CM_CHK_NULL_GOTOFINISH_CMERROR(m_gpuInitTask0);
2761 CM_CHK_CMSTATUS_GOTOFINISH(m_gpuInitTask0->AddKernel(m_kernel0));
2762 // 2-plane surface Y+UV
2763 CM_CHK_CMSTATUS_GOTOFINISH(CreateKernel(m_surfInitKernelProgram, _NAME(surfaceCopy_set_NV12), m_kernel1, "PredefinedGPUInitKernel"));
2764 CM_CHK_CMSTATUS_GOTOFINISH(CreateTask(m_gpuInitTask1));
2765 CM_CHK_NULL_GOTOFINISH_CMERROR(m_gpuInitTask1);
2766 CM_CHK_CMSTATUS_GOTOFINISH(m_gpuInitTask1->AddKernel(m_kernel1));
2767
2768 finish:
2769 return hr;
2770 }
2771
2772
2773 //*-----------------------------------------------------------------------------
2774 //| Purpose: Initialize surface by predefined GPU kernel
2775 //| Returns: Result of the operation.
2776 //*-----------------------------------------------------------------------------
2777 #define BLOCK_PIXEL_WIDTH (32)
2778 #define BLOCK_HEIGHT (8)
GPUinitSurface(CmSurface2D * surf2D,const uint32_t initValue,CmEvent * & event)2779 int32_t CmDeviceRTBase::GPUinitSurface(CmSurface2D* surf2D, const uint32_t initValue, CmEvent*& event)
2780 {
2781 int32_t hr = CM_SUCCESS;
2782 uint32_t width = 0;
2783 uint32_t height = 0;
2784 uint32_t sizePerPixel = 0;
2785 SurfaceIndex* outputIndexCM = nullptr;
2786 CmThreadSpace* threadSpace = nullptr;
2787 uint32_t threadWidth = 0;
2788 uint32_t threadHeight = 0;
2789 uint32_t threadNum = 0;
2790 CM_SURFACE_FORMAT format = CM_SURFACE_FORMAT_INVALID;
2791
2792 if (!HasGpuInitKernel())
2793 {
2794 return CM_NOT_IMPLEMENTED;
2795 }
2796 if (!surf2D)
2797 {
2798 CM_ASSERTMESSAGE("Error: Pointer to surface 2d is null.");
2799 return CM_FAILURE;
2800 }
2801 CmSurface2DRT* surf2DRT = static_cast<CmSurface2DRT*>(surf2D);
2802 CM_CHK_CMSTATUS_GOTOFINISH(surf2DRT->GetSurfaceDesc(width, height, format, sizePerPixel));
2803 CM_CHK_CMSTATUS_GOTOFINISH(surf2D->GetIndex(outputIndexCM));
2804 threadWidth = (uint32_t)ceil((double)width * sizePerPixel / BLOCK_PIXEL_WIDTH / 4);
2805 threadHeight = (uint32_t)ceil((double)height / BLOCK_HEIGHT);
2806 threadNum = threadWidth * threadHeight;
2807
2808 CM_CHK_CMSTATUS_GOTOFINISH(CreateThreadSpace(threadWidth, threadHeight, threadSpace));
2809 CM_CHK_NULL_GOTOFINISH_CMERROR(threadSpace);
2810
2811 if (format == CM_SURFACE_FORMAT_NV12 || format == CM_SURFACE_FORMAT_P010 || format == CM_SURFACE_FORMAT_P016)
2812 {
2813 CM_CHK_CMSTATUS_GOTOFINISH(m_kernel1->SetThreadCount(threadNum));
2814 CM_CHK_CMSTATUS_GOTOFINISH(m_kernel1->SetKernelArg(0, sizeof(uint32_t), &initValue));
2815 CM_CHK_CMSTATUS_GOTOFINISH(m_kernel1->SetKernelArg(1, sizeof(SurfaceIndex), outputIndexCM));
2816 CM_CHK_CMSTATUS_GOTOFINISH(m_InitCmQueue->EnqueueFast(m_gpuInitTask1, event, threadSpace));
2817 }
2818 else
2819 {
2820 CM_CHK_CMSTATUS_GOTOFINISH(m_kernel0->SetThreadCount(threadNum));
2821 CM_CHK_CMSTATUS_GOTOFINISH(m_kernel0->SetKernelArg(0, sizeof(uint32_t), &initValue));
2822 CM_CHK_CMSTATUS_GOTOFINISH(m_kernel0->SetKernelArg(1, sizeof(SurfaceIndex), outputIndexCM));
2823 CM_CHK_CMSTATUS_GOTOFINISH(m_InitCmQueue->EnqueueFast(m_gpuInitTask0, event, threadSpace));
2824 }
2825
2826 finish:
2827 if (threadSpace) DestroyThreadSpace(threadSpace);
2828 return hr;
2829 }
2830
2831
2832 //*-----------------------------------------------------------------------------
2833 //| Purpose: Return HW stepping infor, Not implemented yet.
2834 //| Returns: Result of the operation.
2835 //*-----------------------------------------------------------------------------
GetGenStepInfo(char * & stepinfostr)2836 int32_t CmDeviceRTBase::GetGenStepInfo(char*& stepinfostr)
2837 {
2838 PCM_HAL_STATE cmHalState;
2839 int32_t hr = CM_SUCCESS;
2840
2841 cmHalState = ((PCM_CONTEXT_DATA)GetAccelData())->cmHalState;
2842
2843 CM_CHK_MOSSTATUS_GOTOFINISH_CMERROR(cmHalState->cmHalInterface->GetGenStepInfo(stepinfostr));
2844
2845 finish:
2846 return hr;
2847 }
2848
2849 //*-----------------------------------------------------------------------------
2850 //| Purpose: Create Sampler Surface 2D
2851 //| Returns: Result of the operation.
2852 //*-----------------------------------------------------------------------------
2853 CM_RT_API int32_t
CreateSamplerSurface2D(CmSurface2D * Surface2d,SurfaceIndex * & samplerSurfaceIndex)2854 CmDeviceRTBase::CreateSamplerSurface2D(CmSurface2D* Surface2d,
2855 SurfaceIndex* & samplerSurfaceIndex)
2856 {
2857 INSERT_API_CALL_LOG(GetHalState());
2858
2859 if( ! Surface2d ) {
2860 CM_ASSERTMESSAGE("Error: Pointer to sampler surface 2D is null.");
2861 return CM_NULL_POINTER;
2862 }
2863
2864 uint32_t width = 0;
2865 uint32_t height = 0;
2866 uint32_t sizeperpixel = 0;
2867 CM_SURFACE_FORMAT format = CM_SURFACE_FORMAT_INVALID;
2868
2869 CmSurface2DRT* surface2dRT = static_cast<CmSurface2DRT *>(Surface2d);
2870 surface2dRT->GetSurfaceDesc(width, height, format, sizeperpixel);
2871
2872 if (!m_surfaceMgr->IsSupportedForSamplerSurface2D(format))
2873 {
2874 return CM_SURFACE_FORMAT_NOT_SUPPORTED;
2875 }
2876
2877 CLock locker(m_criticalSectionSurface);
2878
2879 int32_t result = m_surfaceMgr->CreateSamplerSurface( surface2dRT, samplerSurfaceIndex, nullptr);
2880
2881 return result;
2882 }
2883
2884 //*-----------------------------------------------------------------------------
2885 //| Purpose: Create Sampler Surface 2D UP
2886 //| Returns: Result of the operation.
2887 //*-----------------------------------------------------------------------------
2888 CM_RT_API int32_t
CreateSamplerSurface2DUP(CmSurface2DUP * surface2dUP,SurfaceIndex * & samplerSurfaceIndex)2889 CmDeviceRTBase::CreateSamplerSurface2DUP(CmSurface2DUP* surface2dUP,
2890 SurfaceIndex* & samplerSurfaceIndex)
2891 {
2892 INSERT_API_CALL_LOG(GetHalState());
2893
2894 if (!surface2dUP)
2895 {
2896 CM_ASSERTMESSAGE("Error: Pointer to sampler 2D UP is null.");
2897 return CM_NULL_POINTER;
2898 }
2899
2900 uint32_t width = 0;
2901 uint32_t height = 0;
2902 uint32_t sizeperpixel = 0;
2903 CM_SURFACE_FORMAT format = CM_SURFACE_FORMAT_INVALID;
2904 CmSurface2DUPRT *surface2DRT = static_cast<CmSurface2DUPRT *>(surface2dUP);
2905 surface2DRT->GetSurfaceDesc(width, height, format, sizeperpixel);
2906 if (!m_surfaceMgr->IsSupportedForSamplerSurface2D(format))
2907 {
2908 return CM_SURFACE_FORMAT_NOT_SUPPORTED;
2909 }
2910
2911 CLock locker(m_criticalSectionSurface);
2912
2913 int32_t result = m_surfaceMgr->CreateSamplerSurface(surface2DRT, samplerSurfaceIndex);
2914
2915 return result;
2916 }
2917
2918 //*-----------------------------------------------------------------------------
2919 //| Purpose: Create Sampler Surface 3D
2920 //| Returns: Result of the operation.
2921 //*-----------------------------------------------------------------------------
2922 CM_RT_API int32_t
CreateSamplerSurface3D(CmSurface3D * p3DSurface,SurfaceIndex * & samplerSurfaceIndex)2923 CmDeviceRTBase::CreateSamplerSurface3D(CmSurface3D* p3DSurface,
2924 SurfaceIndex* & samplerSurfaceIndex)
2925 {
2926 INSERT_API_CALL_LOG(GetHalState());
2927
2928 if( ! p3DSurface ) {
2929 CM_ASSERTMESSAGE("Error: Pointer to sampler surface 3D is null.");
2930 return CM_NULL_POINTER;
2931 }
2932
2933 uint32_t width = 0;
2934 uint32_t height = 0;
2935 uint32_t depth = 0;
2936 CM_SURFACE_FORMAT format = CM_SURFACE_FORMAT_INVALID;
2937 CmSurface3DRT *surfaceRT = static_cast<CmSurface3DRT *>(p3DSurface);
2938 surfaceRT->GetProperties(width, height, depth, format);
2939 switch(format)
2940 {
2941 case CM_SURFACE_FORMAT_A8R8G8B8:
2942 case CM_SURFACE_FORMAT_A16B16G16R16:
2943 break;
2944
2945 default:
2946 CM_ASSERTMESSAGE("Error: Unsupported surface format.");
2947 return CM_SURFACE_FORMAT_NOT_SUPPORTED;
2948 }
2949
2950 CLock locker(m_criticalSectionSurface);
2951
2952 int32_t result = m_surfaceMgr->CreateSamplerSurface( surfaceRT, samplerSurfaceIndex);
2953
2954 return result;
2955 }
2956
2957 //*-----------------------------------------------------------------------------
2958 //| Purpose: Destroy Sampler Surface
2959 //| Returns: Result of the operation.
2960 //*-----------------------------------------------------------------------------
2961 CM_RT_API int32_t
DestroySamplerSurface(SurfaceIndex * & samplerSurfaceIndex)2962 CmDeviceRTBase::DestroySamplerSurface(SurfaceIndex* & samplerSurfaceIndex)
2963 {
2964 INSERT_API_CALL_LOG(GetHalState());
2965
2966 CLock locker(m_criticalSectionSurface);
2967
2968 int32_t result = m_surfaceMgr->DestroySamplerSurface( samplerSurfaceIndex );
2969
2970 return result;
2971 }
2972
2973 //*-----------------------------------------------------------------------------
2974 //| Purpose: Get Cm Sampler8x8 pointer
2975 //| Returns: Result of the operation.
2976 //*-----------------------------------------------------------------------------
GetSampler8x8(uint32_t index,CmSampler8x8State_RT * & sampler8x8)2977 int32_t CmDeviceRTBase::GetSampler8x8(uint32_t index,
2978 CmSampler8x8State_RT *&sampler8x8)
2979 {
2980 if (CM_MAX_SAMPLER_TABLE_SIZE < index)
2981 {
2982 return CM_EXCEED_SAMPLER_AMOUNT;
2983 }
2984
2985 sampler8x8 = (CmSampler8x8State_RT *)m_sampler8x8Array.GetElement(index);
2986
2987 return CM_SUCCESS;
2988 }
2989
2990 //*-----------------------------------------------------------------------------
2991 //| Purpose: Set L3 config
2992 //| Returns: Result of the operation.
2993 //*-----------------------------------------------------------------------------
SetL3Config(const L3ConfigRegisterValues * l3Config)2994 CM_RT_API int32_t CmDeviceRTBase::SetL3Config(const L3ConfigRegisterValues *l3Config)
2995 {
2996 INSERT_API_CALL_LOG(GetHalState());
2997
2998 L3ConfigRegisterValues l3Values;
2999
3000 l3Values = *l3Config;
3001
3002 PCM_CONTEXT_DATA cmData = (PCM_CONTEXT_DATA)this->GetAccelData();
3003 CM_CHK_NULL_RETURN_CMERROR(cmData);
3004 CM_CHK_NULL_RETURN_CMERROR(cmData->cmHalState);
3005 if (cmData->cmHalState->advExecutor != nullptr)
3006 {
3007 cmData->cmHalState->advExecutor->SetL3Config(l3Config);
3008 }
3009
3010 SetCaps(CAP_L3_CONFIG, sizeof(L3ConfigRegisterValues), &l3Values);
3011
3012 return CM_SUCCESS;
3013 }
3014
3015 //*-----------------------------------------------------------------------------
3016 //| Purpose: Set L3 suggested config
3017 //| Returns: Result of the operation.
3018 //*-----------------------------------------------------------------------------
SetSuggestedL3Config(L3_SUGGEST_CONFIG l3SuggestConfig)3019 CM_RT_API int32_t CmDeviceRTBase::SetSuggestedL3Config(L3_SUGGEST_CONFIG l3SuggestConfig)
3020 {
3021 INSERT_API_CALL_LOG(GetHalState());
3022
3023 CM_RETURN_CODE hr = CM_SUCCESS;
3024
3025 PCM_CONTEXT_DATA cmData = (PCM_CONTEXT_DATA)this->GetAccelData();
3026 CM_CHK_NULL_RETURN_CMERROR(cmData);
3027 CM_CHK_NULL_RETURN_CMERROR(cmData->cmHalState);
3028 if (cmData->cmHalState->advExecutor != nullptr)
3029 {
3030 CM_CHK_MOSSTATUS_GOTOFINISH_CMERROR(cmData->cmHalState->advExecutor->SetSuggestedL3Config(l3SuggestConfig));
3031 }
3032 CM_CHK_MOSSTATUS_GOTOFINISH_CMERROR(cmData->cmHalState->cmHalInterface->SetSuggestedL3Conf(l3SuggestConfig));
3033
3034 finish:
3035 return hr;
3036 }
3037
3038 //!
3039 //! \brief This function can be used to set/limit hardware
3040 //! capabilities- number of threads that HW can run in parallel
3041 //! \details Hardware thread number can be set from 1 to maximum.
3042 //! \param [in] capName
3043 //! Name of cap to set.
3044 //! \param [in] capValueSize
3045 //! The size of the cap value.
3046 //! \param [in] capValue
3047 //! Pointer to the cap value.
3048 //! \retval CM_SUCCESS if cap value is valid and is set correctly.
3049 //! \retval CM_INVALID_HARDWARE_THREAD_NUMBER specific SetCaps error
3050 //! message if cap value is not valid.
3051 //! \retval CM_NOT_IMPLEMENTED for emulation mode.
3052 //! \retval CM_FAILURE otherwise.
3053 //!
SetCaps(CM_DEVICE_CAP_NAME capName,size_t capValueSize,void * capValue)3054 int32_t CmDeviceRTBase::SetCaps(CM_DEVICE_CAP_NAME capName,
3055 size_t capValueSize,
3056 void* capValue)
3057 {
3058 CM_RETURN_CODE hr = CM_SUCCESS;
3059
3060 CM_SET_CAPS setCaps;
3061 uint32_t maxValue;
3062 uint32_t size = sizeof(maxValue);
3063 CmSafeMemSet( &setCaps, 0, sizeof( setCaps ) );
3064
3065 switch(capName)
3066 {
3067 case CAP_HW_THREAD_COUNT:
3068 if (capValueSize != sizeof(uint32_t))
3069 {
3070 CM_ASSERTMESSAGE("Error: Failed to set caps with CAP_HW_THREAD_COUNT.");
3071 return CM_INVALID_HARDWARE_THREAD_NUMBER;
3072 }
3073
3074 if( *(int32_t *)capValue <= 0 )
3075 {
3076 CM_ASSERTMESSAGE("Error: Failed to set caps with CAP_HW_THREAD_COUNT.");
3077 return CM_INVALID_HARDWARE_THREAD_NUMBER;
3078 }
3079
3080 GetCaps(CAP_HW_THREAD_COUNT, size, &maxValue);
3081 if ( *(uint32_t *)capValue > maxValue)
3082 {
3083 CM_ASSERTMESSAGE("Error: Failed to set caps with CAP_HW_THREAD_COUNT.");
3084 return CM_INVALID_HARDWARE_THREAD_NUMBER;
3085 }
3086
3087 setCaps.type = CM_SET_MAX_HW_THREADS;
3088 setCaps.maxValue = *(uint32_t *)capValue;
3089 break;
3090
3091 case CAP_L3_CONFIG:
3092 if (capValueSize != sizeof(L3ConfigRegisterValues))
3093 {
3094 CM_ASSERTMESSAGE("Error: Failed to set caps with CAP_L3_CONFIG.");
3095 return CM_INVALIDE_L3_CONFIGURATION;
3096 }
3097 else
3098 {
3099 L3ConfigRegisterValues *l3Config = (L3ConfigRegisterValues *)capValue;
3100
3101 setCaps.configRegsiter0 = l3Config->config_register0;
3102 setCaps.configRegsiter1 = l3Config->config_register1;
3103 setCaps.configRegsiter2 = l3Config->config_register2;
3104 setCaps.configRegsiter3 = l3Config->config_register3;
3105 setCaps.type = CM_SET_HW_L3_CONFIG;
3106 }
3107 break;
3108
3109 default:
3110 CM_ASSERTMESSAGE("Error: Invalid cap name.");
3111 return CM_INVALID_CAP_NAME;
3112 }
3113
3114 PCM_CONTEXT_DATA cmData = (PCM_CONTEXT_DATA)this->GetAccelData();
3115 CM_CHK_MOSSTATUS_GOTOFINISH_CMERROR(cmData->cmHalState->pfnSetCaps(cmData->cmHalState, (PCM_HAL_MAX_SET_CAPS_PARAM)&setCaps));
3116
3117 finish:
3118 return hr;
3119 }
3120
3121 //*-----------------------------------------------------------------------------
3122 //| Purpose: Create print buffer to support print in cm kernel
3123 //| Returns: result of operation.
3124 //*-----------------------------------------------------------------------------
InitPrintBuffer(size_t printbufsize)3125 CM_RT_API int32_t CmDeviceRTBase::InitPrintBuffer(size_t printbufsize)
3126 {
3127 INSERT_API_CALL_LOG(GetHalState());
3128
3129 m_printBufferSize = printbufsize;
3130 m_isPrintEnabled = true;
3131 return CM_SUCCESS;
3132 }
3133
3134 //*-----------------------------------------------------------------------------
3135 //| Purpose: Create a new static buffer for kernel print
3136 //| Returns: result of operation.
3137 //*-----------------------------------------------------------------------------
CreatePrintBuffer()3138 int32_t CmDeviceRTBase::CreatePrintBuffer()
3139 {
3140 if (m_printBufferMems.size() >= m_maxPrintBuffer)
3141 {
3142 // reuse the oldest buffer if enqueue called without flushPrintBuffer
3143 uint8_t *mem = m_printBufferMems.front();
3144 CmBufferUP *buf = m_printBufferUPs.front();
3145 m_printBufferMems.pop_front();
3146 m_printBufferUPs.pop_front();
3147 m_printBufferMems.push_back(mem);
3148 m_printBufferUPs.push_back(buf);
3149 return CM_SUCCESS;
3150 }
3151 uint8_t *mem = (uint8_t*)MOS_AlignedAllocMemory(m_printBufferSize, 0x1000); //PAGE SIZE
3152 if(!mem)
3153 {
3154 return CM_OUT_OF_HOST_MEMORY;
3155 }
3156
3157 CmSafeMemSet(mem, 0, m_printBufferSize);
3158 *(unsigned int*)mem = PRINT_BUFFER_HEADER_SIZE;
3159
3160 /// Allocate device memory and MemCopy from host to device.
3161 CmBufferUP *buffer = nullptr;
3162 int32_t result = CreateBufferUP((uint32_t)m_printBufferSize, mem, buffer);
3163 if (result != CM_SUCCESS || buffer == nullptr)
3164 {
3165 m_isPrintEnabled = false;
3166 MOS_AlignedFreeMemory(mem);
3167 return result;
3168 }
3169 m_printBufferMems.push_back(mem);
3170 m_printBufferUPs.push_back(buffer);
3171 return CM_SUCCESS;
3172 }
3173
3174 //*-----------------------------------------------------------------------------
3175 //| Purpose: Get print buffer memory
3176 //| Returns: result of operation.
3177 //*-----------------------------------------------------------------------------
GetPrintBufferMem(unsigned char * & printBufferMem) const3178 int32_t CmDeviceRTBase::GetPrintBufferMem(unsigned char * &printBufferMem) const
3179 {
3180 printBufferMem = m_printBufferMems.back();
3181 return CM_SUCCESS;
3182 }
3183
3184 //*-----------------------------------------------------------------------------
3185 //| Purpose: Get the print buffer's surface index
3186 //| Returns: The print buffer's surface index
3187 //*-----------------------------------------------------------------------------
GetPrintBufferIndex(SurfaceIndex * & index) const3188 int32_t CmDeviceRTBase::GetPrintBufferIndex(SurfaceIndex *& index) const
3189 {
3190 m_printBufferUPs.back()->GetIndex(index);
3191 return CM_SUCCESS;
3192 }
3193
3194 //*-----------------------------------------------------------------------------
3195 //| Purpose: Whether the kernel print is enabled
3196 //| Returns: Whether the kernel print is enabled.
3197 //*-----------------------------------------------------------------------------
IsPrintEnable() const3198 bool CmDeviceRTBase::IsPrintEnable() const
3199 {
3200 return m_isPrintEnabled;
3201 }
3202
3203 //*-----------------------------------------------------------------------------
3204 //| Purpose: Whether MDF ETW Log On.
3205 //| Returns: Whether MDF ETW Log On.
3206 //*-----------------------------------------------------------------------------
IsVtuneLogOn() const3207 bool CmDeviceRTBase::IsVtuneLogOn() const
3208 {
3209 return m_vtuneOn;
3210 }
3211
3212 //*-----------------------------------------------------------------------------
3213 //| Purpose: Get Surf2D LookUP Entry
3214 //| Returns: CM_SUCCESS.
3215 //*-----------------------------------------------------------------------------
GetSurf2DLookUpEntry(uint32_t index,PCMLOOKUP_ENTRY & lookupEntry)3216 int32_t CmDeviceRTBase::GetSurf2DLookUpEntry(uint32_t index,
3217 PCMLOOKUP_ENTRY &lookupEntry)
3218 {
3219 PCM_CONTEXT_DATA cmData = (PCM_CONTEXT_DATA)GetAccelData();
3220 if(cmData)
3221 {
3222 lookupEntry = &(cmData->cmHalState->surf2DTable[index]);
3223 }
3224 else
3225 {
3226 return CM_FAILURE;
3227 }
3228
3229 return CM_SUCCESS;
3230 }
3231
3232 //*-----------------------------------------------------------------------------
3233 //| Purpose: Create vebox task
3234 //| Returns: CM_SUCCESS if successfully.
3235 //| CM_OUT_OF_HOST_MEMORY if creation is failed.
3236 //*-----------------------------------------------------------------------------
CreateVebox(CmVebox * & vebox)3237 CM_RT_API int32_t CmDeviceRTBase::CreateVebox(CmVebox* & vebox) //HSW
3238 {
3239 CLock locker(m_criticalSectionVebox);
3240
3241 uint32_t firstfreeslot = m_veboxArray.GetFirstFreeIndex();
3242 CmVeboxRT *veboxRT = nullptr;
3243 CmDeviceRT *cmDevice = static_cast<CmDeviceRT*>(this);
3244 CM_CHK_NULL_RETURN_CMERROR(cmDevice);
3245 int32_t result = CmVeboxRT::Create(cmDevice, firstfreeslot, veboxRT);
3246 if (result == CM_SUCCESS)
3247 {
3248 m_veboxArray.SetElement(firstfreeslot, veboxRT);
3249 m_veboxCount++;
3250 m_memObjectCount.veboxCount++;
3251 }
3252 vebox = veboxRT;
3253 return result;
3254
3255 }
3256
3257 //*-----------------------------------------------------------------------------
3258 //| Purpose: Destroy vebox task
3259 //| Returns: CM_SUCCESS.
3260 //*-----------------------------------------------------------------------------
DestroyVebox(CmVebox * & vebox)3261 CM_RT_API int32_t CmDeviceRTBase::DestroyVebox(CmVebox* & vebox) //HSW
3262 {
3263 if (vebox == nullptr)
3264 {
3265 return CM_NULL_POINTER;
3266 }
3267
3268 CmVeboxRT *veboxRT = static_cast<CmVeboxRT *>(vebox);
3269 uint32_t index = veboxRT->GetIndexInVeboxArray();
3270
3271 if (veboxRT == m_veboxArray.GetElement(index))
3272 {
3273 int32_t status = CmVeboxRT::Destroy(veboxRT);
3274
3275 if (status == CM_SUCCESS)
3276 {
3277 m_memObjectCount.veboxCount--;
3278 m_veboxArray.SetElement(index, nullptr);
3279 vebox = nullptr;
3280 return CM_SUCCESS;
3281 }
3282 else
3283 {
3284 CM_ASSERTMESSAGE("Error: Failed to destroy vebox task.");
3285 return status;
3286 }
3287 }
3288 else
3289 {
3290 CM_ASSERTMESSAGE("Error: Failed to destroy vebox task.");
3291 return CM_FAILURE;
3292 }
3293 }
3294
3295
DestroySurfaceInPool(uint32_t & freeSurfNum)3296 int32_t CmDeviceRTBase::DestroySurfaceInPool(uint32_t &freeSurfNum)
3297 {
3298 CLock locker(m_criticalSectionSurface);
3299
3300 freeSurfNum = m_surfaceMgr->TouchSurfaceInPoolForDestroy();
3301 if ((int32_t)freeSurfNum < 0)
3302 {
3303 freeSurfNum = 0;
3304 return CM_FAILURE;
3305 }
3306
3307 return CM_SUCCESS;
3308 }
3309
CreateBufferSVM(uint32_t size,void * & sysMem,uint32_t accessFlag,CmBufferSVM * & bufferSVM)3310 CM_RT_API int32_t CmDeviceRTBase::CreateBufferSVM(uint32_t size,
3311 void* & sysMem,
3312 uint32_t accessFlag,
3313 CmBufferSVM* & bufferSVM)
3314 {
3315 INSERT_API_CALL_LOG(GetHalState());
3316
3317 bool isCMRTAllocatedSVMBuffer = true;
3318
3319 //SVM buffer is going to stateless access, no size restriction lik CmBuffer and CmBufferUP
3320 if( size == 0 )
3321 {
3322 CM_ASSERTMESSAGE("Error: Invalid buffer width.");
3323 return CM_INVALID_WIDTH;
3324 }
3325
3326 if ( sysMem )
3327 {
3328 if ((uintptr_t)sysMem & CM_PAGE_ALIGNMENT_MASK)
3329 {
3330 CM_ASSERTMESSAGE("Error: System memory is not page aligned.");
3331 return CM_SYSTEM_MEMORY_NOT_4KPAGE_ALIGNED;
3332 }
3333 isCMRTAllocatedSVMBuffer = false;
3334 }
3335 else //Allocate a 4K page aligned memory
3336 {
3337 sysMem = MOS_AlignedAllocMemory(size, CM_PAGE_ALIGNMENT);
3338
3339 if (!sysMem)
3340 {
3341 CM_ASSERTMESSAGE("Error: Out of system memory.");
3342 return CM_FAILED_TO_ALLOCATE_SVM_BUFFER;
3343 }
3344 isCMRTAllocatedSVMBuffer = true;
3345 }
3346
3347 CLock locker(m_criticalSectionSurface);
3348
3349 CmBuffer_RT* p = nullptr;
3350 int result = m_surfaceMgr->CreateBuffer( size, CM_BUFFER_SVM, isCMRTAllocatedSVMBuffer, p, nullptr, sysMem, false, CM_DEFAULT_COMPARISON_VALUE );
3351 bufferSVM = static_cast< CmBufferSVM* >(p);
3352
3353 return result;
3354 }
3355
DestroyBufferSVM(CmBufferSVM * & bufferSVM)3356 CM_RT_API int32_t CmDeviceRTBase::DestroyBufferSVM(CmBufferSVM* & bufferSVM)
3357 {
3358
3359 INSERT_API_CALL_LOG(GetHalState());
3360
3361 CmBuffer_RT* temp = static_cast< CmBuffer_RT* >(bufferSVM);
3362 if (nullptr == temp)
3363 {
3364 return CM_NULL_POINTER;
3365 }
3366
3367 CLock locker(m_criticalSectionSurface);
3368
3369 int32_t status = m_surfaceMgr->DestroySurface(temp, APP_DESTROY);
3370
3371 if (status != CM_FAILURE) //CM_SURFACE_IN_USE, or CM_SURFACE_CACHED may be returned, which should be treated as SUCCESS.
3372 {
3373 bufferSVM = nullptr;
3374 return CM_SUCCESS;
3375 }
3376 else
3377 {
3378 return CM_FAILURE;
3379 }
3380 }
3381
3382 //*-----------------------------------------------------------------------------
3383 //| Purpose: Creates an alias to CmSurface2D, surface2d
3384 //| Returns: Result of the operation
3385 //*-----------------------------------------------------------------------------
CreateSurface2DAlias(CmSurface2D * surface2d,SurfaceIndex * & aliasIndex)3386 CM_RT_API int32_t CmDeviceRTBase::CreateSurface2DAlias(CmSurface2D* surface2d,
3387 SurfaceIndex* &aliasIndex)
3388 {
3389 INSERT_API_CALL_LOG(GetHalState());
3390
3391 int32_t result = CM_SUCCESS;
3392
3393 CLock locker(m_criticalSectionSurface);
3394 if( !surface2d )
3395 {
3396 CM_ASSERTMESSAGE("Error: Pointer to surface 2D is null.");
3397 return CM_NULL_POINTER;
3398 }
3399
3400 CmSurface2DRT *surfaceRT = static_cast<CmSurface2DRT *>(surface2d);
3401 result = surfaceRT->Create2DAlias(aliasIndex);
3402 if( result != CM_SUCCESS )
3403 {
3404 CM_ASSERTMESSAGE("Failed to create surface 2D alias.");
3405 return result;
3406 }
3407
3408 return CM_SUCCESS;
3409 }
3410
3411 //*-----------------------------------------------------------------------------
3412 //| Purpose: Creates an alias to CmBuffer, buffer
3413 //| Returns: Result of the operation
3414 //*-----------------------------------------------------------------------------
CreateBufferAlias(CmBuffer * buffer,SurfaceIndex * & aliasIndex)3415 CM_RT_API int32_t CmDeviceRTBase::CreateBufferAlias(CmBuffer *buffer,
3416 SurfaceIndex* &aliasIndex)
3417 {
3418 INSERT_API_CALL_LOG(GetHalState());
3419
3420 int32_t result = CM_SUCCESS;
3421
3422 CLock locker(m_criticalSectionSurface);
3423 if( !buffer )
3424 {
3425 CM_ASSERTMESSAGE("Error: Pointer to CmBuffer is null.");
3426 return CM_NULL_POINTER;
3427 }
3428
3429 CmBuffer_RT *bufferRT = static_cast<CmBuffer_RT *>(buffer);
3430
3431 result = bufferRT->CreateBufferAlias(aliasIndex);
3432 if( result != CM_SUCCESS )
3433 {
3434 CM_ASSERTMESSAGE("Failed to create buffer alias.");
3435 return result;
3436 }
3437
3438 return CM_SUCCESS;
3439 }
3440
3441 //*-----------------------------------------------------------------------------
3442 //| Purpose: Initialize Dev Create Option
3443 //| Returns: Result of the operation.
3444 //*-----------------------------------------------------------------------------
InitDevCreateOption(CM_HAL_CREATE_PARAM & cmHalCreateParam,uint32_t option)3445 int32_t CmDeviceRTBase::InitDevCreateOption(CM_HAL_CREATE_PARAM & cmHalCreateParam,
3446 uint32_t option)
3447 {
3448 uint32_t maxTaskNumber =0;
3449 uint32_t kernelBinarySizeInGSH = 0;
3450
3451 //Flag to disable scratch space
3452 cmHalCreateParam.disableScratchSpace = (option & CM_DEVICE_CREATE_OPTION_SCRATCH_SPACE_MASK);
3453
3454 //Calculate Scratch Space
3455 if(cmHalCreateParam.disableScratchSpace)
3456 {
3457 cmHalCreateParam.scratchSpaceSize = 0;
3458 }
3459 else
3460 {
3461 //Max Scratch Space Size [1:3] of devCreateOption
3462 cmHalCreateParam.scratchSpaceSize = (option & CM_DEVICE_CONFIG_SCRATCH_SPACE_SIZE_MASK) >> CM_DEVICE_CONFIG_SCRATCH_SPACE_SIZE_OFFSET;
3463 }
3464
3465 //Flag to Disable preemption
3466 cmHalCreateParam.disabledMidThreadPreemption = ((option & CM_DEVICE_CONFIG_MIDTHREADPREEMPTION_DISENABLE) >> CM_DEVICE_CONFIG_MIDTHREADPREEMPTION_OFFSET)? true: false;
3467
3468 //flag to enable kernel debug, so, SIP binary can be created during
3469 cmHalCreateParam.enabledKernelDebug = ((option & CM_DEVICE_CONFIG_KERNEL_DEBUG_ENABLE) >> CM_DEVICE_CONFIG_KERNEL_DEBUG_OFFSET)? true: false;
3470
3471 //Calculate Task Number [4:5] of option [00]:4 ; [01]:8 ; [10]:12; [11]:16
3472 maxTaskNumber = (option & CM_DEVICE_CONFIG_TASK_NUM_MASK) >> CM_DEVICE_CONFIG_TASK_NUM_OFFSET;
3473
3474 cmHalCreateParam.maxTaskNumber = (maxTaskNumber + 1) * CM_DEVICE_CONFIG_TASK_NUM_STEP;
3475
3476 // [9:8] Added bits to increase maximum task number. Value plus one is multiplied by value calculated from bits [5:4].
3477 // [00]:1; [01]:2; [10]:3; [11]:4
3478 maxTaskNumber = (option & CM_DEVICE_CONFIG_EXTRA_TASK_NUM_MASK ) >> CM_DEVICE_CONFIG_EXTRA_TASK_NUM_OFFSET;
3479
3480 cmHalCreateParam.maxTaskNumber = (maxTaskNumber + 1) * cmHalCreateParam.maxTaskNumber;
3481
3482 // [10] request slice shutdown
3483 cmHalCreateParam.requestSliceShutdown = (option & CM_DEVICE_CONFIG_SLICESHUTDOWN_ENABLE ) ? true:false;
3484
3485 // [12] request custom gpu context. This flag is deprecated since GPU context is decoupled with cmhal for supporting multiple context.
3486 cmHalCreateParam.requestCustomGpuContext = (option & CM_DEVICE_CONFIG_GPUCONTEXT_ENABLE) ? true:false;
3487
3488 // [20:13] calculate size in GSH reserved for kernel binary
3489 kernelBinarySizeInGSH = (option & CM_DEVICE_CONFIG_KERNELBINARYGSH_MASK) >> CM_DEVICE_CONFIG_KERNELBINARYGSH_OFFSET;
3490
3491 if (kernelBinarySizeInGSH == 0)
3492 kernelBinarySizeInGSH = 1;
3493
3494 kernelBinarySizeInGSH = kernelBinarySizeInGSH * CM_KERNELBINARY_BLOCKSIZE_2MB;
3495 cmHalCreateParam.kernelBinarySizeinGSH = kernelBinarySizeInGSH;
3496
3497 // [28] vebox
3498 cmHalCreateParam.disableVebox = (option & CM_DEVICE_CONFIG_VEBOX_DISABLE) ? true : false;
3499
3500 // [29] preload kernel
3501 m_preloadKernelEnabled = (option & CM_DEVICE_CONFIG_GPUCOPY_DISABLE) ? false : true;
3502
3503 // [30] fast path
3504 cmHalCreateParam.refactor = (option & CM_DEVICE_CONFIG_FAST_PATH_ENABLE)?true:false;
3505 return CM_SUCCESS;
3506 }
3507
IsScratchSpaceDisabled()3508 bool CmDeviceRTBase::IsScratchSpaceDisabled()
3509 {
3510 return m_cmHalCreateOption.disableScratchSpace ? true : false;
3511 }
3512
3513 //*-----------------------------------------------------------------------------
3514 //| Purpose: Sets surface array size, needed to assign alias surface index
3515 //| Returns: Result of the operation
3516 //*-----------------------------------------------------------------------------
SetSurfaceArraySizeForAlias()3517 int32_t CmDeviceRTBase::SetSurfaceArraySizeForAlias()
3518 {
3519 PCM_CONTEXT_DATA cmData = (PCM_CONTEXT_DATA)this->GetAccelData();
3520 m_surfaceMgr->GetSurfaceArraySize(cmData->cmHalState->surfaceArraySize);
3521 return CM_SUCCESS;
3522 }
3523
3524 #if CM_LOG_ON
Log()3525 std::string CmDeviceRTBase::Log()
3526 {
3527 std::ostringstream oss;
3528 PCM_HAL_STATE cmHalState;
3529 uint64_t timeStampBase = 0;
3530 uint32_t nSize = sizeof(int);
3531
3532 GetCaps( CAP_GPU_CURRENT_FREQUENCY, nSize, &m_nGPUFreqOriginal );
3533 GetCaps( CAP_MIN_FREQUENCY, nSize, &m_nGPUFreqMin );
3534 GetCaps( CAP_MAX_FREQUENCY, nSize, &m_nGPUFreqMax );
3535
3536 int gtInfo;
3537 GetCaps( CAP_GT_PLATFORM, nSize, >Info );
3538
3539 cmHalState = ((PCM_CONTEXT_DATA)GetAccelData())->cmHalState;
3540 CM_CHK_NULL_RETURN(cmHalState,"cmHalState is null pointer");
3541 timeStampBase = HalCm_ConvertTicksToNanoSeconds(cmHalState,1);
3542
3543 oss << "Device Creation "<<std::endl;
3544 // Hw Information
3545 oss << "Platform :" << m_platform << std::endl;
3546 oss << "GT Info :"<< gtInfo << std::endl;
3547 oss << "Frequency Max:" << m_nGPUFreqMax << " Min:" <<m_nGPUFreqMin
3548 << " Current:"<< m_nGPUFreqOriginal << std::endl;
3549
3550 oss << "Device DDI Version :" << m_ddiVersion << std::endl;
3551 oss << "Max Tasks " << m_halMaxValues.maxTasks << std::endl;
3552 oss << "Max HW Threads " << m_halMaxValues.maxHwThreads<< std::endl;
3553 oss << "Max Args Per Kernel " << m_halMaxValues.maxArgsPerKernel << std::endl;
3554 oss << "Max 2D Surface Table Size " << m_halMaxValues.max2DSurfaceTableSize << std::endl;
3555 oss << "Max Buffer Table Size " << m_halMaxValues.maxBufferTableSize << std::endl;
3556 oss << "Max Threads per Task " << m_halMaxValues.maxUserThreadsPerTask << std::endl;
3557 oss << "Max Threads Per Task no Thread Arg " << m_halMaxValues.maxUserThreadsPerTaskNoThreadArg << std::endl;
3558 oss << "MDF timestamp base " << timeStampBase << "ns" << std::endl;
3559
3560 return oss.str();
3561 }
3562 #endif // #if CM_LOG_ON
3563
GetHalState()3564 CM_HAL_STATE* CmDeviceRTBase::GetHalState()
3565 {
3566 return (static_cast<CM_CONTEXT_DATA*>(m_accelData))->cmHalState;
3567 }
3568
3569 #if !(USE_EXTENSION_CODE)
CheckGTPinEnabled()3570 bool CmDeviceRTBase::CheckGTPinEnabled( )
3571 {
3572 return false;
3573 }
3574 #endif
3575
3576 //*-----------------------------------------------------------------------------
3577 //| Purpose: Internal function to flush print buffer on stdout or file.
3578 //| Returns: result of operation.
3579 //*-----------------------------------------------------------------------------
FlushPrintBufferInternal(const char * filename)3580 int32_t CmDeviceRTBase::FlushPrintBufferInternal(const char *filename)
3581 {
3582 #if CM_KERNEL_PRINTF_ON
3583 FILE * streamOutFile = nullptr;
3584
3585 if (filename == nullptr)
3586 {
3587 streamOutFile = stdout;
3588 }
3589 else
3590 {
3591 int err = MosUtilities::MosSecureFileOpen(&streamOutFile, filename, "wb");
3592 if (streamOutFile == nullptr)
3593 {
3594 CM_ASSERTMESSAGE("Error: Failed to open kernel print dump file.");
3595 return CM_FAILURE;
3596 }
3597 if (err)
3598 {
3599 fclose(streamOutFile);
3600 streamOutFile = nullptr;
3601 CM_ASSERTMESSAGE("Error: Failed to open kernel print dump file.");
3602 return CM_FAILURE;
3603 }
3604 }
3605
3606 if( m_printBufferSize == 0 ||
3607 m_isPrintEnabled == false)
3608 {
3609 CM_ASSERTMESSAGE("Error: Print buffer is not initialized.");
3610 if (filename && streamOutFile)
3611 fclose(streamOutFile);
3612 return CM_FAILURE;
3613 }
3614
3615 //Dump memory on the screen.
3616 while(!m_printBufferMems.empty())
3617 {
3618 uint8_t *mem = m_printBufferMems.front();
3619 CmBufferUP *buffer = m_printBufferUPs.front();
3620 DumpAllThreadOutput(streamOutFile, mem, m_printBufferSize);
3621 m_printBufferMems.pop_front();
3622 m_printBufferUPs.pop_front();
3623 DestroyBufferUP(buffer);
3624 MOS_AlignedFreeMemory(mem);
3625 }
3626
3627 //Flush and close stream
3628 fflush(streamOutFile);
3629 if (filename && streamOutFile)
3630 {
3631 fclose(streamOutFile);
3632 streamOutFile = nullptr;
3633 }
3634
3635 return CM_SUCCESS;
3636 #else
3637 return CM_NOT_IMPLEMENTED;
3638 #endif
3639 }
3640
3641 //*-----------------------------------------------------------------------------
3642 //| Purpose: Dump print buffer. Only Avaliable in Release-internal and Debug Mode
3643 //| Returns: CM_SUCCESS
3644 //*-----------------------------------------------------------------------------
FlushPrintBuffer()3645 CM_RT_API int32_t CmDeviceRTBase::FlushPrintBuffer()
3646 {
3647 return FlushPrintBufferInternal(nullptr);
3648 }
3649
3650 //*-----------------------------------------------------------------------------
3651 //| Purpose: Dump print buffer to file. Only Avaliable in Release-internal and Debug Mode
3652 //| Returns: CM_SUCCESS
3653 //*-----------------------------------------------------------------------------
FlushPrintBufferIntoFile(const char * filename)3654 CM_RT_API int32_t CmDeviceRTBase::FlushPrintBufferIntoFile(const char *filename)
3655 {
3656 return FlushPrintBufferInternal(filename);
3657 }
3658
3659 CM_RT_API int32_t
CreateHevcVmeSurfaceG10(CmSurface2D * curSurface,CmSurface2D ** forwardSurfaces,CmSurface2D ** backwardSurfaces,const uint32_t forwardSurfaceCount,const uint32_t backwardSurfaceCount,SurfaceIndex * & vmeIndex)3660 CmDeviceRTBase::CreateHevcVmeSurfaceG10(CmSurface2D * curSurface,
3661 CmSurface2D ** forwardSurfaces,
3662 CmSurface2D ** backwardSurfaces,
3663 const uint32_t forwardSurfaceCount,
3664 const uint32_t backwardSurfaceCount,
3665 SurfaceIndex *& vmeIndex)
3666 {
3667 INSERT_API_CALL_LOG(GetHalState());
3668
3669 if ( curSurface == nullptr )
3670 {
3671 CM_ASSERTMESSAGE("Error: Pointer to current surface is null.");
3672 return CM_NULL_POINTER;
3673 }
3674
3675 if (forwardSurfaceCount > CM_NUM_VME_HEVC_REFS || backwardSurfaceCount > CM_NUM_VME_HEVC_REFS)
3676 {
3677 CM_ASSERTMESSAGE("Error: Invalid count of forward or backward surfaces.");
3678 return CM_INVALID_ARG_VALUE;
3679 }
3680
3681 CmSurface2DRT *currentRT = static_cast< CmSurface2DRT * >( curSurface );
3682 CmSurface2DRT** forwardSurfArray = nullptr;
3683 CmSurface2DRT** backwardSurfArray = nullptr;
3684
3685 forwardSurfArray = MOS_NewArray(CmSurface2DRT*, CM_NUM_VME_HEVC_REFS);
3686 if ( forwardSurfArray == nullptr )
3687 {
3688 CM_ASSERTMESSAGE("Error: Failed to create forward surface array.");
3689 return CM_OUT_OF_HOST_MEMORY;
3690 }
3691
3692 if ( forwardSurfaces != nullptr )
3693 {
3694 for ( uint32_t i = 0; i< forwardSurfaceCount; i++ )
3695 {
3696 forwardSurfArray[ i ] = static_cast< CmSurface2DRT * >( forwardSurfaces[ i ] );
3697 if ( forwardSurfArray[ i ] == nullptr )
3698 {
3699 CM_ASSERTMESSAGE("Error: Invalid forward surface array.");
3700 MosSafeDeleteArray( forwardSurfArray );
3701 return CM_INVALID_ARG_VALUE;
3702 }
3703 }
3704 for ( uint32_t i = forwardSurfaceCount; i < CM_NUM_VME_HEVC_REFS; i++ )
3705 {
3706 forwardSurfArray[ i ] = static_cast< CmSurface2DRT * >( forwardSurfaces[ 0 ] );
3707 }
3708 }
3709 else
3710 {
3711 for ( uint32_t i = 0; i < CM_NUM_VME_HEVC_REFS; i++ )
3712 {
3713 forwardSurfArray[ i ] = currentRT;
3714 }
3715 }
3716
3717 backwardSurfArray = MOS_NewArray(CmSurface2DRT*, CM_NUM_VME_HEVC_REFS);
3718 if ( backwardSurfArray == nullptr )
3719 {
3720 CM_ASSERTMESSAGE("Error: Failed to create backward surface array.");
3721 MosSafeDeleteArray( forwardSurfArray );
3722 return CM_OUT_OF_HOST_MEMORY;
3723 }
3724 if ( backwardSurfaces != nullptr )
3725 {
3726 for ( uint32_t i = 0; i< backwardSurfaceCount; i++ )
3727 {
3728 backwardSurfArray[ i ] = static_cast< CmSurface2DRT * >( backwardSurfaces[ i ] );
3729 if ( backwardSurfArray[ i ] == nullptr )
3730 {
3731 CM_ASSERTMESSAGE("Error: Invalid backward surface array.");
3732 MosSafeDeleteArray( forwardSurfArray );
3733 MosSafeDeleteArray( backwardSurfArray );
3734 return CM_INVALID_ARG_VALUE;
3735 }
3736 }
3737 for ( uint32_t i = backwardSurfaceCount; i < CM_NUM_VME_HEVC_REFS; i++ )
3738 {
3739 backwardSurfArray[ i ] = static_cast< CmSurface2DRT * >( backwardSurfaces[ 0 ] );
3740 }
3741 }
3742 else
3743 {
3744 for ( uint32_t i = 0; i < CM_NUM_VME_HEVC_REFS; i++ )
3745 {
3746 backwardSurfArray[ i ] = currentRT;
3747 }
3748 }
3749
3750 int32_t result = m_surfaceMgr->CreateVmeSurface( currentRT, forwardSurfArray, backwardSurfArray, forwardSurfaceCount, backwardSurfaceCount, vmeIndex );
3751
3752 if ( FAILED( result ) )
3753 {
3754 CM_ASSERTMESSAGE("Error: Failed to create HEVC VME surface.");
3755 }
3756
3757 MosSafeDeleteArray( forwardSurfArray );
3758 MosSafeDeleteArray( backwardSurfArray );
3759
3760 return result;
3761 }
3762
3763 CM_RT_API int32_t
DestroyHevcVmeSurfaceG10(SurfaceIndex * & vmeIndex)3764 CmDeviceRTBase::DestroyHevcVmeSurfaceG10(SurfaceIndex *& vmeIndex)
3765 {
3766 INSERT_API_CALL_LOG(GetHalState());
3767 return DestroyVmeSurface( vmeIndex );
3768 }
3769
CloneKernel(CmKernel * & kernelDest,CmKernel * kernelSrc)3770 CM_RT_API int32_t CmDeviceRTBase::CloneKernel(CmKernel* &kernelDest,
3771 CmKernel *kernelSrc)
3772 {
3773 INSERT_API_CALL_LOG(GetHalState());
3774
3775 int32_t hr = CM_SUCCESS;
3776
3777 if (kernelSrc == nullptr)
3778 {
3779 CM_ASSERTMESSAGE("Error: Pointer to src kernel is null");
3780 return CM_NULL_POINTER;
3781 }
3782
3783 CmKernelRT *kernelSrcRT = static_cast<CmKernelRT *>(kernelSrc);
3784 CmKernelRT *kernelDestRT = static_cast<CmKernelRT *>(kernelDest);
3785 hr = kernelSrcRT->CloneKernel(kernelDestRT, m_kernelCount);
3786 kernelDest = kernelDestRT;
3787
3788 return hr;
3789 }
3790
GetKernelArray()3791 CmDynamicArray* CmDeviceRTBase::GetKernelArray()
3792 {
3793 return &m_kernelArray;
3794 }
3795
GetKernelCount()3796 uint32_t *CmDeviceRTBase::GetKernelCount()
3797 {
3798 return &m_kernelCount;
3799 }
3800
DestroyVmeSurface(SurfaceIndex * & vmeIndex)3801 int32_t CmDeviceRTBase::DestroyVmeSurface(SurfaceIndex *& vmeIndex)
3802 {
3803 CLock locker( m_criticalSectionSurface );
3804
3805 int32_t result = m_surfaceMgr->DestroyVmeSurface( vmeIndex );
3806
3807 return result;
3808 }
3809
GetVISAVersion(uint32_t & majorVersion,uint32_t & minorVersion)3810 int32_t CmDeviceRTBase::GetVISAVersion(uint32_t& majorVersion,
3811 uint32_t& minorVersion)
3812 {
3813 int32_t result = CM_SUCCESS;
3814
3815 result = GetJITVersionFnt(m_fJITVersion);
3816 if(result != CM_SUCCESS)
3817 {
3818 CM_ASSERTMESSAGE("Error: Failed to get VISA version.");
3819 return result;
3820 }
3821
3822 m_fJITVersion(majorVersion, minorVersion);
3823
3824 return CM_SUCCESS;
3825 }
3826
3827
UpdateBuffer(PMOS_RESOURCE mosResource,CmBuffer * & surface,MOS_HW_RESOURCE_DEF mosUsage)3828 CM_RT_API int32_t CmDeviceRTBase::UpdateBuffer(PMOS_RESOURCE mosResource, CmBuffer* &surface,
3829 MOS_HW_RESOURCE_DEF mosUsage)
3830 {
3831 int32_t hr = CM_SUCCESS;
3832 if (surface)
3833 {
3834 CmBuffer_RT *bufferRT = static_cast<CmBuffer_RT *>(surface);
3835 hr = bufferRT->UpdateResource(mosResource);
3836 }
3837 else
3838 {
3839 hr = CreateBuffer(mosResource, surface);
3840 }
3841
3842 if (hr == CM_SUCCESS)
3843 {
3844 hr = surface->SetResourceUsage(mosUsage);
3845 }
3846 return hr;
3847 }
3848
3849
UpdateSurface2D(PMOS_RESOURCE mosResource,CmSurface2D * & surface,MOS_HW_RESOURCE_DEF mosUsage)3850 CM_RT_API int32_t CmDeviceRTBase::UpdateSurface2D(PMOS_RESOURCE mosResource, CmSurface2D* &surface,
3851 MOS_HW_RESOURCE_DEF mosUsage)
3852 {
3853 int32_t hr = CM_SUCCESS;
3854 if (surface)
3855 {
3856 CmSurface2DRT *surfaceRT = static_cast<CmSurface2DRT *>(surface);
3857 hr = surfaceRT->UpdateResource(mosResource);
3858 }
3859 else
3860 {
3861 hr = CreateSurface2D(mosResource, surface);
3862 }
3863
3864 if (hr == CM_SUCCESS)
3865 {
3866 hr = surface->SetResourceUsage(mosUsage);
3867 }
3868 return hr;
3869 }
3870
CreateSampler8x8SurfaceFromAlias(CmSurface2D * originalSurface,SurfaceIndex * aliasIndex,CM_SURFACE_ADDRESS_CONTROL_MODE addressControl,SurfaceIndex * & sampler8x8SurfaceIndex)3871 CM_RT_API int32_t CmDeviceRTBase::CreateSampler8x8SurfaceFromAlias(
3872 CmSurface2D *originalSurface,
3873 SurfaceIndex *aliasIndex,
3874 CM_SURFACE_ADDRESS_CONTROL_MODE addressControl,
3875 SurfaceIndex* &sampler8x8SurfaceIndex)
3876 {
3877 INSERT_API_CALL_LOG(GetHalState());
3878 CmSurface2DRT *original_surface_rt = static_cast<CmSurface2DRT*>(originalSurface);
3879 if (!original_surface_rt) {
3880 CM_ASSERTMESSAGE("Error: Pointer to current surface is null.");
3881 return CM_NULL_POINTER;
3882 }
3883
3884 uint32_t width = 0, height = 0, size_per_pixel = 0;
3885 CM_SURFACE_FORMAT format;
3886 original_surface_rt->GetSurfaceDesc(width, height, format, size_per_pixel);
3887
3888 CLock locker(m_criticalSectionSurface);
3889
3890 return m_surfaceMgr
3891 ->CreateSampler8x8SurfaceFromAlias(original_surface_rt,
3892 aliasIndex,
3893 addressControl,
3894 sampler8x8SurfaceIndex);
3895 }
3896
CreateBufferStateless(size_t size,uint32_t option,void * sysMem,CmBufferStateless * & bufferStateless)3897 CM_RT_API int32_t CmDeviceRTBase::CreateBufferStateless(size_t size,
3898 uint32_t option,
3899 void *sysMem,
3900 CmBufferStateless *&bufferStateless)
3901 {
3902 INSERT_API_CALL_LOG(GetHalState());
3903
3904 int result = CM_SUCCESS;
3905
3906 // Stateless buffer is going to stateless access, no size restriction like
3907 // CmBuffer and CmBufferUP. But current supported size is less than 4G
3908 // because of GMM limitation.
3909 if (size == 0)
3910 {
3911 CM_ASSERTMESSAGE("Error: Invalid buffer width.");
3912 return CM_INVALID_WIDTH;
3913 }
3914
3915 if (option == CM_BUFFER_STATELESS_CREATE_OPTION_SYS_MEM)
3916 {
3917 CM_ASSERTMESSAGE("Error: Stateless buffer created from system memory is not supported.");
3918 return CM_NOT_IMPLEMENTED;
3919 }
3920 else if (option == CM_BUFFER_STATELESS_CREATE_OPTION_GFX_MEM)
3921 {
3922 CLock locker(m_criticalSectionSurface);
3923
3924 CmBuffer_RT *p = nullptr;
3925 void *sysMemory = nullptr;
3926 result = m_surfaceMgr->CreateBuffer(size,
3927 CM_BUFFER_STATELESS,
3928 false,
3929 p,
3930 nullptr,
3931 sysMemory,
3932 false,
3933 CM_DEFAULT_COMPARISON_VALUE);
3934 bufferStateless = static_cast<CmBufferStateless *>(p);
3935 }
3936 else
3937 {
3938 CM_ASSERTMESSAGE("Error: Invalid option value.");
3939 return CM_INVALID_CREATE_OPTION_FOR_BUFFER_STATELESS;
3940 }
3941
3942 return result;
3943 }
3944
DestroyBufferStateless(CmBufferStateless * & bufferStateless)3945 CM_RT_API int32_t CmDeviceRTBase::DestroyBufferStateless(CmBufferStateless *&bufferStateless)
3946 {
3947 INSERT_API_CALL_LOG(GetHalState());
3948
3949 CmBuffer_RT *temp = static_cast<CmBuffer_RT *>(bufferStateless);
3950 if (nullptr == temp)
3951 {
3952 return CM_NULL_POINTER;
3953 }
3954
3955 CLock locker(m_criticalSectionSurface);
3956
3957 int32_t status = m_surfaceMgr->DestroySurface(temp, APP_DESTROY);
3958
3959 if (status != CM_FAILURE) //CM_SURFACE_IN_USE, or CM_SURFACE_CACHED may be returned, which should be treated as SUCCESS.
3960 {
3961 bufferStateless = nullptr;
3962 return CM_SUCCESS;
3963 }
3964 else
3965 {
3966 return CM_FAILURE;
3967 }
3968 }
3969
3970
3971 //check CmDevice remaining memory objects count and return 4bit encoded non zero value in debug & release internal build
CheckObjectCount()3972 int32_t CmDeviceRTBase::CheckObjectCount()
3973 {
3974 int32_t result = CM_SUCCESS;
3975
3976 #if (_DEBUG || _RELEASE_INTERNAL)
3977 PCM_CONTEXT_DATA cmData;
3978 PCM_HAL_STATE cmHalState;
3979 cmData = (PCM_CONTEXT_DATA)GetAccelData();
3980 if (nullptr == cmData)
3981 {
3982 // cmData is not available.
3983 return result;
3984 }
3985 cmHalState = cmData->cmHalState;
3986
3987 // Read VerbosityLevel from RegisterKey
3988 MOS_USER_FEATURE_VALUE_DATA userFeatureValueData = { 0 };
3989 // User feature key reads
3990 int retStatus = MOS_UserFeature_ReadValue_ID(nullptr, __MEDIA_USER_FEATURE_VALUE_MDF_LOG_LEVEL_ID,
3991 &userFeatureValueData, cmHalState->osInterface->pOsContext);
3992
3993 if (userFeatureValueData.u32Data >= CM_LOG_LEVEL_WARN)
3994 {
3995 char msg[1024];
3996
3997 snprintf(msg, 1020,
3998 "\n [CM] check undestroyed objects count kernel %d program %d task %d threadSpace %d threadGroupSpace %d vebox %d event %d \n",
3999 m_memObjectCount.kernelCount, m_memObjectCount.programCount, m_memObjectCount.taskCount,
4000 m_memObjectCount.threadSpaceCount, m_memObjectCount.threadGroupSpaceCount,
4001 m_memObjectCount.veboxCount, m_memObjectCount.eventCount);
4002
4003 // msg send to HLT log file or debug output
4004 CM_ASSERTMESSAGE(msg);
4005 // msg write to CM_LOG file
4006 //CM_WARN(msg); was removed from cm_log.h
4007 _CM_LOG(CM_LOG_LEVEL_WARN, msg, GetHalState());
4008 // console output
4009 if (userFeatureValueData.u32Data >= CM_LOG_LEVEL_DEBUG)
4010 {
4011 printf(" %s \n", msg);
4012 }
4013
4014 if ((m_memObjectCount.kernelCount >> 2) > 0xF)
4015 {
4016 result |= 0xF;
4017 }
4018 else
4019 {
4020 result |= (m_memObjectCount.kernelCount >> 2) & 0xF;
4021 }
4022
4023 if ((m_memObjectCount.programCount >> 2) > 0xF)
4024 {
4025 result |= 0xF << 4;
4026 }
4027 else
4028 {
4029 result |= ((m_memObjectCount.programCount >> 2) & 0xF) << 4;
4030 }
4031
4032 if ((m_memObjectCount.taskCount >>2) > 0xF)
4033 {
4034 result |= 0xF << 8;
4035 }
4036 else
4037 {
4038 result |= ((m_memObjectCount.taskCount >> 2) & 0xF) << 8;
4039 }
4040
4041 if ((m_memObjectCount.threadSpaceCount >> 2) > 0xF)
4042 {
4043 result |= 0xF << 12;
4044 }
4045 else
4046 {
4047 result |= ((m_memObjectCount.threadSpaceCount >> 2) & 0xF) << 12;
4048 }
4049
4050 if ((m_memObjectCount.threadGroupSpaceCount >> 2)> 0xF)
4051 {
4052 result |= 0xF << 16;
4053 }
4054 else
4055 {
4056 result |= ((m_memObjectCount.threadGroupSpaceCount >> 2) & 0xF) << 16;
4057 }
4058
4059 if ((m_memObjectCount.veboxCount >> 2) > 0xF)
4060 {
4061 result |= 0xF << 20;
4062 }
4063 else
4064 {
4065 result |= ((m_memObjectCount.veboxCount >> 2) & 0xF) << 20;
4066 }
4067
4068 if ((m_memObjectCount.eventCount >> 2) > 0xF)
4069 {
4070 result |= 0xF << 24;
4071 }
4072 else
4073 {
4074 result |= ((m_memObjectCount.eventCount >> 2) & 0xF) << 24;
4075 }
4076
4077 // add signature to MSB 4-bit
4078 if (result)
4079 result |= 0xF << 28;
4080 }
4081 #endif
4082
4083 return result;
4084 }
4085
4086 } // namespace
4087