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_manager.cpp
24 //! \brief Contains Class CmSurfaceManager definitions
25 //!
26
27 #include "cm_surface_manager.h"
28
29 #include "cm_debug.h"
30 #include "cm_queue_rt.h"
31 #include "cm_buffer_rt.h"
32 #include "cm_mem.h"
33 #include "cm_state_buffer.h"
34 #include "cm_surface_2d_up_rt.h"
35 #include "cm_surface_2d_rt.h"
36 #include "cm_surface_3d_rt.h"
37 #include "cm_surface_vme.h"
38 #include "cm_surface_sampler.h"
39 #include "cm_surface_sampler8x8.h"
40 #include "cm_device_rt.h"
41 #include "cm_execution_adv.h"
42
43 namespace CMRT_UMD
44 {
UpdateStateForDelayedDestroy(SURFACE_DESTROY_KIND destroyKind,uint32_t index)45 int32_t CmSurfaceManagerBase::UpdateStateForDelayedDestroy(
46 SURFACE_DESTROY_KIND destroyKind, uint32_t index)
47 {
48 switch (destroyKind)
49 {
50 case DELAYED_DESTROY:
51 if (!m_surfaceArray[index]->CanBeDestroyed())
52 {
53 return CM_SURFACE_IN_USE;
54 }
55 break;
56
57 case APP_DESTROY:
58 m_surfaceArray[index]->DelayDestroy();
59 if (!m_surfaceArray[index]->CanBeDestroyed())
60 {
61 return CM_SURFACE_IN_USE;
62 }
63 break;
64
65 default:
66 CM_ASSERTMESSAGE("Error: Invalid surface destroy kind.");
67 return CM_FAILURE;
68 }
69
70 return CM_SUCCESS;
71 }
72
UpdateStateForRealDestroy(uint32_t index,CM_ENUM_CLASS_TYPE surfaceType)73 int32_t CmSurfaceManagerBase::UpdateStateForRealDestroy(uint32_t index,
74 CM_ENUM_CLASS_TYPE surfaceType)
75 {
76 for(auto buffer : m_statelessSurfaceArray)
77 {
78 if (buffer == m_surfaceArray[index])
79 {
80 m_statelessSurfaceArray.erase(buffer);
81 break;
82 }
83 }
84
85 m_surfaceArray[index] = nullptr;
86
87 m_surfaceSizes[index] = 0;
88
89 switch (surfaceType)
90 {
91 case CM_ENUM_CLASS_TYPE_CMBUFFER_RT:
92 m_bufferCount--;
93 break;
94 case CM_ENUM_CLASS_TYPE_CMSURFACE2D:
95 m_2DSurfaceCount--;
96 break;
97 case CM_ENUM_CLASS_TYPE_CMSURFACE2DUP:
98 m_2DUPSurfaceCount--;
99 break;
100 case CM_ENUM_CLASS_TYPE_CMSURFACE3D:
101 m_3DSurfaceCount--;
102 break;
103 case CM_ENUM_CLASS_TYPE_CMSURFACESAMPLER:
104 case CM_ENUM_CLASS_TYPE_CMSURFACESAMPLER8X8:
105 case CM_ENUM_CLASS_TYPE_CMSURFACEVME:
106 break;
107 default:
108 CM_ASSERTMESSAGE("Error: Invalid surface type.");
109 break;
110 }
111
112 return CM_SUCCESS;
113 }
114
UpdateProfileFor2DSurface(uint32_t index,uint32_t width,uint32_t height,CM_SURFACE_FORMAT format)115 int32_t CmSurfaceManagerBase::UpdateProfileFor2DSurface(uint32_t index,
116 uint32_t width, uint32_t height,
117 CM_SURFACE_FORMAT format)
118 {
119 uint32_t size = 0;
120 uint32_t sizeperpixel = 1;
121
122 int32_t hr = GetFormatSize(format, sizeperpixel);
123 if (hr != CM_SUCCESS)
124 {
125 CM_ASSERTMESSAGE("Error: Failed to get correct surface info.");
126 return hr;
127 }
128 size = width * height * sizeperpixel;
129
130 m_2DSurfaceAllCount++;
131 m_2DSurfaceAllSize += size;
132
133 m_2DSurfaceCount ++;
134 m_surfaceSizes[index] = size;
135
136 return CM_SUCCESS;
137 }
138
UpdateProfileFor1DSurface(uint32_t index,uint32_t size)139 int32_t CmSurfaceManagerBase::UpdateProfileFor1DSurface(uint32_t index, uint32_t size)
140 {
141 m_bufferAllCount++;
142 m_bufferAllSize += size;
143
144 m_bufferCount++;
145 m_surfaceSizes[index] = size;
146
147 return CM_SUCCESS;
148 }
149
UpdateProfileFor3DSurface(uint32_t index,uint32_t width,uint32_t height,uint32_t depth,CM_SURFACE_FORMAT format)150 int32_t CmSurfaceManagerBase::UpdateProfileFor3DSurface(uint32_t index, uint32_t width,
151 uint32_t height, uint32_t depth,
152 CM_SURFACE_FORMAT format)
153 {
154 uint32_t size = 0;
155 uint32_t sizeperpixel = 1;
156
157 int32_t hr = GetFormatSize(format, sizeperpixel);
158 if (hr != CM_SUCCESS)
159 {
160 CM_ASSERTMESSAGE("Error: Failed to get surface info.");
161 return hr;
162 }
163 size = width * height * depth * sizeperpixel;
164
165 m_3DSurfaceAllCount++;
166 m_3DSurfaceAllSize += size;
167
168 m_3DSurfaceCount ++;
169 m_surfaceSizes[index] = size;
170
171 return CM_SUCCESS;
172 }
173
174 //*-----------------------------------------------------------------------------
175 //| Purpose: Constructor of CmSurfaceManagerBase
176 //| Returns: None
177 //*-----------------------------------------------------------------------------
CmSurfaceManagerBase(CmDeviceRT * device)178 CmSurfaceManagerBase::CmSurfaceManagerBase(CmDeviceRT* device) :
179 m_device(device),
180 m_surfaceArraySize(0),
181 m_surfaceArray(nullptr),
182 m_maxSurfaceIndexAllocated(0),
183 m_surfaceSizes(nullptr),
184 m_maxBufferCount(0),
185 m_bufferCount(0),
186 m_max2DSurfaceCount(0),
187 m_2DSurfaceCount(0),
188 m_max3DSurfaceCount(0),
189 m_3DSurfaceCount(0),
190 m_max2DUPSurfaceCount(0),
191 m_2DUPSurfaceCount(0),
192 m_bufferAllCount(0),
193 m_2DSurfaceAllCount(0),
194 m_3DSurfaceAllCount(0),
195 m_bufferAllSize(0),
196 m_2DSurfaceAllSize(0),
197 m_3DSurfaceAllSize(0),
198 m_garbageCollectionTriggerTimes(0),
199 m_garbageCollection1DSize(0),
200 m_garbageCollection2DSize(0),
201 m_garbageCollection3DSize(0),
202 m_latestVeboxTracker(nullptr),
203 m_delayDestroyHead(nullptr),
204 m_delayDestroyTail(nullptr)
205 {
206 MOS_ZeroMemory(&m_surfaceBTIInfo, sizeof(m_surfaceBTIInfo));
207 GetSurfaceBTIInfo();
208 };
209
210 //*-----------------------------------------------------------------------------
211 //| Purpose: Destructor of CmSurfaceManagerBase
212 //| Returns: None
213 //*-----------------------------------------------------------------------------
~CmSurfaceManagerBase()214 CmSurfaceManagerBase::~CmSurfaceManagerBase()
215 {
216 for (uint32_t i = ValidSurfaceIndexStart(); i < m_surfaceArraySize; i++)
217 {
218 DestroySurfaceArrayElement(i);
219 }
220
221 #ifdef SURFACE_MANAGE_PROFILE
222 printf("\n\n");
223 printf("Total %d 1D buffers, with size: %d\n", m_bufferAllCount, m_bufferAllSize);
224 printf("Total %d 2D surfaces, with size: %d\n", m_2DSurfaceAllCount, m_2DSurfaceAllSize);
225 printf("Total %d 3D surfaces, with size: %d\n", m_3DSurfaceAllCount, m_3DSurfaceAllSize);
226
227 printf("\nGarbage Collection trigger times: %d\n", m_garbageCollectionTriggerTimes);
228 printf("Garbage collection 1D surface size: %d\n", m_garbageCollection1DSize);
229 printf("Garbage collection 2D surface size: %d\n", m_garbageCollection2DSize);
230 printf("Garbage collection 3D surface size: %d\n", m_garbageCollection3DSize);
231
232 printf("\n\n");
233 #endif
234
235 MosSafeDeleteArray(m_surfaceSizes);
236 MosSafeDeleteArray(m_surfaceArray);
237
238 m_statelessSurfaceArray.clear();
239 }
240
241 //*-----------------------------------------------------------------------------
242 //| Purpose: Destructor one specific element from SuffaceArray
243 //| Returns: None
244 //*-----------------------------------------------------------------------------
DestroySurfaceArrayElement(uint32_t index)245 int32_t CmSurfaceManagerBase::DestroySurfaceArrayElement( uint32_t index )
246 {
247 uint32_t i = index;
248
249 if (i >= m_surfaceArraySize)
250 return CM_FAILURE;
251
252 CmSurface* surface = m_surfaceArray[ i ];
253
254 if( surface )
255 {
256 CmSurface2DRT* surf2D = nullptr;
257 CmBuffer_RT* surf1D = nullptr;
258 CmSurface3DRT* surf3D = nullptr;
259 CmSurfaceVme* surfVme = nullptr;
260 CmSurface2DUPRT* surf2DUP = nullptr;
261 CmSurfaceSampler* surfaceSampler = nullptr;
262 CmSurfaceSampler8x8* surfaceSampler8x8 = nullptr;
263 CmStateBuffer* stateBuff = nullptr;
264
265 switch (surface->Type())
266 {
267 case CM_ENUM_CLASS_TYPE_CMSURFACE2D :
268 surf2D = static_cast< CmSurface2DRT* >( surface );
269 if (surf2D)
270 {
271 DestroySurface( surf2D, FORCE_DESTROY);
272 }
273 break;
274
275 case CM_ENUM_CLASS_TYPE_CMBUFFER_RT :
276 surf1D = static_cast< CmBuffer_RT* >( surface );
277 if (surf1D)
278 {
279 DestroySurface( surf1D, FORCE_DESTROY);
280 }
281 break;
282
283 case CM_ENUM_CLASS_TYPE_CMSURFACE3D :
284 surf3D = static_cast< CmSurface3DRT* >( surface );
285 if (surf3D)
286 {
287 DestroySurface( surf3D, FORCE_DESTROY);
288 }
289 break;
290
291 case CM_ENUM_CLASS_TYPE_CMSURFACEVME:
292 surfVme = static_cast< CmSurfaceVme* >( surface );
293 if( surfVme )
294 {
295 DestroySurface( surfVme );
296 }
297 break;
298
299 case CM_ENUM_CLASS_TYPE_CMSURFACE2DUP:
300 surf2DUP = static_cast< CmSurface2DUPRT* >( surface );
301 if( surf2DUP )
302 {
303 DestroySurface( surf2DUP, FORCE_DESTROY );
304 }
305 break;
306
307 case CM_ENUM_CLASS_TYPE_CMSURFACESAMPLER:
308 surfaceSampler = static_cast< CmSurfaceSampler* >( surface );
309 if ( surfaceSampler )
310 {
311 DestroySurface( surfaceSampler );
312 }
313 break;
314
315 case CM_ENUM_CLASS_TYPE_CMSURFACESAMPLER8X8:
316 surfaceSampler8x8 = static_cast< CmSurfaceSampler8x8* >( surface );
317 if ( surfaceSampler8x8 )
318 {
319 DestroySurface( surfaceSampler8x8 );
320 }
321 break;
322
323 case CM_ENUM_CLASS_TYPE_CM_STATE_BUFFER:
324 stateBuff = static_cast< CmStateBuffer* >( surface );
325 if ( stateBuff )
326 {
327 DestroyStateBuffer( stateBuff, FORCE_DESTROY );
328 }
329 break;
330
331 default:
332 break;
333 }
334 }
335
336 return CM_SUCCESS;
337 }
338
GetSurfaceArraySize(uint32_t & surfaceArraySize)339 int32_t CmSurfaceManagerBase::GetSurfaceArraySize(uint32_t& surfaceArraySize)
340 {
341 surfaceArraySize = m_surfaceArraySize;
342 return CM_SUCCESS;
343 }
344
345 //*-----------------------------------------------------------------------------
346 //| Purpose: Create Surface 2D
347 //| Arguments :
348 //| halMaxValues [in] HAL max values
349 //| halMaxValuesEx [in] Extended HAL max values
350 //|
351 //| Returns: Result of the operation.
352 //*-----------------------------------------------------------------------------
Initialize(CM_HAL_MAX_VALUES halMaxValues,CM_HAL_MAX_VALUES_EX halMaxValuesEx)353 int32_t CmSurfaceManagerBase::Initialize( CM_HAL_MAX_VALUES halMaxValues,
354 CM_HAL_MAX_VALUES_EX halMaxValuesEx )
355 {
356 uint32_t totalSurfaceCount = halMaxValues.maxBufferTableSize +
357 halMaxValues.max2DSurfaceTableSize +
358 halMaxValues.max3DSurfaceTableSize +
359 halMaxValuesEx.max2DUPSurfaceTableSize;
360 uint32_t totalVirtualSurfaceCount = halMaxValues.maxSamplerTableSize +
361 halMaxValuesEx.maxSampler8x8TableSize;
362 m_surfaceArraySize = totalSurfaceCount + totalVirtualSurfaceCount;
363 m_maxSurfaceIndexAllocated = 0;
364
365 m_maxBufferCount = halMaxValues.maxBufferTableSize;
366 m_max2DSurfaceCount = halMaxValues.max2DSurfaceTableSize;
367 m_max3DSurfaceCount = halMaxValues.max3DSurfaceTableSize;
368 m_max2DUPSurfaceCount = halMaxValuesEx.max2DUPSurfaceTableSize;
369
370 typedef CmSurface* PCMSURFACE;
371
372 m_surfaceArray = MOS_NewArray(PCMSURFACE, m_surfaceArraySize);
373 m_surfaceSizes = MOS_NewArray(int32_t, m_surfaceArraySize);
374
375 if( m_surfaceArray == nullptr ||
376 m_surfaceSizes == nullptr)
377 {
378 MosSafeDeleteArray(m_surfaceSizes);
379 MosSafeDeleteArray(m_surfaceArray);
380
381 CM_ASSERTMESSAGE("Error: Out of system memory.");
382 return CM_OUT_OF_HOST_MEMORY;
383 }
384
385 CmSafeMemSet( m_surfaceArray, 0, m_surfaceArraySize * sizeof( CmSurface* ) );
386 CmSafeMemSet( m_surfaceSizes, 0, m_surfaceArraySize * sizeof( int32_t ) );
387
388 return CM_SUCCESS;
389 }
390
391 // Sysmem based surface allocation will always use new surface entry.
RefreshDelayDestroySurfaces(uint32_t & freeSurfaceCount)392 int32_t CmSurfaceManagerBase::RefreshDelayDestroySurfaces(uint32_t &freeSurfaceCount)
393 {
394 CmSurface* surface = m_delayDestroyHead;
395 CmBuffer_RT* surf1D = nullptr;
396 CmSurface2DRT* surf2D = nullptr;
397 CmSurface2DUPRT* surf2DUP = nullptr;
398 CmSurface3DRT* surf3D = nullptr;
399 CmStateBuffer* surfStateBuffer = nullptr;
400 int32_t status = CM_FAILURE;
401
402 freeSurfaceCount = 0;
403 uint32_t count = 0;
404
405 while(surface != nullptr && count <= m_maxSurfaceIndexAllocated)
406 {
407 status = CM_FAILURE;
408 CmSurface *next = surface->DelayDestroyNext();
409
410 switch (surface->Type())
411 {
412 case CM_ENUM_CLASS_TYPE_CMSURFACE2D :
413 surf2D = static_cast< CmSurface2DRT* >( surface );
414 if (surf2D)
415 {
416 status = DestroySurface( surf2D, DELAYED_DESTROY);
417 }
418 break;
419
420 case CM_ENUM_CLASS_TYPE_CMBUFFER_RT :
421 surf1D = static_cast< CmBuffer_RT* >( surface );
422 if (surf1D)
423 {
424 status = DestroySurface( surf1D, DELAYED_DESTROY);
425 }
426 break;
427
428 case CM_ENUM_CLASS_TYPE_CMSURFACE3D :
429 surf3D = static_cast< CmSurface3DRT* >( surface );
430 if (surf3D)
431 {
432 status = DestroySurface( surf3D, DELAYED_DESTROY);
433 }
434 break;
435
436 case CM_ENUM_CLASS_TYPE_CMSURFACE2DUP:
437 surf2DUP = static_cast< CmSurface2DUPRT* >( surface );
438 if( surf2DUP )
439 {
440 status = DestroySurface( surf2DUP, DELAYED_DESTROY );
441 }
442 break;
443
444 case CM_ENUM_CLASS_TYPE_CM_STATE_BUFFER:
445 surfStateBuffer = static_cast< CmStateBuffer* >( surface );
446 if ( surfStateBuffer )
447 {
448 status = DestroyStateBuffer( surfStateBuffer, DELAYED_DESTROY );
449 }
450 break;
451
452 case CM_ENUM_CLASS_TYPE_CMSURFACESAMPLER:
453 case CM_ENUM_CLASS_TYPE_CMSURFACESAMPLER8X8:
454 case CM_ENUM_CLASS_TYPE_CMSURFACEVME:
455 //Do nothing to these kind surfaces
456 break;
457
458 default:
459 CM_ASSERTMESSAGE("Error: Invalid surface type.");
460 break;
461 }
462
463 if(status == CM_SUCCESS)
464 {
465 freeSurfaceCount++;
466 }
467
468 surface = next;
469 ++ count;
470 }
471
472 return CM_SUCCESS;
473 }
474
TouchSurfaceInPoolForDestroy()475 int32_t CmSurfaceManagerBase::TouchSurfaceInPoolForDestroy()
476 {
477 uint32_t freeNum = 0;
478 std::vector<CmQueueRT*> &pCmQueue = m_device->GetQueue();
479
480 RefreshDelayDestroySurfaces(freeNum);
481 if (pCmQueue.size() == 0)
482 {
483 return freeNum;
484 }
485
486 while (m_delayDestroyHead && !freeNum)
487 {
488 CSync *lock = m_device->GetQueueLock();
489 lock->Acquire();
490 for (auto iter = pCmQueue.begin(); iter != pCmQueue.end(); iter++)
491 {
492 int32_t result = (*iter)->TouchFlushedTasks();
493 if (FAILED(result))
494 {
495 CM_ASSERTMESSAGE("Error: Flush tasks to flushed queue failure.");
496 lock->Release();
497 return result;
498 }
499 }
500 lock->Release();
501
502 RefreshDelayDestroySurfaces(freeNum);
503 }
504
505 m_garbageCollectionTriggerTimes++;
506
507 return freeNum;
508 }
509
GetFreeSurfaceIndexFromPool(uint32_t & freeIndex)510 int32_t CmSurfaceManagerBase::GetFreeSurfaceIndexFromPool(uint32_t &freeIndex)
511 {
512 uint32_t index = ValidSurfaceIndexStart();
513
514 while( ( index < m_surfaceArraySize ) && m_surfaceArray[ index ] )
515 {
516 index ++;
517 }
518
519 if( index >= m_surfaceArraySize )
520 {
521 CM_ASSERTMESSAGE("Error: Invalid surface index.");
522 return CM_FAILURE;
523 }
524
525 freeIndex = index;
526
527 return CM_SUCCESS;
528 }
529
GetFreeSurfaceIndex(uint32_t & freeIndex)530 int32_t CmSurfaceManagerBase::GetFreeSurfaceIndex(uint32_t &freeIndex)
531 {
532 uint32_t index = 0;
533
534 if (GetFreeSurfaceIndexFromPool(index) != CM_SUCCESS)
535 {
536 if (!TouchSurfaceInPoolForDestroy())
537 {
538 CM_ASSERTMESSAGE("Error: Flush tasks to flushed queue failure.");
539 return CM_FAILURE;
540 }
541 //Try again
542 if (GetFreeSurfaceIndexFromPool(index) != CM_SUCCESS)
543 {
544 CM_ASSERTMESSAGE("Error: Invalid surface index.");
545 return CM_FAILURE;
546 }
547 }
548
549 freeIndex = index;
550 m_maxSurfaceIndexAllocated = Max(freeIndex, m_maxSurfaceIndexAllocated);
551
552 return CM_SUCCESS;
553 }
554
GetFormatSize(CM_SURFACE_FORMAT format,uint32_t & sizePerPixel)555 int32_t CmSurfaceManagerBase::GetFormatSize(CM_SURFACE_FORMAT format,
556 uint32_t &sizePerPixel)
557 {
558 switch( format )
559 {
560
561 case CM_SURFACE_FORMAT_R32G32B32A32F:
562 sizePerPixel = 16;
563 break;
564
565 case CM_SURFACE_FORMAT_A16B16G16R16:
566 case CM_SURFACE_FORMAT_A16B16G16R16F:
567 case CM_SURFACE_FORMAT_Y416:
568 case CM_SURFACE_FORMAT_D32F_S8X24_UINT:
569 case CM_SURFACE_FORMAT_R32G8X24_TYPELESS:
570 sizePerPixel = 8;
571 break;
572
573 case CM_SURFACE_FORMAT_X8R8G8B8:
574 case CM_SURFACE_FORMAT_A8R8G8B8:
575 case CM_SURFACE_FORMAT_R32F:
576 case CM_SURFACE_FORMAT_D32F:
577 case CM_SURFACE_FORMAT_R10G10B10A2:
578 case CM_SURFACE_FORMAT_R32_UINT:
579 case CM_SURFACE_FORMAT_R32_SINT:
580 case CM_SURFACE_FORMAT_AYUV:
581 case CM_SURFACE_FORMAT_A8B8G8R8:
582 case CM_SURFACE_FORMAT_R16G16_UNORM:
583 case CM_SURFACE_FORMAT_Y410:
584 case CM_SURFACE_FORMAT_Y216:
585 case CM_SURFACE_FORMAT_Y210:
586 case CM_SURFACE_FORMAT_D24_UNORM_S8_UINT:
587 case CM_SURFACE_FORMAT_R16G16_SINT:
588 case CM_SURFACE_FORMAT_R24G8_TYPELESS:
589 case CM_SURFACE_FORMAT_R32_TYPELESS:
590 sizePerPixel = 4;
591 break;
592
593 case CM_SURFACE_FORMAT_R8G8_UNORM:
594 case CM_SURFACE_FORMAT_R8G8_SNORM:
595 case CM_SURFACE_FORMAT_V8U8:
596 case CM_SURFACE_FORMAT_Y16_UNORM:
597 case CM_SURFACE_FORMAT_Y16_SNORM:
598 case CM_SURFACE_FORMAT_R16_UINT:
599 case CM_SURFACE_FORMAT_R16_SINT:
600 case CM_SURFACE_FORMAT_R16_UNORM:
601 case CM_SURFACE_FORMAT_D16:
602 case CM_SURFACE_FORMAT_L16:
603 case CM_SURFACE_FORMAT_UYVY:
604 case CM_SURFACE_FORMAT_VYUY:
605 case CM_SURFACE_FORMAT_YUY2:
606 case CM_SURFACE_FORMAT_P016:
607 case CM_SURFACE_FORMAT_P010:
608 case CM_SURFACE_FORMAT_IRW0:
609 case CM_SURFACE_FORMAT_IRW1:
610 case CM_SURFACE_FORMAT_IRW2:
611 case CM_SURFACE_FORMAT_IRW3:
612 case CM_SURFACE_FORMAT_R16_FLOAT:
613 case CM_SURFACE_FORMAT_A8P8:
614 case CM_SURFACE_FORMAT_R16_TYPELESS:
615 sizePerPixel = 2;
616 break;
617
618 case CM_SURFACE_FORMAT_A8:
619 case CM_SURFACE_FORMAT_P8:
620 case CM_SURFACE_FORMAT_R8_UINT:
621 case CM_SURFACE_FORMAT_411P:
622 case CM_SURFACE_FORMAT_411R:
623 case CM_SURFACE_FORMAT_422H:
624 case CM_SURFACE_FORMAT_444P:
625 case CM_SURFACE_FORMAT_IMC3:
626 case CM_SURFACE_FORMAT_I420:
627 case CM_SURFACE_FORMAT_RGBP:
628 case CM_SURFACE_FORMAT_BGRP:
629 case CM_SURFACE_FORMAT_422V:
630 case CM_SURFACE_FORMAT_L8:
631 case CM_SURFACE_FORMAT_IA44:
632 case CM_SURFACE_FORMAT_AI44:
633 case CM_SURFACE_FORMAT_400P:
634 case CM_SURFACE_FORMAT_P208:
635 case CM_SURFACE_FORMAT_BUFFER_2D:
636 case CM_SURFACE_FORMAT_R8_UNORM:
637 case CM_SURFACE_FORMAT_Y8_UNORM:
638 sizePerPixel = 1;
639 break;
640
641 case CM_SURFACE_FORMAT_NV12:
642 case CM_SURFACE_FORMAT_YV12:
643 sizePerPixel = 1;
644 break;
645
646 default:
647 CM_ASSERTMESSAGE("Error: Unsupported surface format.");
648 return CM_SURFACE_FORMAT_NOT_SUPPORTED;
649 }
650
651 return CM_SUCCESS;
652 }
653
GetMemorySizeOfSurfaces()654 inline int32_t CmSurfaceManagerBase::GetMemorySizeOfSurfaces()
655 {
656 uint32_t index = ValidSurfaceIndexStart();
657 uint32_t memSize = 0;
658
659 while( ( index < m_surfaceArraySize ))
660 {
661 if (!m_surfaceArray[index])
662 {
663 index ++;
664 continue;
665 }
666
667 memSize += m_surfaceSizes[index];
668 index++;
669 }
670
671 return memSize;
672 }
673
674 // Allocate surface index from surface pool
AllocateSurfaceIndex(size_t width,uint32_t height,uint32_t depth,CM_SURFACE_FORMAT format,uint32_t & freeIndex,void * sysMem)675 int32_t CmSurfaceManagerBase::AllocateSurfaceIndex(size_t width, uint32_t height,
676 uint32_t depth,
677 CM_SURFACE_FORMAT format,
678 uint32_t &freeIndex, void *sysMem)
679 {
680 uint32_t index = ValidSurfaceIndexStart();
681
682 if ((m_bufferCount >= m_maxBufferCount && width && !height && !depth) ||
683 (m_2DSurfaceCount >= m_max2DSurfaceCount && width && height && !depth) ||
684 (m_3DSurfaceCount >= m_max3DSurfaceCount && width && height && depth))
685 {
686 if (!TouchSurfaceInPoolForDestroy())
687 {
688 CM_ASSERTMESSAGE("Error: Failed to flush surface in pool for destroy.");
689 return CM_FAILURE;
690 }
691 }
692
693 if (GetFreeSurfaceIndex(index) != CM_SUCCESS)
694 {
695 return CM_FAILURE;
696 }
697
698 freeIndex = index;
699 m_maxSurfaceIndexAllocated = Max(index, m_maxSurfaceIndexAllocated);
700
701 return CM_SUCCESS;
702 }
703
704 //*-----------------------------------------------------------------------------
705 //| Purpose: Create Buffer
706 //| Arguments :
707 //| size [in] the size of buffer
708 //| buffer [in/out] Reference to cm buffer
709 //| mosResource [in] pointer to mos resource
710 //| sysMem [in] Pointer to system memory
711 //|
712 //| Returns: Result of the operation.
713 //*-----------------------------------------------------------------------------
CreateBuffer(size_t size,CM_BUFFER_TYPE type,bool svmAllocatedByCm,CmBuffer_RT * & buffer,MOS_RESOURCE * mosResource,void * & sysMem,bool isConditionalBuffer,uint32_t comparisonValue)714 int32_t CmSurfaceManagerBase::CreateBuffer(size_t size, CM_BUFFER_TYPE type,
715 bool svmAllocatedByCm, CmBuffer_RT* & buffer,
716 MOS_RESOURCE * mosResource, void* &sysMem,
717 bool isConditionalBuffer, uint32_t comparisonValue)
718 {
719 uint32_t index = ValidSurfaceIndexStart();
720 buffer = nullptr;
721
722 //Not created by CM
723 if (mosResource)
724 {
725 if (GetFreeSurfaceIndex(index) != CM_SUCCESS)
726 {
727 return CM_EXCEED_SURFACE_AMOUNT;
728 }
729 }
730 else
731 {
732 if (AllocateSurfaceIndex(size, 0, 0, CM_SURFACE_FORMAT_INVALID, index, sysMem)
733 != CM_SUCCESS)
734 {
735 return CM_EXCEED_SURFACE_AMOUNT;
736 }
737
738 }
739
740 if( m_bufferCount >= m_maxBufferCount )
741 {
742 CM_ASSERTMESSAGE("Error: Exceed maximum buffer count.");
743 return CM_EXCEED_SURFACE_AMOUNT;
744 }
745
746 uint32_t handle = 0;
747 uint64_t gfxMem = 0;
748 int32_t result = AllocateBuffer(size, type, handle, mosResource, sysMem, gfxMem);
749 if( result != CM_SUCCESS )
750 {
751 CM_ASSERTMESSAGE("Error: Falied to allocate buffer.");
752 return result;
753 }
754
755 CmSurfaceManager * surfaceManager = dynamic_cast<CmSurfaceManager *>(this);
756 CM_CHK_NULL_RETURN_CMERROR(surfaceManager);
757
758 result = CmBuffer_RT::Create( index, handle, size, mosResource == nullptr,
759 surfaceManager, type, svmAllocatedByCm, sysMem,
760 buffer, isConditionalBuffer, comparisonValue, gfxMem);
761 if( result != CM_SUCCESS )
762 {
763 FreeBuffer( handle );
764 CM_ASSERTMESSAGE("Error: Falied to create CM buffer.");
765 return result;
766 }
767
768 m_surfaceArray[ index ] = buffer;
769 UpdateProfileFor1DSurface(index, size);
770
771 if (type == CM_BUFFER_STATELESS || type == CM_BUFFER_SVM) {
772 // add this buffer into svm/stateless buffer array: <address, size, surface>
773 m_statelessSurfaceArray.insert(buffer);
774 }
775
776 return CM_SUCCESS;
777 }
778
779 //*-----------------------------------------------------------------------------
780 //| Purpose: Allocate Buffer
781 //| Arguments :
782 //| size [in] the size of buffer
783 //| handle [in/out] Reference to handle of cm buffer
784 //| mosResource [in] pointer to mos resource
785 //| sysMem [in] Pointer to system memory
786 //|
787 //| Returns: Result of the operation.
788 //*-----------------------------------------------------------------------------
AllocateBuffer(size_t size,CM_BUFFER_TYPE type,uint32_t & handle,MOS_RESOURCE * mosResource,void * & sysMem,uint64_t & gfxMem)789 int32_t CmSurfaceManagerBase::AllocateBuffer(size_t size,
790 CM_BUFFER_TYPE type,
791 uint32_t &handle,
792 MOS_RESOURCE *mosResource,
793 void *&sysMem,
794 uint64_t &gfxMem)
795 {
796 CM_RETURN_CODE hr = CM_SUCCESS;
797 MOS_STATUS mosStatus = MOS_STATUS_SUCCESS;
798
799 PCM_CONTEXT_DATA cmData = (PCM_CONTEXT_DATA)m_device->GetAccelData();
800
801 handle = 0;
802 CM_HAL_BUFFER_PARAM inParam;
803 CmSafeMemSet( &inParam, 0, sizeof( CM_HAL_BUFFER_PARAM ) );
804 inParam.size = size;
805
806 inParam.type = type;
807
808 if (mosResource)
809 {
810 inParam.mosResource = mosResource;
811 inParam.isAllocatedbyCmrtUmd = false;
812 }
813 else
814 {
815 inParam.mosResource = nullptr;
816 inParam.isAllocatedbyCmrtUmd = true;
817 }
818 if( sysMem )
819 { // For BufferUp/BufferSVM
820 inParam.data = sysMem;
821 }
822
823 mosStatus = cmData->cmHalState->pfnAllocateBuffer(cmData->cmHalState, &inParam);
824 while (mosStatus == MOS_STATUS_NO_SPACE )
825 {
826 if (!TouchSurfaceInPoolForDestroy())
827 {
828 CM_ASSERTMESSAGE("Error: Failed to flush surface in pool for destroy.");
829 return CM_SURFACE_ALLOCATION_FAILURE;
830 }
831 mosStatus = cmData->cmHalState->pfnAllocateBuffer(cmData->cmHalState, &inParam);
832 }
833 CM_CHK_MOSSTATUS_GOTOFINISH_CMERROR(mosStatus);
834
835 handle = inParam.handle;
836 gfxMem = inParam.gfxAddress;
837
838 finish:
839 return hr;
840 }
841
842 //*-----------------------------------------------------------------------------
843 //| Purpose: Free buffer
844 //| Returns: Result of the operation.
845 //*-----------------------------------------------------------------------------
FreeBuffer(uint32_t handle)846 int32_t CmSurfaceManagerBase::FreeBuffer( uint32_t handle )
847 {
848 CM_RETURN_CODE hr = CM_SUCCESS;
849
850 PCM_CONTEXT_DATA cmData = (PCM_CONTEXT_DATA)m_device->GetAccelData();
851 CM_CHK_MOSSTATUS_GOTOFINISH_CMERROR(cmData->cmHalState->pfnFreeBuffer(
852 cmData->cmHalState, (uint32_t)handle));
853
854 finish:
855 return hr;
856 }
857
858 //*-----------------------------------------------------------------------------
859 //| Purpose: Create surface 2d up
860 //| Arguments :
861 //| width [in] width of surface 2d up
862 //| height [in] height of surface 2d up
863 //| format [in] format of surface 2d UP
864 //| sysMem [in] Pointer to system memory
865 //| surface [IN/out] Reference to pointer of CmSurface2DUP
866 //|
867 //| Returns: Result of the operation.
868 //*-----------------------------------------------------------------------------
CreateSurface2DUP(uint32_t width,uint32_t height,CM_SURFACE_FORMAT format,void * sysMem,CmSurface2DUPRT * & surface)869 int32_t CmSurfaceManagerBase::CreateSurface2DUP(uint32_t width, uint32_t height,
870 CM_SURFACE_FORMAT format,
871 void* sysMem,
872 CmSurface2DUPRT* &surface)
873 {
874 surface = nullptr;
875 uint32_t index = ValidSurfaceIndexStart();
876
877 if (GetFreeSurfaceIndex(index) != CM_SUCCESS)
878 {
879 return CM_EXCEED_SURFACE_AMOUNT;
880 }
881
882 if( m_2DUPSurfaceCount >= m_max2DUPSurfaceCount )
883 {
884 CM_ASSERTMESSAGE("Error: Exceed the maximum surface 2D UP count.");
885 return CM_EXCEED_SURFACE_AMOUNT;
886 }
887
888 uint32_t handle = 0;
889 int32_t result = AllocateSurface2DUP( width, height, format, sysMem, handle );
890 if( result != CM_SUCCESS )
891 {
892 CM_ASSERTMESSAGE("Error: Falied to allocate surface 2D UP.");
893 return result;
894 }
895
896 CmSurfaceManager * surfaceManager = dynamic_cast<CmSurfaceManager *>(this);
897 CM_CHK_NULL_RETURN_CMERROR(surfaceManager);
898
899 result = CmSurface2DUPRT::Create( index, handle, width, height, format,
900 sysMem, surfaceManager, surface );
901 if( result != CM_SUCCESS )
902 {
903 FreeSurface2DUP( handle );
904 CM_ASSERTMESSAGE("Error: Falied to create CmSurface2DUP.");
905 return result;
906 }
907
908 m_surfaceArray[ index ] = surface;
909 m_2DUPSurfaceCount ++;
910 uint32_t sizeperpixel = 1;
911
912 result = GetFormatSize(format, sizeperpixel);
913 if (result != CM_SUCCESS)
914 {
915 CM_ASSERTMESSAGE("Error: Unsupported surface format.");
916 return result;
917 }
918 m_surfaceSizes[index] = width * height * sizeperpixel;
919
920 return CM_SUCCESS;
921 }
922
923 //*-----------------------------------------------------------------------------
924 //| Purpose: Allocate surface 2d up
925 //| Arguments :
926 //| width [in] width of surface 2d up
927 //| height [in] height of surface 2d up
928 //| format [in] format of surface 2d UP
929 //| sysMem [in] Pointer to system memory
930 //| handle [IN/out] Reference to handle of CmSurface2DUP
931 //|
932 //| Returns: Result of the operation.
933 //*-----------------------------------------------------------------------------
AllocateSurface2DUP(uint32_t width,uint32_t height,CM_SURFACE_FORMAT format,void * sysMem,uint32_t & handle)934 int32_t CmSurfaceManagerBase::AllocateSurface2DUP(uint32_t width, uint32_t height,
935 CM_SURFACE_FORMAT format,
936 void* sysMem, uint32_t & handle)
937 {
938 CM_RETURN_CODE hr = CM_SUCCESS;
939 MOS_STATUS mosStatus = MOS_STATUS_SUCCESS;
940
941 handle = 0;
942 PCM_CONTEXT_DATA cmData = (PCM_CONTEXT_DATA)m_device->GetAccelData();
943
944 CM_HAL_SURFACE2D_UP_PARAM inParam;
945 CmSafeMemSet( &inParam, 0, sizeof( CM_HAL_SURFACE2D_UP_PARAM ) );
946 inParam.width = width;
947 inParam.height = height;
948 inParam.format = format;
949 inParam.data = sysMem;
950
951 mosStatus = cmData->cmHalState->pfnAllocateSurface2DUP(cmData->cmHalState,&inParam);
952 while ( mosStatus == MOS_STATUS_NO_SPACE )
953 {
954 if (!TouchSurfaceInPoolForDestroy())
955 {
956 CM_ASSERTMESSAGE("Error: Failed to flush surface in pool for destroy.");
957 return CM_SURFACE_ALLOCATION_FAILURE;
958 }
959 mosStatus = cmData->cmHalState->pfnAllocateSurface2DUP(cmData->cmHalState,&inParam);
960 }
961 CM_CHK_MOSSTATUS_GOTOFINISH_CMERROR(mosStatus);
962
963 handle = inParam.handle;
964
965 finish:
966 return hr;
967 }
968
969 //*-----------------------------------------------------------------------------
970 //| Purpose: Free surface 2d up
971 //| Returns: Result of the operation.
972 //*-----------------------------------------------------------------------------
FreeSurface2DUP(uint32_t handle)973 int32_t CmSurfaceManagerBase::FreeSurface2DUP( uint32_t handle )
974 {
975 CM_RETURN_CODE hr = CM_SUCCESS;
976
977 PCM_CONTEXT_DATA cmData = (PCM_CONTEXT_DATA)m_device->GetAccelData();
978
979 CM_CHK_MOSSTATUS_GOTOFINISH_CMERROR(cmData->cmHalState->pfnFreeSurface2DUP(
980 cmData->cmHalState, (uint32_t)handle));
981
982 finish:
983 return hr;
984 }
985
986 //*-----------------------------------------------------------------------------
987 //| Purpose: Allocate surface 2d
988 //| Arguments :
989 //| width [in] width of surface 2d
990 //| height [in] height of surface 2d
991 //| format [in] format of surface 2d
992 //| handle [in/out] Reference to handle of Surface 2D
993 //| pitch [in/out] Reference to pitch of surface 2d
994 //|
995 //| Returns: Result of the operation.
996 //*-----------------------------------------------------------------------------
AllocateSurface2D(uint32_t width,uint32_t height,CM_SURFACE_FORMAT format,uint32_t & handle,uint32_t & pitch)997 int32_t CmSurfaceManagerBase::AllocateSurface2D(uint32_t width, uint32_t height,
998 CM_SURFACE_FORMAT format,
999 uint32_t & handle,uint32_t & pitch)
1000 {
1001 CM_RETURN_CODE hr = CM_SUCCESS;
1002 MOS_STATUS mosStatus = MOS_STATUS_SUCCESS;
1003 PCM_CONTEXT_DATA cmData = (PCM_CONTEXT_DATA)m_device->GetAccelData();
1004
1005 CM_HAL_SURFACE2D_PARAM inParam;
1006 CmSafeMemSet( &inParam, 0, sizeof( CM_HAL_SURFACE2D_PARAM ) );
1007 inParam.width = width;
1008 inParam.height = height;
1009 inParam.format = format;
1010 inParam.data = nullptr;
1011 inParam.isAllocatedbyCmrtUmd = true;
1012
1013 mosStatus = cmData->cmHalState->pfnAllocateSurface2D(cmData->cmHalState,&inParam);
1014 while (mosStatus == MOS_STATUS_NO_SPACE)
1015 {
1016 if (!TouchSurfaceInPoolForDestroy())
1017 {
1018 CM_ASSERTMESSAGE("Error: Failed to flush surface in pool for destroy.");
1019 return CM_SURFACE_ALLOCATION_FAILURE;
1020 }
1021 mosStatus = cmData->cmHalState->pfnAllocateSurface2D(cmData->cmHalState,&inParam);
1022 }
1023 CM_CHK_MOSSTATUS_GOTOFINISH_CMERROR(mosStatus);
1024
1025 handle = inParam.handle;
1026
1027 //Get pitch size for 2D surface
1028 CM_CHK_MOSSTATUS_GOTOFINISH_CMERROR(cmData->cmHalState->pfnGetSurface2DTileYPitch(
1029 cmData->cmHalState, &inParam));
1030
1031 pitch = inParam.pitch;
1032
1033 finish:
1034 return hr;
1035 }
1036
1037 //*-----------------------------------------------------------------------------
1038 //| Purpose: Create surface 2d
1039 //| Arguments :
1040 //| width [in] width of surface 2d
1041 //| height [in] height of surface 2d
1042 //| format [in] format of surface 2d
1043 //| mosResource [in] pointer to mos resource
1044 //| handle [in/out] Reference to handle of Surface 2D
1045 //| pitch [in/out] Reference to pitch of surface 2d
1046 //|
1047 //| Returns: Result of the operation.
1048 //*-----------------------------------------------------------------------------
AllocateSurface2D(uint32_t width,uint32_t height,CM_SURFACE_FORMAT format,MOS_RESOURCE * mosResource,uint32_t & handle)1049 int32_t CmSurfaceManagerBase::AllocateSurface2D( uint32_t width, uint32_t height,
1050 CM_SURFACE_FORMAT format,
1051 MOS_RESOURCE * mosResource,
1052 uint32_t &handle)
1053 {
1054 CM_RETURN_CODE hr = CM_SUCCESS;
1055 MOS_STATUS mosStatus = MOS_STATUS_SUCCESS;
1056
1057 PCM_CONTEXT_DATA cmData = (PCM_CONTEXT_DATA)m_device->GetAccelData();
1058
1059 CM_HAL_SURFACE2D_PARAM inParam;
1060 CmSafeMemSet( &inParam, 0, sizeof( CM_HAL_SURFACE2D_PARAM ) );
1061 inParam.width = width;
1062 inParam.height = height;
1063 inParam.format = format;
1064 inParam.mosResource = mosResource;
1065 inParam.isAllocatedbyCmrtUmd = false;
1066
1067 mosStatus = cmData->cmHalState->pfnAllocateSurface2D(cmData->cmHalState,&inParam);
1068 while (mosStatus == MOS_STATUS_NO_SPACE)
1069 {
1070 if (!TouchSurfaceInPoolForDestroy())
1071 {
1072 CM_ASSERTMESSAGE("Error: Failed to flush surface in pool for destroy.");
1073 return CM_SURFACE_ALLOCATION_FAILURE;
1074 }
1075 mosStatus = cmData->cmHalState->pfnAllocateSurface2D(cmData->cmHalState,&inParam);
1076 }
1077 CM_CHK_MOSSTATUS_GOTOFINISH_CMERROR(mosStatus);
1078
1079 handle = inParam.handle;
1080
1081 finish:
1082 return hr;
1083 }
1084
1085 //*-----------------------------------------------------------------------------
1086 //| Purpose: Free surface 2D
1087 //| Returns: Result of the operation.
1088 //*-----------------------------------------------------------------------------
FreeSurface2D(uint32_t handle)1089 int32_t CmSurfaceManagerBase::FreeSurface2D( uint32_t handle )
1090 {
1091 CM_RETURN_CODE hr = CM_SUCCESS;
1092
1093 PCM_CONTEXT_DATA cmData = (PCM_CONTEXT_DATA)m_device->GetAccelData();
1094 CM_CHK_MOSSTATUS_GOTOFINISH_CMERROR(cmData->cmHalState->pfnFreeSurface2D(cmData->cmHalState, handle));
1095
1096 finish:
1097 return hr;
1098 }
1099
1100 //*-----------------------------------------------------------------------------
1101 //| Purpose: Create Sampler8x8 surface
1102 //| Returns: Result of the operation.
1103 //*-----------------------------------------------------------------------------
CreateSampler8x8Surface(CmSurface2DRT * currentSurface,SurfaceIndex * & sampler8x8SurfaceIndex,CM_SAMPLER8x8_SURFACE sampler8x8Type,CM_SURFACE_ADDRESS_CONTROL_MODE addressControl,CM_FLAG * flag)1104 int32_t CmSurfaceManagerBase::CreateSampler8x8Surface(CmSurface2DRT* currentSurface,
1105 SurfaceIndex* & sampler8x8SurfaceIndex,
1106 CM_SAMPLER8x8_SURFACE sampler8x8Type,
1107 CM_SURFACE_ADDRESS_CONTROL_MODE addressControl,
1108 CM_FLAG* flag)
1109 {
1110 uint32_t index = ValidSurfaceIndexStart();
1111 CmSurfaceSampler8x8* cmSurfaceSampler8x8 = nullptr;
1112 SurfaceIndex * surfCurrent = nullptr;
1113 uint32_t cmIndex = 0xFFFFFFFF;
1114
1115 if (AllocateSurfaceIndex(0, 0, 0, CM_SURFACE_FORMAT_INVALID, index, nullptr) != CM_SUCCESS)
1116 {
1117 return CM_EXCEED_SURFACE_AMOUNT;
1118 }
1119
1120 uint32_t indexFor2D = 0xFFFFFFFF;
1121 currentSurface->GetIndexFor2D( indexFor2D );
1122 currentSurface->GetIndex(surfCurrent);
1123 cmIndex = surfCurrent->get_data();
1124
1125 CmSurfaceManager * surfaceManager = dynamic_cast<CmSurfaceManager *>(this);
1126 CM_CHK_NULL_RETURN_CMERROR(surfaceManager);
1127
1128 int32_t result = CmSurfaceSampler8x8::Create( index, indexFor2D, cmIndex,
1129 surfaceManager, cmSurfaceSampler8x8,
1130 sampler8x8Type, addressControl, flag);
1131 if ( result != CM_SUCCESS )
1132 {
1133 CM_ASSERTMESSAGE("Error: Falied to create sampler8x8 surface.");
1134 return result;
1135 }
1136
1137 if(cmSurfaceSampler8x8)
1138 {
1139 m_surfaceArray[ index ] = cmSurfaceSampler8x8;
1140 cmSurfaceSampler8x8->GetIndex( sampler8x8SurfaceIndex );
1141 return CM_SUCCESS;
1142 }
1143 else
1144 {
1145 return CM_OUT_OF_HOST_MEMORY;
1146 }
1147 }
1148
CreateSampler8x8SurfaceFromAlias(CmSurface2DRT * originalSurface,SurfaceIndex * aliasIndex,CM_SURFACE_ADDRESS_CONTROL_MODE addressControl,SurfaceIndex * & sampler8x8SurfaceIndex)1149 int32_t CmSurfaceManagerBase::CreateSampler8x8SurfaceFromAlias(
1150 CmSurface2DRT *originalSurface,
1151 SurfaceIndex *aliasIndex,
1152 CM_SURFACE_ADDRESS_CONTROL_MODE addressControl,
1153 SurfaceIndex* &sampler8x8SurfaceIndex)
1154 {
1155 uint32_t surface_index_value = ValidSurfaceIndexStart();
1156 if (CM_SUCCESS != AllocateSurfaceIndex(0, 0, 0, CM_SURFACE_FORMAT_INVALID,
1157 surface_index_value, nullptr))
1158 {
1159 return CM_EXCEED_SURFACE_AMOUNT;
1160 }
1161
1162 uint32_t original_surface_handle = 0;
1163 originalSurface->GetIndexFor2D(original_surface_handle);
1164 CmSurfaceSampler8x8 *sampler8x8_surface = nullptr;
1165
1166 CmSurfaceManager * surfaceManager = dynamic_cast<CmSurfaceManager *>(this);
1167 CM_CHK_NULL_RETURN_CMERROR(surfaceManager);
1168
1169 int32_t result = CmSurfaceSampler8x8::Create(surface_index_value,
1170 original_surface_handle,
1171 aliasIndex->get_data(), surfaceManager,
1172 sampler8x8_surface,
1173 CM_AVS_SURFACE, addressControl,
1174 nullptr);
1175 if ( result != CM_SUCCESS )
1176 {
1177 CM_ASSERTMESSAGE("Error: Falied to create sampler8x8 surface.");
1178 return result;
1179 }
1180 m_surfaceArray[surface_index_value] = sampler8x8_surface;
1181 sampler8x8_surface->GetIndex(sampler8x8SurfaceIndex);
1182 return CM_SUCCESS;
1183 }
1184
1185 //*-----------------------------------------------------------------------------
1186 //| Purpose: Destroy Sampler8x8 surface
1187 //| Returns: Result of the operation.
1188 //*-----------------------------------------------------------------------------
DestroySampler8x8Surface(SurfaceIndex * & sampler8x8SurfaceIndex)1189 int32_t CmSurfaceManagerBase::DestroySampler8x8Surface(SurfaceIndex* & sampler8x8SurfaceIndex )
1190 {
1191 if(!sampler8x8SurfaceIndex) {
1192 return CM_FAILURE;
1193 }
1194
1195 uint32_t index = sampler8x8SurfaceIndex->get_data();
1196 CmSurface* surface = m_surfaceArray[ index ];
1197 CmSurfaceSampler8x8* surfSampler8x8 = nullptr;
1198 if (surface && ( surface->Type() == CM_ENUM_CLASS_TYPE_CMSURFACESAMPLER8X8 ))
1199 {
1200 surfSampler8x8 = static_cast< CmSurfaceSampler8x8* >( surface );
1201 }
1202
1203 if(surfSampler8x8)
1204 {
1205 int32_t result = DestroySurface( surfSampler8x8 );
1206 if( result == CM_SUCCESS )
1207 {
1208 sampler8x8SurfaceIndex = nullptr;
1209 return CM_SUCCESS;
1210 }
1211 else
1212 {
1213 return CM_FAILURE;
1214 }
1215 }
1216 else
1217 {
1218 return CM_FAILURE;
1219 }
1220 }
1221
1222 //*-----------------------------------------------------------------------------
1223 //| Purpose: Create Sampler8x8 surface
1224 //| Returns: Result of the operation.
1225 //*-----------------------------------------------------------------------------
DestroySurface(CmSurfaceSampler8x8 * & sampler8x8Surface)1226 int32_t CmSurfaceManagerBase::DestroySurface( CmSurfaceSampler8x8* & sampler8x8Surface )
1227 {
1228 if( !sampler8x8Surface )
1229 {
1230 return CM_FAILURE;
1231 }
1232
1233 SurfaceIndex* index = nullptr;
1234 sampler8x8Surface->GetIndex( index );
1235 CM_ASSERT( index );
1236 uint32_t indexData = index->get_data();
1237
1238 CM_ASSERT( m_surfaceArray[ indexData ] == sampler8x8Surface );
1239
1240 UpdateStateForRealDestroy(indexData, CM_ENUM_CLASS_TYPE_CMSURFACESAMPLER8X8);
1241
1242 CmSurface* surface = sampler8x8Surface;
1243 CmSurface::Destroy( surface ) ;
1244 return CM_SUCCESS;
1245 }
1246
1247 //*-----------------------------------------------------------------------------
1248 //| Purpose: Destroy Vme surface
1249 //| Returns: Result of the operation.
1250 //*-----------------------------------------------------------------------------
DestroyVmeSurface(SurfaceIndex * & vmeSurfaceIndex)1251 int32_t CmSurfaceManagerBase::DestroyVmeSurface( SurfaceIndex* & vmeSurfaceIndex )
1252 {
1253 if( !vmeSurfaceIndex )
1254 {
1255 return CM_INVALID_ARG_VALUE;
1256 }
1257
1258 uint32_t index = vmeSurfaceIndex->get_data();
1259
1260 CmSurface* surface = m_surfaceArray[ index ];
1261 CmSurfaceVme* surfVme = nullptr;
1262 if (surface && ( surface->Type() == CM_ENUM_CLASS_TYPE_CMSURFACEVME ))
1263 {
1264 surfVme = static_cast< CmSurfaceVme* >( surface );
1265 }
1266
1267 if( surfVme )
1268 {
1269 int32_t result = DestroySurface( surfVme);
1270 if( result == CM_SUCCESS )
1271 {
1272 vmeSurfaceIndex = nullptr;
1273 }
1274 return result;
1275 }
1276 else
1277 {
1278 return CM_INVALID_ARG_VALUE;
1279 }
1280 }
1281
CreateVmeSurface(CmSurface2DRT * currentSurface,CmSurface2DRT ** forwardSurfaceArray,CmSurface2DRT ** backwardSurfaceArray,const uint32_t surfaceCountForward,const uint32_t surfaceCountBackward,SurfaceIndex * & vmeSurfaceIndex)1282 int32_t CmSurfaceManagerBase::CreateVmeSurface( CmSurface2DRT* currentSurface,
1283 CmSurface2DRT** forwardSurfaceArray,
1284 CmSurface2DRT** backwardSurfaceArray,
1285 const uint32_t surfaceCountForward,
1286 const uint32_t surfaceCountBackward,
1287 SurfaceIndex* & vmeSurfaceIndex )
1288 {
1289 uint32_t index = ValidSurfaceIndexStart();
1290 CmSurfaceVme* cmSurfaceVme = nullptr;
1291
1292 if (AllocateSurfaceIndex(0, 0, 0, CM_SURFACE_FORMAT_INVALID, index, nullptr) != CM_SUCCESS)
1293 {
1294 return CM_EXCEED_SURFACE_AMOUNT;
1295 }
1296
1297 uint32_t indexFor2DCurrent = CM_INVALID_VME_SURFACE;
1298 uint32_t *indexFor2DForward = nullptr;
1299 uint32_t *indexFor2DBackward = nullptr;
1300
1301 uint32_t indexCurrent = CM_INVALID_VME_SURFACE;
1302 uint32_t *indexForward = nullptr;
1303 uint32_t *indexBackward = nullptr;
1304 SurfaceIndex * surfCurrent = nullptr;
1305 SurfaceIndex * surfForward = nullptr;
1306 SurfaceIndex * surfBackward = nullptr;
1307
1308 currentSurface->GetIndexFor2D( indexFor2DCurrent );
1309 currentSurface->GetIndex( surfCurrent );
1310 indexCurrent = surfCurrent->get_data();
1311
1312 if( forwardSurfaceArray )
1313 {
1314
1315 indexFor2DForward = MOS_NewArray(uint32_t, surfaceCountForward);
1316 indexForward = MOS_NewArray(uint32_t, surfaceCountForward);
1317
1318 if (!indexFor2DForward || !indexForward)
1319 {
1320 CM_ASSERTMESSAGE("Error: Out of system memory.");
1321 MosSafeDeleteArray( indexFor2DForward );
1322 MosSafeDeleteArray( indexForward );
1323 return CM_OUT_OF_HOST_MEMORY;
1324 }
1325 for (uint32_t i = 0; i < surfaceCountForward; i++) {
1326 forwardSurfaceArray[i]->GetIndexFor2D( indexFor2DForward[i]);
1327 forwardSurfaceArray[i]->GetIndex(surfForward);
1328 indexForward[i] = surfForward->get_data();
1329 }
1330 }
1331
1332 if( backwardSurfaceArray )
1333 {
1334 indexFor2DBackward = MOS_NewArray(uint32_t, surfaceCountBackward);
1335 indexBackward = MOS_NewArray(uint32_t, surfaceCountBackward);
1336
1337 if (!indexFor2DBackward || !indexBackward )
1338 {
1339 CM_ASSERTMESSAGE("Error: Out of system memory.");
1340 MosSafeDeleteArray( indexFor2DForward );
1341 MosSafeDeleteArray( indexForward );
1342 MosSafeDeleteArray( indexFor2DBackward );
1343 MosSafeDeleteArray( indexBackward );
1344 return CM_OUT_OF_HOST_MEMORY;
1345 }
1346
1347 for (uint32_t i = 0; i < surfaceCountBackward; i++)
1348 {
1349 backwardSurfaceArray[i]->GetIndexFor2D( indexFor2DBackward[i]);
1350 backwardSurfaceArray[i]->GetIndex(surfBackward);
1351 indexBackward[i] = surfBackward->get_data();
1352 }
1353 }
1354
1355 CmSurfaceManager * surfaceManager = dynamic_cast<CmSurfaceManager *>(this);
1356 CM_CHK_NULL_RETURN_CMERROR(surfaceManager);
1357
1358 int32_t result = CmSurfaceVme::Create( index, indexFor2DCurrent, indexFor2DForward,
1359 indexFor2DBackward, indexCurrent,
1360 indexForward, indexBackward,
1361 surfaceCountForward, surfaceCountBackward,
1362 surfaceManager, cmSurfaceVme );
1363 if( result != CM_SUCCESS )
1364 {
1365 CM_ASSERTMESSAGE("Error: Failed to create CmSurfaceVme.");
1366 MosSafeDeleteArray( indexFor2DBackward );
1367 MosSafeDeleteArray( indexBackward );
1368 MosSafeDeleteArray( indexFor2DForward );
1369 MosSafeDeleteArray( indexForward );
1370 return result;
1371 }
1372
1373 m_surfaceArray[ index ] = cmSurfaceVme;
1374 cmSurfaceVme->GetIndex( vmeSurfaceIndex );
1375
1376 return CM_SUCCESS;
1377 }
1378
1379 //*-----------------------------------------------------------------------------
1380 //| Purpose: Destroy CMBuffer in SurfaceManager
1381 //| Returns: Result of the operation.
1382 //*-----------------------------------------------------------------------------
DestroySurface(CmBuffer_RT * & buffer,SURFACE_DESTROY_KIND destroyKind)1383 int32_t CmSurfaceManagerBase::DestroySurface( CmBuffer_RT* & buffer,
1384 SURFACE_DESTROY_KIND destroyKind)
1385 {
1386 uint32_t handle = 0;
1387 void *address = nullptr;
1388 int32_t result = CM_SUCCESS;
1389
1390 SurfaceIndex* index = nullptr;
1391 buffer->GetIndex( index );
1392 CM_ASSERT( index );
1393 uint32_t indexData = index->get_data();
1394 CM_ASSERT( m_surfaceArray[ indexData ] == buffer );
1395
1396 if (destroyKind == FORCE_DESTROY)
1397 {
1398 buffer->WaitForReferenceFree();
1399 }
1400 else
1401 {
1402 //Delayed destroy
1403 bool alreadyInList = m_surfaceArray[indexData]->IsDelayDestroyed();
1404 result = UpdateStateForDelayedDestroy(destroyKind, indexData);
1405 bool delayDestroy = m_surfaceArray[indexData]->IsDelayDestroyed();
1406
1407 if (result != CM_SUCCESS)
1408 {
1409 if (!alreadyInList && delayDestroy)
1410 {
1411 AddToDelayDestroyList(m_surfaceArray[indexData]);
1412 }
1413 return result;
1414 }
1415 }
1416
1417 //Destroy surface
1418 result = buffer->GetHandle( handle );
1419 if( result != CM_SUCCESS )
1420 {
1421 return result;
1422 }
1423
1424 result = FreeBuffer( handle );
1425 if( result != CM_SUCCESS )
1426 {
1427 return result;
1428 }
1429
1430 buffer->GetAddress(address);
1431 if ((buffer->GetBufferType() == CM_BUFFER_SVM) && address && buffer->IsCMRTAllocatedSVMBuffer())
1432 {
1433 MOS_AlignedFreeMemory(address);
1434 }
1435
1436 CmSurface* surface = buffer;
1437 RemoveFromDelayDestroyList(surface); // this function can handle the case if surface not in the list
1438 CmSurface::Destroy( surface ) ;
1439
1440 UpdateStateForRealDestroy(indexData, CM_ENUM_CLASS_TYPE_CMBUFFER_RT);
1441
1442 return CM_SUCCESS;
1443 }
1444
1445 //*-----------------------------------------------------------------------------
1446 //| Purpose: Destroy Surface2d up in SurfaceManager
1447 //| Returns: Result of the operation.
1448 //*-----------------------------------------------------------------------------
DestroySurface(CmSurface2DUPRT * & surface2dUP,SURFACE_DESTROY_KIND destroyKind)1449 int32_t CmSurfaceManagerBase::DestroySurface( CmSurface2DUPRT* & surface2dUP,
1450 SURFACE_DESTROY_KIND destroyKind)
1451 {
1452 uint32_t handle = 0;
1453 int32_t result = CM_SUCCESS;
1454
1455 SurfaceIndex* index = nullptr;
1456 surface2dUP->GetIndex( index );
1457 CM_ASSERT( index );
1458 uint32_t indexData = index->get_data();
1459
1460 CM_ASSERT( m_surfaceArray[ indexData ] == surface2dUP );
1461
1462 if (destroyKind == FORCE_DESTROY)
1463 {
1464 surface2dUP->WaitForReferenceFree();
1465 }
1466 else
1467 {
1468 bool alreadyInList = m_surfaceArray[indexData]->IsDelayDestroyed();
1469 result = UpdateStateForDelayedDestroy(destroyKind, indexData);
1470 bool delayDestroy = m_surfaceArray[indexData]->IsDelayDestroyed();
1471 if (result != CM_SUCCESS)
1472 {
1473 if (!alreadyInList && delayDestroy)
1474 {
1475 AddToDelayDestroyList(m_surfaceArray[indexData]);
1476 }
1477 return result;
1478 }
1479 }
1480
1481 result = surface2dUP->GetHandle( handle );
1482 if( result != CM_SUCCESS )
1483 {
1484 return result;
1485 }
1486
1487 result = FreeSurface2DUP( handle );
1488 if( result != CM_SUCCESS )
1489 {
1490 return result;
1491 }
1492
1493 CmSurface* surface = surface2dUP;
1494 RemoveFromDelayDestroyList(surface); // this function can handle the case if surface not in the list
1495 CmSurface::Destroy( surface ) ;
1496
1497 UpdateStateForRealDestroy(indexData, CM_ENUM_CLASS_TYPE_CMSURFACE2DUP);
1498
1499 return CM_SUCCESS;
1500 }
1501
1502 //*-----------------------------------------------------------------------------
1503 //| Purpose: Destroy surface in SurfaceManager
1504 //| Returns: Result of the operation.
1505 //*-----------------------------------------------------------------------------
DestroySurface(CmSurface2DRT * & surface2d,SURFACE_DESTROY_KIND destroyKind)1506 int32_t CmSurfaceManagerBase::DestroySurface( CmSurface2DRT* & surface2d,
1507 SURFACE_DESTROY_KIND destroyKind)
1508 {
1509 uint32_t handle = 0;
1510 SurfaceIndex* index = nullptr;
1511 surface2d->GetIndex( index );
1512 CM_ASSERT( index );
1513 uint32_t indexData = index->get_data();
1514 int32_t result = CM_SUCCESS;
1515
1516 CM_ASSERT( m_surfaceArray[ indexData ] == surface2d );
1517
1518 if (destroyKind == FORCE_DESTROY )
1519 {
1520 //For none-cm created surface, no caching, sync is required instead.
1521 surface2d->WaitForReferenceFree();
1522 }
1523 else
1524 {
1525 bool alreadyInList = m_surfaceArray[indexData]->IsDelayDestroyed();
1526 result = UpdateStateForDelayedDestroy(destroyKind, indexData);
1527 bool delayDestroy = m_surfaceArray[indexData]->IsDelayDestroyed();
1528
1529 if (result != CM_SUCCESS)
1530 {
1531 if (!alreadyInList && delayDestroy)
1532 {
1533 AddToDelayDestroyList(m_surfaceArray[indexData]);
1534 }
1535 return result;
1536 }
1537 }
1538
1539 result = surface2d->GetHandle( handle );
1540 if( result != CM_SUCCESS )
1541 {
1542 return result;
1543 }
1544
1545 result = FreeSurface2D( handle );
1546 if( result != CM_SUCCESS )
1547 {
1548 return result;
1549 }
1550
1551 CmSurface* surface = surface2d;
1552 RemoveFromDelayDestroyList(surface); // this function can handle the case if surface not in the list
1553 CmSurface::Destroy( surface ) ;
1554
1555 UpdateStateForRealDestroy(indexData, CM_ENUM_CLASS_TYPE_CMSURFACE2D);
1556
1557 return CM_SUCCESS;
1558 }
1559
1560 //*-----------------------------------------------------------------------------
1561 //| Purpose: Destroy surface vme in SurfaceManager
1562 //| Returns: Result of the operation.
1563 //*-----------------------------------------------------------------------------
DestroySurface(CmSurfaceVme * & vmeSurface)1564 int32_t CmSurfaceManagerBase::DestroySurface( CmSurfaceVme* & vmeSurface )
1565 {
1566 if( !vmeSurface )
1567 {
1568 return CM_FAILURE;
1569 }
1570
1571 SurfaceIndex* index = nullptr;
1572 vmeSurface->GetIndex( index );
1573 CM_ASSERT( index );
1574
1575 uint32_t indexData = index->get_data();
1576 CM_ASSERT( m_surfaceArray[ indexData ] == vmeSurface );
1577
1578 UpdateStateForRealDestroy(indexData, CM_ENUM_CLASS_TYPE_CMSURFACEVME);
1579
1580 CmSurface* surface = vmeSurface;
1581 CmSurface::Destroy( surface ) ;
1582
1583 return CM_SUCCESS;
1584 }
1585
1586 //*-----------------------------------------------------------------------------
1587 //| Purpose: Get Cm surface pointer
1588 //| Returns: Result of the operation.
1589 //*-----------------------------------------------------------------------------
GetSurface(const uint32_t index,CmSurface * & surface)1590 int32_t CmSurfaceManagerBase::GetSurface( const uint32_t index, CmSurface* & surface )
1591 {
1592 if( index == CM_NULL_SURFACE)
1593 {
1594 surface = nullptr;
1595 return CM_FAILURE;
1596 }
1597
1598 if( index < m_surfaceArraySize )
1599 {
1600 surface = m_surfaceArray[ index ];
1601 }
1602 else
1603 {
1604 // check if alias surface
1605 surface = m_surfaceArray[(index % m_surfaceArraySize)];
1606 if (surface->Type() == CM_ENUM_CLASS_TYPE_CMSURFACE2D)
1607 {
1608 CmSurface2DRT* surf2D = nullptr;
1609 uint32_t numAliases = 0;
1610 surf2D = static_cast< CmSurface2DRT* >(surface);
1611 surf2D->GetNumAliases(numAliases);
1612 if (numAliases == 0)
1613 {
1614 // index was out of bounds and not alias surface
1615 surface = nullptr;
1616 return CM_FAILURE;
1617 }
1618 }
1619 else if (surface->Type() == CM_ENUM_CLASS_TYPE_CMBUFFER_RT)
1620 {
1621 CmBuffer_RT* bufferRT = nullptr;
1622 uint32_t numAliases = 0;
1623 bufferRT = static_cast< CmBuffer_RT* >(surface);
1624 bufferRT->GetNumAliases(numAliases);
1625 if (numAliases == 0)
1626 {
1627 // index was out of bounds and not alias surface
1628 surface = nullptr;
1629 return CM_FAILURE;
1630 }
1631 }
1632 else
1633 {
1634 surface = nullptr;
1635 return CM_FAILURE;
1636 }
1637 }
1638
1639 return CM_SUCCESS;
1640 }
1641
1642 //*-----------------------------------------------------------------------------
1643 //| Purpose: Get Cm Device pointer
1644 //| Returns: Result of the operation.
1645 //*-----------------------------------------------------------------------------
GetCmDevice(CmDeviceRT * & device)1646 int32_t CmSurfaceManagerBase::GetCmDevice( CmDeviceRT* & device )
1647 {
1648 device = m_device;
1649 return CM_SUCCESS;
1650 }
1651
1652 //*-----------------------------------------------------------------------------
1653 //| Purpose: Get bytes per pixel and height
1654 //| Returns: Result of the operation.
1655 //*-----------------------------------------------------------------------------
GetPixelBytesAndHeight(uint32_t width,uint32_t height,CM_SURFACE_FORMAT format,uint32_t & sizePerPixel,uint32_t & updatedHeight)1656 int32_t CmSurfaceManagerBase::GetPixelBytesAndHeight(uint32_t width, uint32_t height,
1657 CM_SURFACE_FORMAT format,
1658 uint32_t& sizePerPixel,
1659 uint32_t& updatedHeight)
1660 {
1661 UNUSED(width);
1662 updatedHeight = height;
1663 switch( format )
1664 {
1665 case CM_SURFACE_FORMAT_R32G32B32A32F:
1666 sizePerPixel = 16;
1667 break;
1668
1669 case CM_SURFACE_FORMAT_A16B16G16R16:
1670 case CM_SURFACE_FORMAT_A16B16G16R16F:
1671 case CM_SURFACE_FORMAT_Y416:
1672 case CM_SURFACE_FORMAT_D32F_S8X24_UINT:
1673 case CM_SURFACE_FORMAT_R32G8X24_TYPELESS:
1674 sizePerPixel = 8;
1675 break;
1676
1677 case CM_SURFACE_FORMAT_X8R8G8B8:
1678 case CM_SURFACE_FORMAT_A8R8G8B8:
1679 case CM_SURFACE_FORMAT_A8B8G8R8:
1680 case CM_SURFACE_FORMAT_R32F:
1681 case CM_SURFACE_FORMAT_D32F:
1682 case CM_SURFACE_FORMAT_R32_UINT:
1683 case CM_SURFACE_FORMAT_R32_SINT:
1684 case CM_SURFACE_FORMAT_R10G10B10A2:
1685 case CM_SURFACE_FORMAT_AYUV:
1686 case CM_SURFACE_FORMAT_R16G16_UNORM:
1687 case CM_SURFACE_FORMAT_Y410:
1688 case CM_SURFACE_FORMAT_Y216:
1689 case CM_SURFACE_FORMAT_Y210:
1690 case CM_SURFACE_FORMAT_D24_UNORM_S8_UINT:
1691 case CM_SURFACE_FORMAT_R32_TYPELESS:
1692 case CM_SURFACE_FORMAT_R24G8_TYPELESS:
1693 case CM_SURFACE_FORMAT_R16G16_SINT:
1694 sizePerPixel = 4;
1695 break;
1696
1697 case CM_SURFACE_FORMAT_R8G8_SNORM:
1698 case CM_SURFACE_FORMAT_R16_UINT:
1699 case CM_SURFACE_FORMAT_R16_SINT:
1700 case CM_SURFACE_FORMAT_R16_UNORM:
1701 case CM_SURFACE_FORMAT_D16:
1702 case CM_SURFACE_FORMAT_L16:
1703 case CM_SURFACE_FORMAT_R8G8_UNORM:
1704 case CM_SURFACE_FORMAT_UYVY:
1705 case CM_SURFACE_FORMAT_VYUY:
1706 case CM_SURFACE_FORMAT_YUY2:
1707 case CM_SURFACE_FORMAT_Y16_SNORM:
1708 case CM_SURFACE_FORMAT_Y16_UNORM:
1709 case CM_SURFACE_FORMAT_IRW0:
1710 case CM_SURFACE_FORMAT_IRW1:
1711 case CM_SURFACE_FORMAT_IRW2:
1712 case CM_SURFACE_FORMAT_IRW3:
1713 case CM_SURFACE_FORMAT_R16_FLOAT:
1714 case CM_SURFACE_FORMAT_V8U8:
1715 case CM_SURFACE_FORMAT_A8P8:
1716 case CM_SURFACE_FORMAT_R16_TYPELESS:
1717 sizePerPixel = 2;
1718 break;
1719
1720 case CM_SURFACE_FORMAT_P016:
1721 case CM_SURFACE_FORMAT_P010:
1722 sizePerPixel = 2;
1723 updatedHeight += updatedHeight/2;
1724 break;
1725
1726 case CM_SURFACE_FORMAT_A8:
1727 case CM_SURFACE_FORMAT_P8:
1728 case CM_SURFACE_FORMAT_R8_UINT:
1729 case CM_SURFACE_FORMAT_Y8_UNORM:
1730 case CM_SURFACE_FORMAT_L8:
1731 case CM_SURFACE_FORMAT_IA44:
1732 case CM_SURFACE_FORMAT_AI44:
1733 case CM_SURFACE_FORMAT_400P:
1734 case CM_SURFACE_FORMAT_BUFFER_2D:
1735 case CM_SURFACE_FORMAT_R8_UNORM:
1736 sizePerPixel = 1;
1737 break;
1738
1739 case CM_SURFACE_FORMAT_NV12: //NV12
1740 sizePerPixel = 1;
1741 //To support NV12 format with odd height here.
1742 //if original height is even, the UV plane's height is set as updatedHeight/2, which equals to (updatedHeight+1)/2
1743 //if original height is odd, the UV plane's height is set as roundup(updatedHeight/2), which equals to (updatedHeight+1)/2 too
1744 updatedHeight += (updatedHeight + 1) / 2;
1745 break;
1746
1747 // 4:1:1 (12-bits per pixel) // 4:2:2 (16-bits per pixel)
1748 // 411P // 422H
1749 // -----------------> // ----------------->
1750 // ________________________ // ________________________
1751 //|Y0|Y1| | //|Y0|Y1| |
1752 //|__|__| | //|__|__| |
1753 //| | //| |
1754 //| | //| |
1755 //| | //| |
1756 //| | //| |
1757 //| | //| |
1758 //|________________________| //|________________________|
1759 //|U0|U1|| | //|U0|U1| | |
1760 //|__|__|| | //|__|__| | |
1761 //| | | //| | |
1762 //| | PAD | //| | PAD |
1763 //| | | //| | |
1764 //| | | //| | |
1765 //| | | //| | |
1766 //|______|_________________| //|____________|___________|
1767 //|V0|V1|| | //|V0|V1| | |
1768 //|__|__|| | //|__|__| | |
1769 //| | | //| | |
1770 //| | PAD | //| | PAD |
1771 //| | | //| | |
1772 //| | | //| | |
1773 //| | | //| | |
1774 //|______|_________________| //|____________|___________|
1775
1776 // 4:4:4 (24-bits per pixel)
1777 // 444P
1778 // ----------------->
1779 // ________________________
1780 //|Y0|Y1| |
1781 //|__|__| |
1782 //| |
1783 //| |
1784 //| |
1785 //| |
1786 //| |
1787 //|________________________|
1788 //|U0|U1| |
1789 //|__|__| |
1790 //| |
1791 //| |
1792 //| |
1793 //| |
1794 //| |
1795 //|________________________|
1796 //|V0|V1| |
1797 //|__|__| |
1798 //| |
1799 //| |
1800 //| |
1801 //| |
1802 //| |
1803 //|________________________|
1804
1805 case CM_SURFACE_FORMAT_411P:
1806 case CM_SURFACE_FORMAT_422H:
1807 case CM_SURFACE_FORMAT_444P:
1808 case CM_SURFACE_FORMAT_RGBP:
1809 case CM_SURFACE_FORMAT_BGRP:
1810 sizePerPixel = 1;
1811 updatedHeight = height * 3;
1812 break;
1813
1814 // 4:2:0 (12-bits per pixel)
1815 // IMC1 // IMC3
1816 // -----------------> // ----------------->
1817 // ________________________ // ________________________
1818 //|Y0|Y1| | //|Y0|Y1| |
1819 //|__|__| | //|__|__| |
1820 //| | //| |
1821 //| | //| |
1822 //| | //| |
1823 //| | //| |
1824 //| | //| |
1825 //|________________________| //|________________________|
1826 //|V0|V1| | | //|U0|U1| | |
1827 //|__|__| | | //|__|__| | |
1828 //| | | //| | |
1829 //|____________| PAD | //|____________| PAD |
1830 //|U0|U1| | | //|V0|V1| | |
1831 //|__|__| | | //|__|__| | |
1832 //| | | //| | |
1833 //|____________|___________| //|____________|___________|
1834 case CM_SURFACE_FORMAT_IMC3:
1835 sizePerPixel = 1;
1836 updatedHeight = height * 2;
1837 break;
1838
1839 // 4:2:2V (16-bits per pixel)
1840 // 422V
1841 // ----------------->
1842 // ________________________
1843 //|Y0|Y1| |
1844 //|__|__| |
1845 //| |
1846 //| |
1847 //| |
1848 //| |
1849 //| |
1850 //|________________________|
1851 //|U0|U1| |
1852 //|__|__| |
1853 //| |
1854 //|________________________|
1855 //|V0|V1| |
1856 //|__|__| |
1857 //| |
1858 //|________________________|
1859 case CM_SURFACE_FORMAT_422V:
1860 sizePerPixel = 1;
1861 updatedHeight = height * 2;
1862 break;
1863 case CM_SURFACE_FORMAT_P208:
1864 sizePerPixel = 1;
1865 updatedHeight = height * 2;
1866 break;
1867 case CM_SURFACE_FORMAT_YV12:
1868 case CM_SURFACE_FORMAT_411R://411R
1869 case CM_SURFACE_FORMAT_I420: //I420
1870 sizePerPixel = 1;
1871 updatedHeight += updatedHeight/2;
1872 break;
1873
1874 default:
1875 CM_ASSERTMESSAGE("Error: Unsupported surface format.");
1876 return CM_SURFACE_FORMAT_NOT_SUPPORTED;
1877 }
1878
1879 return CM_SUCCESS;
1880 }
1881
1882 //*-----------------------------------------------------------------------------
1883 //| Purpose: Create Surface 3D
1884 //| Returns: Result of the operation.
1885 //*-----------------------------------------------------------------------------
CreateSurface3D(uint32_t width,uint32_t height,uint32_t depth,CM_SURFACE_FORMAT format,CmSurface3DRT * & surface3d)1886 int32_t CmSurfaceManagerBase::CreateSurface3D(uint32_t width, uint32_t height, uint32_t depth, CM_SURFACE_FORMAT format, CmSurface3DRT* & surface3d )
1887 {
1888 switch( format )
1889 {
1890 case CM_SURFACE_FORMAT_X8R8G8B8:
1891 case CM_SURFACE_FORMAT_A8R8G8B8:
1892 case CM_SURFACE_FORMAT_A16B16G16R16:
1893 break;
1894 default:
1895 CM_ASSERTMESSAGE("Error: Unsupported surface format.");
1896 return CM_SURFACE_FORMAT_NOT_SUPPORTED;
1897 }
1898
1899 uint32_t size = 0;
1900 uint32_t sizeperpixel = 1;
1901
1902 uint32_t index = ValidSurfaceIndexStart();
1903 int32_t result = 0;
1904 result = GetFormatSize(format, sizeperpixel);
1905 if (result != CM_SUCCESS)
1906 {
1907 CM_ASSERTMESSAGE("Error: Faied to get correct surface info.");
1908 return result;
1909 }
1910 size = width * height * depth * sizeperpixel;
1911 surface3d = nullptr;
1912
1913 if (AllocateSurfaceIndex(width, height, depth, format, index, nullptr) != CM_SUCCESS)
1914 {
1915 return CM_EXCEED_SURFACE_AMOUNT;
1916 }
1917
1918 if( m_3DSurfaceCount >= m_max3DSurfaceCount )
1919 {
1920 CM_ASSERTMESSAGE("Error: Exceed the maximum surface 3d count.");
1921 return CM_EXCEED_SURFACE_AMOUNT;
1922 }
1923
1924 uint32_t handle = 0;
1925
1926 result = Allocate3DSurface( width, height, depth, format, handle );
1927 if( result != CM_SUCCESS )
1928 {
1929 CM_ASSERTMESSAGE("Error: Failed to allocate surface 3d.");
1930 return result;
1931 }
1932
1933 CmSurfaceManager * surfaceManager = dynamic_cast<CmSurfaceManager *>(this);
1934 CM_CHK_NULL_RETURN_CMERROR(surfaceManager);
1935
1936 result = CmSurface3DRT::Create( index, handle, width, height, depth, format,
1937 surfaceManager, surface3d );
1938 if( result != CM_SUCCESS )
1939 {
1940 Free3DSurface( handle );
1941 CM_ASSERTMESSAGE("Error: Failed to create CM surface 3d.");
1942 return result;
1943 }
1944
1945 m_surfaceArray[ index ] = surface3d;
1946
1947 result = UpdateProfileFor3DSurface(index, width, height, depth, format);
1948 if (result != CM_SUCCESS)
1949 {
1950 Free3DSurface(handle);
1951 CM_ASSERTMESSAGE("Error: Failed to update profile for surface 3d.");
1952 return result;
1953 }
1954
1955 return CM_SUCCESS;
1956 }
1957
1958 //*-----------------------------------------------------------------------------
1959 //| Purpose: Destory Surface 3D
1960 //| Returns: Result of the operation.
1961 //*-----------------------------------------------------------------------------
DestroySurface(CmSurface3DRT * & surface3d,SURFACE_DESTROY_KIND destroyKind)1962 int32_t CmSurfaceManagerBase::DestroySurface( CmSurface3DRT* & surface3d,
1963 SURFACE_DESTROY_KIND destroyKind)
1964 {
1965 uint32_t handle = 0;
1966 SurfaceIndex* index = nullptr;
1967 surface3d->GetIndex( index );
1968 CM_ASSERT( index );
1969 uint32_t indexData = index->get_data();
1970 int32_t result = CM_SUCCESS;
1971
1972 CM_ASSERT( m_surfaceArray[ indexData ] == surface3d );
1973
1974 if (destroyKind == FORCE_DESTROY)
1975 {
1976 surface3d->WaitForReferenceFree();
1977 }
1978 else
1979 {
1980 bool alreadyInList = m_surfaceArray[indexData]->IsDelayDestroyed();
1981 result = UpdateStateForDelayedDestroy(destroyKind, indexData);
1982 bool delayDestroy = m_surfaceArray[indexData]->IsDelayDestroyed();
1983
1984 if (result != CM_SUCCESS)
1985 {
1986 if (!alreadyInList && delayDestroy)
1987 {
1988 AddToDelayDestroyList(m_surfaceArray[indexData]);
1989 }
1990 return result;
1991 }
1992 }
1993
1994 result = surface3d->GetHandle( handle );
1995 if( result != CM_SUCCESS )
1996 {
1997 return result;
1998 }
1999
2000 result = Free3DSurface( handle );
2001 if( result != CM_SUCCESS )
2002 {
2003 return result;
2004 }
2005
2006 CmSurface* surface = surface3d;
2007 RemoveFromDelayDestroyList(surface); // this function can handle the case if surface not in the list
2008 CmSurface::Destroy( surface ) ;
2009
2010 UpdateStateForRealDestroy(indexData, CM_ENUM_CLASS_TYPE_CMSURFACE3D);
2011
2012 return CM_SUCCESS;
2013 }
2014
2015 //*-----------------------------------------------------------------------------
2016 //| Purpose: Allocate 3D surface
2017 //| Returns: Result of the operation.
2018 //*-----------------------------------------------------------------------------
Allocate3DSurface(uint32_t width,uint32_t height,uint32_t depth,CM_SURFACE_FORMAT format,uint32_t & handle)2019 int32_t CmSurfaceManagerBase::Allocate3DSurface(uint32_t width, uint32_t height,
2020 uint32_t depth, CM_SURFACE_FORMAT format,
2021 uint32_t & handle )
2022 {
2023 CM_RETURN_CODE hr = CM_SUCCESS;
2024 MOS_STATUS mosStatus = MOS_STATUS_SUCCESS;
2025
2026 handle = 0;
2027
2028 CM_HAL_3DRESOURCE_PARAM inParam;
2029 CmSafeMemSet( &inParam, 0, sizeof( CM_HAL_3DRESOURCE_PARAM ) );
2030 inParam.width = width;
2031 inParam.height = height;
2032 inParam.depth = depth;
2033 inParam.format = format;
2034
2035 PCM_CONTEXT_DATA cmData = (PCM_CONTEXT_DATA)m_device->GetAccelData();
2036
2037 mosStatus = cmData->cmHalState->pfnAllocate3DResource(cmData->cmHalState,&inParam);
2038 while (mosStatus == MOS_STATUS_NO_SPACE)
2039 {
2040 if (!TouchSurfaceInPoolForDestroy())
2041 {
2042 CM_ASSERTMESSAGE("Error: Failed to flush surface in pool for destroy.");
2043 return CM_SURFACE_ALLOCATION_FAILURE;
2044 }
2045 mosStatus = cmData->cmHalState->pfnAllocate3DResource(cmData->cmHalState,&inParam);
2046 }
2047 CM_CHK_MOSSTATUS_GOTOFINISH_CMERROR(mosStatus);
2048
2049 handle = inParam.handle;
2050
2051 finish:
2052 return hr;
2053 }
2054
2055 //*-----------------------------------------------------------------------------
2056 //| Purpose: Free 3D surface
2057 //| Returns: Result of the operation.
2058 //*-----------------------------------------------------------------------------
Free3DSurface(uint32_t handle)2059 int32_t CmSurfaceManagerBase::Free3DSurface( uint32_t handle )
2060 {
2061 CM_RETURN_CODE hr = CM_SUCCESS;
2062
2063 PCM_CONTEXT_DATA cmData = (PCM_CONTEXT_DATA)m_device->GetAccelData();
2064
2065 CM_CHK_MOSSTATUS_GOTOFINISH_CMERROR(cmData->cmHalState->pfnFree3DResource(cmData->cmHalState,
2066 (uint32_t)handle));
2067
2068 finish:
2069 return hr;
2070 }
2071
CreateSamplerSurface(CmSurface2DRT * currentSurface2d,SurfaceIndex * & samplerSurfaceIndex,CM_FLAG * flag)2072 int32_t CmSurfaceManagerBase::CreateSamplerSurface(CmSurface2DRT* currentSurface2d,
2073 SurfaceIndex* & samplerSurfaceIndex,
2074 CM_FLAG* flag)
2075 {
2076 uint32_t index = ValidSurfaceIndexStart();
2077 CmSurfaceSampler* cmSurfaceSampler = nullptr;
2078 SurfaceIndex * surfCurrent = nullptr;
2079 uint32_t indexForCurrent = 0xFFFFFFFF;
2080
2081 if (AllocateSurfaceIndex(0, 0, 0, CM_SURFACE_FORMAT_INVALID, index, nullptr) != CM_SUCCESS)
2082 {
2083 return CM_EXCEED_SURFACE_AMOUNT;
2084 }
2085
2086 uint32_t indexFor2D = 0xFFFFFFFF;
2087
2088 currentSurface2d->GetIndexFor2D( indexFor2D );
2089 currentSurface2d->GetIndex(surfCurrent);
2090 indexForCurrent = surfCurrent->get_data();
2091
2092 CmSurfaceManager * surfaceManager = dynamic_cast<CmSurfaceManager *>(this);
2093 CM_CHK_NULL_RETURN_CMERROR(surfaceManager);
2094
2095 int32_t result = CmSurfaceSampler::Create( index, indexFor2D, indexForCurrent,
2096 SAMPLER_SURFACE_TYPE_2D,
2097 surfaceManager, cmSurfaceSampler, flag);
2098 if( result != CM_SUCCESS )
2099 {
2100 CM_ASSERTMESSAGE("Error: Failed to create CM sampler surface.");
2101 return result;
2102 }
2103
2104 m_surfaceArray[ index ] = cmSurfaceSampler;
2105 cmSurfaceSampler->GetSurfaceIndex( samplerSurfaceIndex );
2106
2107 return CM_SUCCESS;
2108 }
2109
CreateSamplerSurface(CmSurface2DUPRT * currentSurface2dUP,SurfaceIndex * & samplerSurfaceIndex)2110 int32_t CmSurfaceManagerBase::CreateSamplerSurface(CmSurface2DUPRT* currentSurface2dUP,
2111 SurfaceIndex* & samplerSurfaceIndex)
2112 {
2113 uint32_t index = ValidSurfaceIndexStart();
2114 CmSurfaceSampler* cmSurfaceSampler = nullptr;
2115 SurfaceIndex * surfCurrent = nullptr;
2116 uint32_t indexForCurrent = 0xFFFFFFFF;
2117
2118 if (AllocateSurfaceIndex(0, 0, 0, CM_SURFACE_FORMAT_INVALID, index, nullptr) != CM_SUCCESS)
2119 {
2120 return CM_EXCEED_SURFACE_AMOUNT;
2121 }
2122
2123 uint32_t indexFor2D = 0xFFFFFFFF;
2124
2125 currentSurface2dUP->GetHandle( indexFor2D );
2126 currentSurface2dUP->GetIndex(surfCurrent);
2127 indexForCurrent = surfCurrent->get_data();
2128
2129 CmSurfaceManager * surfaceManager = dynamic_cast<CmSurfaceManager *>(this);
2130 CM_CHK_NULL_RETURN_CMERROR(surfaceManager);
2131
2132 int32_t result = CmSurfaceSampler::Create( index, indexFor2D, indexForCurrent,
2133 SAMPLER_SURFACE_TYPE_2DUP,
2134 surfaceManager, cmSurfaceSampler, nullptr);
2135 if( result != CM_SUCCESS )
2136 {
2137 CM_ASSERTMESSAGE("Error: Failed to create CM sampler surface.");
2138 return result;
2139 }
2140
2141 m_surfaceArray[ index ] = cmSurfaceSampler;
2142 cmSurfaceSampler->GetSurfaceIndex( samplerSurfaceIndex );
2143
2144 return CM_SUCCESS;
2145 }
2146
CreateSamplerSurface(CmSurface3DRT * currentSurface3d,SurfaceIndex * & samplerSurfaceIndex)2147 int32_t CmSurfaceManagerBase::CreateSamplerSurface(CmSurface3DRT* currentSurface3d,
2148 SurfaceIndex* & samplerSurfaceIndex)
2149 {
2150 uint32_t index = ValidSurfaceIndexStart();
2151 CmSurfaceSampler* cmSurfaceSampler = nullptr;
2152 SurfaceIndex * surfCurrent = nullptr;
2153 uint32_t indexForCurrent = 0xFFFFFFFF;
2154
2155 if (AllocateSurfaceIndex(0, 0, 0, CM_SURFACE_FORMAT_INVALID, index, nullptr) != CM_SUCCESS)
2156 {
2157 return CM_EXCEED_SURFACE_AMOUNT;
2158 }
2159
2160 uint32_t handleFor3D = 0xFFFFFFFF;
2161 currentSurface3d->GetHandle( handleFor3D );
2162 currentSurface3d->GetIndex(surfCurrent);
2163 indexForCurrent = surfCurrent->get_data();
2164
2165 CmSurfaceManager * surfaceManager = dynamic_cast<CmSurfaceManager *>(this);
2166 CM_CHK_NULL_RETURN_CMERROR(surfaceManager);
2167
2168 int32_t result = CmSurfaceSampler::Create( index, handleFor3D, indexForCurrent,
2169 SAMPLER_SURFACE_TYPE_3D, surfaceManager,
2170 cmSurfaceSampler, nullptr);
2171 if( result != CM_SUCCESS ) {
2172 CM_ASSERTMESSAGE("Error: Failed to create CM sampler surface.");
2173 return result;
2174 }
2175
2176 m_surfaceArray[ index ] = cmSurfaceSampler;
2177 cmSurfaceSampler->GetSurfaceIndex( samplerSurfaceIndex );
2178
2179 return CM_SUCCESS;
2180 }
2181
DestroySamplerSurface(SurfaceIndex * & samplerSurfaceIndex)2182 int32_t CmSurfaceManagerBase::DestroySamplerSurface(SurfaceIndex* &samplerSurfaceIndex)
2183 {
2184 if(!samplerSurfaceIndex) {
2185 return CM_FAILURE;
2186 }
2187
2188 uint32_t index = samplerSurfaceIndex->get_data();
2189 CmSurface* surface = m_surfaceArray[ index ];
2190
2191 CmSurfaceSampler* surfSampler = nullptr;
2192 if (surface && ( surface->Type() == CM_ENUM_CLASS_TYPE_CMSURFACESAMPLER ))
2193 {
2194 surfSampler = static_cast< CmSurfaceSampler* >( surface );
2195 }
2196
2197 if(surfSampler) {
2198 int32_t result = DestroySurface( surfSampler);
2199 if( result == CM_SUCCESS )
2200 {
2201 samplerSurfaceIndex = nullptr;
2202 return CM_SUCCESS;
2203 }
2204 else
2205 {
2206 return CM_FAILURE;
2207 }
2208 }
2209 else
2210 {
2211 return CM_FAILURE;
2212 }
2213 }
2214
DestroySurface(CmSurfaceSampler * & surfaceSampler)2215 int32_t CmSurfaceManagerBase::DestroySurface( CmSurfaceSampler* & surfaceSampler )
2216 {
2217 if( !surfaceSampler )
2218 {
2219 return CM_FAILURE;
2220 }
2221
2222 SurfaceIndex* index = nullptr;
2223 surfaceSampler->GetSurfaceIndex( index );
2224 CM_ASSERT( index );
2225 uint32_t indexData = index->get_data();
2226
2227 CM_ASSERT( m_surfaceArray[ indexData ] == surfaceSampler );
2228
2229 CmSurface* surface = surfaceSampler;
2230 CmSurface::Destroy( surface ) ;
2231
2232 UpdateStateForRealDestroy(indexData, CM_ENUM_CLASS_TYPE_CMSURFACESAMPLER);
2233
2234 return CM_SUCCESS;
2235 }
2236
GetSurfacePoolSize()2237 uint32_t CmSurfaceManagerBase::GetSurfacePoolSize()
2238 {
2239 return m_surfaceArraySize;
2240 }
2241
UpdateSurface2DTableMosResource(uint32_t index,MOS_RESOURCE * mosResource)2242 int32_t CmSurfaceManagerBase::UpdateSurface2DTableMosResource( uint32_t index,
2243 MOS_RESOURCE * mosResource )
2244 {
2245 PCM_CONTEXT_DATA cmData = ( PCM_CONTEXT_DATA )m_device->GetAccelData();
2246 PCM_HAL_STATE state = cmData->cmHalState;
2247
2248 PCM_HAL_SURFACE2D_ENTRY entry = nullptr;
2249 entry = &state->umdSurf2DTable[ index ];
2250 entry->osResource = *mosResource;
2251 HalCm_OsResource_Reference( &entry->osResource );
2252
2253 for ( int i = 0; i < CM_HAL_GPU_CONTEXT_COUNT; i++ )
2254 {
2255 entry->readSyncs[ i ] = false;
2256 }
2257 return CM_SUCCESS;
2258 }
2259
2260 //*-----------------------------------------------------------------------------
2261 //| Purpose: convert from CM_ROTATION TO MHW_ROTATION
2262 //| Returns: Result of the operation
2263 //*-----------------------------------------------------------------------------
CmRotationToMhwRotation(CM_ROTATION cmRotation)2264 MHW_ROTATION CmRotationToMhwRotation(CM_ROTATION cmRotation)
2265 {
2266 switch (cmRotation)
2267 {
2268 case CM_ROTATION_IDENTITY:
2269 return MHW_ROTATION_IDENTITY;
2270 case CM_ROTATION_90:
2271 return MHW_ROTATION_90;
2272 case CM_ROTATION_180:
2273 return MHW_ROTATION_180;
2274 case CM_ROTATION_270:
2275 return MHW_ROTATION_270;
2276 default:
2277 return MHW_ROTATION_IDENTITY;
2278 }
2279 }
2280
UpdateSurface2DTableRotation(uint32_t index,CM_ROTATION rotationFlag)2281 int32_t CmSurfaceManagerBase::UpdateSurface2DTableRotation(uint32_t index, CM_ROTATION rotationFlag)
2282 {
2283 PCM_CONTEXT_DATA cmData = (PCM_CONTEXT_DATA)m_device->GetAccelData();
2284 PCM_HAL_STATE state = cmData->cmHalState;
2285
2286 PCM_HAL_SURFACE2D_ENTRY entry = nullptr;
2287 entry = &state->umdSurf2DTable[index];
2288 entry->rotationFlag = CmRotationToMhwRotation(rotationFlag);
2289 if(state->advExecutor)
2290 {
2291 state->advExecutor->SetRotationFlag(entry->surfStateMgr, entry->rotationFlag);
2292 }
2293
2294 return CM_SUCCESS;
2295 }
2296
UpdateSurface2DTableFrameType(uint32_t index,CM_FRAME_TYPE frameType)2297 int32_t CmSurfaceManagerBase::UpdateSurface2DTableFrameType(uint32_t index, CM_FRAME_TYPE frameType)
2298 {
2299 PCM_CONTEXT_DATA cmData = (PCM_CONTEXT_DATA)m_device->GetAccelData();
2300 PCM_HAL_STATE state = cmData->cmHalState;
2301
2302 PCM_HAL_SURFACE2D_ENTRY entry = nullptr;
2303 entry = &state->umdSurf2DTable[index];
2304 entry->frameType = frameType;
2305 if(state->advExecutor)
2306 {
2307 state->advExecutor->Set2DFrameType(entry->surfStateMgr, frameType);
2308 }
2309
2310 return CM_SUCCESS;
2311 }
2312
UpdateSurface2DTableChromaSiting(uint32_t index,int32_t chromaSiting)2313 int32_t CmSurfaceManagerBase::UpdateSurface2DTableChromaSiting(uint32_t index, int32_t chromaSiting)
2314 {
2315 PCM_CONTEXT_DATA cmData = (PCM_CONTEXT_DATA)m_device->GetAccelData();
2316 PCM_HAL_STATE state = cmData->cmHalState;
2317 PCM_HAL_SURFACE2D_ENTRY entry = nullptr;
2318 entry = &state->umdSurf2DTable[index];
2319 entry->chromaSiting = chromaSiting;
2320 if(state->advExecutor)
2321 {
2322 state->advExecutor->SetChromaSitting(entry->surfStateMgr, (uint8_t)entry->chromaSiting);
2323 }
2324 return CM_SUCCESS;
2325 }
2326
GetSurfaceBTIInfo()2327 int32_t CmSurfaceManagerBase::GetSurfaceBTIInfo()
2328 {
2329 PCM_HAL_STATE cmHalState;
2330 cmHalState = ((PCM_CONTEXT_DATA)m_device->GetAccelData())->cmHalState;
2331
2332 return cmHalState->cmHalInterface->GetHwSurfaceBTIInfo(&m_surfaceBTIInfo);
2333 }
2334
ValidSurfaceIndexStart()2335 uint32_t CmSurfaceManagerBase::ValidSurfaceIndexStart()
2336 {
2337 return m_surfaceBTIInfo.normalSurfaceStart;
2338 }
2339
MaxIndirectSurfaceCount()2340 uint32_t CmSurfaceManagerBase::MaxIndirectSurfaceCount()
2341 {
2342 return (m_surfaceBTIInfo.normalSurfaceEnd -
2343 m_surfaceBTIInfo.normalSurfaceStart + 1);
2344 }
2345
2346 //*-----------------------------------------------------------------------------
2347 //| Purpose: To check if the surface index is CM reserved or not
2348 //| Returns: Result of the operation.
2349 //*-----------------------------------------------------------------------------
IsCmReservedSurfaceIndex(uint32_t surfaceBTI)2350 bool CmSurfaceManagerBase::IsCmReservedSurfaceIndex(uint32_t surfaceBTI)
2351 {
2352 if(surfaceBTI >= m_surfaceBTIInfo.reservedSurfaceStart &&
2353 surfaceBTI <= m_surfaceBTIInfo.reservedSurfaceEnd)
2354 {
2355 return true;
2356 }
2357 else
2358 {
2359 return false;
2360
2361 }
2362 }
2363
2364 //*-----------------------------------------------------------------------------
2365 //| Purpose: To check if the surface index a normal surface index
2366 //| Returns: Result of the operation.
2367 //*-----------------------------------------------------------------------------
IsValidSurfaceIndex(uint32_t surfaceBTI)2368 bool CmSurfaceManagerBase::IsValidSurfaceIndex(uint32_t surfaceBTI)
2369 {
2370 if(surfaceBTI >= m_surfaceBTIInfo.normalSurfaceStart &&
2371 surfaceBTI <= m_surfaceBTIInfo.normalSurfaceEnd)
2372 {
2373 return true;
2374 }
2375 else
2376 {
2377 return false;
2378
2379 }
2380 }
2381
2382 //*-----------------------------------------------------------------------------
2383 //| Purpose: Destroy CmBuffer of state heap in SurfaceManager
2384 //| Returns: Result of the operation.
2385 //*-----------------------------------------------------------------------------
DestroyStateBuffer(CmStateBuffer * & buffer,SURFACE_DESTROY_KIND destroyKind)2386 int32_t CmSurfaceManagerBase::DestroyStateBuffer( CmStateBuffer *&buffer,
2387 SURFACE_DESTROY_KIND destroyKind )
2388 {
2389 int32_t result = CM_SUCCESS;
2390
2391 if ( !buffer )
2392 {
2393 return CM_FAILURE;
2394 }
2395 SurfaceIndex* index = nullptr;
2396 buffer->GetIndex( index );
2397 CM_ASSERT( index );
2398 uint32_t indexData = index->get_data();
2399 CM_ASSERT( m_surfaceArray[ indexData ] == buffer );
2400
2401 if ( destroyKind == FORCE_DESTROY )
2402 {
2403 buffer->WaitForReferenceFree();
2404 }
2405 else
2406 {
2407 //Delayed destroy
2408 bool alreadyInList = m_surfaceArray[indexData]->IsDelayDestroyed();
2409 result = UpdateStateForDelayedDestroy( destroyKind, indexData );
2410 bool delayDestroy = m_surfaceArray[indexData]->IsDelayDestroyed();
2411
2412 if ( result != CM_SUCCESS )
2413 {
2414 if (!alreadyInList && delayDestroy)
2415 {
2416 AddToDelayDestroyList(m_surfaceArray[indexData]);
2417 }
2418 return result;
2419 }
2420 }
2421
2422 //Destroy surface
2423 CmSurface* surface = buffer;
2424 RemoveFromDelayDestroyList(surface); // this function can handle the case if surface not in the list
2425 CmSurface::Destroy( surface );
2426
2427 UpdateStateForRealDestroy( indexData, CM_ENUM_CLASS_TYPE_CMBUFFER_RT );
2428
2429 return result;
2430 }
2431
DestroyMediaState(void * mediaState)2432 int32_t CMRT_UMD::CmSurfaceManagerBase::DestroyMediaState( void *mediaState )
2433 {
2434 int32_t result = CM_SUCCESS;
2435
2436 return result;
2437 }
2438
IsSupportedForSamplerSurface2D(CM_SURFACE_FORMAT format)2439 bool CMRT_UMD::CmSurfaceManagerBase::IsSupportedForSamplerSurface2D(CM_SURFACE_FORMAT format)
2440 {
2441 switch (format)
2442 {
2443 case CM_SURFACE_FORMAT_A16B16G16R16:
2444 case CM_SURFACE_FORMAT_A16B16G16R16F:
2445 case CM_SURFACE_FORMAT_A8:
2446 case CM_SURFACE_FORMAT_A8R8G8B8:
2447 case CM_SURFACE_FORMAT_A8B8G8R8:
2448 case CM_SURFACE_FORMAT_YUY2:
2449 case CM_SURFACE_FORMAT_R32F:
2450 case CM_SURFACE_FORMAT_R32_UINT:
2451 case CM_SURFACE_FORMAT_L16:
2452 case CM_SURFACE_FORMAT_R16_FLOAT:
2453 case CM_SURFACE_FORMAT_R16G16_UNORM:
2454 case CM_SURFACE_FORMAT_R16_UNORM:
2455 case CM_SURFACE_FORMAT_NV12:
2456 case CM_SURFACE_FORMAT_L8:
2457 case CM_SURFACE_FORMAT_AYUV:
2458 case CM_SURFACE_FORMAT_Y410:
2459 case CM_SURFACE_FORMAT_Y416:
2460 case CM_SURFACE_FORMAT_Y210:
2461 case CM_SURFACE_FORMAT_Y216:
2462 case CM_SURFACE_FORMAT_P010:
2463 case CM_SURFACE_FORMAT_P208:
2464 case CM_SURFACE_FORMAT_P016:
2465 case CM_SURFACE_FORMAT_YV12:
2466 case CM_SURFACE_FORMAT_411P:
2467 case CM_SURFACE_FORMAT_411R:
2468 case CM_SURFACE_FORMAT_IMC3:
2469 case CM_SURFACE_FORMAT_I420:
2470 case CM_SURFACE_FORMAT_422H:
2471 case CM_SURFACE_FORMAT_422V:
2472 case CM_SURFACE_FORMAT_444P:
2473 case CM_SURFACE_FORMAT_RGBP:
2474 case CM_SURFACE_FORMAT_BGRP:
2475 case CM_SURFACE_FORMAT_BUFFER_2D:
2476 case CM_SURFACE_FORMAT_R10G10B10A2:
2477 case CM_SURFACE_FORMAT_R8_UNORM:
2478 case CM_SURFACE_FORMAT_Y8_UNORM:
2479 return true;
2480
2481 default:
2482 CM_ASSERTMESSAGE("Error: Unsupported surface format.");
2483 return false;
2484 }
2485 }
2486
UpdateBuffer(MOS_RESOURCE * mosResource,int index,uint32_t handle)2487 int32_t CmSurfaceManagerBase::UpdateBuffer(MOS_RESOURCE * mosResource, int index, uint32_t handle)
2488 {
2489 PCM_CONTEXT_DATA cmData = (PCM_CONTEXT_DATA)m_device->GetAccelData();
2490 PCM_HAL_STATE state = cmData->cmHalState;
2491
2492 MOS_SURFACE mosSurfDetails;
2493 MOS_ZeroMemory(&mosSurfDetails, sizeof(mosSurfDetails));
2494 int hr = state->osInterface->pfnGetResourceInfo(state->osInterface, mosResource, &mosSurfDetails);
2495 if(hr != MOS_STATUS_SUCCESS)
2496 {
2497 CM_ASSERTMESSAGE("Error: Get resource info failure.");
2498 return hr;
2499 }
2500
2501 uint32_t size = mosSurfDetails.dwWidth;
2502
2503 CM_HAL_BUFFER_PARAM inParam;
2504 CmSafeMemSet( &inParam, 0, sizeof( CM_HAL_BUFFER_PARAM ) );
2505 inParam.size = size;
2506 inParam.handle = handle;
2507
2508 inParam.type = CM_BUFFER_N;
2509 inParam.mosResource = mosResource;
2510 inParam.isAllocatedbyCmrtUmd = false;
2511
2512 state->pfnUpdateBuffer(state, &inParam);
2513
2514 CmBuffer_RT *buffer = static_cast<CmBuffer_RT*>(m_surfaceArray[index]);
2515 int ret = buffer->UpdateProperty(size);
2516
2517 return ret;
2518 }
2519
AddToDelayDestroyList(CmSurface * surface)2520 void CmSurfaceManagerBase::AddToDelayDestroyList(CmSurface *surface)
2521 {
2522 CM_ASSERT(surface->DelayDestroyNext() == nullptr); // not added in any list
2523 CM_ASSERT(surface->DelayDestroyPrev() == nullptr);
2524
2525 m_delayDestoryListSync.Acquire();
2526
2527 // add to the end of the list
2528 if (m_delayDestroyTail == nullptr)
2529 {
2530 CM_ASSERT(m_delayDestroyHead == nullptr);
2531 m_delayDestroyHead = m_delayDestroyTail = surface;
2532 }
2533 else
2534 {
2535 m_delayDestroyTail->DelayDestroyNext() = surface;
2536 surface->DelayDestroyPrev() = m_delayDestroyTail;
2537 m_delayDestroyTail = surface;
2538 }
2539
2540 m_delayDestoryListSync.Release();
2541 }
2542
RemoveFromDelayDestroyList(CmSurface * surface)2543 void CmSurfaceManagerBase::RemoveFromDelayDestroyList(CmSurface *surface)
2544 {
2545 if (surface->DelayDestroyPrev() == nullptr && (m_delayDestroyHead != surface))
2546 {
2547 return; // not in the list
2548 }
2549 if (surface->DelayDestroyNext() == nullptr && (m_delayDestroyTail != surface))
2550 {
2551 return; // not in the list
2552 }
2553 m_delayDestoryListSync.Acquire();
2554 if (surface->DelayDestroyPrev() == nullptr) // remove the first node
2555 {
2556 m_delayDestroyHead = surface->DelayDestroyNext();
2557 }
2558 else
2559 {
2560 surface->DelayDestroyPrev()->DelayDestroyNext() = surface->DelayDestroyNext();
2561 }
2562
2563 if (surface->DelayDestroyNext() == nullptr) // remove the last node
2564 {
2565 m_delayDestroyTail = surface->DelayDestroyPrev();
2566 }
2567 else
2568 {
2569 surface->DelayDestroyNext()->DelayDestroyPrev() = surface->DelayDestroyPrev();
2570 }
2571
2572 surface->DelayDestroyNext() = surface->DelayDestroyPrev() = nullptr;
2573 m_delayDestoryListSync.Release();
2574 }
2575
2576 #if MDF_SURFACE_CONTENT_DUMP
GetHalState()2577 CM_HAL_STATE* CmSurfaceManagerBase::GetHalState() { return m_device->GetHalState(); }
2578 #endif // #if MDF_SURFACE_CONTENT_DUMP
2579
2580
2581 //*-----------------------------------------------------------------------------
2582 //| Purpose: Create surface 2d
2583 //| Arguments :
2584 //| width [in] width of surface 2d
2585 //| height [in] height of surface 2d
2586 //| pitch [in] pitch of surface 2d
2587 //| format [in] format of surface 2d
2588 //| surface [IN/out] Reference to CmSurface2D
2589 //|
2590 //| Returns: Result of the operation.
2591 //| NOTE: It's only called within CMRT@UMD, will not be called by CMRT Thin
2592 //| For 2D surface, since the real memory buffer is not allocated in CMRT@UMD, no reuse/manager can be done
2593 //*-----------------------------------------------------------------------------
CreateSurface2D(uint32_t width,uint32_t height,uint32_t pitch,bool createdByCm,CM_SURFACE_FORMAT format,CmSurface2DRT * & surface)2594 int32_t CmSurfaceManagerBase::CreateSurface2D(uint32_t width, uint32_t height,
2595 uint32_t pitch, bool createdByCm,
2596 CM_SURFACE_FORMAT format,
2597 CmSurface2DRT* &surface)
2598 {
2599 uint32_t handle = 0;
2600 uint32_t index = ValidSurfaceIndexStart();
2601 int32_t result = 0;
2602
2603 surface = nullptr;
2604
2605 result = Surface2DSanityCheck(width, height, format);
2606 if (result != CM_SUCCESS)
2607 {
2608 CM_ASSERTMESSAGE("Error: Surface 2D sanity check failure.");
2609 return result;
2610 }
2611
2612 if (createdByCm)
2613 {
2614 if (AllocateSurfaceIndex(width, height, 0, format, index, nullptr) != CM_SUCCESS)
2615 {
2616 return CM_EXCEED_SURFACE_AMOUNT;
2617 }
2618 }
2619 else
2620 {
2621 if (GetFreeSurfaceIndex(index) != CM_SUCCESS)
2622 {
2623 return CM_EXCEED_SURFACE_AMOUNT;
2624 }
2625 }
2626
2627 if (m_2DSurfaceCount >= m_max2DSurfaceCount)
2628 {
2629 CM_ASSERTMESSAGE("Error: Exceed the maximum surface 2D count.");
2630 return CM_EXCEED_SURFACE_AMOUNT;
2631 }
2632
2633 result = AllocateSurface2D(width, height, format, handle, pitch);
2634 if (result != CM_SUCCESS)
2635 {
2636 CM_ASSERTMESSAGE("Error: Falied to allocate surface.");
2637 return result;
2638 }
2639
2640 CmSurfaceManager * surfaceManager = dynamic_cast<CmSurfaceManager *>(this);
2641 CM_CHK_NULL_RETURN_CMERROR(surfaceManager);
2642
2643 result = CmSurface2DRT::Create(index, handle, width, height, pitch, format,
2644 true, surfaceManager, surface);
2645 if (result != CM_SUCCESS)
2646 {
2647 FreeSurface2D(handle);
2648 CM_ASSERTMESSAGE("Error: Falied to create CmSurface2D.");
2649 return result;
2650 }
2651
2652 m_surfaceArray[index] = surface;
2653
2654 result = UpdateProfileFor2DSurface(index, width, height, format);
2655 if (result != CM_SUCCESS)
2656 {
2657 FreeSurface2D(handle);
2658 CM_ASSERTMESSAGE("Error: Falied to update profile for surface 2D.");
2659 return result;
2660 }
2661 return CM_SUCCESS;
2662 }
2663 }
2664