xref: /aosp_15_r20/external/intel-media-driver/media_driver/agnostic/common/cm/cm_surface_2d_rt_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_2d_rt.cpp
24 //! \brief     Contains OS-agnostic CmSurface2DRTBase member functions
25 //!
26 
27 #include "cm_surface_2d_rt.h"
28 
29 #include "cm_event_rt.h"
30 #include "cm_surface_manager.h"
31 #include "cm_device_rt.h"
32 #include "cm_mem.h"
33 #include "cm_queue_rt.h"
34 #include "cm_wrapper_os.h"
35 
36 #define COPY_OPTION(option)    (option & 0x1)
37 
38 namespace CMRT_UMD
39 {
40 //*-----------------------------------------------------------------------------
41 //| Purpose:    Constructor of CmSurface2DBase
42 //| Returns:    None.
43 //*-----------------------------------------------------------------------------
CmSurface2DRTBase(uint32_t handle,uint32_t width,uint32_t height,uint32_t pitch,CM_SURFACE_FORMAT format,CmSurfaceManager * pSurfaceManager,bool isCmCreated)44 CmSurface2DRTBase::CmSurface2DRTBase(
45     uint32_t handle,
46     uint32_t width,
47     uint32_t height,
48     uint32_t pitch,
49     CM_SURFACE_FORMAT format,
50     CmSurfaceManager* pSurfaceManager,
51     bool isCmCreated) :
52     CmSurface(pSurfaceManager, isCmCreated),
53     m_width(width),
54     m_height(height),
55     m_handle(handle),
56     m_pitch(pitch),
57     m_format(format),
58     m_umdResource(nullptr),
59     m_numAliases(0),
60     m_frameType(CM_FRAME)
61     {
62         CmSurface::SetMemoryObjectControl(MEMORY_OBJECT_CONTROL_UNKNOW, CM_USE_PTE, 0);
63         CmSafeMemSet(m_aliasIndexes, 0, sizeof(SurfaceIndex*) * CM_HAL_MAX_NUM_2D_ALIASES);
64     }
65 
66 //*-----------------------------------------------------------------------------
67 //| Purpose:    Destructor of CmSurface2DRTBase
68 //| Returns:    None.
69 //*-----------------------------------------------------------------------------
~CmSurface2DRTBase(void)70 CmSurface2DRTBase::~CmSurface2DRTBase(void){}
71 
72 //*-----------------------------------------------------------------------------
73 //| Purpose:    Initialize CmSurface2D
74 //| Returns:    Result of the operation.
75 //*-----------------------------------------------------------------------------
Initialize(uint32_t index)76 int32_t CmSurface2DRTBase::Initialize( uint32_t index )
77 {
78     return CmSurface::Initialize( index );
79 }
80 
IsGPUCopy(void * sysMem,uint32_t widthInBytes,uint32_t height,uint32_t horizontalStrideInBytes)81 bool CmSurface2DRTBase::IsGPUCopy(void *sysMem, uint32_t widthInBytes, uint32_t height, uint32_t horizontalStrideInBytes)
82 {
83     return ( (widthInBytes <= CM_MAX_THREADSPACE_WIDTH_FOR_MW*128) && (height <= CM_MAX_THREADSPACE_HEIGHT_FOR_MW*32) && (uintptr_t(sysMem) & 0xF) == 0 && (horizontalStrideInBytes & 0xF) == 0 );
84 }
85 
IsUnalignedGPUCopy(uint32_t widthInBytes,uint32_t height)86 bool CmSurface2DRTBase::IsUnalignedGPUCopy(uint32_t widthInBytes, uint32_t height)
87 {
88     return (widthInBytes <= CM_MAX_THREADSPACE_WIDTH_FOR_MW*64) && (height <= CM_MAX_THREADSPACE_HEIGHT_FOR_MW*8);
89 }
90 
91 
92 //*-----------------------------------------------------------------------------
93 //| Purpose:    Get planar memory layout information details
94 //| Returns:    Result of the operation.
95 //*-----------------------------------------------------------------------------
GetPlanarInfomation(CM_HAL_SURFACE2D_LOCK_UNLOCK_PARAM inParam,uint32_t & sizePerPixel,uint32_t & UVwidth,uint32_t & UVheight,uint32_t & UVpitch,uint32_t & planes)96 int32_t GetPlanarInfomation(CM_HAL_SURFACE2D_LOCK_UNLOCK_PARAM inParam, uint32_t& sizePerPixel, uint32_t& UVwidth, uint32_t& UVheight, uint32_t& UVpitch, uint32_t& planes)
97 {
98     //default single plane format UVheight = 0
99     UVheight = 0;
100     UVpitch = 0;
101     UVwidth = 0;
102     planes = 1;
103     switch (inParam.format)
104     {
105     case CM_SURFACE_FORMAT_R32G32B32A32F:
106         sizePerPixel = 16;
107         break;
108 
109     case CM_SURFACE_FORMAT_A16B16G16R16:
110     case CM_SURFACE_FORMAT_A16B16G16R16F:
111     case CM_SURFACE_FORMAT_Y416:
112     case CM_SURFACE_FORMAT_D32F_S8X24_UINT:
113     case CM_SURFACE_FORMAT_R32G8X24_TYPELESS:
114         sizePerPixel = 8;
115         break;
116 
117     case CM_SURFACE_FORMAT_X8R8G8B8:
118     case CM_SURFACE_FORMAT_A8R8G8B8:
119     case CM_SURFACE_FORMAT_A8B8G8R8:
120     case CM_SURFACE_FORMAT_R32F:
121     case CM_SURFACE_FORMAT_D32F:
122     case CM_SURFACE_FORMAT_R32_UINT:
123     case CM_SURFACE_FORMAT_R32_SINT:
124     case CM_SURFACE_FORMAT_R10G10B10A2:
125     case CM_SURFACE_FORMAT_AYUV:
126     case CM_SURFACE_FORMAT_R16G16_UNORM:
127     case CM_SURFACE_FORMAT_Y410:
128     case CM_SURFACE_FORMAT_Y216:
129     case CM_SURFACE_FORMAT_Y210:
130     case CM_SURFACE_FORMAT_D24_UNORM_S8_UINT:
131     case CM_SURFACE_FORMAT_R32_TYPELESS:
132     case CM_SURFACE_FORMAT_R24G8_TYPELESS:
133     case CM_SURFACE_FORMAT_R16G16_SINT:
134         sizePerPixel = 4;
135         break;
136 
137     case CM_SURFACE_FORMAT_R8G8_SNORM:
138     case CM_SURFACE_FORMAT_R16_UINT:
139     case CM_SURFACE_FORMAT_R16_SINT:
140     case CM_SURFACE_FORMAT_R16_UNORM:
141     case CM_SURFACE_FORMAT_D16:
142     case CM_SURFACE_FORMAT_L16:
143     case CM_SURFACE_FORMAT_R8G8_UNORM:
144     case CM_SURFACE_FORMAT_UYVY:
145     case CM_SURFACE_FORMAT_VYUY:
146     case CM_SURFACE_FORMAT_YUY2:
147     case CM_SURFACE_FORMAT_Y16_SNORM:
148     case CM_SURFACE_FORMAT_Y16_UNORM:
149     case CM_SURFACE_FORMAT_IRW0:
150     case CM_SURFACE_FORMAT_IRW1:
151     case CM_SURFACE_FORMAT_IRW2:
152     case CM_SURFACE_FORMAT_IRW3:
153     case CM_SURFACE_FORMAT_R16_FLOAT:
154     case CM_SURFACE_FORMAT_V8U8:
155     case CM_SURFACE_FORMAT_A8P8:
156     case CM_SURFACE_FORMAT_R16_TYPELESS:
157         sizePerPixel = 2;
158         break;
159 
160     case CM_SURFACE_FORMAT_A8:
161     case CM_SURFACE_FORMAT_P8:
162     case CM_SURFACE_FORMAT_R8_UINT:
163     case CM_SURFACE_FORMAT_Y8_UNORM:
164     case CM_SURFACE_FORMAT_L8:
165     case CM_SURFACE_FORMAT_IA44:
166     case CM_SURFACE_FORMAT_AI44:
167     case CM_SURFACE_FORMAT_400P:
168     case CM_SURFACE_FORMAT_BUFFER_2D:
169     case CM_SURFACE_FORMAT_R8_UNORM:
170         sizePerPixel = 1;
171         break;
172 
173         // 2 planes
174         //_________________________
175         //|Y0|Y1|                  |
176         //|__|__|                  |
177         //|                        |
178         //|                        |
179         //|                        |
180         //|                        |
181         //|                        |
182         //|________________________|
183         //|U0|V0|                  |
184         //|__|__|                  |
185         //|                        |
186         //|________________________|
187 
188     case CM_SURFACE_FORMAT_P016:
189     case CM_SURFACE_FORMAT_P010:
190         sizePerPixel = 2;
191         UVheight = (inParam.height + 1) / 2;
192         UVpitch = inParam.pitch;
193         UVwidth = inParam.width;
194         planes = 2;
195         break;
196     case CM_SURFACE_FORMAT_NV12:            //NV12
197         sizePerPixel = 1;
198         //To support NV12 format with odd height here.
199         //if original height is even, the UV plane's height is set as updatedHeight/2, which equals to (updatedHeight+1)/2
200         //if original height is odd, the UV plane's height is set as roundup(updatedHeight/2), which equals to (updatedHeight+1)/2 too
201         UVheight = (inParam.height + 1) / 2;
202         UVpitch = inParam.pitch;
203         UVwidth = inParam.width;
204         planes = 2;
205         break;
206     case CM_SURFACE_FORMAT_P208:
207         sizePerPixel = 1;
208         UVheight = inParam.height;
209         UVpitch = inParam.pitch;
210         UVwidth = inParam.width;
211         planes = 2;
212         break;
213 
214         // 3 planes
215         // 4:1:1 (12-bits per pixel)      // 4:2:2 (16-bits per pixel)
216         // 411P                           // 422H
217         // ----------------->             // ----------------->
218         // ________________________       // ________________________
219         //|Y0|Y1|                  |      //|Y0|Y1|                  |
220         //|__|__|                  |      //|__|__|                  |
221         //|                        |      //|                        |
222         //|                        |      //|                        |
223         //|                        |      //|                        |
224         //|                        |      //|                        |
225         //|                        |      //|                        |
226         //|________________________|      //|________________________|
227         //|U0|U1||                 |      //|U0|U1|      |           |
228         //|__|__||                 |      //|__|__|      |           |
229         //|      |                 |      //|            |           |
230         //|      |      PAD        |      //|            |    PAD    |
231         //|      |                 |      //|            |           |
232         //|      |                 |      //|            |           |
233         //|      |                 |      //|            |           |
234         //|______|_________________|      //|____________|___________|
235         //|V0|V1||                 |      //|V0|V1|      |           |
236         //|__|__||                 |      //|__|__|      |           |
237         //|      |                 |      //|            |           |
238         //|      |      PAD        |      //|            |    PAD    |
239         //|      |                 |      //|            |           |
240         //|      |                 |      //|            |           |
241         //|      |                 |      //|            |           |
242         //|______|_________________|      //|____________|___________|
243 
244         // 4:4:4 (24-bits per pixel)
245         // 444P
246         // ----------------->
247         // ________________________
248         //|Y0|Y1|                  |
249         //|__|__|                  |
250         //|                        |
251         //|                        |
252         //|                        |
253         //|                        |
254         //|                        |
255         //|________________________|
256         //|U0|U1|                  |
257         //|__|__|                  |
258         //|                        |
259         //|                        |
260         //|                        |
261         //|                        |
262         //|                        |
263         //|________________________|
264         //|V0|V1|                  |
265         //|__|__|                  |
266         //|                        |
267         //|                        |
268         //|                        |
269         //|                        |
270         //|                        |
271         //|________________________|
272 
273     case CM_SURFACE_FORMAT_411P:
274     case CM_SURFACE_FORMAT_422H:
275     case CM_SURFACE_FORMAT_444P:
276     case CM_SURFACE_FORMAT_RGBP:
277     case CM_SURFACE_FORMAT_BGRP:
278         sizePerPixel = 1;
279         UVheight = inParam.height;
280         UVpitch = inParam.pitch;
281         UVwidth = inParam.width;
282         planes = 3;
283         break;
284 
285         // 4:2:0 (12-bits per pixel)
286         // IMC1                           // IMC3
287         // ----------------->             // ----------------->
288         // ________________________       // ________________________
289         //|Y0|Y1|                  |      //|Y0|Y1|                  |
290         //|__|__|                  |      //|__|__|                  |
291         //|                        |      //|                        |
292         //|                        |      //|                        |
293         //|                        |      //|                        |
294         //|                        |      //|                        |
295         //|                        |      //|                        |
296         //|________________________|      //|________________________|
297         //|V0|V1|      |           |      //|U0|U1|      |           |
298         //|__|__|      |           |      //|__|__|      |           |
299         //|            |           |      //|            |           |
300         //|____________|  PAD      |      //|____________|  PAD      |
301         //|U0|U1|      |           |      //|V0|V1|      |           |
302         //|__|__|      |           |      //|__|__|      |           |
303         //|            |           |      //|            |           |
304         //|____________|___________|      //|____________|___________|
305     case CM_SURFACE_FORMAT_IMC3:
306         sizePerPixel = 1;
307         UVheight = (inParam.height + 1) / 2;
308         UVpitch = inParam.pitch;
309         UVwidth = inParam.width;
310         planes = 3;
311         break;
312 
313 
314         // 4:2:2V (16-bits per pixel)
315         // 422V
316         // ----------------->
317         // ________________________
318         //|Y0|Y1|                  |
319         //|__|__|                  |
320         //|                        |
321         //|                        |
322         //|                        |
323         //|                        |
324         //|                        |
325         //|________________________|
326         //|U0|U1|                  |
327         //|__|__|                  |
328         //|                        |
329         //|________________________|
330         //|V0|V1|                  |
331         //|__|__|                  |
332         //|                        |
333         //|________________________|
334 
335     case CM_SURFACE_FORMAT_422V:
336         sizePerPixel = 1;
337         UVheight = (inParam.height + 1) / 2;
338         UVpitch = inParam.pitch;
339         UVwidth = inParam.width;
340         planes = 3;
341         break;
342 
343         // 4:2:0 (12-bits per pixel)
344         // I420
345         // ----------------->
346         // ________________________
347         //|Y0|Y1|                  |
348         //|__|__|                  |
349         //|                        |
350         //|                        |
351         //|                        |
352         //|                        |
353         //|                        |
354         //|________________________|
355         //|U0|U1|      |
356         //|__|__|      |
357         //|            |
358         //|____________|
359         //|V0|V1|      |
360         //|__|__|      |
361         //|            |
362         //|____________|
363     case CM_SURFACE_FORMAT_YV12:
364     case CM_SURFACE_FORMAT_I420:            //I420
365         sizePerPixel = 1;
366         UVheight = (inParam.height + 1) / 2;
367         UVpitch = inParam.pitch / 2;
368         UVwidth = inParam.width / 2;
369         planes = 3;
370         break;
371     case CM_SURFACE_FORMAT_411R://411R
372         sizePerPixel = 1;
373         UVheight = inParam.height;
374         UVpitch = inParam.pitch / 4;
375         UVwidth = inParam.width / 4;
376         planes = 3;
377         break;
378 
379     default:
380         CM_ASSERTMESSAGE("Error: Unsupported surface format.");
381         return CM_SURFACE_FORMAT_NOT_SUPPORTED;
382     }
383 
384     return CM_SUCCESS;
385 }
386 
387 //*-----------------------------------------------------------------------------
388 //| Purpose:    Get the index of CmSurface2D
389 //| Returns:    Result of the operation.
390 //*-----------------------------------------------------------------------------
GetIndex(SurfaceIndex * & index)391 CM_RT_API int32_t CmSurface2DRTBase::GetIndex(SurfaceIndex*& index)
392 {
393     index = m_index;
394     return CM_SUCCESS;
395 }
396 
SetCompressionMode(MEMCOMP_STATE mmcMode)397 CM_RT_API int32_t CmSurface2DRTBase::SetCompressionMode(MEMCOMP_STATE mmcMode)
398 {
399     INSERT_API_CALL_LOG(nullptr);
400 
401     CM_RETURN_CODE  hr = CM_SUCCESS;
402     CM_HAL_SURFACE2D_COMPRESSIOM_PARAM mmcModeParam;
403     CmDeviceRT * cmDevice = nullptr;
404     m_surfaceMgr->GetCmDevice(cmDevice);
405     CM_ASSERT(cmDevice);
406     mmcModeParam.handle = m_handle;
407     mmcModeParam.mmcMode = mmcMode;
408     PCM_CONTEXT_DATA cmData = (PCM_CONTEXT_DATA)cmDevice->GetAccelData();
409     CM_ASSERT(cmData);
410     CM_CHK_NULL_RETURN_CMERROR(cmData->cmHalState);
411 
412     CM_CHK_MOSSTATUS_GOTOFINISH_CMERROR(cmData->cmHalState->pfnSetCompressionMode(cmData->cmHalState, mmcModeParam));
413     ++ m_propertyIndex;
414 
415 finish:
416     return hr;
417 }
418 
419 
420 //*-----------------------------------------------------------------------------
421 //| Purpose:    Write data from  system memory to Surface 2D to with stride
422 //|             It clips larger picture frame content into smaller gfx surface size
423 //|             horizontalStride >= surface width * sizePerPixel
424 //|             verticalStride   >= surface height
425 //| Arguments :
426 //|               sysMem      [in]       Pointer to system memory
427 //|               event       [in]       Pointer to CmEvent
428 //|               horizontalStride [in]  Stride in system memory in bytes
429 //|               verticalStride[in]     Height Stride in system memory in rows
430 //|               sysMemSize   [out]     Size of Memory need to read
431 //|
432 //| Returns:    Result of the operation.
433 //*-----------------------------------------------------------------------------
WriteSurfaceFullStride(const unsigned char * sysMem,CmEvent * event,const uint32_t horizontalStride,const uint32_t verticalStride,uint64_t sysMemSize)434 CM_RT_API int32_t CmSurface2DRTBase::WriteSurfaceFullStride(
435     const unsigned char* sysMem, CmEvent* event, const uint32_t horizontalStride,
436     const uint32_t verticalStride, uint64_t sysMemSize)
437 {
438     INSERT_API_CALL_LOG(nullptr);
439 
440     CM_RETURN_CODE  hr = CM_SUCCESS;
441     uint8_t         *dst = nullptr;
442     uint8_t         *src = nullptr;
443     uint32_t        sizePerPixel = 0;
444     uint32_t        updatedHeight = 0;
445     uint32_t        widthInByte = 0;
446     uint32_t        pitch = 0;
447     uint32_t        row = 0;
448     uint32_t        UVHeight = 0;
449     uint32_t        UVpitch = 0;
450     uint32_t        UVwidth = 0;
451     uint32_t        planeHeight = 0;
452     uint32_t        planes = 0;
453     uint32_t        offset0 = 0;
454     uint32_t        offset1 = 0;
455     uint32_t        offset2 = 0;
456     uint32_t        offsetn = 0;
457     uint32_t        tmp = 0;
458     UNUSED(sysMemSize);
459 
460     if (sysMem == nullptr)
461     {
462         CM_ASSERTMESSAGE("Error: Pointer to system memory is null.")
463             return CM_INVALID_ARG_VALUE;
464     }
465 
466     if (event)
467     {
468         CmEventRT *eventRT = dynamic_cast<CmEventRT *>(event);
469         if (eventRT)
470         {
471             FlushDeviceQueue(eventRT);
472         }
473         else
474         {
475             event->WaitForTaskFinished();
476         }
477     }
478     WaitForReferenceFree();   // wait all owner task finished
479 
480     CmDeviceRT * cmDevice = nullptr;
481     m_surfaceMgr->GetCmDevice(cmDevice);
482     CM_CHK_NULL_RETURN_CMERROR(cmDevice);
483     uint32_t platform = 0;
484     cmDevice->GetGenPlatform(platform);
485     //Lock for surface read/write
486     CSync* surfaceLock = cmDevice->GetSurfaceLock();
487     CM_ASSERT(surfaceLock);
488     CLock locker(*surfaceLock);
489 
490     PCM_CONTEXT_DATA cmData = (PCM_CONTEXT_DATA)cmDevice->GetAccelData();
491     CM_CHK_NULL_RETURN_CMERROR(cmData);
492     CM_CHK_NULL_RETURN_CMERROR(cmData->cmHalState);
493 
494     CM_HAL_SURFACE2D_LOCK_UNLOCK_PARAM inParam;
495     CmSafeMemSet(&inParam, 0, sizeof(CM_HAL_SURFACE2D_LOCK_UNLOCK_PARAM));
496     inParam.width = m_width;
497     inParam.height = m_height;
498     inParam.handle = m_handle;
499     inParam.lockFlag = CM_HAL_LOCKFLAG_WRITEONLY;
500     inParam.useGmmOffset = true;
501 
502     // Lock Surface Resource
503     CM_CHK_MOSSTATUS_GOTOFINISH_CMERROR(cmData->cmHalState->pfnLock2DResource(cmData->cmHalState, &inParam));
504     CM_CHK_NULL_GOTOFINISH_CMERROR(inParam.data);
505     //make sure format is set correctly
506     inParam.format = m_format;
507     // Get planar memory layout information according to the format
508     CM_CHK_CMSTATUS_GOTOFINISH(GetPlanarInfomation(inParam, sizePerPixel, UVwidth, UVHeight, UVpitch, planes));
509 
510     // Write copy surface content data
511     widthInByte = m_width * sizePerPixel;
512     pitch = m_pitch;
513     planeHeight = inParam.height;
514 
515     // convert gmmlib plane offset to linear offset
516     offset0 = inParam.YSurfaceOffset.iSurfaceOffset + (inParam.YSurfaceOffset.iXOffset * sizePerPixel) + (inParam.YSurfaceOffset.iYOffset * pitch);
517     offset1 = inParam.USurfaceOffset.iSurfaceOffset + (inParam.USurfaceOffset.iXOffset * sizePerPixel) + (inParam.USurfaceOffset.iYOffset * UVpitch);
518     offset2 = inParam.VSurfaceOffset.iSurfaceOffset + (inParam.VSurfaceOffset.iXOffset * sizePerPixel) + (inParam.VSurfaceOffset.iYOffset * UVpitch);
519 
520     tmp = offset1;
521     if (offset1 > offset2)
522     {
523         offset1 = offset2;
524         offset2 = tmp;
525         // some VSurfaceOffset.iSurfaceOffset could be 0 from gmm resource info
526         if (offset1 == 0)
527             offset1 = offset2;
528     }
529 
530     // write copy Y plane or single plane format
531     dst = (uint8_t *)(inParam.data);
532     src = (uint8_t *)sysMem;
533     if ((pitch > widthInByte) || (horizontalStride != pitch))
534     {
535         // scan line copy
536         for (row = 0; row < planeHeight; row++)
537         {
538             CmFastMemCopyWC(dst, src, widthInByte);
539             src += horizontalStride;
540             dst += pitch;
541         }
542     }
543     else
544     {   // block copy
545         CmFastMemCopyWC(dst, src, widthInByte * planeHeight);
546     }
547 
548     if (UVHeight > 0)
549     {
550         // Write copy 2nd plane
551         if (planes > 1)
552         {
553             offsetn = offset1;
554             //  Limit the Gmm offset usage to after Gen11
555             if (!inParam.useGmmOffset)
556             {
557                 offsetn = (planeHeight * pitch);
558             }
559             dst = (uint8_t *)(inParam.data) + offsetn;
560             src = (uint8_t *)sysMem + horizontalStride * verticalStride;
561             for (row = 0; row < UVHeight; row++)
562             {
563                 CmFastMemCopyWC(dst, src, UVwidth * sizePerPixel);
564                 src += horizontalStride * UVwidth / m_width;
565                 dst += UVpitch;
566             }
567         }
568 
569         // Write copy 3rd plane
570         if (planes > 2)
571         {
572             offsetn = offset2;
573             //  Limit the Gmm offset usage to after Gen11
574             if (!inParam.useGmmOffset)
575             {
576                 offsetn = (planeHeight * pitch) + (UVHeight * UVpitch);
577             }
578             dst = (uint8_t *)(inParam.data) + offsetn;
579             // calculate system memory frame buffer UV plain width and height with ratio of video surface UV plane vs Y plane
580             // UVwidth / m_width  is horizontal ratio;  UVHeight / m_height  is vertical ratio
581             // system memory frame buffer 3rd plane offset is Y plane size + 2nd Plane size
582             src = (uint8_t *)sysMem + (horizontalStride * verticalStride) +
583                   (horizontalStride * UVwidth / m_width * verticalStride * UVHeight / m_height);
584             for (row = 0; row < UVHeight; row++)
585             {
586                 CmFastMemCopyWC(dst, src, UVwidth * sizePerPixel);
587                 src += horizontalStride * UVwidth / m_width;
588                 dst += UVpitch;
589             }
590         }
591     }
592 
593     //Unlock Surface2D
594     inParam.data = nullptr;
595     CM_CHK_MOSSTATUS_GOTOFINISH_CMERROR(cmData->cmHalState->pfnUnlock2DResource(cmData->cmHalState, &inParam));
596 finish:
597     return hr;
598 }
599 
600 //*-----------------------------------------------------------------------------
601 //| Purpose:    Write data from  system memory to Surface 2D to with stride
602 //|             It clips larger picture frame content into smaller gfx surface size
603 //|             horizontalStride >= surface width * sizePerPixel
604 //|             verticalStride   == surface height
605 //| Arguments :
606 //|               sysMem      [in]       Pointer to system memory
607 //|               event       [in]       Pointer to CmEvent
608 //|               Stride       [in]       Stride in system memory in bytes
609 //|               sysMemSize   [out]      Size of Memory need to read
610 //|
611 //| Returns:    Result of the operation.
612 //*-----------------------------------------------------------------------------
WriteSurfaceStride(const unsigned char * sysMem,CmEvent * event,const uint32_t stride,uint64_t sysMemSize)613 CM_RT_API int32_t CmSurface2DRTBase::WriteSurfaceStride(const unsigned char* sysMem, CmEvent* event, const uint32_t stride, uint64_t sysMemSize)
614 {
615     INSERT_API_CALL_LOG(nullptr);
616 
617     return WriteSurfaceFullStride(sysMem, event, stride, m_height, sysMemSize);
618 }
619 
620 //*-----------------------------------------------------------------------------
621 //| Purpose:    Write data from system memory to Surface 2D
622 //|             picture frame content size equals gfx surface size
623 //| Arguments :
624 //|               sysMem      [in]       Pointer to system memory
625 //|               event       [in]       Pointer to CmEvent
626 //|               sysMemSize   [out]      Size of Memory need to write
627 //|
628 //| Returns:    Result of the operation.
629 //*-----------------------------------------------------------------------------
630 
WriteSurface(const unsigned char * sysMem,CmEvent * event,uint64_t sysMemSize)631 CM_RT_API int32_t CmSurface2DRTBase::WriteSurface(const unsigned char* sysMem, CmEvent* event, uint64_t sysMemSize)
632 {
633     INSERT_API_CALL_LOG(nullptr);
634     uint32_t        sizePerPixel = 0;
635     uint32_t        UVHeight = 0;
636     uint32_t        UVpitch = 0;
637     uint32_t        UVwidth = 0;
638     uint32_t        planes = 0;
639     CM_HAL_SURFACE2D_LOCK_UNLOCK_PARAM inParam;
640     CmSafeMemSet(&inParam, 0, sizeof(CM_HAL_SURFACE2D_LOCK_UNLOCK_PARAM));
641     inParam.width = m_width;
642     inParam.height = m_height;
643     inParam.format = m_format;
644     // Get planar memory layout information according to the format
645     GetPlanarInfomation(inParam, sizePerPixel, UVwidth, UVHeight, UVpitch, planes);
646     return WriteSurfaceFullStride(sysMem, event, sizePerPixel * m_width, m_height, sysMemSize);
647 }
648 
649 
650 //*-----------------------------------------------------------------------------
651 //| Purpose:    Hybrid memory copy from  system memory to Surface 2D to with stride
652 //| Arguments :
653 //|               sysMem      [in]       Pointer to system memory
654 //|               event       [in]       Pointer to CmEvent
655 //|               horizontalStride [in]       Stride in system memory in bytes
656 //|               verticalStride[in]       Height Stride in system memory in rows
657 //|               sysMemSize   [in]       Size of Memory need to read
658 //|               option     [in]       Option to disable/enable hybrid memory copy
659 //| Returns:    Result of the operation.
660 //*-----------------------------------------------------------------------------
WriteSurfaceHybridStrides(const unsigned char * sysMem,CmEvent * event,const uint32_t horizontalStride,const uint32_t verticalStride,uint64_t sysMemSize,uint32_t option)661 CM_RT_API int32_t CmSurface2DRTBase::WriteSurfaceHybridStrides( const unsigned char* sysMem, CmEvent* event, const uint32_t horizontalStride, const uint32_t verticalStride, uint64_t sysMemSize, uint32_t option )
662 {
663     INSERT_API_CALL_LOG(nullptr);
664 
665     int32_t     hr                  = CM_SUCCESS;
666     uint32_t    sizePerPixel        = 0;
667     uint32_t    updatedHeight       = 0;
668     uint32_t    widthInBytes        = 0;
669     CmQueue    *cmQueue            = nullptr;
670     CmDeviceRT *cmDevice           = nullptr;
671     CmQueueRT  *cmQueueRT          = nullptr;
672     bool        forceCPUCopy       = COPY_OPTION(option);
673     CM_STATUS   status;
674 
675     m_surfaceMgr->GetCmDevice(cmDevice);
676     CM_CHK_NULL_RETURN_CMERROR(cmDevice);
677 
678     int32_t result = m_surfaceMgr->GetPixelBytesAndHeight(m_width, m_height, m_format, sizePerPixel, updatedHeight);
679     if (result != CM_SUCCESS)
680     {
681         CM_ASSERTMESSAGE("Error: Failed to get correct surface info.")
682         return result;
683     }
684 
685     widthInBytes = m_width * sizePerPixel;
686 
687     WaitForReferenceFree();   // wait all owner task finished
688 
689     if (forceCPUCopy)
690     {
691         CM_CHK_CMSTATUS_GOTOFINISH(WriteSurfaceFullStride(sysMem, event, horizontalStride, verticalStride, sysMemSize));
692     }
693     else
694     {
695         CM_CHK_CMSTATUS_GOTOFINISH(cmDevice->CreateQueue(cmQueue));
696 
697         if(IsGPUCopy((void*)sysMem, widthInBytes, m_height, horizontalStride))
698         {
699             CmEvent *tempEvent = CM_NO_EVENT;
700             CM_CHK_CMSTATUS_GOTOFINISH(cmQueue->EnqueueCopyCPUToGPUFullStride(this, sysMem, horizontalStride, verticalStride, CM_FASTCOPY_OPTION_BLOCKING, tempEvent));
701         }
702         else if (IsUnalignedGPUCopy(widthInBytes, m_height))
703         {
704             cmQueueRT = static_cast<CmQueueRT *>(cmQueue);
705             CmSurface2DRT * cmSurface2DRT = dynamic_cast<CmSurface2DRT *>(this);
706             CM_CHK_NULL_RETURN_CMERROR(cmSurface2DRT);
707 
708             CM_CHK_CMSTATUS_GOTOFINISH(cmQueueRT->EnqueueUnalignedCopyInternal(cmSurface2DRT, (unsigned char*)sysMem, horizontalStride, verticalStride, CM_FASTCOPY_CPU2GPU));
709         }
710         else
711         {
712             CM_CHK_CMSTATUS_GOTOFINISH(WriteSurfaceFullStride(sysMem, event, horizontalStride, verticalStride, sysMemSize));
713         }
714     }
715 
716 finish:
717     return hr;
718 }
719 
720 
721 //*-----------------------------------------------------------------------------
722 //| Purpose:    Read data from  Surface 2D to system memory with stride
723 //|             It copies smaller gfx surface content into larger system memory picture frame
724 //|             horizontalStride >= surface width * sizePerPixel
725 //|             verticalStride   == surface height
726 //| Arguments :
727 //|               sysMem      [in]       Pointer to system memory
728 //|               event       [in]       Pointer to CmEvent
729 //|               Stride       [in]       Stride in system memory in bytes
730 //|               sysMemSize   [out]      Size of Memory need to read
731 //|
732 //| Returns:    Result of the operation.
733 //*-----------------------------------------------------------------------------
ReadSurfaceStride(unsigned char * sysMem,CmEvent * event,const uint32_t stride,uint64_t sysMemSize)734 CM_RT_API int32_t CmSurface2DRTBase::ReadSurfaceStride( unsigned char* sysMem, CmEvent* event, const uint32_t stride, uint64_t sysMemSize )
735 {
736     INSERT_API_CALL_LOG(nullptr);
737 
738     return ReadSurfaceFullStride(sysMem, event, stride, m_height, sysMemSize);
739 }
740 
741 //*-----------------------------------------------------------------------------
742 //| Purpose:    Read data from  Surface 2D to system memory with stride
743 //|             It copies smaller gfx surface content into larger system memory picture frame
744 //|             horizontalStride >= surface width * sizePerPixel
745 //|             verticalStride   >= surface height
746 //| Arguments :
747 //|               sysMem      [in]       Pointer to system memory
748 //|               event       [in]       Pointer to CmEvent
749 //|               horizontalStride [in]       Width  Stride in system memory in bytes
750 //|               verticalStride[in]       Height Stride in system memory in rows
751 //|               sysMemSize   [out]      Size of Memory need to read
752 //|
753 //| Returns:    Result of the operation.
754 //*-----------------------------------------------------------------------------
ReadSurfaceFullStride(unsigned char * sysMem,CmEvent * event,const uint32_t horizontalStride,const uint32_t verticalStride,uint64_t sysMemSize)755 CM_RT_API int32_t CmSurface2DRTBase::ReadSurfaceFullStride( unsigned char* sysMem, CmEvent* event,
756                     const uint32_t horizontalStride, const uint32_t verticalStride, uint64_t sysMemSize )
757 {
758     INSERT_API_CALL_LOG(nullptr);
759 
760     CM_RETURN_CODE  hr = CM_SUCCESS;
761     uint8_t         *dst = nullptr;
762     uint8_t         *src = nullptr;
763     uint32_t        sizePerPixel = 0;
764     uint32_t        UVHeight = 0;
765     uint32_t        UVwidth = 0;
766     uint32_t        UVpitch = 0;
767     uint32_t        updatedHeight = 0;
768     uint32_t        widthInByte = 0;
769     uint32_t        pitch = 0;
770     uint32_t        row = 0;
771     uint32_t        planeHeight = 0;
772     uint32_t        planes = 0;
773     uint32_t        offset0 = 0;
774     uint32_t        offset1 = 0;
775     uint32_t        offset2 = 0;
776     uint32_t        tmp = 0;
777     UNUSED(sysMemSize);
778 
779     if (sysMem == nullptr)
780     {
781         CM_ASSERTMESSAGE("Error: Pointer to system memory is null.")
782             return CM_INVALID_ARG_VALUE;
783     }
784 
785     if (event)
786     {
787         CmEventRT *eventRT = dynamic_cast<CmEventRT *>(event);
788         if (eventRT)
789         {
790             FlushDeviceQueue(eventRT);
791         }
792         else
793         {
794             event->WaitForTaskFinished();
795         }
796     }
797 
798     WaitForReferenceFree();   // wait all owner task finished
799 
800     CmDeviceRT * cmDevice = nullptr;
801     m_surfaceMgr->GetCmDevice(cmDevice);
802     CM_CHK_NULL_RETURN_CMERROR(cmDevice);
803     uint32_t platform = 0;
804     cmDevice->GetGenPlatform(platform);
805 
806     //Lock for surface read/write
807     CSync* surfaceLock = cmDevice->GetSurfaceLock();
808     CM_ASSERT(surfaceLock);
809     CLock locker(*surfaceLock);
810 
811     PCM_CONTEXT_DATA cmData = (PCM_CONTEXT_DATA)cmDevice->GetAccelData();
812     CM_CHK_NULL_RETURN_CMERROR(cmData);
813     CM_CHK_NULL_RETURN_CMERROR(cmData->cmHalState);
814 
815     CM_HAL_SURFACE2D_LOCK_UNLOCK_PARAM inParam;
816     CmSafeMemSet(&inParam, 0, sizeof(CM_HAL_SURFACE2D_LOCK_UNLOCK_PARAM));
817     inParam.width = m_width;
818     inParam.height = m_height;
819     inParam.handle = m_handle;
820     inParam.lockFlag = CM_HAL_LOCKFLAG_READONLY;
821     inParam.useGmmOffset = true;
822 
823     // Lock Surface Resource
824     CM_CHK_MOSSTATUS_GOTOFINISH_CMERROR(cmData->cmHalState->pfnLock2DResource(cmData->cmHalState, &inParam));
825     CM_CHK_NULL_GOTOFINISH_CMERROR(inParam.data);
826     //make sure format is set correctly
827     inParam.format = m_format;
828     // Get planar memory layout information according to the format
829     CM_CHK_CMSTATUS_GOTOFINISH(GetPlanarInfomation(inParam, sizePerPixel, UVwidth, UVHeight, UVpitch, planes));
830 
831     // Read copy surface content data
832     widthInByte = m_width * sizePerPixel;
833     pitch = m_pitch;
834     planeHeight = inParam.height;
835 
836     // convert gmmlib plane offset to linear offset
837     offset0 = inParam.YSurfaceOffset.iSurfaceOffset + (inParam.YSurfaceOffset.iXOffset * sizePerPixel) + (inParam.YSurfaceOffset.iYOffset * pitch);
838     offset1 = inParam.USurfaceOffset.iSurfaceOffset + (inParam.USurfaceOffset.iXOffset * sizePerPixel) + (inParam.USurfaceOffset.iYOffset * UVpitch);
839     offset2 = inParam.VSurfaceOffset.iSurfaceOffset + (inParam.VSurfaceOffset.iXOffset * sizePerPixel) + (inParam.VSurfaceOffset.iYOffset * UVpitch);
840 
841     tmp = offset1;
842     if (offset1 > offset2)
843     {
844         offset1 = offset2;
845         offset2 = tmp;
846         if (offset1 == 0)
847             offset1 = offset2;
848     }
849 
850     dst = (uint8_t *)sysMem;
851     src = (uint8_t *)(inParam.data);
852     // Read copy Y plane
853     if ((pitch > widthInByte) || (horizontalStride != pitch))
854     {
855         // scan line copy
856         for (row = 0; row < planeHeight; row++)
857         {
858             CmFastMemCopyFromWC(dst, src, widthInByte, GetCpuInstructionLevel());
859             dst += horizontalStride;
860             src += pitch;
861         }
862     }
863     else
864     {   // block copy
865         CmFastMemCopyFromWC(dst, src, pitch * planeHeight, GetCpuInstructionLevel());
866     }
867 
868     // Read copy 2nd plane
869     if (UVHeight > 0)
870     {
871         if (planes > 1)
872         {
873             int offsetn = offset1;
874             //  Limit the Gmm offset usage to after Gen11
875             if (!inParam.useGmmOffset)
876             {
877                 offsetn = planeHeight * pitch;
878             }
879             src = (uint8_t *)(inParam.data) + offsetn;
880             dst = (uint8_t *)sysMem + (horizontalStride * verticalStride);
881             for (row = 0; row < UVHeight; row++)
882             {
883                 CmFastMemCopyFromWC(dst, src, UVwidth * sizePerPixel, GetCpuInstructionLevel());
884                 dst += horizontalStride * UVwidth / m_width;
885                 src += UVpitch;
886             }
887         }
888 
889         // Read copy 3rd plane
890         if (planes > 2)
891         {
892             int offsetn = offset2;
893             //  Limit the Gmm offset usage to after Gen11
894             if (!inParam.useGmmOffset)
895             {
896                 offsetn = (planeHeight * pitch) + (UVHeight * UVpitch);
897             }
898             src = (uint8_t *)(inParam.data) + offsetn;
899             // calculate system memory frame buffer UV plain width and height with ratio of video surface UV plane vs Y plane
900             // UVwidth / m_width  is horizontal ratio;  UVHeight / m_height  is vertical ratio
901             // system memory frame buffer 3rd plane offset is Y plane size + 2nd Plane size
902             dst = (uint8_t *)sysMem + (horizontalStride * verticalStride) +
903                   (horizontalStride * UVwidth / m_width * verticalStride * UVHeight / m_height);
904 
905             for (row = 0; row < UVHeight; row++)
906             {
907                 CmFastMemCopyFromWC(dst, src, UVwidth * sizePerPixel, GetCpuInstructionLevel());
908                 dst += horizontalStride * UVwidth / m_width;
909                 src += UVpitch;
910             }
911         }
912     }
913 
914     //Unlock
915     inParam.data = nullptr;
916     CM_CHK_MOSSTATUS_GOTOFINISH_CMERROR(cmData->cmHalState->pfnUnlock2DResource(cmData->cmHalState, &inParam));
917 
918 finish:
919     return hr;
920 }
921 
922 
923 //*-----------------------------------------------------------------------------
924 //| Purpose:    Read data from  Surface 2D to system memory
925 //| Arguments :
926 //|               sysMem      [in]       Pointer to system memory
927 //|               event       [in]       Pointer to CmEvent
928 //|               sysMemSize   [out]      Size of Memory need to read
929 //|
930 //| Returns:    Result of the operation.
931 //*-----------------------------------------------------------------------------
ReadSurface(unsigned char * sysMem,CmEvent * event,uint64_t sysMemSize)932 CM_RT_API int32_t CmSurface2DRTBase::ReadSurface(unsigned char* sysMem, CmEvent* event, uint64_t sysMemSize)
933 {
934     INSERT_API_CALL_LOG(nullptr);
935     uint32_t        sizePerPixel = 0;
936     uint32_t        UVHeight = 0;
937     uint32_t        UVpitch = 0;
938     uint32_t        UVwidth = 0;
939     uint32_t        planes = 0;
940     CM_HAL_SURFACE2D_LOCK_UNLOCK_PARAM inParam;
941     CmSafeMemSet(&inParam, 0, sizeof(CM_HAL_SURFACE2D_LOCK_UNLOCK_PARAM));
942     inParam.width = m_width;
943     inParam.height = m_height;
944     inParam.format = m_format;
945     // Get planar memory layout information according to the format
946     GetPlanarInfomation(inParam, sizePerPixel, UVwidth, UVHeight, UVpitch, planes);
947     return ReadSurfaceFullStride(sysMem, event, sizePerPixel * m_width, m_height, sysMemSize);
948 }
949 
950 //*-----------------------------------------------------------------------------
951 //| Purpose:    Hybrid memory copy from  Surface 2D to system memory with stride
952 //| Arguments :
953 //|               sysMem      [out]       Pointer to system memory
954 //|               event       [in]       Pointer to CmEvent
955 //|               horizontalStride [in]       Width  Stride in system memory in bytes
956 //|               verticalStride[in]       Height Stride in system memory in rows
957 //|               sysMemSize   [in]       Size of Memory need to read
958 //|               option     [in]       Option to disable/enable hybrid memory copy
959 //| Returns:    Result of the operation.
960 //*-----------------------------------------------------------------------------
ReadSurfaceHybridStrides(unsigned char * sysMem,CmEvent * event,const uint32_t horizontalStride,const uint32_t verticalStride,uint64_t sysMemSize,uint32_t option)961 CM_RT_API int32_t CmSurface2DRTBase::ReadSurfaceHybridStrides(unsigned char* sysMem, CmEvent* event, const uint32_t horizontalStride, const uint32_t verticalStride, uint64_t sysMemSize, uint32_t option)
962 {
963     INSERT_API_CALL_LOG(nullptr);
964 
965     int32_t     hr = CM_SUCCESS;
966     uint32_t    sizePerPixel = 0;
967     uint32_t    updatedHeight = 0;
968     uint32_t    widthInBytes = 0;
969     CmQueue    *cmQueue = nullptr;
970     CmDeviceRT *cmDevice = nullptr;
971     CmQueueRT  *cmQueueRT = nullptr;
972     bool        forceCPUCopy = COPY_OPTION(option);
973     CM_STATUS   status;
974 
975     m_surfaceMgr->GetCmDevice(cmDevice);
976     CM_CHK_NULL_RETURN_CMERROR(cmDevice);
977 
978     int32_t result = m_surfaceMgr->GetPixelBytesAndHeight(m_width, m_height, m_format, sizePerPixel, updatedHeight);
979     if (result != CM_SUCCESS)
980     {
981         CM_ASSERTMESSAGE("Error: Failed to get correct surface info.")
982             return result;
983     }
984 
985     widthInBytes = m_width * sizePerPixel;
986 
987     WaitForReferenceFree();   // wait all owner task finished
988 
989     if (forceCPUCopy)
990     {
991         CM_CHK_CMSTATUS_GOTOFINISH(ReadSurfaceFullStride(sysMem, event, horizontalStride, verticalStride, sysMemSize));
992     }
993     else
994     {
995         CM_CHK_CMSTATUS_GOTOFINISH(cmDevice->CreateQueue(cmQueue));
996 
997         if (IsGPUCopy((void*)sysMem, widthInBytes, m_height, horizontalStride))
998         {
999             CmEvent *tempEvent = CM_NO_EVENT;
1000             CM_CHK_CMSTATUS_GOTOFINISH(cmQueue->EnqueueCopyGPUToCPUFullStride(this, sysMem, horizontalStride, verticalStride, CM_FASTCOPY_OPTION_BLOCKING, tempEvent));
1001         }
1002         else if (IsUnalignedGPUCopy(widthInBytes, m_height))
1003         {
1004             cmQueueRT = static_cast<CmQueueRT *>(cmQueue);
1005             CmSurface2DRT * cmSurface2DRT = dynamic_cast<CmSurface2DRT *>(this);
1006             CM_CHK_NULL_RETURN_CMERROR(cmSurface2DRT);
1007 
1008             CM_CHK_CMSTATUS_GOTOFINISH(cmQueueRT->EnqueueUnalignedCopyInternal(cmSurface2DRT, (unsigned char*)sysMem, horizontalStride, verticalStride, CM_FASTCOPY_GPU2CPU));
1009         }
1010         else
1011         {
1012             CM_CHK_CMSTATUS_GOTOFINISH(ReadSurfaceFullStride(sysMem, event, horizontalStride, verticalStride, sysMemSize));
1013         }
1014     }
1015 
1016 finish:
1017     return hr;
1018 }
1019 
1020 
1021 //*-----------------------------------------------------------------------------
1022 //| Purpose:    Let CM know that the UMD resource of current CmSurface2D
1023 //              wrapper was changed. This change may happen at the CmSurface2D
1024 //              creation and destroy time or changed from outside of CM. This
1025 //              should be called immediately after the UMD resource changed.
1026 //
1027 //| Arguments :
1028 //|             umdResource       [in]  Pointer to the UMD resource for the CM
1029 //|                                     wrapper. Set it to nullptr when the
1030 //|                                     third party MosResource was deleted
1031 //|                                     before the CmSurface2D.
1032 //|             updateMosResource [in]  1: will update the MosResource.
1033 //|                                     0: will not update the MosResource.
1034 //|             mosResource      [in]  Pointer to the new valid MosResource
1035 //|                                     that the CMSurface2D will be based on.
1036 //|                                     Do not set this parameter if the
1037 //|                                     MosResource is already deleted.
1038 //| Returns:    Result of the operation.
1039 //*-----------------------------------------------------------------------------
1040 CMRT_UMD_API int32_t
NotifyUmdResourceChanged(void * umdResource,int updateMosResource,PMOS_RESOURCE mosResource)1041 CmSurface2DRTBase::NotifyUmdResourceChanged(void *umdResource,
1042                                             int updateMosResource,
1043                                             PMOS_RESOURCE mosResource)
1044 {
1045     m_umdResource = umdResource;
1046 
1047     if ( updateMosResource )
1048     {
1049         m_surfaceMgr->UpdateSurface2DTableMosResource( m_handle, mosResource );
1050     }
1051 
1052     return CM_SUCCESS;
1053 }
1054 
1055 //*-----------------------------------------------------------------------------
1056 //| Purpose:    Get the handle of  CmSurface2D
1057 //| Returns:    Result of the operation.
1058 //*-----------------------------------------------------------------------------
GetHandle(uint32_t & handle)1059 int32_t CmSurface2DRTBase::GetHandle( uint32_t& handle)
1060 {
1061     handle = m_handle;
1062     return CM_SUCCESS;
1063 }
1064 
1065 //*-----------------------------------------------------------------------------
1066 //| Purpose:    Get the handle of  CmSurface2D
1067 //| Returns:    Result of the operation.
1068 //*-----------------------------------------------------------------------------
GetIndexFor2D(uint32_t & index)1069 int32_t CmSurface2DRTBase::GetIndexFor2D( uint32_t& index )
1070 {
1071     index = m_handle;
1072     return CM_SUCCESS;
1073 }
1074 
SetSurfaceProperties(uint32_t width,uint32_t height,CM_SURFACE_FORMAT format)1075 int32_t CmSurface2DRTBase::SetSurfaceProperties(uint32_t width, uint32_t height, CM_SURFACE_FORMAT format)
1076 {
1077     if (format == CM_SURFACE_FORMAT_NV12)
1078     {
1079         m_pitch = MOS_ALIGN_CEIL(width * m_pitch /m_width , 2);
1080     }
1081     m_width = width;
1082     m_height = height;
1083     m_format = format;
1084 
1085     return CM_SUCCESS;
1086 }
1087 
1088 //*-----------------------------------------------------------------------------
1089 //| Purpose:    Get the description of surface 2d, width,height,format and the size of pixel .
1090 //| Arguments :
1091 //|               width         [out]     Reference to  width of surface
1092 //|               height        [out]     Reference to  height of surface
1093 //|               format        [out]     Reference to  format of surface
1094 //|               sizeperpixel  [out]     Reference to  the pixel's size in bytes
1095 //|
1096 //| Returns:    Result of the operation.
1097 //*-----------------------------------------------------------------------------
GetSurfaceDesc(uint32_t & width,uint32_t & height,CM_SURFACE_FORMAT & format,uint32_t & sizeperpixel)1098 CM_RT_API int32_t CmSurface2DRTBase::GetSurfaceDesc(uint32_t &width, uint32_t &height, CM_SURFACE_FORMAT &format,uint32_t &sizeperpixel)
1099 {
1100 
1101     int ret = CM_SUCCESS;
1102     uint32_t updatedHeight = 0 ;
1103 
1104     width  = m_width;
1105     height = m_height;
1106     format = m_format;
1107 
1108     // Get size per pixel
1109     ret = m_surfaceMgr->GetPixelBytesAndHeight(width,  height,  format,  sizeperpixel, updatedHeight);
1110 
1111     return ret;
1112 }
1113 
InitSurface(const unsigned int initValue,CmEvent * event,unsigned int useGPU)1114 CM_RT_API int32_t CmSurface2DRTBase::InitSurface(const unsigned int initValue, CmEvent* event, unsigned int useGPU)
1115 {
1116     INSERT_API_CALL_LOG(nullptr);
1117 
1118     CM_RETURN_CODE                      hr          = CM_SUCCESS;
1119     CmDeviceRT*                         cmDevice   = nullptr;
1120     CmQueueRT*                          queueRT     = nullptr;
1121     CmQueue*                            pCmQueue    = nullptr;
1122     PCM_CONTEXT_DATA                    cmData     = nullptr;
1123     CM_HAL_SURFACE2D_LOCK_UNLOCK_PARAM  inParam;
1124     uint32_t                            pitch       = 0;
1125     uint32_t                            *surf       = nullptr;
1126     uint32_t                            widthInBytes = 0;
1127 #if defined(_FULL_OPEN_SOURCE)
1128     useGPU = 0;
1129 #endif
1130 
1131 #if (_DEBUG || _RELEASE_INTERNAL)
1132     // Read VerbosityLevel from RegisterKey
1133     MOS_USER_FEATURE_VALUE_DATA userFeatureValueData = { 0 };
1134     m_surfaceMgr->GetCmDevice(cmDevice);
1135     CM_CHK_NULL_RETURN_CMERROR(cmDevice);
1136     cmData = (PCM_CONTEXT_DATA)cmDevice->GetAccelData();
1137     CM_ASSERT(cmData);
1138     CM_ASSERT(cmData->cmHalState);
1139 
1140     // User feature key reads
1141     int retStatus = MOS_UserFeature_ReadValue_ID(nullptr, __MEDIA_USER_FEATURE_VALUE_MDF_LOG_LEVEL_ID,
1142                     &userFeatureValueData, cmData->cmHalState->osInterface->pOsContext);
1143 #endif
1144 
1145     if( event )
1146     {
1147         CmEventRT *eventRT = dynamic_cast<CmEventRT *>(event);
1148         if (eventRT)
1149         {
1150             FlushDeviceQueue(eventRT);
1151         }
1152         else
1153         {
1154             event->WaitForTaskFinished();
1155         }
1156     }
1157 
1158     WaitForReferenceFree();   // wait all owner task finished
1159 
1160     uint32_t sizePerPixel  = 0;
1161     uint32_t updatedHeight = 0;
1162     CM_CHK_CMSTATUS_GOTOFINISH(m_surfaceMgr->GetPixelBytesAndHeight(m_width, m_height, m_format, sizePerPixel, updatedHeight));
1163 
1164     if (useGPU == 1)
1165     {
1166         m_surfaceMgr->GetCmDevice(cmDevice);
1167         CM_CHK_NULL_RETURN_CMERROR(cmDevice);
1168         event = nullptr;
1169         hr = (CM_RETURN_CODE)cmDevice->GPUinitSurface(this, initValue, event);
1170         if (hr != CM_SUCCESS)
1171         {
1172             CM_ASSERTMESSAGE("Error: EnqueueInitSurface2D failure in CmSurface2DRTBase::InitSurface.")
1173         }
1174         hr = (CM_RETURN_CODE)event->WaitForTaskFinished();
1175         if (hr != CM_SUCCESS)
1176         {
1177             CM_ASSERTMESSAGE("Error: WaitForTaskFinished failure in CmSurface2DRTBase::InitSurface.")
1178         }
1179 
1180         uint64_t executionTimeInNS = 0;
1181         hr = (CM_RETURN_CODE)event->GetExecutionTime(executionTimeInNS);
1182         if (hr != CM_SUCCESS)
1183         {
1184             CM_ASSERTMESSAGE("Error: GetExecutionTime failure in CmSurface2DRTBase::InitSurface.")
1185         }
1186 #if (_DEBUG || _RELEASE_INTERNAL)
1187         if (userFeatureValueData.u32Data >= CM_LOG_LEVEL_DEBUG)
1188         {
1189             printf("  CmSurface2DRTBase::InitSurface   GPU Kernel init surface execution time is %d ns\n", (unsigned int)executionTimeInNS);
1190         }
1191 #endif
1192     }
1193     else
1194     {
1195         m_surfaceMgr->GetCmDevice(cmDevice);
1196         CM_CHK_NULL_RETURN_CMERROR(cmDevice);
1197         cmData = (PCM_CONTEXT_DATA)cmDevice->GetAccelData();
1198         CM_CHK_NULL_RETURN_CMERROR(cmData);
1199         CM_CHK_NULL_RETURN_CMERROR(cmData->cmHalState);
1200 
1201         CmSafeMemSet(&inParam, 0, sizeof(CM_HAL_SURFACE2D_LOCK_UNLOCK_PARAM));
1202         inParam.width = m_width;
1203         inParam.height = m_height;
1204         inParam.handle = m_handle;
1205         inParam.lockFlag = CM_HAL_LOCKFLAG_WRITEONLY;
1206 
1207         CM_CHK_MOSSTATUS_GOTOFINISH_CMERROR(cmData->cmHalState->pfnLock2DResource(cmData->cmHalState, &inParam));
1208         CM_CHK_NULL_GOTOFINISH_CMERROR(inParam.data);
1209 
1210         pitch = inParam.pitch;
1211         surf = (uint32_t*)inParam.data;
1212 
1213         widthInBytes = m_width * sizePerPixel;
1214         if (widthInBytes != pitch)
1215         {
1216             for (uint32_t i = 0; i < updatedHeight; i++)
1217             {
1218                 if (widthInBytes % sizeof(uint32_t) == 0)
1219                 {
1220                     CmDwordMemSet(surf, initValue, widthInBytes);
1221                 }
1222                 else
1223                 {
1224                     CmDwordMemSet(surf, initValue, widthInBytes + sizeof(uint32_t));
1225                 }
1226 
1227                 surf += (pitch >> 2); // divide by 4 byte to dword
1228             }
1229         }
1230         else
1231         {
1232             CmDwordMemSet(surf, initValue, pitch * updatedHeight);
1233         }
1234 
1235         //Unlock Surface2D
1236         inParam.data = nullptr;
1237         CM_CHK_MOSSTATUS_GOTOFINISH_CMERROR(cmData->cmHalState->pfnUnlock2DResource(cmData->cmHalState, &inParam));
1238     }
1239 
1240 finish:
1241     return hr;
1242 }
1243 
1244 
SetMemoryObjectControl(MEMORY_OBJECT_CONTROL memCtrl,MEMORY_TYPE memType,uint32_t age)1245 int32_t CmSurface2DRTBase::SetMemoryObjectControl( MEMORY_OBJECT_CONTROL memCtrl, MEMORY_TYPE memType, uint32_t age)
1246 {
1247     int32_t  hr = CM_SUCCESS;
1248     uint16_t mocs = 0;
1249     hr = CmSurface::SetMemoryObjectControl(memCtrl, memType, age);
1250     CmDeviceRT *cmDevice = nullptr;
1251     m_surfaceMgr->GetCmDevice(cmDevice);
1252     CM_CHK_NULL_RETURN_CMERROR(cmDevice);
1253     PCM_CONTEXT_DATA cmData = (PCM_CONTEXT_DATA)cmDevice->GetAccelData();
1254     CM_CHK_NULL_RETURN_CMERROR(cmData);
1255     CM_CHK_NULL_RETURN_CMERROR(cmData->cmHalState);
1256 
1257     mocs = (m_memObjCtrl.mem_ctrl << 8) | (m_memObjCtrl.mem_type<<4) | m_memObjCtrl.age;
1258     CM_CHK_MOSSTATUS_GOTOFINISH_CMERROR(cmData->cmHalState->pfnSetSurfaceMOCS(cmData->cmHalState, m_handle, mocs, ARG_KIND_SURFACE_2D));
1259     ++ m_propertyIndex;
1260 finish:
1261     return hr;
1262 }
1263 
SelectMemoryObjectControlSetting(MEMORY_OBJECT_CONTROL memCtrl)1264 CM_RT_API int32_t CmSurface2DRTBase::SelectMemoryObjectControlSetting(MEMORY_OBJECT_CONTROL memCtrl)
1265 {
1266     INSERT_API_CALL_LOG(nullptr);
1267     ++ m_propertyIndex;
1268     return SetMemoryObjectControl(memCtrl, CM_USE_PTE, 0);
1269 }
1270 
SetResourceUsage(const MOS_HW_RESOURCE_DEF mosUsage)1271 CMRT_UMD_API int32_t CmSurface2DRTBase::SetResourceUsage(const MOS_HW_RESOURCE_DEF mosUsage)
1272 {
1273     INSERT_API_CALL_LOG(nullptr);
1274     int32_t  hr = CM_SUCCESS;
1275     uint16_t mocs = 0;
1276     hr = CmSurface::SetResourceUsage(mosUsage);
1277 
1278     CmDeviceRT *cmDevice = nullptr;
1279     m_surfaceMgr->GetCmDevice(cmDevice);
1280     CM_CHK_NULL_RETURN_CMERROR(cmDevice);
1281     PCM_CONTEXT_DATA cmData = (PCM_CONTEXT_DATA)cmDevice->GetAccelData();
1282     CM_CHK_NULL_RETURN_CMERROR(cmData);
1283     CM_CHK_NULL_RETURN_CMERROR(cmData->cmHalState);
1284 
1285     mocs = (m_memObjCtrl.mem_ctrl << 8) | (m_memObjCtrl.mem_type << 4) | m_memObjCtrl.age;
1286     CM_CHK_MOSSTATUS_GOTOFINISH_CMERROR(cmData->cmHalState->pfnSetSurfaceMOCS(cmData->cmHalState, m_handle, mocs, ARG_KIND_SURFACE_2D));
1287     ++ m_propertyIndex;
1288 finish:
1289     return hr;
1290 }
1291 
Create2DAlias(SurfaceIndex * & aliasIndex)1292 int32_t CmSurface2DRTBase::Create2DAlias(SurfaceIndex* & aliasIndex)
1293 {
1294     INSERT_API_CALL_LOG(nullptr);
1295 
1296     uint32_t surfArraySize = 0;
1297 
1298     if( m_numAliases < CM_HAL_MAX_NUM_2D_ALIASES )
1299     {
1300         uint32_t origIndex = m_index->get_data();
1301         m_surfaceMgr->GetSurfaceArraySize(surfArraySize);
1302         uint32_t newIndex = origIndex + ( (m_numAliases + 1) * surfArraySize);
1303         m_aliasIndexes[m_numAliases] = MOS_New(SurfaceIndex, newIndex);
1304         if( m_aliasIndexes[m_numAliases] )
1305         {
1306             aliasIndex = m_aliasIndexes[m_numAliases];
1307             m_numAliases++;
1308             return CM_SUCCESS;
1309         }
1310         else
1311         {
1312             CM_ASSERTMESSAGE("Error: Failed to create surface 2d alias due to out of system memory.");
1313             return CM_OUT_OF_HOST_MEMORY;
1314         }
1315     }
1316     else
1317     {
1318         return CM_EXCEED_MAX_NUM_2D_ALIASES;
1319     }
1320 }
1321 
GetNumAliases(uint32_t & numAliases)1322 CM_RT_API int32_t CmSurface2DRTBase::GetNumAliases(uint32_t& numAliases)
1323 {
1324     numAliases = m_numAliases;
1325     return CM_SUCCESS;
1326 }
1327 
SetSurfaceStateParam(SurfaceIndex * surfIndex,const CM_SURFACE2D_STATE_PARAM * surfStateParam)1328 CM_RT_API int32_t CmSurface2DRTBase::SetSurfaceStateParam( SurfaceIndex *surfIndex, const CM_SURFACE2D_STATE_PARAM *surfStateParam )
1329 {
1330     CM_RETURN_CODE  hr = CM_SUCCESS;
1331     CmDeviceRT * cmDevice = nullptr;
1332     PCM_CONTEXT_DATA cmData = nullptr;
1333     CM_HAL_SURFACE2D_SURFACE_STATE_PARAM inParam;
1334     uint32_t aliasIndex = 0;
1335 
1336     m_surfaceMgr->GetCmDevice( cmDevice );
1337     CM_CHK_NULL_GOTOFINISH_CMERROR(cmDevice);
1338     cmData = ( PCM_CONTEXT_DATA )cmDevice->GetAccelData();
1339     CM_CHK_NULL_GOTOFINISH_CMERROR(cmData);
1340     CM_CHK_NULL_GOTOFINISH_CMERROR(cmData->cmHalState);
1341 
1342     CmSafeMemSet( &inParam, 0, sizeof( inParam ) );
1343     inParam.width       = surfStateParam->width;
1344     inParam.height      = surfStateParam->height;
1345     if (surfStateParam->format)
1346     {
1347         inParam.format = surfStateParam->format;
1348     }
1349     inParam.depth       = surfStateParam->depth;
1350     inParam.pitch       = surfStateParam->pitch;
1351     inParam.memoryObjectControl   = surfStateParam->memory_object_control;
1352     inParam.surfaceXOffset        = surfStateParam->surface_x_offset;
1353     inParam.surfaceYOffset        = surfStateParam->surface_y_offset;
1354     inParam.surfaceOffset         = surfStateParam->surface_offset;
1355 
1356     if (surfIndex)
1357     {
1358         aliasIndex = surfIndex->get_data();
1359     }
1360     else
1361     {
1362         aliasIndex = m_index->get_data();
1363     }
1364 
1365     CM_CHK_MOSSTATUS_GOTOFINISH_CMERROR( cmData->cmHalState->pfnSet2DSurfaceStateParam(cmData->cmHalState, &inParam, aliasIndex, m_handle) );
1366 
1367     ++ m_propertyIndex;
1368 
1369 finish:
1370     return hr;
1371 }
1372 
SetReadSyncFlag(bool readSync,CmQueue * cmQueue)1373 CMRT_UMD_API int32_t CmSurface2DRTBase::SetReadSyncFlag(bool readSync, CmQueue *cmQueue)
1374 {
1375     int32_t hr = CM_SUCCESS;
1376 
1377     CmDeviceRT *cmDevice = nullptr;
1378     m_surfaceMgr->GetCmDevice(cmDevice);
1379     CM_CHK_NULL_RETURN_CMERROR(cmDevice);
1380     PCM_CONTEXT_DATA cmData = (PCM_CONTEXT_DATA)cmDevice->GetAccelData();
1381     CM_CHK_NULL_RETURN_CMERROR(cmData);
1382     CM_CHK_NULL_RETURN_CMERROR(cmData->cmHalState);
1383 
1384     CmQueueRT *cmQueueRT = static_cast<CmQueueRT *>(cmQueue);
1385     CM_CHK_NULL_RETURN_CMERROR(cmQueueRT);
1386 
1387     hr = cmData->cmHalState->pfnSetSurfaceReadFlag(cmData->cmHalState, m_handle, readSync,
1388                                                    (MOS_GPU_CONTEXT)cmQueueRT->GetQueueOption().GPUContext);
1389 
1390     if( FAILED(hr) )
1391     {
1392         CM_ASSERTMESSAGE("Error: Set read sync flag failure.")
1393         return CM_FAILURE;
1394     }
1395 
1396     return hr;
1397 }
1398 
Log(std::ostringstream & oss)1399 void CmSurface2DRTBase::Log(std::ostringstream &oss)
1400 {
1401 #if CM_LOG_ON
1402     oss << " Surface2D Info "
1403         << " Width:" << m_width
1404         << " Height:"<< m_height
1405         << " Format:"<< GetFormatString(m_format)
1406         << " Pitch:" << m_pitch
1407         << " Handle:" << m_handle
1408         << " SurfaceIndex:" << m_index->get_data()
1409         << " IsCmCreated:"<<m_isCmCreated
1410         << std::endl;
1411 #endif
1412 }
1413 
DumpContent(uint32_t kernelNumber,char * kernelName,int32_t taskId,uint32_t argIndex,uint32_t vectorIndex)1414 void CmSurface2DRTBase::DumpContent(uint32_t kernelNumber, char *kernelName, int32_t taskId, uint32_t argIndex, uint32_t vectorIndex)
1415 {
1416 #if MDF_SURFACE_CONTENT_DUMP
1417     std::ostringstream         outputFileName;
1418 
1419     outputFileName << "t_" << taskId
1420         << "_k_" << kernelNumber
1421         << "_" << kernelName
1422         << "_argi_" << argIndex
1423         << "_vector_index_" << vectorIndex;
1424 
1425     DumpContentToFile(outputFileName.str().c_str());
1426 #endif
1427 }
1428 
DumpContentToFile(const char * filename)1429 void CmSurface2DRTBase::DumpContentToFile(const char *filename)
1430 {
1431 #if MDF_SURFACE_CONTENT_DUMP
1432     static uint32_t surface2DDumpNumber = 0;
1433     std::ostringstream outputFileName;
1434     char fileNamePrefix[MAX_PATH] = {0};
1435 
1436     outputFileName << filename
1437         << "_surf2d_surfi_"<< m_index->get_data()
1438         << "_w_" << m_width
1439         << "_h_" << m_height
1440         << "_p_" << m_pitch
1441         << "_f_" << GetFormatString(m_format)
1442         << "_" << surface2DDumpNumber;
1443 
1444     GetLogFileLocation(outputFileName.str().c_str(), fileNamePrefix,
1445                        GetMosContext());
1446     std::ofstream outputFileStream;
1447     // Open file
1448     outputFileStream.open(fileNamePrefix, std::ios::app | std::ios::binary);
1449     CM_ASSERT(outputFileStream);
1450 
1451     CmDeviceRT * cmDevice = nullptr;
1452     m_surfaceMgr->GetCmDevice(cmDevice);
1453     CM_ASSERT(cmDevice);
1454 
1455     CSync* surfaceLock = cmDevice->GetSurfaceLock();
1456     CM_ASSERT(surfaceLock);
1457     CLock locker(*surfaceLock);
1458     uint32_t        sizePerPixel = 0;
1459     uint32_t        updatedHeight = 0;
1460     uint32_t        surfaceSize = 0;
1461     uint32_t        widthInByte = 0;
1462     uint8_t         *dst = nullptr;
1463     uint8_t         *surf = nullptr;
1464     m_surfaceMgr->GetPixelBytesAndHeight(m_width, m_height, m_format, sizePerPixel, updatedHeight);
1465     surfaceSize = m_width*sizePerPixel*updatedHeight;
1466     widthInByte = m_width * sizePerPixel;
1467 
1468     std::vector<char>surface(surfaceSize);
1469 
1470     PCM_CONTEXT_DATA cmData = (PCM_CONTEXT_DATA)cmDevice->GetAccelData();
1471     CM_ASSERT(cmData);
1472     CM_ASSERT(cmData->cmHalState);
1473 
1474     PCM_HAL_SURFACE2D_ENTRY pEntry = &cmData->cmHalState->umdSurf2DTable[m_handle];
1475     CM_ASSERT(pEntry);
1476 
1477     PMOS_RESOURCE           pOsResource = &pEntry->osResource;
1478     CM_ASSERT(pOsResource->pGmmResInfo);
1479 
1480     GMM_RESOURCE_FLAG gmmFlags = pOsResource->pGmmResInfo->GetResFlags();
1481     if (gmmFlags.Info.NotLockable == true)
1482     {
1483         size_t alignSize = 4096;
1484         unsigned char* system = (unsigned char*)MOS_AlignedAllocMemory(surfaceSize, alignSize);
1485         CM_CHK_NULL_RETURN_VOID(system);
1486 
1487         CmQueue* queue = nullptr;
1488         int ret = cmDevice->CreateQueue(queue);
1489         if (ret != 0)
1490         {
1491             CM_ASSERTMESSAGE("Error: CreateQueue failure in dump.")
1492             return;
1493         }
1494 
1495         CmSurface2D* cmSurface2D = static_cast<CmSurface2D*>(this);
1496         CmQueueRT* queueRT = dynamic_cast<CmQueueRT*>(queue);
1497         CmEvent* event = nullptr;
1498         cmData->cmHalState->dumpSurfaceContent = false;
1499         ret = queueRT->EnqueueCopyGPUToCPU(cmSurface2D, system, event);
1500         if (ret != 0)
1501         {
1502             CM_ASSERTMESSAGE("Error: EnqueueCopyGPUToCPU failure in surface content dump.")
1503         }
1504         ret = event->WaitForTaskFinished();
1505         if (ret != 0)
1506         {
1507             CM_ASSERTMESSAGE("Error: WaitForTaskFinished failure in surface content dump.")
1508         }
1509 
1510         outputFileStream.write((char*)system, surfaceSize);
1511         cmData->cmHalState->dumpSurfaceContent = true;
1512         MOS_AlignedFreeMemory(system);
1513         if (queueRT)
1514         {
1515             CmQueueRT::Destroy(queueRT);
1516         }
1517     }
1518     else
1519     {
1520        int ret = ReadSurface((unsigned char*)&surface[0],nullptr);
1521        if (ret != 0)
1522        {
1523            CM_ASSERTMESSAGE("Error: ReadSurface failure in surface content dump.")
1524        }
1525        outputFileStream.write(&surface[0], surfaceSize);
1526     }
1527     outputFileStream.close();
1528     surface2DDumpNumber++;
1529 #endif
1530 }
1531 
SetProperty(CM_FRAME_TYPE frameType)1532 CM_RT_API int32_t CmSurface2DRTBase::SetProperty(CM_FRAME_TYPE frameType)
1533 {
1534     m_frameType = frameType;
1535     m_surfaceMgr->UpdateSurface2DTableFrameType(m_handle, frameType);
1536     ++ m_propertyIndex;
1537     return CM_SUCCESS;
1538 }
1539 
UpdateResource(MOS_RESOURCE * resource)1540 int32_t CmSurface2DRTBase::UpdateResource(MOS_RESOURCE *resource)
1541 {
1542     // get index
1543     int index = m_index->get_data();
1544     return m_surfaceMgr->UpdateSurface2D(resource, index, m_handle);
1545 }
1546 
UpdateSurfaceProperty(uint32_t width,uint32_t height,uint32_t pitch,CM_SURFACE_FORMAT format)1547 int32_t CmSurface2DRTBase::UpdateSurfaceProperty(uint32_t width, uint32_t height, uint32_t pitch, CM_SURFACE_FORMAT format)
1548 {
1549     int result = m_surfaceMgr->Surface2DSanityCheck(width, height, format);
1550     if( result != CM_SUCCESS )
1551     {
1552         CM_ASSERTMESSAGE("Error: Surface 2D sanity check failure.");
1553         return result;
1554     }
1555     m_width = width;
1556     m_height = height;
1557     m_pitch = pitch;
1558     m_format = format;
1559     ++ m_propertyIndex;
1560     return CM_SUCCESS;
1561 }
1562 
1563 }
1564