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_2d_up_rt.cpp
24 //! \brief     Contains Class CmSurface2DUPRT implementations.
25 //!
26 
27 #include "cm_surface_2d_up_rt.h"
28 
29 #include "cm_device_rt.h"
30 #include "cm_surface_manager.h"
31 #include "cm_hal.h"
32 
33 namespace CMRT_UMD
34 {
35 //*-----------------------------------------------------------------------------
36 //| Purpose:    Create Surface 2D Up
37 //| Arguments :
38 //|               index             [in]     index in runtime Surface2D table
39 //|               handle            [in]     index in driver's surface2D table
40 //|               width             [in]     width of the  CmSurface2DUP
41 //|               height            [in]     height of the CmSurface2DUP
42 //|               pitch             [in]     pitch of the CmSurface2DUP
43 //|               format            [in]     format to CmSurface2DUP
44 //|               sysMem           [in]     user provided buffer to CmSurface2DUP
45 //|               isCmCreated       [out]    ture,if the surface created by CM;
46 //|                                          false,if the surface created externally
47 //|               surfaceManager   [out]    Pointer to CmSurfaceManager
48 //|               surface          [out]    Reference to the Pointer to CmSurface2DUP
49 
50 //| Returns:    Result of the operation.
51 //*-----------------------------------------------------------------------------
Create(uint32_t index,uint32_t handle,uint32_t width,uint32_t height,CM_SURFACE_FORMAT format,void * sysMem,CmSurfaceManager * surfaceManager,CmSurface2DUPRT * & surface)52 int32_t CmSurface2DUPRT::Create( uint32_t index, uint32_t handle, uint32_t width, uint32_t height, CM_SURFACE_FORMAT format, void  *sysMem, CmSurfaceManager* surfaceManager, CmSurface2DUPRT* &surface )
53 {
54     int32_t result = CM_SUCCESS;
55 
56     surface = new (std::nothrow) CmSurface2DUPRT( handle, width, height, format, sysMem, surfaceManager );
57     if( surface )
58     {
59         result = surface->Initialize( index );
60         if( result != CM_SUCCESS )
61         {
62             CmSurface* baseSurface = surface;
63             CmSurface::Destroy( baseSurface );
64         }
65 
66     }
67     else
68     {
69         CM_ASSERTMESSAGE("Error: Failed to create CmSurface2DUP due to out of system memory.")
70         result = CM_OUT_OF_HOST_MEMORY;
71     }
72 
73     return result;
74 
75 }
76 
77 //*-----------------------------------------------------------------------------
78 //| Purpose:    Constructor of Surface 2DUP
79 //| Returns:    None.
80 //*-----------------------------------------------------------------------------
CmSurface2DUPRT(uint32_t handle,uint32_t width,uint32_t height,CM_SURFACE_FORMAT format,void * sysMem,CmSurfaceManager * surfaceManager)81 CmSurface2DUPRT::CmSurface2DUPRT( uint32_t handle, uint32_t width, uint32_t height, CM_SURFACE_FORMAT format, void  *sysMem, CmSurfaceManager* surfaceManager ):
82     CmSurface( surfaceManager,true ),
83     m_handle( handle ),
84     m_width( width ),
85     m_height( height ),
86     m_frameType(CM_FRAME),
87     m_format ( format ),
88     m_sysMem(sysMem)
89 {
90     CmSurface::SetMemoryObjectControl(MEMORY_OBJECT_CONTROL_UNKNOW, CM_USE_PTE, 0);
91 }
92 
93 //*-----------------------------------------------------------------------------
94 //| Purpose:    Destructor of Surface 2DUP
95 //| Returns:    None.
96 //*-----------------------------------------------------------------------------
~CmSurface2DUPRT(void)97 CmSurface2DUPRT::~CmSurface2DUPRT( void )
98 {
99 
100 }
101 
102 //*-----------------------------------------------------------------------------
103 //| Purpose:    Initialize the Surface 2D up
104 //| Returns:    None.
105 //*-----------------------------------------------------------------------------
Initialize(uint32_t index)106 int32_t CmSurface2DUPRT::Initialize( uint32_t index )
107 {
108     return CmSurface::Initialize( index );
109 
110 }
111 
112 //*-----------------------------------------------------------------------------
113 //| Purpose:    Get the handle of Surface 2D up
114 //| Returns:    CM_SUCCESS.
115 //*-----------------------------------------------------------------------------
GetHandle(uint32_t & handle)116 int32_t CmSurface2DUPRT::GetHandle( uint32_t& handle)
117 {
118     handle = m_handle;
119     return CM_SUCCESS;
120 }
121 
122 //*-----------------------------------------------------------------------------
123 //| Purpose:    Get Surface Index
124 //| Returns:    CM_SUCCESS.
125 //*-----------------------------------------------------------------------------
GetIndex(SurfaceIndex * & index)126 CM_RT_API int32_t CmSurface2DUPRT::GetIndex(SurfaceIndex*& index)
127 {
128     index = m_index;
129     return CM_SUCCESS;
130 }
131 
SetProperty(CM_FRAME_TYPE frameType)132 CM_RT_API int32_t CmSurface2DUPRT::SetProperty(CM_FRAME_TYPE frameType)
133 {
134     m_frameType = frameType;
135     m_surfaceMgr->UpdateSurface2DTableFrameType(m_handle, frameType);
136 
137     return CM_SUCCESS;
138 }
139 
SetMemoryObjectControl(MEMORY_OBJECT_CONTROL memCtrl,MEMORY_TYPE memType,uint32_t age)140 int32_t CmSurface2DUPRT::SetMemoryObjectControl( MEMORY_OBJECT_CONTROL memCtrl, MEMORY_TYPE memType, uint32_t age)
141 {
142     CM_RETURN_CODE  hr = CM_SUCCESS;
143     uint16_t mocs = 0;
144     CmSurface::SetMemoryObjectControl( memCtrl, memType, age );
145 
146     CmDeviceRT *cmDevice = nullptr;
147     m_surfaceMgr->GetCmDevice(cmDevice);
148     CM_CHK_NULL_RETURN_CMERROR(cmDevice);
149 
150     PCM_CONTEXT_DATA cmData = (PCM_CONTEXT_DATA)cmDevice->GetAccelData();
151     CM_CHK_NULL_RETURN_CMERROR(cmData);
152     CM_CHK_NULL_RETURN_CMERROR(cmData->cmHalState);
153 
154     mocs = (m_memObjCtrl.mem_ctrl << 8) | (m_memObjCtrl.mem_type<<4) | m_memObjCtrl.age;
155 
156     CM_CHK_MOSSTATUS_GOTOFINISH_CMERROR(cmData->cmHalState->pfnSetSurfaceMOCS(cmData->cmHalState, m_handle, mocs, ARG_KIND_SURFACE_2D_UP));
157 
158 finish:
159     return hr;
160 }
161 
SelectMemoryObjectControlSetting(MEMORY_OBJECT_CONTROL memCtrl)162 CM_RT_API int32_t CmSurface2DUPRT::SelectMemoryObjectControlSetting(MEMORY_OBJECT_CONTROL memCtrl)
163 {
164     return SetMemoryObjectControl(memCtrl, CM_USE_PTE, 0);
165 }
166 
SetResourceUsage(const MOS_HW_RESOURCE_DEF mosUsage)167 CMRT_UMD_API int32_t CmSurface2DUPRT::SetResourceUsage(const MOS_HW_RESOURCE_DEF mosUsage)
168 {
169     int32_t  hr = CM_SUCCESS;
170     uint16_t mocs = 0;
171     hr = CmSurface::SetResourceUsage(mosUsage);
172 
173     CmDeviceRT *cmDevice = nullptr;
174     m_surfaceMgr->GetCmDevice(cmDevice);
175     CM_CHK_NULL_RETURN_CMERROR(cmDevice);
176     PCM_CONTEXT_DATA cmData = (PCM_CONTEXT_DATA)cmDevice->GetAccelData();
177     CM_CHK_NULL_RETURN_CMERROR(cmData);
178     CM_CHK_NULL_RETURN_CMERROR(cmData->cmHalState);
179 
180     mocs = (m_memObjCtrl.mem_ctrl << 8) | (m_memObjCtrl.mem_type << 4) | m_memObjCtrl.age;
181     CM_CHK_MOSSTATUS_GOTOFINISH_CMERROR(cmData->cmHalState->pfnSetSurfaceMOCS(cmData->cmHalState, m_handle, mocs, ARG_KIND_SURFACE_2D_UP));
182 finish:
183     return hr;
184 }
185 
186 //*-------------------------------------------------------------------------------------------
187 //| Purpose:    Get the description of surface 2d, width,height,format and the size PER pixel.
188 //| Arguments :
189 //|               width         [out]     Reference to  width of surface
190 //|               height        [out]     Reference to  height of surface
191 //|               format        [out]     Reference to  format of surface
192 //|               sizeperpixel  [out]     Reference to  the pixel's size in bytes
193 //|
194 //| Returns:    Result of the operation.
195 //*-------------------------------------------------------------------------------------------
GetSurfaceDesc(uint32_t & width,uint32_t & height,CM_SURFACE_FORMAT & format,uint32_t & sizeperpixel)196 CM_RT_API int32_t CmSurface2DUPRT::GetSurfaceDesc(uint32_t &width, uint32_t &height, CM_SURFACE_FORMAT &format,uint32_t &sizeperpixel)
197 {
198     int ret = CM_SUCCESS;
199     uint32_t updatedHeight = 0 ;
200 
201     width  = m_width;
202     height = m_height;
203     format = m_format;
204 
205     // Get size per pixel
206     ret = m_surfaceMgr->GetPixelBytesAndHeight(width,  height,  format,  sizeperpixel, updatedHeight);
207 
208     return ret;
209 }
210 
Log(std::ostringstream & oss)211 void CmSurface2DUPRT::Log(std::ostringstream &oss)
212 {
213 #if CM_LOG_ON
214     oss << " Surface2D UP Info "
215         << " Width:" << m_width
216         << " Height:"<< m_height
217         << " Format:" << GetFormatString(m_format)
218         << " Handle:" << m_handle
219         << " SurfaceIndex:" << m_index->get_data()
220         << " Sys Address:" << m_sysMem
221         << " IsCmCreated:"<<m_isCmCreated
222         << std::endl;
223 #endif
224 }
225 
DumpContent(uint32_t kernelNumber,char * kernelName,int32_t taskId,uint32_t argIndex,uint32_t vectorIndex)226 void CmSurface2DUPRT::DumpContent(uint32_t kernelNumber, char *kernelName, int32_t taskId, uint32_t argIndex, uint32_t vectorIndex)
227 {
228 #if MDF_SURFACE_CONTENT_DUMP
229     char fileNamePrefix[MAX_PATH] = { 0 };
230     std::ostringstream outputFileName;
231     static uint32_t surface2DUPDumpNumber = 0;
232     outputFileName << "t_" << taskId
233         << "_k_" << kernelNumber
234         << "_" << kernelName
235         << "_argi_" << argIndex
236         << "_vector_index_" << vectorIndex
237         << "_surf2d_surfi_"<< m_index->get_data()
238         << "_w_" << m_width
239         << "_h_" << m_height
240         << "_f_" << GetFormatString(m_format)
241         << "_" << surface2DUPDumpNumber;
242 
243     GetLogFileLocation(outputFileName.str().c_str(), fileNamePrefix);
244 
245     std::ofstream outputFileStream;
246     outputFileStream.open(fileNamePrefix, std::ofstream::binary);
247 
248     uint32_t        sizePerPixel = 0;
249     uint32_t        updatedHeight = 0;
250     uint32_t        surfaceSize = 0;
251     m_surfaceMgr->GetPixelBytesAndHeight(m_width, m_height, m_format, sizePerPixel, updatedHeight);
252     surfaceSize = m_width*sizePerPixel*updatedHeight;
253     outputFileStream.write((char *)m_sysMem, surfaceSize);
254     outputFileStream.close();
255     surface2DUPDumpNumber++;
256 #endif
257 }
258 }  // namespace
259