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