xref: /aosp_15_r20/external/intel-media-driver/media_driver/agnostic/common/cm/cm_surface_manager_base.cpp (revision ba62d9d3abf0e404f2022b4cd7a85e107f48596f)
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