1 /*
2 * Copyright (c) 2007-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_3d_rt.cpp
24 //! \brief     Contains CmSurface3DRT implementations.
25 //!
26 
27 #include "cm_surface_3d_rt.h"
28 
29 #include "cm_device_rt.h"
30 #include "cm_event_rt.h"
31 #include "cm_mem.h"
32 #include "cm_surface_manager.h"
33 #include "cm_hal.h"
34 
35 namespace CMRT_UMD
36 {
Create(uint32_t index,uint32_t handle,uint32_t width,uint32_t height,uint32_t depth,CM_SURFACE_FORMAT format,CmSurfaceManager * surfaceManager,CmSurface3DRT * & surface)37 int32_t CmSurface3DRT::Create( uint32_t index, uint32_t handle,
38                             uint32_t width, uint32_t height, uint32_t depth,
39                             CM_SURFACE_FORMAT format,
40                             CmSurfaceManager* surfaceManager, CmSurface3DRT* &surface )
41 {
42     int32_t result = CM_SUCCESS;
43 
44     surface = new (std::nothrow) CmSurface3DRT( handle, width, height, depth, format, surfaceManager );
45     if( surface )
46     {
47 
48         result = surface->Initialize( index );
49         if( result != CM_SUCCESS )
50         {
51             CmSurface* baseSurface = surface;
52             CmSurface::Destroy( baseSurface );
53         }
54 
55     }
56     else
57     {
58         CM_ASSERTMESSAGE("Error: Failed to create CmSurface3D due to out of system memory.")
59         result = CM_OUT_OF_HOST_MEMORY;
60     }
61 
62     return result;
63 }
64 
CmSurface3DRT(uint32_t handle,uint32_t width,uint32_t height,uint32_t depth,CM_SURFACE_FORMAT format,CmSurfaceManager * surfaceManager)65 CmSurface3DRT::CmSurface3DRT( uint32_t handle,
66     uint32_t width,
67     uint32_t height,
68     uint32_t depth,
69     CM_SURFACE_FORMAT format,
70     CmSurfaceManager* surfaceManager ):
71     CmSurface( surfaceManager,true ),
72     m_handle( handle ),
73     m_width( width ),
74     m_height( height ),
75     m_depth( depth ),
76     m_format( format )
77 {
78     CmSurface::SetMemoryObjectControl(MEMORY_OBJECT_CONTROL_UNKNOW, CM_USE_PTE, 0);
79 }
80 
~CmSurface3DRT(void)81 CmSurface3DRT::~CmSurface3DRT( void )
82 {
83 }
84 
Initialize(uint32_t index)85 int32_t CmSurface3DRT::Initialize( uint32_t index )
86 {
87     return CmSurface::Initialize( index );
88 }
89 
GetHandle(uint32_t & handle)90 int32_t CmSurface3DRT::GetHandle( uint32_t& handle)
91 {
92     handle = m_handle;
93     return CM_SUCCESS;
94 }
95 
WriteSurface(const unsigned char * sysMem,CmEvent * event,uint64_t sysMemSize)96 CM_RT_API int32_t CmSurface3DRT::WriteSurface( const unsigned char* sysMem,
97                                                 CmEvent* event,
98                                                 uint64_t sysMemSize )
99 {
100     INSERT_API_CALL_LOG(nullptr);
101     CM_RETURN_CODE  hr              = CM_SUCCESS;
102     uint64_t        uSizeInBytes    = 0;
103     uint32_t        uWidthInBytes   = 0;
104     uint8_t         *tempDst        = nullptr;
105     uint8_t         *tempSrc        = nullptr;
106     uint8_t         *rPlane         = nullptr;
107 
108     if(sysMem == nullptr)
109     {
110         CM_ASSERTMESSAGE("Error: Pointer to system memory is null.")
111         return CM_INVALID_ARG_VALUE;
112     }
113 
114     uint32_t pixel = 0;
115     switch (m_format)
116     {
117         case CM_SURFACE_FORMAT_X8R8G8B8:
118         case CM_SURFACE_FORMAT_A8R8G8B8:
119             pixel = 4;
120             break;
121         case CM_SURFACE_FORMAT_A16B16G16R16:
122             pixel = 8;
123             break;
124         default:
125             CM_ASSERTMESSAGE("Error: Unsupported surface format.")
126             return CM_INVALID_ARG_VALUE;
127     }
128 
129     uSizeInBytes = m_width * m_height * m_depth * pixel;
130     if (sysMemSize < uSizeInBytes)
131     {
132         CM_ASSERTMESSAGE("Error: Invalid copy size.")
133         return CM_INVALID_ARG_VALUE;
134     }
135 
136     // It makes sense to flush the whole enqueued tasks for each surface read
137     // because usually we read the output of the last task.
138     // Update: using event not to flush the whole enqueued tasks
139     if( event )
140     {
141         CmEventRT *eventRT = static_cast<CmEventRT *>(event);
142         FlushDeviceQueue( eventRT );  // wait specific owner task finished
143     }
144 
145     WaitForReferenceFree();   // wait all owner task finished
146 
147     CM_HAL_3DRESOURCE_PARAM inParam;
148     CmSafeMemSet( &inParam, 0, sizeof( CM_HAL_3DRESOURCE_PARAM ) );
149 
150     CmDeviceRT* device = nullptr;
151     m_surfaceMgr->GetCmDevice( device );
152     CM_ASSERT( device );
153     PCM_CONTEXT_DATA cmData = (PCM_CONTEXT_DATA)device->GetAccelData();
154     CM_CHK_NULL_RETURN_CMERROR(cmData);
155     CM_CHK_NULL_RETURN_CMERROR(cmData->cmHalState);
156 
157     inParam.handle = m_handle;
158     inParam.data = (void*)sysMem; //Any non-nullptr value will work
159     inParam.width = m_width;
160     inParam.height = m_height;
161     inParam.depth = m_depth;
162     inParam.lockFlag = CM_HAL_LOCKFLAG_WRITEONLY;
163 
164     // Lock 3D Resource
165     // Lock may fail due to the out of memory/out of page-in in KMD.
166     // Touch queue for the buffer/surface data release
167     CM_CHK_MOSSTATUS_GOTOFINISH_CMERROR(cmData->cmHalState->pfnLock3DResource(cmData->cmHalState, &inParam));
168     CM_CHK_NULL_GOTOFINISH_CMERROR(inParam.data);
169 
170     uWidthInBytes = inParam.width * pixel;
171 
172     //Copy Resource
173     tempDst    = (uint8_t*)inParam.data;
174     tempSrc    = (uint8_t*)sysMem;
175     rPlane     = (uint8_t*)inParam.data;
176 
177     // Only use Qpitch when Qpitch is supported by HW
178     if (inParam.qpitchEnabled)
179     {
180         if (inParam.pitch == uWidthInBytes && inParam.qpitch == inParam.height)
181         {
182             CmFastMemCopyWC(tempDst, tempSrc, (size_t)uSizeInBytes);
183         }
184         else
185         {
186             for (uint32_t uZ = 0; uZ < inParam.depth; uZ++)
187             {
188                 tempDst = rPlane;
189                 for (uint32_t uY = 0; uY < inParam.height; uY++)
190                 {
191                     CmFastMemCopyWC(tempDst, tempSrc, uWidthInBytes);
192                     tempSrc += uWidthInBytes;
193                     tempDst += inParam.pitch;
194                 }
195                 rPlane += inParam.qpitch * inParam.pitch;
196             }
197         }
198     }
199     else
200     {
201         if (inParam.pitch == uWidthInBytes)
202         {
203             CmFastMemCopyWC(tempDst, tempSrc, (size_t)uSizeInBytes);
204         }
205         else
206         {
207             for (uint32_t uZ = 0; uZ < inParam.depth; uZ++)
208             {
209                 for (uint32_t uY = 0; uY < inParam.height; uY++)
210                 {
211                     CmFastMemCopyWC(tempDst, tempSrc, uWidthInBytes);
212                     tempSrc += uWidthInBytes;
213                     tempDst += inParam.pitch;
214                 }
215             }
216         }
217     }
218 
219     // unlock 3D resource
220     CM_CHK_MOSSTATUS_GOTOFINISH_CMERROR(cmData->cmHalState->pfnUnlock3DResource(cmData->cmHalState, &inParam));
221 
222 finish:
223     if (hr < CM_MOS_STATUS_CONVERTED_CODE_OFFSET) {
224         hr = CM_LOCK_SURFACE_FAIL;
225     }
226     return hr;
227 }
228 
ReadSurface(unsigned char * sysMem,CmEvent * event,uint64_t sysMemSize)229 CM_RT_API int32_t CmSurface3DRT::ReadSurface( unsigned char* sysMem, CmEvent* event, uint64_t sysMemSize )
230 {
231     INSERT_API_CALL_LOG(nullptr);
232     CM_RETURN_CODE  hr              = CM_SUCCESS;
233     uint64_t        uSizeInBytes    = 0;
234     uint32_t        uWidthInBytes   = 0;
235     uint8_t         *tempDst        = nullptr;
236     uint8_t         *tempSrc        = nullptr;
237     uint8_t         *rPlane         = nullptr;
238 
239     if(sysMem == nullptr)
240     {
241         CM_ASSERTMESSAGE("Error: Pointer to system memory is null.")
242         return CM_INVALID_ARG_VALUE;
243     }
244 
245     uint32_t pixel = 0;
246     switch (m_format)
247     {
248         case CM_SURFACE_FORMAT_X8R8G8B8:
249         case CM_SURFACE_FORMAT_A8R8G8B8:
250             pixel = 4;
251             break;
252         case CM_SURFACE_FORMAT_A16B16G16R16:
253             pixel = 8;
254             break;
255         default:
256             CM_ASSERTMESSAGE("Error: Unsupported surface format.")
257             return CM_INVALID_ARG_VALUE;
258     }
259 
260     uSizeInBytes = m_width * m_height * m_depth * pixel;
261     if (sysMemSize < uSizeInBytes)
262     {
263         CM_ASSERTMESSAGE("Error: Invalid copy size.")
264         return CM_INVALID_ARG_VALUE;
265     }
266 
267     // It makes sense to flush the whole enqueued tasks for each surface read
268     // because usually we read the output of the last task.
269     // Update: using event not to flush the whole enqueued tasks
270     if( event )
271     {
272         CmEventRT *eventRT = static_cast<CmEventRT *>(event);
273         int hr = FlushDeviceQueue( eventRT );  // wait specific owner task finished
274         {
275             CM_ASSERTMESSAGE("Fail to flush queue.");
276             return hr;
277         }
278     }
279 
280     WaitForReferenceFree();   // wait all owner task finished
281 
282     CM_HAL_3DRESOURCE_PARAM inParam;
283     CmSafeMemSet( &inParam, 0, sizeof( CM_HAL_3DRESOURCE_PARAM ) );
284 
285     CmDeviceRT* device = nullptr;
286     m_surfaceMgr->GetCmDevice( device );
287     CM_ASSERT( device );
288     PCM_CONTEXT_DATA cmData = (PCM_CONTEXT_DATA)device->GetAccelData();
289     CM_CHK_NULL_RETURN_CMERROR(cmData);
290     CM_CHK_NULL_RETURN_CMERROR(cmData->cmHalState);
291 
292     inParam.handle = m_handle;
293     inParam.data = (void*)sysMem; //Any non-nullptr value will work
294     inParam.width = m_width;
295     inParam.height = m_height;
296     inParam.depth = m_depth;
297     inParam.lockFlag = CM_HAL_LOCKFLAG_READONLY;
298 
299     // Lock 3D Resource
300     // Lock may fail due to the out of memory/out of page-in in KMD.
301     // Touch queue for the buffer/surface data release
302     CM_CHK_MOSSTATUS_GOTOFINISH_CMERROR(cmData->cmHalState->pfnLock3DResource(cmData->cmHalState, &inParam));
303     CM_CHK_NULL_GOTOFINISH_CMERROR(inParam.data);
304 
305     uWidthInBytes = inParam.width * pixel;
306 
307     //Copy Resource
308     tempDst    = (uint8_t*)sysMem;
309     tempSrc    = (uint8_t*)inParam.data;
310     rPlane     = (uint8_t*)inParam.data;
311 
312     // Only use Qpitch when Qpitch is supported by HW
313     if (inParam.qpitchEnabled)
314     {
315         if (inParam.pitch == uWidthInBytes && inParam.qpitch == inParam.height)
316         {
317             CmFastMemCopyFromWC(tempDst, tempSrc, (size_t)uSizeInBytes, GetCpuInstructionLevel());
318         }
319         else
320         {
321             for (uint32_t uZ = 0; uZ < inParam.depth; uZ++)
322             {
323                 tempSrc = rPlane;
324                 for (uint32_t uY = 0; uY < inParam.height; uY++)
325                 {
326                     CmFastMemCopyFromWC(tempDst, tempSrc, uWidthInBytes, GetCpuInstructionLevel());
327                     tempSrc += inParam.pitch;
328                     tempDst += uWidthInBytes;
329                 }
330                 rPlane += inParam.qpitch * inParam.pitch;
331             }
332         }
333     }
334     else
335     {
336         if (inParam.pitch == uWidthInBytes)
337         {
338             CmFastMemCopyFromWC(tempDst, tempSrc, (size_t)uSizeInBytes, GetCpuInstructionLevel());
339         }
340         else
341         {
342             for (uint32_t uZ = 0; uZ < inParam.depth; uZ++)
343             {
344                 for (uint32_t uY = 0; uY < inParam.height; uY++)
345                 {
346                     CmFastMemCopyFromWC(tempDst, tempSrc, uWidthInBytes, GetCpuInstructionLevel());
347                     tempSrc += inParam.pitch;
348                     tempDst += uWidthInBytes;
349                 }
350             }
351         }
352     }
353 
354     // unlock 3D resource
355     CM_CHK_MOSSTATUS_GOTOFINISH_CMERROR(cmData->cmHalState->pfnUnlock3DResource(cmData->cmHalState, &inParam));
356 
357 finish:
358     if (hr < CM_MOS_STATUS_CONVERTED_CODE_OFFSET) {
359         hr = CM_LOCK_SURFACE_FAIL;
360     }
361     return hr;
362 }
363 
GetIndex(SurfaceIndex * & index)364 CM_RT_API int32_t CmSurface3DRT::GetIndex( SurfaceIndex*& index )
365 {
366     index = m_index;
367     return CM_SUCCESS;
368 }
369 
370 //*-----------------------------------------------------------------------------
371 //| Purpose:    Get Properties of  CmSurface3DRT
372 //| Returns:    CM_SUCCESS.
373 //*-----------------------------------------------------------------------------
GetProperties(uint32_t & width,uint32_t & height,uint32_t & depth,CM_SURFACE_FORMAT & format)374 int32_t CmSurface3DRT::GetProperties( uint32_t& width,  uint32_t& height, uint32_t& depth, CM_SURFACE_FORMAT& format)
375 {
376     width  = m_width;
377     height = m_height;
378     depth = m_depth;
379     format = m_format;
380     return CM_SUCCESS;
381 }
382 
SetProperties(uint32_t width,uint32_t height,uint32_t depth,CM_SURFACE_FORMAT format)383 int32_t CmSurface3DRT::SetProperties( uint32_t width,  uint32_t height, uint32_t depth, CM_SURFACE_FORMAT format)
384 {
385     m_width  = width;
386     m_height = height;
387     m_depth  = depth;
388     m_format = format;
389     return CM_SUCCESS;
390 }
391 
InitSurface(const uint32_t initValue,CmEvent * event)392 CM_RT_API int32_t CmSurface3DRT::InitSurface(const uint32_t initValue, CmEvent* event)
393 {
394     INSERT_API_CALL_LOG(nullptr);
395     CM_RETURN_CODE  hr = CM_SUCCESS;
396     uint32_t        uSizeInBytes = 0;
397     uint32_t        uWidthInBytes = 0;
398     uint8_t         *tempDst = nullptr;
399     uint8_t         *rPlane = nullptr;
400 
401     // It makes sense to flush the whole enqueued tasks for each surface read
402     // because usually we read the output of the last task.
403     // Update: using event not to flush the whole enqueued tasks
404     if( event )
405     {
406         CmEventRT *eventRT = static_cast<CmEventRT *>(event);
407         FlushDeviceQueue( eventRT );  // wait specific owner task finished
408     }
409 
410     WaitForReferenceFree();   // wait all owner task finished
411 
412     CM_HAL_3DRESOURCE_PARAM inParam;
413     CmSafeMemSet( &inParam, 0, sizeof( CM_HAL_3DRESOURCE_PARAM ) );
414 
415     CmDeviceRT* device = nullptr;
416     m_surfaceMgr->GetCmDevice( device );
417     CM_ASSERT( device );
418     PCM_CONTEXT_DATA cmData = (PCM_CONTEXT_DATA)device->GetAccelData();
419     CM_CHK_NULL_RETURN_CMERROR(cmData);
420     CM_CHK_NULL_RETURN_CMERROR(cmData->cmHalState);
421 
422     uint32_t sizePerPixel = 0;
423     uint32_t updatedHeight = 0;
424     CM_CHK_CMSTATUS_GOTOFINISH(m_surfaceMgr->GetPixelBytesAndHeight(m_width, m_height, m_format, sizePerPixel, updatedHeight));
425 
426     inParam.handle = m_handle;
427     inParam.data = (void*)0x44; //Any non-nullptr value will work
428     inParam.width = m_width;
429     inParam.height = m_height;
430     inParam.depth = m_depth;
431     inParam.lockFlag = CM_HAL_LOCKFLAG_WRITEONLY;
432 
433     CM_CHK_MOSSTATUS_GOTOFINISH_CMERROR(cmData->cmHalState->pfnLock3DResource(cmData->cmHalState, &inParam));
434     CM_CHK_NULL_GOTOFINISH_CMERROR(inParam.data);
435 
436     uSizeInBytes = inParam.width * inParam.height * inParam.depth * sizePerPixel;
437     uWidthInBytes = inParam.width * sizePerPixel;
438 
439     //Copy Resource
440     tempDst = (uint8_t*)inParam.data;
441     rPlane  = (uint8_t*)inParam.data;
442 
443     // Only use Qpitch when Qpitch is supported by HW
444     if (inParam.qpitchEnabled)
445     {
446         if (inParam.pitch == uWidthInBytes && inParam.qpitch == inParam.height)
447         {
448             CmDwordMemSet(tempDst, initValue, uSizeInBytes);
449         }
450         else
451         {
452             for (uint32_t uZ = 0; uZ < inParam.depth; uZ++)
453             {
454                 tempDst = rPlane;
455                 for (uint32_t uY = 0; uY < inParam.height; uY++)
456                 {
457                     CmDwordMemSet(tempDst, initValue, uWidthInBytes);
458                     tempDst += inParam.pitch;
459                 }
460                 rPlane += inParam.qpitch * inParam.pitch;
461             }
462         }
463     }
464     else
465     {
466         if (inParam.pitch == uWidthInBytes)
467         {
468             CmDwordMemSet(tempDst, initValue, uSizeInBytes);
469         }
470         else
471         {
472             for (uint32_t uZ = 0; uZ < inParam.depth; uZ++)
473             {
474                 for (uint32_t uY = 0; uY < inParam.height; uY++)
475                 {
476                     CmDwordMemSet(tempDst, initValue, uWidthInBytes);
477                     tempDst += inParam.pitch;
478                 }
479             }
480         }
481     }
482 
483     // unlock
484     inParam.data = nullptr;
485     inParam.handle = m_handle;
486 
487     CM_CHK_MOSSTATUS_GOTOFINISH_CMERROR(cmData->cmHalState->pfnUnlock3DResource(cmData->cmHalState, &inParam));
488 
489 finish:
490     if (hr < CM_MOS_STATUS_CONVERTED_CODE_OFFSET) {
491         hr = CM_LOCK_SURFACE_FAIL;
492     }
493     return hr;
494 }
495 
SetMemoryObjectControl(MEMORY_OBJECT_CONTROL memCtrl,MEMORY_TYPE memType,uint32_t age)496 int32_t CmSurface3DRT::SetMemoryObjectControl( MEMORY_OBJECT_CONTROL memCtrl, MEMORY_TYPE memType, uint32_t age)
497 {
498     CM_RETURN_CODE  hr = CM_SUCCESS;
499     uint16_t mocs = 0;
500 
501     CmSurface::SetMemoryObjectControl( memCtrl, memType, age );
502 
503     CmDeviceRT *cmDevice = nullptr;
504     m_surfaceMgr->GetCmDevice(cmDevice);
505     CM_CHK_NULL_RETURN_CMERROR(cmDevice);
506     PCM_CONTEXT_DATA cmData = (PCM_CONTEXT_DATA)cmDevice->GetAccelData();
507     CM_CHK_NULL_RETURN_CMERROR(cmData);
508     CM_CHK_NULL_RETURN_CMERROR(cmData->cmHalState);
509 
510     mocs = (m_memObjCtrl.mem_ctrl << 8) | (m_memObjCtrl.mem_type<<4) | m_memObjCtrl.age;
511 
512     CM_CHK_MOSSTATUS_GOTOFINISH_CMERROR(cmData->cmHalState->pfnSetSurfaceMOCS(cmData->cmHalState, m_handle, mocs, ARG_KIND_SURFACE_3D));
513 
514 finish:
515     return hr;
516 }
517 
SelectMemoryObjectControlSetting(MEMORY_OBJECT_CONTROL memCtrl)518 CM_RT_API int32_t CmSurface3DRT::SelectMemoryObjectControlSetting(MEMORY_OBJECT_CONTROL memCtrl)
519 {
520     return SetMemoryObjectControl(memCtrl, CM_USE_PTE, 0);
521 }
522 
SetResourceUsage(const MOS_HW_RESOURCE_DEF mosUsage)523 CMRT_UMD_API int32_t CmSurface3DRT::SetResourceUsage(const MOS_HW_RESOURCE_DEF mosUsage)
524 {
525     int32_t  hr = CM_SUCCESS;
526     uint16_t mocs = 0;
527     hr = CmSurface::SetResourceUsage(mosUsage);
528 
529     CmDeviceRT *cmDevice = nullptr;
530     m_surfaceMgr->GetCmDevice(cmDevice);
531     CM_CHK_NULL_RETURN_CMERROR(cmDevice);
532     PCM_CONTEXT_DATA cmData = (PCM_CONTEXT_DATA)cmDevice->GetAccelData();
533     CM_CHK_NULL_RETURN_CMERROR(cmData);
534     CM_CHK_NULL_RETURN_CMERROR(cmData->cmHalState);
535 
536     mocs = (m_memObjCtrl.mem_ctrl << 8) | (m_memObjCtrl.mem_type << 4) | m_memObjCtrl.age;
537     CM_CHK_MOSSTATUS_GOTOFINISH_CMERROR(cmData->cmHalState->pfnSetSurfaceMOCS(cmData->cmHalState, m_handle, mocs, ARG_KIND_SURFACE_3D));
538 finish:
539     return hr;
540 }
541 
542 
Log(std::ostringstream & oss)543 void CmSurface3DRT::Log(std::ostringstream &oss)
544 {
545 #if CM_LOG_ON
546     oss << " Surface3D Info "
547         << " Width:" << m_width
548         << " Height:" << m_height
549         << " Depth:" << m_depth
550         << " Format:" << GetFormatString(m_format)
551         << " Handle:" << m_handle
552         << " SurfaceIndex:" << m_index->get_data()
553         << " IsCmCreated:" << m_isCmCreated
554         << std::endl;
555 #endif
556 }
557 
DumpContent(uint32_t kernelNumber,char * kernelName,int32_t taskId,uint32_t argIndex,uint32_t vectorIndex)558 void CmSurface3DRT::DumpContent(uint32_t kernelNumber, char *kernelName, int32_t taskId, uint32_t argIndex, uint32_t vectorIndex)
559 {
560 #if MDF_SURFACE_CONTENT_DUMP
561     std::ostringstream outputFileName;
562     static uint32_t    surface3DDumpNumber = 0;
563     char               fileNamePrefix[MAX_PATH] = { 0 };
564     std::ofstream      outputFileStream;
565 
566     outputFileName << "t_" << taskId
567         << "_k_" << kernelNumber
568         << "_" << kernelName
569         << "_argi_" << argIndex
570         << "_vector_index_" << vectorIndex
571         << "_surf2d_surfi_" << m_index->get_data()
572         << "_w_" << m_width
573         << "_h_" << m_height
574         << "_d_" << m_depth
575         << "_f_" << GetFormatString(m_format)
576         << "_" << surface3DDumpNumber;
577 
578     GetLogFileLocation(outputFileName.str().c_str(), fileNamePrefix,
579                        GetMosContext());
580     // Open file
581     outputFileStream.open(fileNamePrefix, std::ios::app | std::ios::binary);
582     CM_ASSERT(outputFileStream);
583 
584     uint32_t        surfaceSize = 0;
585     uint32_t        sizePerPixel = 0;
586     uint32_t        updatedHeight = 0;
587     uint32_t        uWidthInBytes = 0;
588     uint8_t         *tempDst = nullptr;
589     uint8_t         *tempSrc = nullptr;
590     uint8_t         *rPlane = nullptr;
591     m_surfaceMgr->GetPixelBytesAndHeight(m_width, m_height, m_format, sizePerPixel, updatedHeight);
592     surfaceSize = m_width * updatedHeight * m_depth * sizePerPixel;
593     uWidthInBytes = m_width * sizePerPixel;
594     std::vector<char>surface(surfaceSize);
595 
596     CM_HAL_3DRESOURCE_PARAM inParam;
597     CmSafeMemSet(&inParam, 0, sizeof(CM_HAL_3DRESOURCE_PARAM));
598 
599     CmDeviceRT* device = nullptr;
600     m_surfaceMgr->GetCmDevice(device);
601     CM_ASSERT(device);
602     PCM_CONTEXT_DATA cmData = (PCM_CONTEXT_DATA)device->GetAccelData();
603     CM_ASSERT(cmData);
604     CM_ASSERT(cmData->cmHalState);
605 
606     inParam.handle = m_handle;
607     inParam.data = (void*)&surface[0];
608     inParam.width = m_width;
609     inParam.height = m_height;
610     inParam.depth = m_depth;
611     inParam.lockFlag = CM_HAL_LOCKFLAG_READONLY;
612 
613     cmData->cmHalState->pfnLock3DResource(cmData->cmHalState, &inParam);
614     if (inParam.data == nullptr)
615         return;
616     tempDst = (uint8_t*)&surface[0];
617     tempSrc = (uint8_t*)inParam.data;
618     rPlane = (uint8_t*)inParam.data;
619     if (inParam.qpitchEnabled)
620     {
621         if (inParam.pitch == uWidthInBytes && inParam.qpitch == inParam.height)
622         {
623             CmFastMemCopyFromWC(tempDst, tempSrc, (size_t)surfaceSize, GetCpuInstructionLevel());
624         }
625         else
626         {
627             for (uint32_t uZ = 0; uZ < inParam.depth; uZ++)
628             {
629                 tempSrc = rPlane;
630                 for (uint32_t uY = 0; uY < inParam.height; uY++)
631                 {
632                     CmFastMemCopyFromWC(tempDst, tempSrc, uWidthInBytes, GetCpuInstructionLevel());
633                     tempSrc += inParam.pitch;
634                     tempDst += uWidthInBytes;
635                 }
636                 rPlane += inParam.qpitch * inParam.pitch;
637             }
638         }
639     }
640     else
641     {
642         if (inParam.pitch == uWidthInBytes)
643         {
644             CmFastMemCopyFromWC(tempDst, tempSrc, (size_t)surfaceSize, GetCpuInstructionLevel());
645         }
646         else
647         {
648             for (uint32_t uZ = 0; uZ < inParam.depth; uZ++)
649             {
650                 for (uint32_t uY = 0; uY < inParam.height; uY++)
651                 {
652                     CmFastMemCopyFromWC(tempDst, tempSrc, uWidthInBytes, GetCpuInstructionLevel());
653                     tempSrc += inParam.pitch;
654                     tempDst += uWidthInBytes;
655                 }
656             }
657         }
658     }
659     cmData->cmHalState->pfnUnlock3DResource(cmData->cmHalState, &inParam);
660 
661     outputFileStream.write(&surface[0], surfaceSize);
662     outputFileStream.close();
663     surface3DDumpNumber++;
664 #endif
665 }
666 }
667