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