1 /*
2 * Copyright � 2014 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
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sub license, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial portions
14 * of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
19 * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
20 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 *
24 * Authors:
25 * Wei Lin<wei.w.lin@intel.com>
26 * Yuting Yang<yuting.yang@intel.com>
27 * Lina Sun<lina.sun@intel.com>
28 */
29
30 #include "cm_buffer.h"
31 #include "cm_surface_manager.h"
32 #include "cm_event.h"
33 #include "cm_device.h"
34 #include "cm_mem.h"
35 #include "cm_def.h"
36 #include "hal_cm.h"
37
Create(UINT index,UINT handle,UINT size,BOOL bIsCmCreated,CmSurfaceManager * pSurfaceManager,UINT uiBufferType,VOID * pSysMem,CmBuffer_RT * & pSurface)38 INT CmBuffer_RT::Create(UINT index, UINT handle, UINT size, BOOL bIsCmCreated,
39 CmSurfaceManager * pSurfaceManager, UINT uiBufferType,
40 VOID * pSysMem, CmBuffer_RT * &pSurface)
41 {
42 INT result = CM_SUCCESS;
43
44 pSurface =
45 new(std::nothrow) CmBuffer_RT(handle, size, bIsCmCreated,
46 pSurfaceManager, uiBufferType,
47 pSysMem);
48 if (pSurface) {
49 result = pSurface->Initialize(index);
50 if (result != CM_SUCCESS) {
51 CmSurface *pBaseSurface = pSurface;
52 CmSurface::Destroy(pBaseSurface);
53 }
54 } else {
55 CM_ASSERT(0);
56 result = CM_OUT_OF_HOST_MEMORY;
57 }
58
59 return result;
60 }
61
CmBuffer_RT(UINT handle,UINT size,BOOL bIsCmCreated,CmSurfaceManager * pSurfaceManager,UINT uiBufferType,VOID * pSysMem)62 CmBuffer_RT::CmBuffer_RT(UINT handle, UINT size, BOOL bIsCmCreated, CmSurfaceManager * pSurfaceManager, UINT uiBufferType, VOID * pSysMem):
63 CmSurface(pSurfaceManager, bIsCmCreated),
64 m_Handle(handle), m_Size(size), m_uiBufferType(uiBufferType), m_pSysMem(pSysMem)
65 {
66 CmSurface::SetMemoryObjectControl(MEMORY_OBJECT_CONTROL_UNKNOW,
67 CM_USE_PTE, 0);
68 }
69
~CmBuffer_RT(void)70 CmBuffer_RT::~CmBuffer_RT(void)
71 {
72 }
73
Initialize(UINT index)74 INT CmBuffer_RT::Initialize(UINT index)
75 {
76 return CmSurface::Initialize(index);
77 }
78
GetHandle(UINT & handle)79 INT CmBuffer_RT::GetHandle(UINT & handle)
80 {
81 handle = m_Handle;
82 return CM_SUCCESS;
83 }
84
85 CM_RT_API INT
WriteSurface(const unsigned char * pSysMem,CmEvent * pEvent,UINT64 sysMemSize)86 CmBuffer_RT::WriteSurface(const unsigned char *pSysMem, CmEvent * pEvent,
87 UINT64 sysMemSize)
88 {
89 CM_RETURN_CODE hr = CM_SUCCESS;
90 BYTE *pDst = NULL;
91 BYTE *pSurf = NULL;
92
93 if (pSysMem == NULL) {
94 CM_ASSERT(0);
95 return CM_INVALID_ARG_VALUE;
96 }
97
98 if (sysMemSize < m_Size) {
99 CM_ASSERT(0);
100 return CM_INVALID_ARG_VALUE;
101 }
102 if (pEvent) {
103 FlushDeviceQueue(pEvent);
104 }
105
106 WaitForReferenceFree();
107
108 CmDevice_RT *pCmDevice = NULL;
109 m_SurfaceMgr->GetCmDevice(pCmDevice);
110 PCM_CONTEXT pCmData = (PCM_CONTEXT) pCmDevice->GetAccelData();
111
112 CM_HAL_BUFFER_PARAM inParam;
113 CmSafeMemSet(&inParam, 0, sizeof(CM_HAL_BUFFER_PARAM));
114 inParam.iLockFlag = CM_HAL_LOCKFLAG_WRITEONLY;
115 inParam.dwHandle = m_Handle;
116
117 CHK_GENOSSTATUS_RETURN_CMERROR(pCmData->pCmHalState->
118 pfnLockBuffer(pCmData->pCmHalState,
119 &inParam));
120 CMCHK_NULL(inParam.pData);
121
122 pDst = (BYTE *) (inParam.pData);
123 pSurf = (BYTE *) pSysMem;
124
125 CmFastMemCopyWC(pDst, pSurf, m_Size);
126
127 CHK_GENOSSTATUS_RETURN_CMERROR(pCmData->pCmHalState->
128 pfnUnlockBuffer(pCmData->pCmHalState,
129 &inParam));
130
131 finish:
132 return hr;
133 }
134
135 CM_RT_API INT
ReadSurface(unsigned char * pSysMem,CmEvent * pEvent,UINT64 sysMemSize)136 CmBuffer_RT::ReadSurface(unsigned char *pSysMem, CmEvent * pEvent,
137 UINT64 sysMemSize)
138 {
139 CM_RETURN_CODE hr = CM_SUCCESS;
140
141 if (pSysMem == NULL) {
142 CM_ASSERT(0);
143 return CM_INVALID_ARG_VALUE;
144 }
145
146 if (sysMemSize < m_Size) {
147 CM_ASSERT(0);
148 return CM_INVALID_ARG_VALUE;
149 }
150 if (pEvent) {
151 FlushDeviceQueue(pEvent);
152 }
153
154 WaitForReferenceFree();
155
156 CmDevice_RT *pCmDevice = NULL;
157 m_SurfaceMgr->GetCmDevice(pCmDevice);
158 PCM_CONTEXT pCmData = (PCM_CONTEXT) pCmDevice->GetAccelData();
159
160 CM_HAL_BUFFER_PARAM inParam;
161 CmSafeMemSet(&inParam, 0, sizeof(CM_HAL_BUFFER_PARAM));
162 inParam.iLockFlag = CM_HAL_LOCKFLAG_READONLY;
163 inParam.dwHandle = m_Handle;
164
165 CHK_GENOSSTATUS_RETURN_CMERROR(pCmData->pCmHalState->
166 pfnLockBuffer(pCmData->pCmHalState,
167 &inParam));
168 CMCHK_NULL(inParam.pData);
169
170 CmFastMemCopyFromWC(pSysMem, inParam.pData, m_Size,
171 GetCpuInstructionLevel());
172
173 CHK_GENOSSTATUS_RETURN_CMERROR(pCmData->pCmHalState->
174 pfnUnlockBuffer(pCmData->pCmHalState,
175 &inParam));
176
177 finish:
178 return hr;
179 }
180
GetIndex(SurfaceIndex * & pIndex)181 CM_RT_API INT CmBuffer_RT::GetIndex(SurfaceIndex * &pIndex)
182 {
183 pIndex = m_pIndex;
184 return CM_SUCCESS;
185 }
186
InitSurface(const DWORD initValue,CmEvent * pEvent)187 CM_RT_API INT CmBuffer_RT::InitSurface(const DWORD initValue, CmEvent * pEvent)
188 {
189 CM_RETURN_CODE hr = CM_SUCCESS;
190
191 if (pEvent) {
192 FlushDeviceQueue(pEvent);
193 }
194
195 CmDevice_RT *pCmDevice = NULL;
196 m_SurfaceMgr->GetCmDevice(pCmDevice);
197 CM_ASSERT(pCmDevice);
198 PCM_CONTEXT pCmData = (PCM_CONTEXT) pCmDevice->GetAccelData();
199
200 CM_HAL_BUFFER_PARAM inParam;
201 CmSafeMemSet(&inParam, 0, sizeof(CM_HAL_BUFFER_PARAM));
202 inParam.dwHandle = m_Handle;
203 inParam.iLockFlag = CM_HAL_LOCKFLAG_WRITEONLY;
204
205 CHK_GENOSSTATUS_RETURN_CMERROR(pCmData->pCmHalState->
206 pfnLockBuffer(pCmData->pCmHalState,
207 &inParam));
208 CMCHK_NULL(inParam.pData);
209
210 CmDwordMemSet(inParam.pData, initValue, m_Size);
211
212 CHK_GENOSSTATUS_RETURN_CMERROR(pCmData->pCmHalState->
213 pfnUnlockBuffer(pCmData->pCmHalState,
214 &inParam));
215
216 finish:
217 return hr;
218 }
219
220 CM_RT_API INT
SetMemoryObjectControl(MEMORY_OBJECT_CONTROL mem_ctrl,MEMORY_TYPE mem_type,UINT age)221 CmBuffer_RT::SetMemoryObjectControl(MEMORY_OBJECT_CONTROL mem_ctrl,
222 MEMORY_TYPE mem_type, UINT age)
223 {
224 CmSurface::SetMemoryObjectControl(mem_ctrl, mem_type, age);
225
226 return CM_SUCCESS;
227 }
228
GetSize(UINT & size)229 INT CmBuffer_RT::GetSize(UINT & size)
230 {
231 size = m_Size;
232 return CM_SUCCESS;
233 }
234
SetSize(UINT size)235 INT CmBuffer_RT::SetSize(UINT size)
236 {
237 m_Size = size;
238 return CM_SUCCESS;
239 }
240
IsUpSurface()241 BOOL CmBuffer_RT::IsUpSurface()
242 {
243 return (m_uiBufferType == CM_BUFFER_UP);
244 }
245
GetAddress(VOID * & pAddr)246 CM_RT_API INT CmBuffer_RT::GetAddress(VOID * &pAddr)
247 {
248 pAddr = m_pSysMem;
249 return CM_SUCCESS;
250 }
251