1 /*
2 * Copyright (c) 2017, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 //!
23 //! \file      cm_surface.cpp
24 //! \brief     Contains Class CmSurface  definitions
25 //!
26 
27 #include "cm_surface.h"
28 
29 #include "cm_device_rt.h"
30 #include "cm_event_rt.h"
31 #include "cm_hal.h"
32 #include "cm_mem.h"
33 #include "cm_queue_rt.h"
34 #include "cm_surface_manager.h"
35 #include "cm_execution_adv.h"
36 
37 namespace CMRT_UMD
38 {
39 //*-----------------------------------------------------------------------------
40 //| Purpose:    Destory CmSurface
41 //| Returns:    Result of the operation.
42 //*-----------------------------------------------------------------------------
Destroy(CmSurface * & surface)43 int32_t CmSurface::Destroy( CmSurface* &surface )
44 {
45     CmSafeDelete( surface );
46 
47     return CM_SUCCESS;
48 }
49 
50 //*-----------------------------------------------------------------------------
51 //| Purpose:    Constructor of CmSurface
52 //| Returns:    Result of the operation.
53 //*-----------------------------------------------------------------------------
CmSurface(CmSurfaceManager * surfMgr,bool isCmCreated)54 CmSurface::CmSurface( CmSurfaceManager* surfMgr ,bool isCmCreated):
55     m_index( nullptr ),
56     m_surfaceMgr( surfMgr ),
57     m_isCmCreated (isCmCreated),
58     m_lastVeboxTracker(0),
59     m_released(false),
60     m_delayDestroyPrev(nullptr),
61     m_delayDestroyNext(nullptr),
62     m_propertyIndex(0)
63 {
64     MOS_ZeroMemory(&m_memObjCtrl, sizeof(m_memObjCtrl));
65 }
66 
67 //*-----------------------------------------------------------------------------
68 //| Purpose:    Destructor of CmSurface
69 //| Returns:    Result of the operation.
70 //*-----------------------------------------------------------------------------
~CmSurface(void)71 CmSurface::~CmSurface( void )
72 {
73     MosSafeDelete(m_index);
74 }
75 
76 //*-----------------------------------------------------------------------------
77 //| Purpose:    Initialize CmSurface
78 //| Returns:    Result of the operation.
79 //*-----------------------------------------------------------------------------
Initialize(uint32_t index)80 int32_t CmSurface::Initialize( uint32_t index )
81 {
82     // set the tracker producer
83     CmDeviceRT* cmDevice =  nullptr;
84     m_surfaceMgr->GetCmDevice(cmDevice);
85     PCM_HAL_STATE  cmHalState = ((PCM_CONTEXT_DATA)cmDevice->GetAccelData())->cmHalState;
86     if (cmHalState == nullptr)
87     {
88         return CM_FAILURE;
89     }
90     m_lastRenderTracker.SetProducer(&cmHalState->renderHal->trackerProducer);
91     if (cmHalState->advExecutor)
92     {
93         m_lastFastTracker.SetProducer(cmHalState->advExecutor->GetFastTrackerProducer());
94     }
95     // using CM compiler data structure
96     m_index = MOS_New(SurfaceIndex, index);
97     if( m_index )
98     {
99         return CM_SUCCESS;
100     }
101     else
102     {
103         return CM_OUT_OF_HOST_MEMORY;
104     }
105 }
106 
107 //*-----------------------------------------------------------------------------
108 //| Purpose:    Flush the task, once flushed, lock will untill the task finishes
109 //|             the execution of kernels upon the surface
110 //| Returns:    Result of the operation.
111 //*-----------------------------------------------------------------------------
FlushDeviceQueue(CmEventRT * event)112 int32_t CmSurface::FlushDeviceQueue( CmEventRT* event )
113 {
114     if( event == nullptr )
115     {
116         CM_ASSERTMESSAGE("Error: Pointer to CM event is null.")
117         return CM_FAILURE;
118     }
119 
120     CmDeviceRT* device = nullptr;
121     m_surfaceMgr->GetCmDevice( device );
122     CM_ASSERT( device );
123 
124     //Used for timeout detection
125     CmQueueRT* cmQueue = nullptr;
126     event->GetQueue(cmQueue);
127     uint32_t numTasks;
128     cmQueue->GetTaskCount(numTasks);
129     LARGE_INTEGER freq;
130     MOS_QueryPerformanceFrequency((uint64_t*)&freq.QuadPart);
131     LARGE_INTEGER start;
132     MOS_QueryPerformanceCounter((uint64_t*)&start.QuadPart);
133     int64_t timeout = start.QuadPart + (CM_MAX_TIMEOUT * freq.QuadPart * numTasks); //Count to timeout at
134 
135     CM_STATUS status;
136     event->GetStatusNoFlush( status );
137     // Not necessary CM_STATUS_FINISHED, once flushed, lock will wait
138     // untill the task finishes the execution of kernels upon the surface
139     while( status == CM_STATUS_QUEUED )
140     {
141         LARGE_INTEGER current;
142         MOS_QueryPerformanceCounter((uint64_t*)&current.QuadPart);
143 
144         if( current.QuadPart > timeout )
145             return CM_EXCEED_MAX_TIMEOUT;
146 
147         event->GetStatusNoFlush( status );
148     }
149 
150     return CM_SUCCESS;
151 }
152 
TouchDeviceQueue()153 int32_t CmSurface::TouchDeviceQueue()
154 {
155     CmDeviceRT* device = nullptr;
156 
157     m_surfaceMgr->GetCmDevice(device);
158     CM_ASSERT(device);
159 
160     std::vector<CmQueueRT *> &cmQueue = device->GetQueue();
161     CSync *lock = device->GetQueueLock();
162     lock->Acquire();
163     for (auto iter = cmQueue.begin(); iter != cmQueue.end(); iter++)
164     {
165         int32_t result = (*iter)->TouchFlushedTasks();
166         if (FAILED(result))
167         {
168             lock->Release();
169             return result;
170         }
171     }
172 
173     lock->Release();
174     return CM_SUCCESS;;
175 }
176 
WaitForReferenceFree()177 int32_t CmSurface::WaitForReferenceFree()
178 {
179     // Make sure the surface is not referenced any more
180     while (!AllReferenceCompleted())
181     {
182         if (FAILED(TouchDeviceQueue()))
183         {
184             CM_ASSERTMESSAGE("Error: Failed to touch device queue.")
185             return CM_FAILURE;
186         };
187     };
188 
189     return CM_SUCCESS;
190 }
191 
MemoryObjectCtrlPolicyCheck(MEMORY_OBJECT_CONTROL memCtrl)192 bool CmSurface::MemoryObjectCtrlPolicyCheck(MEMORY_OBJECT_CONTROL memCtrl)
193 {
194     if (memCtrl == MEMORY_OBJECT_CONTROL_UNKNOW)
195     {
196         return true;
197     }
198 
199     CmDeviceRT* cmDevice =  nullptr;
200     m_surfaceMgr->GetCmDevice(cmDevice);
201     if(cmDevice == nullptr)
202     {
203         return false;
204     }
205 
206     PCM_HAL_STATE  cmHalState = ((PCM_CONTEXT_DATA)cmDevice->GetAccelData())->cmHalState;
207     if (cmHalState == nullptr)
208     {
209         return false;
210     }
211 
212     return cmHalState->cmHalInterface->MemoryObjectCtrlPolicyCheck(memCtrl);
213 
214 }
215 
SetMemoryObjectControl(MEMORY_OBJECT_CONTROL memCtrl,MEMORY_TYPE memType,uint32_t age)216 int32_t CmSurface::SetMemoryObjectControl(MEMORY_OBJECT_CONTROL memCtrl, MEMORY_TYPE memType, uint32_t age)
217 {
218     if (!MemoryObjectCtrlPolicyCheck(memCtrl))
219     {
220         return CM_FAILURE;
221     }
222     CmDeviceRT* cmDevice = nullptr;
223     m_surfaceMgr->GetCmDevice(cmDevice);
224     CM_CHK_NULL_RETURN_CMERROR(cmDevice);
225     uint32_t platform = 0;
226     cmDevice->GetGenPlatform(platform);
227 
228     m_memObjCtrl.mem_ctrl = memCtrl;
229     m_memObjCtrl.mem_type = memType;
230     m_memObjCtrl.age= age;
231 
232     if (platform > IGFX_GEN8_CORE)
233     {
234         MOS_HW_RESOURCE_DEF defaultMocs = MOS_CM_RESOURCE_USAGE_SurfaceState;
235         PCM_HAL_STATE  cmHalState = ((PCM_CONTEXT_DATA)cmDevice->GetAccelData())->cmHalState;
236         if (cmHalState && cmHalState->cmHalInterface)
237         {
238             defaultMocs = cmHalState->cmHalInterface->GetDefaultMOCS();
239         }
240 
241         switch (memCtrl)
242         {
243         case MEMORY_OBJECT_CONTROL_DEFAULT:
244             m_memObjCtrl.mem_ctrl = (unsigned int)defaultMocs;
245             break;
246 
247         case MEMORY_OBJECT_CONTROL_NO_L3:
248             m_memObjCtrl.mem_ctrl = MOS_CM_RESOURCE_USAGE_NO_L3_SurfaceState;
249             break;
250 
251         case MEMORY_OBJECT_CONTROL_NO_LLC_ELLC:
252             m_memObjCtrl.mem_ctrl = MOS_CM_RESOURCE_USAGE_NO_LLC_ELLC_SurfaceState;
253             break;
254 
255         case MEMORY_OBJECT_CONTROL_NO_LLC:
256             m_memObjCtrl.mem_ctrl = MOS_CM_RESOURCE_USAGE_NO_LLC_SurfaceState;
257             break;
258 
259         case MEMORY_OBJECT_CONTROL_NO_ELLC:
260             m_memObjCtrl.mem_ctrl = MOS_CM_RESOURCE_USAGE_NO_ELLC_SurfaceState;
261             break;
262 
263         case MEMORY_OBJECT_CONTROL_NO_LLC_L3:
264             m_memObjCtrl.mem_ctrl = MOS_CM_RESOURCE_USAGE_NO_LLC_L3_SurfaceState;
265             break;
266 
267         case MEMORY_OBJECT_CONTROL_NO_ELLC_L3:
268             m_memObjCtrl.mem_ctrl = MOS_CM_RESOURCE_USAGE_NO_ELLC_L3_SurfaceState;
269             break;
270 
271         case MEMORY_OBJECT_CONTROL_NO_CACHE:
272             m_memObjCtrl.mem_ctrl = MOS_CM_RESOURCE_USAGE_NO_CACHE_SurfaceState;
273             break;
274 
275         case MEMORY_OBJECT_CONTROL_L1_ENABLED:
276             m_memObjCtrl.mem_ctrl = MOS_CM_RESOURCE_USAGE_L1_Enabled_SurfaceState;
277             break;
278 
279         default:
280             // any invalid CM_HAL_MEMORY_OBJECT_CONTROL value is converted to default
281             m_memObjCtrl.mem_ctrl = (unsigned int)defaultMocs;
282             break;
283         }
284     }
285 
286     return CM_SUCCESS;
287 }
288 
SetResourceUsage(MOS_HW_RESOURCE_DEF mosUsage)289 int32_t CmSurface::SetResourceUsage(MOS_HW_RESOURCE_DEF mosUsage)
290 {
291     CmDeviceRT* cmDevice = nullptr;
292     m_surfaceMgr->GetCmDevice(cmDevice);
293     CM_CHK_NULL_RETURN_CMERROR(cmDevice);
294     uint32_t platform = 0;
295     cmDevice->GetGenPlatform(platform);
296     // MOS usage memory object setting is only available to gen9+
297     if (platform > IGFX_GEN8_CORE)
298     if (mosUsage < MOS_HW_RESOURCE_DEF_MAX)
299     {
300         m_memObjCtrl.mem_ctrl = mosUsage;
301         m_memObjCtrl.mem_type = CM_USE_PTE;
302         m_memObjCtrl.age = 0;
303         return CM_SUCCESS;
304     }
305     return CM_FAILURE;
306 }
307 
GetFormatString(CM_SURFACE_FORMAT format)308 std::string CmSurface::GetFormatString(CM_SURFACE_FORMAT format)
309 {
310     switch (format)
311     {
312         case CM_SURFACE_FORMAT_A8R8G8B8:           return "argb";
313         case CM_SURFACE_FORMAT_X8R8G8B8:           return "xrgb";
314         case CM_SURFACE_FORMAT_A8B8G8R8:           return "abgr";
315         case CM_SURFACE_FORMAT_A8:                 return "a8";
316         case CM_SURFACE_FORMAT_P8:                 return "p8";
317         case CM_SURFACE_FORMAT_R32F:               return "r32f";
318         case CM_SURFACE_FORMAT_NV12:               return "nv12";
319         case CM_SURFACE_FORMAT_P016:               return "p016";
320         case CM_SURFACE_FORMAT_P010:               return "p010";
321         case CM_SURFACE_FORMAT_P208:               return "p208";
322         case CM_SURFACE_FORMAT_V8U8:               return "v8u8";
323         case CM_SURFACE_FORMAT_A8L8:               return "a8l8";
324         case CM_SURFACE_FORMAT_D16:                return "d16";
325         case CM_SURFACE_FORMAT_A16B16G16R16F:      return "argb16f";
326         case CM_SURFACE_FORMAT_R10G10B10A2:        return "r10g10b10a2";
327         case CM_SURFACE_FORMAT_A16B16G16R16:       return "argb16";
328         case CM_SURFACE_FORMAT_IRW0:               return "irw0";
329         case CM_SURFACE_FORMAT_IRW1:               return "irw1";
330         case CM_SURFACE_FORMAT_IRW2:               return "irw2";
331         case CM_SURFACE_FORMAT_IRW3:               return "irw3";
332         case CM_SURFACE_FORMAT_R32_SINT:           return "r32s";
333         case CM_SURFACE_FORMAT_R16_FLOAT:          return "r16f";
334         case CM_SURFACE_FORMAT_A8P8:               return "a8p8";
335         case CM_SURFACE_FORMAT_I420:               return "i420";
336         case CM_SURFACE_FORMAT_IMC3:               return "imc3";
337         case CM_SURFACE_FORMAT_IA44:               return "ia44";
338         case CM_SURFACE_FORMAT_AI44:               return "ai44";
339         case CM_SURFACE_FORMAT_Y410:               return "y410";
340         case CM_SURFACE_FORMAT_Y416:               return "y416";
341         case CM_SURFACE_FORMAT_Y210:               return "y210";
342         case CM_SURFACE_FORMAT_Y216:               return "y216";
343         case CM_SURFACE_FORMAT_AYUV:               return "ayuv";
344         case CM_SURFACE_FORMAT_YV12:               return "yv12";
345         case CM_SURFACE_FORMAT_400P:               return "400p";
346         case CM_SURFACE_FORMAT_411P:               return "411p";
347         case CM_SURFACE_FORMAT_411R:               return "411r";
348         case CM_SURFACE_FORMAT_422H:               return "422h";
349         case CM_SURFACE_FORMAT_422V:               return "422v";
350         case CM_SURFACE_FORMAT_444P:               return "444p";
351         case CM_SURFACE_FORMAT_RGBP:               return "rgbp";
352         case CM_SURFACE_FORMAT_BGRP:               return "bgrp";
353         case CM_SURFACE_FORMAT_R8_UINT:            return "r8u";
354         case CM_SURFACE_FORMAT_R32_UINT:           return "r32u";
355         case CM_SURFACE_FORMAT_R16_SINT:           return "r16s";
356         case CM_SURFACE_FORMAT_R16_UNORM:          return "r16un";
357         case CM_SURFACE_FORMAT_R8G8_UNORM:         return "r8g8un";
358         case CM_SURFACE_FORMAT_R16_UINT:           return "r16u";
359         case CM_SURFACE_FORMAT_R16G16_UNORM:       return "r16g16un";
360         case CM_SURFACE_FORMAT_L16:                return "l16";
361         case CM_SURFACE_FORMAT_YUY2:               return "yuy2";
362         case CM_SURFACE_FORMAT_L8:                 return "l8";
363         case CM_SURFACE_FORMAT_UYVY:               return "uyvy";
364         case CM_SURFACE_FORMAT_VYUY:               return "vyuy";
365         case CM_SURFACE_FORMAT_R8G8_SNORM:         return "r8g8sn";
366         case CM_SURFACE_FORMAT_Y16_SNORM:          return "y16sn";
367         case CM_SURFACE_FORMAT_Y16_UNORM:          return "y16un";
368         case CM_SURFACE_FORMAT_Y8_UNORM:           return "y8un";
369         case CM_SURFACE_FORMAT_BUFFER_2D:          return "buffer2d";
370         case CM_SURFACE_FORMAT_D32F:               return "d32f";
371         case CM_SURFACE_FORMAT_D24_UNORM_S8_UINT:  return "d24uns8ui";
372         case CM_SURFACE_FORMAT_D32F_S8X24_UINT:    return "d32fs8x24ui";
373         case CM_SURFACE_FORMAT_R16G16_SINT:        return "r16g16si";
374         case CM_SURFACE_FORMAT_R16_TYPELESS:       return "r16";
375         case CM_SURFACE_FORMAT_R24G8_TYPELESS:     return "r24g8";
376         case CM_SURFACE_FORMAT_R32_TYPELESS:       return "r32";
377         case CM_SURFACE_FORMAT_R32G8X24_TYPELESS:  return "r32g8x24";
378         case CM_SURFACE_FORMAT_R8_UNORM:           return "r8un";
379         case CM_SURFACE_FORMAT_R32G32B32A32F:      return "rgba32f";
380         default:                                   return "Invalid";
381     }
382 }
383 }