xref: /aosp_15_r20/external/intel-media-driver/media_driver/agnostic/common/cm/cm_device_rt_base.cpp (revision ba62d9d3abf0e404f2022b4cd7a85e107f48596f)
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, &gtPlatform, 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(&param, 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, &param));
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(&param, 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, &param));
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(&param, 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, &param));
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, &gtInfo        );
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