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_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 MosUtilities::MosQueryPerformanceFrequency((uint64_t *)&freq.QuadPart);
131 LARGE_INTEGER start;
132 MosUtilities::MosQueryPerformanceCounter((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 MosUtilities::MosQueryPerformanceCounter((uint64_t*)¤t.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
384 #if MDF_SURFACE_CONTENT_DUMP
GetMosContext()385 MOS_CONTEXT* CmSurface::GetMosContext()
386 {
387 return m_surfaceMgr->GetHalState()->osInterface->pOsContext;
388 }
389 #endif // #if MDF_SURFACE_CONTENT_DUMP
390
391 } // namespace
392