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 #include "cm_surface_manager.h"
24 #include "cm_debug.h"
25 #include "cm_mem.h"
26 #include "cm_device.h"
27 
28 enum DESTROY_KIND
29 {
30     APP_DESTROY         = 0,
31     DELAYED_DESTROY     = 1,
32     FORCE_DESTROY       = 2,
33     THIN_DESTROY        = 3
34 };
35 
36 struct CM_DESTROYSURFACE2D_PARAM
37 {
38     void *cmSurface2DHandle;  // [in/out] pointer to CmSurface2D object
39     int32_t returnValue;      // [out] the return value from CMRT@UMD
40 };
41 
42 struct CM_DESTROYSURFACE2DUP_PARAM
43 {
44     void *cmSurface2DUPHandle;  // [in/out] pointer to CmSurface2D object
45     int32_t returnValue;        // [out] the return value from CMRT@UMD
46 };
47 
48 struct CM_DESTROY_SURFACE3D_PARAM
49 {
50     void *cmSurface3DHandle;  // [in] pointer of CmSurface3D used in driver
51     int32_t returnValue;      // [out] the return value from driver
52 };
53 
54 struct CM_DESTROYBUFFER_PARAM
55 {
56     void *cmBufferHandle;  // [in/out] pointer to CmBuffer object
57     int32_t returnValue;   // [out] the return value from CMRT@UMD
58 };
59 
60 struct CM_CREATESURFACE2DUP_PARAM
61 {
62     uint32_t width;             // [in] width of 2D texture in pixel
63     uint32_t height;            // [in] height of 2D texture in pixel
64     CM_SURFACE_FORMAT format;    // [in] DXGI format of 2D texture
65     void *sysMem;               // [in] Pointer to system memory
66     void *cmSurface2DUPHandle;  // [out] pointer of CmSurface2D used in driver
67     int32_t returnValue;        // [out] the return value from driver
68 };
69 
70 struct CM_CREATE_SURFACE3D_PARAM
71 {
72     uint32_t width;            // [in] width of 3D  in pixel
73     uint32_t height;           // [in] height of 3D  in pixel
74     uint32_t depth;            // [in] depth of 3D surface in pixel
75     CM_SURFACE_FORMAT format;   // [in] DXGI format of 3D texture
76     void *cmSurface3DHandle;   // [out] pointer of CmSurface3D used in driver
77     int32_t returnValue;       // [out] the return value from driver
78 };
79 
CmSurfaceManager(CmDevice_RT * device)80 CmSurfaceManager::CmSurfaceManager(CmDevice_RT *device)
81 {
82     m_device = device;
83 }
84 
~CmSurfaceManager()85 CmSurfaceManager::~CmSurfaceManager() {}
86 
DestroySurface(CmSurface2D * & surface)87 int32_t CmSurfaceManager::DestroySurface(CmSurface2D *&surface)
88 {
89     int32_t result = CM_SUCCESS;
90     CHK_NULL(surface);
91 
92     //Destroy surface in UMD
93     CHK_RET(DestroySurface2DInUmd(surface));
94     surface = nullptr;
95 
96 finish:
97     return result;
98 }
99 
DestroySurface2DInUmd(CmSurface2D * & surface)100 int32_t CmSurfaceManager::DestroySurface2DInUmd(CmSurface2D *&surface)
101 {
102     int32_t result = CM_SUCCESS;
103 
104     CHK_NULL_RETURN(surface);
105     //Call Into CMRT@UMD to free Surface
106     CM_DESTROYSURFACE2D_PARAM inParam;
107     CmSafeMemSet(&inParam, 0, sizeof(CM_DESTROYSURFACE2D_PARAM));
108     inParam.cmSurface2DHandle = surface;
109 
110     result = m_device->OSALExtensionExecute(CM_FN_CMDEVICE_DESTROYSURFACE2D,
111                                             &inParam, sizeof(inParam));
112     CHK_FAILURE_RETURN(result);
113     return inParam.returnValue;
114 }
115 
CreateBuffer(uint32_t size,CmBuffer * & buffer)116 int32_t CmSurfaceManager::CreateBuffer(uint32_t size, CmBuffer *&buffer)
117 {
118     if ((size < CM_MIN_SURF_WIDTH) || (size > CM_MAX_1D_SURF_WIDTH))
119     {
120         CmAssert(0);
121         return CM_INVALID_WIDTH;
122     }
123 
124     CM_CREATEBUFFER_PARAM inParam;
125     CmSafeMemSet(&inParam, 0, sizeof(inParam));
126     inParam.size = size;
127     inParam.bufferType = CM_BUFFER_N;
128     inParam.sysMem = nullptr;
129     int32_t hr = m_device->OSALExtensionExecute(CM_FN_CMDEVICE_CREATEBUFFER,
130                                                 &inParam, sizeof(inParam));
131     CHK_FAILURE_RETURN(hr);
132     CHK_FAILURE_RETURN(inParam.returnValue);
133     buffer = (CmBuffer *)inParam.cmBufferHandle;
134 
135     return CM_SUCCESS;
136 }
137 
CreateBufferUP(uint32_t size,void * sysMem,CmBufferUP * & buffer)138 int32_t CmSurfaceManager::CreateBufferUP(uint32_t size,
139                                      void *sysMem,
140                                      CmBufferUP *&buffer)
141 {
142     if ((size < CM_MIN_SURF_WIDTH) || (size > CM_MAX_1D_SURF_WIDTH))
143     {
144         CmAssert(0);
145         return CM_INVALID_WIDTH;
146     }
147     if (sysMem == nullptr)
148     {
149         CmAssert(0);
150         return CM_INVALID_ARG_VALUE;
151     }
152 
153     CM_CREATEBUFFER_PARAM inParam;
154     CmSafeMemSet(&inParam, 0, sizeof(inParam));
155     inParam.size = size;
156     inParam.bufferType = CM_BUFFER_UP;
157     inParam.sysMem = sysMem;
158     int32_t hr = m_device->OSALExtensionExecute(CM_FN_CMDEVICE_CREATEBUFFER,
159                                                 &inParam, sizeof(inParam));
160 
161     CHK_FAILURE_RETURN(hr);
162     CHK_FAILURE_RETURN(inParam.returnValue);
163 
164     buffer = (CmBufferUP *)inParam.cmBufferHandle;
165     return CM_SUCCESS;
166 }
167 
DestroyBuffer(CmBuffer * & buffer)168 int32_t CmSurfaceManager::DestroyBuffer(CmBuffer *&buffer)
169 {
170     CM_DESTROYBUFFER_PARAM inParam;
171     CmSafeMemSet(&inParam, 0, sizeof(CM_DESTROYBUFFER_PARAM));
172     inParam.cmBufferHandle = buffer;
173 
174     int32_t hr = m_device->OSALExtensionExecute(CM_FN_CMDEVICE_DESTROYBUFFER,
175                                                 &inParam, sizeof(inParam));
176     CHK_FAILURE_RETURN(hr);
177     CHK_FAILURE_RETURN(inParam.returnValue);
178     buffer = nullptr;
179 
180     return hr;
181 }
182 
DestroyBufferUP(CmBufferUP * & buffer)183 int32_t CmSurfaceManager::DestroyBufferUP(CmBufferUP *&buffer)
184 {
185     CM_DESTROYBUFFER_PARAM inParam;
186     CmSafeMemSet(&inParam, 0, sizeof(CM_DESTROYBUFFER_PARAM));
187     inParam.cmBufferHandle = buffer;
188 
189     int32_t hr = m_device->OSALExtensionExecute(CM_FN_CMDEVICE_DESTROYBUFFERUP,
190                                                 &inParam, sizeof(inParam));
191     CHK_FAILURE_RETURN(hr);
192     CHK_FAILURE_RETURN(inParam.returnValue);
193     buffer = nullptr;
194 
195     return hr;
196 }
197 
CreateSurface2DUP(uint32_t width,uint32_t height,CM_SURFACE_FORMAT format,void * sysMem,CmSurface2DUP * & surface)198 int32_t CmSurfaceManager::CreateSurface2DUP(uint32_t width,
199                                         uint32_t height,
200                                         CM_SURFACE_FORMAT format,
201                                         void *sysMem,
202                                         CmSurface2DUP *&surface)
203 {
204     int32_t result = Surface2DSanityCheck(width, height, format);
205     if (result != CM_SUCCESS)
206     {
207         CmAssert(0);
208         return result;
209     }
210     if (nullptr == sysMem)
211     {
212         CmAssert(0);
213         return CM_INVALID_ARG_VALUE;
214     }
215 
216     CM_CREATESURFACE2DUP_PARAM inParam;
217     CmSafeMemSet(&inParam, 0, sizeof(CM_CREATESURFACE2DUP_PARAM));
218     inParam.width = width;
219     inParam.height = height;
220     inParam.format = format;
221     inParam.sysMem = sysMem;
222     int32_t hr =
223         m_device->OSALExtensionExecute(CM_FN_CMDEVICE_CREATESURFACE2DUP,
224                                        &inParam, sizeof(inParam));
225 
226     CHK_FAILURE_RETURN(hr);
227     CHK_FAILURE_RETURN(inParam.returnValue);
228     surface = (CmSurface2DUP *)inParam.cmSurface2DUPHandle;
229 
230     return hr;
231 }
232 
DestroySurface2DUP(CmSurface2DUP * & surface)233 int32_t CmSurfaceManager::DestroySurface2DUP(CmSurface2DUP *&surface)
234 {
235     CM_DESTROYSURFACE2DUP_PARAM inParam;
236     CmSafeMemSet(&inParam, 0, sizeof(CM_DESTROYSURFACE2DUP_PARAM));
237     inParam.cmSurface2DUPHandle = surface;
238     int32_t hr =
239         m_device->OSALExtensionExecute(CM_FN_CMDEVICE_DESTROYSURFACE2DUP,
240                                        &inParam, sizeof(inParam));
241 
242     CHK_FAILURE_RETURN(hr);
243     CHK_FAILURE_RETURN(inParam.returnValue);
244     surface = nullptr;
245     return hr;
246 }
247 
CreateSurface3D(uint32_t width,uint32_t height,uint32_t depth,CM_SURFACE_FORMAT format,CmSurface3D * & surface)248 int32_t CmSurfaceManager::CreateSurface3D(uint32_t width,
249                                       uint32_t height,
250                                       uint32_t depth,
251                                       CM_SURFACE_FORMAT format,
252                                       CmSurface3D *&surface)
253 {
254     CM_CREATE_SURFACE3D_PARAM inParam;
255     CmSafeMemSet(&inParam, 0, sizeof(CM_CREATE_SURFACE3D_PARAM));
256 
257     inParam.width = width;
258     inParam.height = height;
259     inParam.depth = depth;
260     inParam.format = format;
261     int32_t hr = m_device->OSALExtensionExecute(CM_FN_CMDEVICE_CREATESURFACE3D,
262                                                 &inParam, sizeof(inParam),
263                                                 nullptr, 0);
264 
265     CHK_FAILURE_RETURN(hr);
266     CHK_FAILURE_RETURN(inParam.returnValue);
267     surface = (CmSurface3D *)inParam.cmSurface3DHandle;
268 
269     return hr;
270 }
271 
DestroySurface3D(CmSurface3D * & surface)272 int32_t CmSurfaceManager::DestroySurface3D(CmSurface3D *&surface)
273 {
274     CM_DESTROY_SURFACE3D_PARAM inParam;
275     CmSafeMemSet(&inParam, 0, sizeof(CM_DESTROY_SURFACE3D_PARAM));
276     inParam.cmSurface3DHandle = surface;
277 
278     int32_t hr = m_device->OSALExtensionExecute(CM_FN_CMDEVICE_DESTROYSURFACE3D,
279                                                 &inParam, sizeof(inParam),
280                                                 nullptr, 0);
281 
282     CHK_FAILURE_RETURN(hr);
283     CHK_FAILURE_RETURN(inParam.returnValue);
284     surface = nullptr;
285 
286     return hr;
287 }
288 
CreateBufferSVM(uint32_t size,void * & sysMem,uint32_t accessFlag,CmBufferSVM * & buffer)289 int32_t CmSurfaceManager::CreateBufferSVM(uint32_t size,
290                                       void *&sysMem,
291                                       uint32_t accessFlag,
292                                       CmBufferSVM *&buffer)
293 {
294     CM_CREATEBUFFER_PARAM inParam;
295     CmSafeMemSet(&inParam, 0, sizeof(inParam));
296     inParam.size = size;
297     inParam.bufferType = CM_BUFFER_SVM;
298     inParam.sysMem = sysMem;
299     int32_t hr = m_device->OSALExtensionExecute(CM_FN_CMDEVICE_CREATEBUFFER,
300                                                 &inParam, sizeof(inParam));
301     CHK_FAILURE_RETURN(hr);
302     CHK_FAILURE_RETURN(inParam.returnValue);
303 
304     buffer = (CmBufferSVM *)inParam.cmBufferHandle;
305     sysMem = inParam.sysMem;  //Update pSystem
306 
307     return hr;
308 }
309 
DestroyBufferSVM(CmBufferSVM * & buffer)310 int32_t CmSurfaceManager::DestroyBufferSVM(CmBufferSVM *&buffer)
311 {
312     CM_DESTROYBUFFER_PARAM inParam;
313     CmSafeMemSet(&inParam, 0, sizeof(CM_DESTROYBUFFER_PARAM));
314     inParam.cmBufferHandle = buffer;
315 
316     int32_t hr = m_device->OSALExtensionExecute(CM_FN_CMDEVICE_DESTROYBUFFERSVM,
317                                                 &inParam, sizeof(inParam));
318     CHK_FAILURE_RETURN(hr);
319     CHK_FAILURE_RETURN(inParam.returnValue);
320 
321     buffer = nullptr;
322 
323     return hr;
324 }
325 
CreateBufferStateless(size_t size,uint32_t option,void * sysMem,CmBufferStateless * & buffer)326 int32_t CmSurfaceManager::CreateBufferStateless(size_t size,
327                                                 uint32_t option,
328                                                 void *sysMem,
329                                                 CmBufferStateless *&buffer)
330 {
331     CM_CREATEBUFFER_PARAM inParam;
332     CmSafeMemSet(&inParam, 0, sizeof(inParam));
333     inParam.size = size;
334     inParam.bufferType = CM_BUFFER_STATELESS;
335     inParam.sysMem = sysMem;
336     inParam.option = option;
337     int32_t hr = m_device->OSALExtensionExecute(CM_FN_CMDEVICE_CREATEBUFFER,
338                                                 &inParam, sizeof(inParam));
339     CHK_FAILURE_RETURN(hr);
340     CHK_FAILURE_RETURN(inParam.returnValue);
341 
342     buffer = (CmBufferStateless *)inParam.cmBufferHandle;
343 
344     return hr;
345 }
346 
DestroyBufferStateless(CmBufferStateless * & buffer)347 int32_t CmSurfaceManager::DestroyBufferStateless(CmBufferStateless *&buffer)
348 {
349     CM_DESTROYBUFFER_PARAM inParam;
350     CmSafeMemSet(&inParam, 0, sizeof(CM_DESTROYBUFFER_PARAM));
351     inParam.cmBufferHandle = buffer;
352 
353     int32_t hr = m_device->OSALExtensionExecute(CM_FN_CMDEVICE_DESTROYBUFFERSTATELESS,
354                                                 &inParam,
355                                                 sizeof(inParam));
356     CHK_FAILURE_RETURN(hr);
357     CHK_FAILURE_RETURN(inParam.returnValue);
358 
359     buffer = nullptr;
360     return hr;
361 }
362