diff options
Diffstat (limited to 'drivers/gpu/pvr/deviceclass.c')
-rw-r--r-- | drivers/gpu/pvr/deviceclass.c | 2012 |
1 files changed, 2012 insertions, 0 deletions
diff --git a/drivers/gpu/pvr/deviceclass.c b/drivers/gpu/pvr/deviceclass.c new file mode 100644 index 00000000000..869253b2ecb --- /dev/null +++ b/drivers/gpu/pvr/deviceclass.c | |||
@@ -0,0 +1,2012 @@ | |||
1 | /********************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful but, except | ||
10 | * as otherwise stated in writing, without any warranty; without even the | ||
11 | * implied warranty of merchantability or fitness for a particular purpose. | ||
12 | * See the GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | ||
17 | * | ||
18 | * The full GNU General Public License is included in this distribution in | ||
19 | * the file called "COPYING". | ||
20 | * | ||
21 | * Contact Information: | ||
22 | * Imagination Technologies Ltd. <gpl-support@imgtec.com> | ||
23 | * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK | ||
24 | * | ||
25 | ******************************************************************************/ | ||
26 | |||
27 | #include "services_headers.h" | ||
28 | #include "buffer_manager.h" | ||
29 | #include "kernelbuffer.h" | ||
30 | #include "kerneldisplay.h" | ||
31 | #include "pvr_bridge_km.h" | ||
32 | #include "pdump_km.h" | ||
33 | #include "deviceid.h" | ||
34 | |||
35 | #include "lists.h" | ||
36 | |||
37 | PVRSRV_ERROR AllocateDeviceID(SYS_DATA *psSysData, IMG_UINT32 *pui32DevID); | ||
38 | PVRSRV_ERROR FreeDeviceID(SYS_DATA *psSysData, IMG_UINT32 ui32DevID); | ||
39 | |||
40 | #if defined(SUPPORT_MISR_IN_THREAD) | ||
41 | void OSVSyncMISR(IMG_HANDLE, IMG_BOOL); | ||
42 | #endif | ||
43 | |||
44 | #if defined(SUPPORT_CUSTOM_SWAP_OPERATIONS) | ||
45 | IMG_VOID PVRSRVFreeCommandCompletePacketKM(IMG_HANDLE hCmdCookie, | ||
46 | IMG_BOOL bScheduleMISR); | ||
47 | #endif | ||
48 | typedef struct PVRSRV_DC_SRV2DISP_KMJTABLE_TAG *PPVRSRV_DC_SRV2DISP_KMJTABLE; | ||
49 | |||
50 | typedef struct PVRSRV_DC_BUFFER_TAG | ||
51 | { | ||
52 | |||
53 | PVRSRV_DEVICECLASS_BUFFER sDeviceClassBuffer; | ||
54 | |||
55 | struct PVRSRV_DISPLAYCLASS_INFO_TAG *psDCInfo; | ||
56 | struct PVRSRV_DC_SWAPCHAIN_TAG *psSwapChain; | ||
57 | } PVRSRV_DC_BUFFER; | ||
58 | |||
59 | typedef struct PVRSRV_DC_SWAPCHAIN_TAG | ||
60 | { | ||
61 | IMG_HANDLE hExtSwapChain; | ||
62 | IMG_UINT32 ui32SwapChainID; | ||
63 | IMG_UINT32 ui32RefCount; | ||
64 | IMG_UINT32 ui32Flags; | ||
65 | PVRSRV_QUEUE_INFO *psQueue; | ||
66 | PVRSRV_DC_BUFFER asBuffer[PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS]; | ||
67 | IMG_UINT32 ui32BufferCount; | ||
68 | PVRSRV_DC_BUFFER *psLastFlipBuffer; | ||
69 | IMG_UINT32 ui32MinSwapInterval; | ||
70 | IMG_UINT32 ui32MaxSwapInterval; | ||
71 | struct PVRSRV_DISPLAYCLASS_INFO_TAG *psDCInfo; | ||
72 | struct PVRSRV_DC_SWAPCHAIN_TAG *psNext; | ||
73 | } PVRSRV_DC_SWAPCHAIN; | ||
74 | |||
75 | |||
76 | typedef struct PVRSRV_DC_SWAPCHAIN_REF_TAG | ||
77 | { | ||
78 | struct PVRSRV_DC_SWAPCHAIN_TAG *psSwapChain; | ||
79 | IMG_HANDLE hResItem; | ||
80 | } PVRSRV_DC_SWAPCHAIN_REF; | ||
81 | |||
82 | |||
83 | typedef struct PVRSRV_DISPLAYCLASS_INFO_TAG | ||
84 | { | ||
85 | IMG_UINT32 ui32RefCount; | ||
86 | IMG_UINT32 ui32DeviceID; | ||
87 | IMG_HANDLE hExtDevice; | ||
88 | PPVRSRV_DC_SRV2DISP_KMJTABLE psFuncTable; | ||
89 | IMG_HANDLE hDevMemContext; | ||
90 | PVRSRV_DC_BUFFER sSystemBuffer; | ||
91 | struct PVRSRV_DC_SWAPCHAIN_TAG *psDCSwapChainShared; | ||
92 | } PVRSRV_DISPLAYCLASS_INFO; | ||
93 | |||
94 | |||
95 | typedef struct PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO_TAG | ||
96 | { | ||
97 | PVRSRV_DISPLAYCLASS_INFO *psDCInfo; | ||
98 | PRESMAN_ITEM hResItem; | ||
99 | } PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO; | ||
100 | |||
101 | |||
102 | typedef struct PVRSRV_BC_SRV2BUFFER_KMJTABLE_TAG *PPVRSRV_BC_SRV2BUFFER_KMJTABLE; | ||
103 | |||
104 | typedef struct PVRSRV_BC_BUFFER_TAG | ||
105 | { | ||
106 | |||
107 | PVRSRV_DEVICECLASS_BUFFER sDeviceClassBuffer; | ||
108 | |||
109 | struct PVRSRV_BUFFERCLASS_INFO_TAG *psBCInfo; | ||
110 | } PVRSRV_BC_BUFFER; | ||
111 | |||
112 | |||
113 | typedef struct PVRSRV_BUFFERCLASS_INFO_TAG | ||
114 | { | ||
115 | IMG_UINT32 ui32RefCount; | ||
116 | IMG_UINT32 ui32DeviceID; | ||
117 | IMG_HANDLE hExtDevice; | ||
118 | PPVRSRV_BC_SRV2BUFFER_KMJTABLE psFuncTable; | ||
119 | IMG_HANDLE hDevMemContext; | ||
120 | |||
121 | IMG_UINT32 ui32BufferCount; | ||
122 | PVRSRV_BC_BUFFER *psBuffer; | ||
123 | |||
124 | } PVRSRV_BUFFERCLASS_INFO; | ||
125 | |||
126 | |||
127 | typedef struct PVRSRV_BUFFERCLASS_PERCONTEXT_INFO_TAG | ||
128 | { | ||
129 | PVRSRV_BUFFERCLASS_INFO *psBCInfo; | ||
130 | IMG_HANDLE hResItem; | ||
131 | } PVRSRV_BUFFERCLASS_PERCONTEXT_INFO; | ||
132 | |||
133 | |||
134 | static PVRSRV_DISPLAYCLASS_INFO* DCDeviceHandleToDCInfo (IMG_HANDLE hDeviceKM) | ||
135 | { | ||
136 | PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *psDCPerContextInfo; | ||
137 | |||
138 | psDCPerContextInfo = (PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *)hDeviceKM; | ||
139 | |||
140 | return psDCPerContextInfo->psDCInfo; | ||
141 | } | ||
142 | |||
143 | |||
144 | static PVRSRV_BUFFERCLASS_INFO* BCDeviceHandleToBCInfo (IMG_HANDLE hDeviceKM) | ||
145 | { | ||
146 | PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *psBCPerContextInfo; | ||
147 | |||
148 | psBCPerContextInfo = (PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *)hDeviceKM; | ||
149 | |||
150 | return psBCPerContextInfo->psBCInfo; | ||
151 | } | ||
152 | |||
153 | static IMG_VOID PVRSRVEnumerateDCKM_ForEachVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va) | ||
154 | { | ||
155 | IMG_UINT *pui32DevCount; | ||
156 | IMG_UINT32 **ppui32DevID; | ||
157 | PVRSRV_DEVICE_CLASS peDeviceClass; | ||
158 | |||
159 | pui32DevCount = va_arg(va, IMG_UINT*); | ||
160 | ppui32DevID = va_arg(va, IMG_UINT32**); | ||
161 | peDeviceClass = va_arg(va, PVRSRV_DEVICE_CLASS); | ||
162 | |||
163 | if ((psDeviceNode->sDevId.eDeviceClass == peDeviceClass) | ||
164 | && (psDeviceNode->sDevId.eDeviceType == PVRSRV_DEVICE_TYPE_EXT)) | ||
165 | { | ||
166 | (*pui32DevCount)++; | ||
167 | if(*ppui32DevID) | ||
168 | { | ||
169 | *(*ppui32DevID)++ = psDeviceNode->sDevId.ui32DeviceIndex; | ||
170 | } | ||
171 | } | ||
172 | } | ||
173 | |||
174 | |||
175 | IMG_EXPORT | ||
176 | PVRSRV_ERROR PVRSRVEnumerateDCKM (PVRSRV_DEVICE_CLASS DeviceClass, | ||
177 | IMG_UINT32 *pui32DevCount, | ||
178 | IMG_UINT32 *pui32DevID ) | ||
179 | { | ||
180 | |||
181 | IMG_UINT ui32DevCount = 0; | ||
182 | SYS_DATA *psSysData; | ||
183 | |||
184 | SysAcquireData(&psSysData); | ||
185 | |||
186 | |||
187 | List_PVRSRV_DEVICE_NODE_ForEach_va(psSysData->psDeviceNodeList, | ||
188 | &PVRSRVEnumerateDCKM_ForEachVaCb, | ||
189 | &ui32DevCount, | ||
190 | &pui32DevID, | ||
191 | DeviceClass); | ||
192 | |||
193 | if(pui32DevCount) | ||
194 | { | ||
195 | *pui32DevCount = ui32DevCount; | ||
196 | } | ||
197 | else if(pui32DevID == IMG_NULL) | ||
198 | { | ||
199 | PVR_DPF((PVR_DBG_ERROR,"PVRSRVEnumerateDCKM: Invalid parameters")); | ||
200 | return (PVRSRV_ERROR_INVALID_PARAMS); | ||
201 | } | ||
202 | |||
203 | return PVRSRV_OK; | ||
204 | } | ||
205 | |||
206 | |||
207 | static | ||
208 | PVRSRV_ERROR PVRSRVRegisterDCDeviceKM (PVRSRV_DC_SRV2DISP_KMJTABLE *psFuncTable, | ||
209 | IMG_UINT32 *pui32DeviceID) | ||
210 | { | ||
211 | PVRSRV_DISPLAYCLASS_INFO *psDCInfo = IMG_NULL; | ||
212 | PVRSRV_DEVICE_NODE *psDeviceNode; | ||
213 | SYS_DATA *psSysData; | ||
214 | |||
215 | |||
216 | |||
217 | |||
218 | |||
219 | |||
220 | |||
221 | |||
222 | |||
223 | |||
224 | |||
225 | |||
226 | |||
227 | |||
228 | |||
229 | |||
230 | SysAcquireData(&psSysData); | ||
231 | |||
232 | |||
233 | |||
234 | |||
235 | |||
236 | if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP, | ||
237 | sizeof(*psDCInfo), | ||
238 | (IMG_VOID **)&psDCInfo, IMG_NULL, | ||
239 | "Display Class Info") != PVRSRV_OK) | ||
240 | { | ||
241 | PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterDCDeviceKM: Failed psDCInfo alloc")); | ||
242 | return PVRSRV_ERROR_OUT_OF_MEMORY; | ||
243 | } | ||
244 | OSMemSet (psDCInfo, 0, sizeof(*psDCInfo)); | ||
245 | |||
246 | |||
247 | if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP, | ||
248 | sizeof(PVRSRV_DC_SRV2DISP_KMJTABLE), | ||
249 | (IMG_VOID **)&psDCInfo->psFuncTable, IMG_NULL, | ||
250 | "Function table for SRVKM->DISPLAY") != PVRSRV_OK) | ||
251 | { | ||
252 | PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterDCDeviceKM: Failed psFuncTable alloc")); | ||
253 | goto ErrorExit; | ||
254 | } | ||
255 | OSMemSet (psDCInfo->psFuncTable, 0, sizeof(PVRSRV_DC_SRV2DISP_KMJTABLE)); | ||
256 | |||
257 | |||
258 | *psDCInfo->psFuncTable = *psFuncTable; | ||
259 | |||
260 | |||
261 | if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP, | ||
262 | sizeof(PVRSRV_DEVICE_NODE), | ||
263 | (IMG_VOID **)&psDeviceNode, IMG_NULL, | ||
264 | "Device Node") != PVRSRV_OK) | ||
265 | { | ||
266 | PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterDCDeviceKM: Failed psDeviceNode alloc")); | ||
267 | goto ErrorExit; | ||
268 | } | ||
269 | OSMemSet (psDeviceNode, 0, sizeof(PVRSRV_DEVICE_NODE)); | ||
270 | |||
271 | psDeviceNode->pvDevice = (IMG_VOID*)psDCInfo; | ||
272 | psDeviceNode->ui32pvDeviceSize = sizeof(*psDCInfo); | ||
273 | psDeviceNode->ui32RefCount = 1; | ||
274 | psDeviceNode->sDevId.eDeviceType = PVRSRV_DEVICE_TYPE_EXT; | ||
275 | psDeviceNode->sDevId.eDeviceClass = PVRSRV_DEVICE_CLASS_DISPLAY; | ||
276 | psDeviceNode->psSysData = psSysData; | ||
277 | |||
278 | |||
279 | if (AllocateDeviceID(psSysData, &psDeviceNode->sDevId.ui32DeviceIndex) != PVRSRV_OK) | ||
280 | { | ||
281 | PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterBCDeviceKM: Failed to allocate Device ID")); | ||
282 | goto ErrorExit; | ||
283 | } | ||
284 | psDCInfo->ui32DeviceID = psDeviceNode->sDevId.ui32DeviceIndex; | ||
285 | if (pui32DeviceID) | ||
286 | { | ||
287 | *pui32DeviceID = psDeviceNode->sDevId.ui32DeviceIndex; | ||
288 | } | ||
289 | |||
290 | |||
291 | SysRegisterExternalDevice(psDeviceNode); | ||
292 | |||
293 | |||
294 | List_PVRSRV_DEVICE_NODE_Insert(&psSysData->psDeviceNodeList, psDeviceNode); | ||
295 | |||
296 | return PVRSRV_OK; | ||
297 | |||
298 | ErrorExit: | ||
299 | |||
300 | if(psDCInfo->psFuncTable) | ||
301 | { | ||
302 | OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DC_SRV2DISP_KMJTABLE), psDCInfo->psFuncTable, IMG_NULL); | ||
303 | psDCInfo->psFuncTable = IMG_NULL; | ||
304 | } | ||
305 | |||
306 | OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DISPLAYCLASS_INFO), psDCInfo, IMG_NULL); | ||
307 | |||
308 | |||
309 | return PVRSRV_ERROR_OUT_OF_MEMORY; | ||
310 | } | ||
311 | |||
312 | static PVRSRV_ERROR PVRSRVRemoveDCDeviceKM(IMG_UINT32 ui32DevIndex) | ||
313 | { | ||
314 | SYS_DATA *psSysData; | ||
315 | PVRSRV_DEVICE_NODE *psDeviceNode; | ||
316 | PVRSRV_DISPLAYCLASS_INFO *psDCInfo; | ||
317 | |||
318 | SysAcquireData(&psSysData); | ||
319 | |||
320 | |||
321 | psDeviceNode = (PVRSRV_DEVICE_NODE*) | ||
322 | List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList, | ||
323 | &MatchDeviceKM_AnyVaCb, | ||
324 | ui32DevIndex, | ||
325 | IMG_FALSE, | ||
326 | PVRSRV_DEVICE_CLASS_DISPLAY); | ||
327 | if (!psDeviceNode) | ||
328 | { | ||
329 | |||
330 | PVR_DPF((PVR_DBG_ERROR,"PVRSRVRemoveDCDeviceKM: requested device %d not present", ui32DevIndex)); | ||
331 | return PVRSRV_ERROR_NO_DEVICENODE_FOUND; | ||
332 | } | ||
333 | |||
334 | |||
335 | psDCInfo = (PVRSRV_DISPLAYCLASS_INFO*)psDeviceNode->pvDevice; | ||
336 | |||
337 | |||
338 | |||
339 | |||
340 | if(psDCInfo->ui32RefCount == 0) | ||
341 | { | ||
342 | |||
343 | |||
344 | List_PVRSRV_DEVICE_NODE_Remove(psDeviceNode); | ||
345 | |||
346 | |||
347 | SysRemoveExternalDevice(psDeviceNode); | ||
348 | |||
349 | |||
350 | |||
351 | |||
352 | PVR_ASSERT(psDCInfo->ui32RefCount == 0); | ||
353 | (IMG_VOID)FreeDeviceID(psSysData, ui32DevIndex); | ||
354 | (IMG_VOID)OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DC_SRV2DISP_KMJTABLE), psDCInfo->psFuncTable, IMG_NULL); | ||
355 | psDCInfo->psFuncTable = IMG_NULL; | ||
356 | (IMG_VOID)OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DISPLAYCLASS_INFO), psDCInfo, IMG_NULL); | ||
357 | |||
358 | (IMG_VOID)OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DEVICE_NODE), psDeviceNode, IMG_NULL); | ||
359 | |||
360 | } | ||
361 | else | ||
362 | { | ||
363 | PVR_DPF((PVR_DBG_ERROR,"PVRSRVRemoveDCDeviceKM: failed as %d Services DC API connections are still open", psDCInfo->ui32RefCount)); | ||
364 | return PVRSRV_ERROR_UNABLE_TO_REMOVE_DEVICE; | ||
365 | } | ||
366 | |||
367 | return PVRSRV_OK; | ||
368 | } | ||
369 | |||
370 | |||
371 | static | ||
372 | PVRSRV_ERROR PVRSRVRegisterBCDeviceKM (PVRSRV_BC_SRV2BUFFER_KMJTABLE *psFuncTable, | ||
373 | IMG_UINT32 *pui32DeviceID) | ||
374 | { | ||
375 | PVRSRV_BUFFERCLASS_INFO *psBCInfo = IMG_NULL; | ||
376 | PVRSRV_DEVICE_NODE *psDeviceNode; | ||
377 | SYS_DATA *psSysData; | ||
378 | |||
379 | |||
380 | |||
381 | |||
382 | |||
383 | |||
384 | |||
385 | |||
386 | |||
387 | |||
388 | |||
389 | |||
390 | |||
391 | |||
392 | SysAcquireData(&psSysData); | ||
393 | |||
394 | |||
395 | |||
396 | |||
397 | |||
398 | if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP, | ||
399 | sizeof(*psBCInfo), | ||
400 | (IMG_VOID **)&psBCInfo, IMG_NULL, | ||
401 | "Buffer Class Info") != PVRSRV_OK) | ||
402 | { | ||
403 | PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterBCDeviceKM: Failed psBCInfo alloc")); | ||
404 | return PVRSRV_ERROR_OUT_OF_MEMORY; | ||
405 | } | ||
406 | OSMemSet (psBCInfo, 0, sizeof(*psBCInfo)); | ||
407 | |||
408 | |||
409 | if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP, | ||
410 | sizeof(PVRSRV_BC_SRV2BUFFER_KMJTABLE), | ||
411 | (IMG_VOID **)&psBCInfo->psFuncTable, IMG_NULL, | ||
412 | "Function table for SRVKM->BUFFER") != PVRSRV_OK) | ||
413 | { | ||
414 | PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterBCDeviceKM: Failed psFuncTable alloc")); | ||
415 | goto ErrorExit; | ||
416 | } | ||
417 | OSMemSet (psBCInfo->psFuncTable, 0, sizeof(PVRSRV_BC_SRV2BUFFER_KMJTABLE)); | ||
418 | |||
419 | |||
420 | *psBCInfo->psFuncTable = *psFuncTable; | ||
421 | |||
422 | |||
423 | if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP, | ||
424 | sizeof(PVRSRV_DEVICE_NODE), | ||
425 | (IMG_VOID **)&psDeviceNode, IMG_NULL, | ||
426 | "Device Node") != PVRSRV_OK) | ||
427 | { | ||
428 | PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterBCDeviceKM: Failed psDeviceNode alloc")); | ||
429 | goto ErrorExit; | ||
430 | } | ||
431 | OSMemSet (psDeviceNode, 0, sizeof(PVRSRV_DEVICE_NODE)); | ||
432 | |||
433 | psDeviceNode->pvDevice = (IMG_VOID*)psBCInfo; | ||
434 | psDeviceNode->ui32pvDeviceSize = sizeof(*psBCInfo); | ||
435 | psDeviceNode->ui32RefCount = 1; | ||
436 | psDeviceNode->sDevId.eDeviceType = PVRSRV_DEVICE_TYPE_EXT; | ||
437 | psDeviceNode->sDevId.eDeviceClass = PVRSRV_DEVICE_CLASS_BUFFER; | ||
438 | psDeviceNode->psSysData = psSysData; | ||
439 | |||
440 | |||
441 | if (AllocateDeviceID(psSysData, &psDeviceNode->sDevId.ui32DeviceIndex) != PVRSRV_OK) | ||
442 | { | ||
443 | PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterBCDeviceKM: Failed to allocate Device ID")); | ||
444 | goto ErrorExit; | ||
445 | } | ||
446 | psBCInfo->ui32DeviceID = psDeviceNode->sDevId.ui32DeviceIndex; | ||
447 | if (pui32DeviceID) | ||
448 | { | ||
449 | *pui32DeviceID = psDeviceNode->sDevId.ui32DeviceIndex; | ||
450 | } | ||
451 | |||
452 | |||
453 | List_PVRSRV_DEVICE_NODE_Insert(&psSysData->psDeviceNodeList, psDeviceNode); | ||
454 | |||
455 | return PVRSRV_OK; | ||
456 | |||
457 | ErrorExit: | ||
458 | |||
459 | if(psBCInfo->psFuncTable) | ||
460 | { | ||
461 | OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PPVRSRV_BC_SRV2BUFFER_KMJTABLE), psBCInfo->psFuncTable, IMG_NULL); | ||
462 | psBCInfo->psFuncTable = IMG_NULL; | ||
463 | } | ||
464 | |||
465 | OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_BUFFERCLASS_INFO), psBCInfo, IMG_NULL); | ||
466 | |||
467 | |||
468 | return PVRSRV_ERROR_OUT_OF_MEMORY; | ||
469 | } | ||
470 | |||
471 | |||
472 | static PVRSRV_ERROR PVRSRVRemoveBCDeviceKM(IMG_UINT32 ui32DevIndex) | ||
473 | { | ||
474 | SYS_DATA *psSysData; | ||
475 | PVRSRV_DEVICE_NODE *psDevNode; | ||
476 | PVRSRV_BUFFERCLASS_INFO *psBCInfo; | ||
477 | |||
478 | SysAcquireData(&psSysData); | ||
479 | |||
480 | |||
481 | psDevNode = (PVRSRV_DEVICE_NODE*) | ||
482 | List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList, | ||
483 | &MatchDeviceKM_AnyVaCb, | ||
484 | ui32DevIndex, | ||
485 | IMG_FALSE, | ||
486 | PVRSRV_DEVICE_CLASS_BUFFER); | ||
487 | |||
488 | if (!psDevNode) | ||
489 | { | ||
490 | PVR_DPF((PVR_DBG_ERROR,"PVRSRVRemoveBCDeviceKM: requested device %d not present", ui32DevIndex)); | ||
491 | return PVRSRV_ERROR_NO_DEVICENODE_FOUND; | ||
492 | } | ||
493 | |||
494 | |||
495 | |||
496 | psBCInfo = (PVRSRV_BUFFERCLASS_INFO*)psDevNode->pvDevice; | ||
497 | |||
498 | |||
499 | |||
500 | |||
501 | if(psBCInfo->ui32RefCount == 0) | ||
502 | { | ||
503 | |||
504 | |||
505 | List_PVRSRV_DEVICE_NODE_Remove(psDevNode); | ||
506 | |||
507 | |||
508 | |||
509 | |||
510 | (IMG_VOID)FreeDeviceID(psSysData, ui32DevIndex); | ||
511 | |||
512 | |||
513 | (IMG_VOID)OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_BC_SRV2BUFFER_KMJTABLE), psBCInfo->psFuncTable, IMG_NULL); | ||
514 | psBCInfo->psFuncTable = IMG_NULL; | ||
515 | (IMG_VOID)OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_BUFFERCLASS_INFO), psBCInfo, IMG_NULL); | ||
516 | |||
517 | (IMG_VOID)OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DEVICE_NODE), psDevNode, IMG_NULL); | ||
518 | |||
519 | } | ||
520 | else | ||
521 | { | ||
522 | PVR_DPF((PVR_DBG_ERROR,"PVRSRVRemoveBCDeviceKM: failed as %d Services BC API connections are still open", psBCInfo->ui32RefCount)); | ||
523 | return PVRSRV_ERROR_UNABLE_TO_REMOVE_DEVICE; | ||
524 | } | ||
525 | |||
526 | return PVRSRV_OK; | ||
527 | } | ||
528 | |||
529 | |||
530 | |||
531 | IMG_EXPORT | ||
532 | PVRSRV_ERROR PVRSRVCloseDCDeviceKM (IMG_HANDLE hDeviceKM, | ||
533 | IMG_BOOL bResManCallback) | ||
534 | { | ||
535 | PVRSRV_ERROR eError; | ||
536 | PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *psDCPerContextInfo; | ||
537 | |||
538 | PVR_UNREFERENCED_PARAMETER(bResManCallback); | ||
539 | |||
540 | psDCPerContextInfo = (PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *)hDeviceKM; | ||
541 | |||
542 | |||
543 | eError = ResManFreeResByPtr(psDCPerContextInfo->hResItem); | ||
544 | |||
545 | return eError; | ||
546 | } | ||
547 | |||
548 | |||
549 | static PVRSRV_ERROR CloseDCDeviceCallBack(IMG_PVOID pvParam, | ||
550 | IMG_UINT32 ui32Param) | ||
551 | { | ||
552 | PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *psDCPerContextInfo; | ||
553 | PVRSRV_DISPLAYCLASS_INFO *psDCInfo; | ||
554 | |||
555 | PVR_UNREFERENCED_PARAMETER(ui32Param); | ||
556 | |||
557 | psDCPerContextInfo = (PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *)pvParam; | ||
558 | psDCInfo = psDCPerContextInfo->psDCInfo; | ||
559 | |||
560 | psDCInfo->ui32RefCount--; | ||
561 | if(psDCInfo->ui32RefCount == 0) | ||
562 | { | ||
563 | |||
564 | psDCInfo->psFuncTable->pfnCloseDCDevice(psDCInfo->hExtDevice); | ||
565 | |||
566 | if (--psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo->ui32RefCount == 0) | ||
567 | { | ||
568 | PVRSRVFreeSyncInfoKM(psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo); | ||
569 | } | ||
570 | |||
571 | psDCInfo->hDevMemContext = IMG_NULL; | ||
572 | psDCInfo->hExtDevice = IMG_NULL; | ||
573 | } | ||
574 | |||
575 | OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO), psDCPerContextInfo, IMG_NULL); | ||
576 | |||
577 | |||
578 | return PVRSRV_OK; | ||
579 | } | ||
580 | |||
581 | |||
582 | IMG_EXPORT | ||
583 | PVRSRV_ERROR PVRSRVOpenDCDeviceKM (PVRSRV_PER_PROCESS_DATA *psPerProc, | ||
584 | IMG_UINT32 ui32DeviceID, | ||
585 | IMG_HANDLE hDevCookie, | ||
586 | IMG_HANDLE *phDeviceKM) | ||
587 | { | ||
588 | PVRSRV_DISPLAYCLASS_INFO *psDCInfo; | ||
589 | PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *psDCPerContextInfo; | ||
590 | PVRSRV_DEVICE_NODE *psDeviceNode; | ||
591 | SYS_DATA *psSysData; | ||
592 | PVRSRV_ERROR eError; | ||
593 | |||
594 | if(!phDeviceKM || !hDevCookie) | ||
595 | { | ||
596 | PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenDCDeviceKM: Invalid params")); | ||
597 | return PVRSRV_ERROR_INVALID_PARAMS; | ||
598 | } | ||
599 | |||
600 | SysAcquireData(&psSysData); | ||
601 | |||
602 | |||
603 | psDeviceNode = (PVRSRV_DEVICE_NODE*) | ||
604 | List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList, | ||
605 | &MatchDeviceKM_AnyVaCb, | ||
606 | ui32DeviceID, | ||
607 | IMG_FALSE, | ||
608 | PVRSRV_DEVICE_CLASS_DISPLAY); | ||
609 | if (!psDeviceNode) | ||
610 | { | ||
611 | PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenDCDeviceKM: no devnode matching index %d", ui32DeviceID)); | ||
612 | return PVRSRV_ERROR_NO_DEVICENODE_FOUND; | ||
613 | } | ||
614 | psDCInfo = (PVRSRV_DISPLAYCLASS_INFO*)psDeviceNode->pvDevice; | ||
615 | |||
616 | |||
617 | |||
618 | |||
619 | if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, | ||
620 | sizeof(*psDCPerContextInfo), | ||
621 | (IMG_VOID **)&psDCPerContextInfo, IMG_NULL, | ||
622 | "Display Class per Context Info") != PVRSRV_OK) | ||
623 | { | ||
624 | PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenDCDeviceKM: Failed psDCPerContextInfo alloc")); | ||
625 | return PVRSRV_ERROR_OUT_OF_MEMORY; | ||
626 | } | ||
627 | OSMemSet(psDCPerContextInfo, 0, sizeof(*psDCPerContextInfo)); | ||
628 | |||
629 | if(psDCInfo->ui32RefCount++ == 0) | ||
630 | { | ||
631 | |||
632 | psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevCookie; | ||
633 | |||
634 | |||
635 | psDCInfo->hDevMemContext = (IMG_HANDLE)psDeviceNode->sDevMemoryInfo.pBMKernelContext; | ||
636 | |||
637 | |||
638 | eError = PVRSRVAllocSyncInfoKM(IMG_NULL, | ||
639 | (IMG_HANDLE)psDeviceNode->sDevMemoryInfo.pBMKernelContext, | ||
640 | &psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo); | ||
641 | if(eError != PVRSRV_OK) | ||
642 | { | ||
643 | PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenDCDeviceKM: Failed sync info alloc")); | ||
644 | psDCInfo->ui32RefCount--; | ||
645 | return eError; | ||
646 | } | ||
647 | |||
648 | |||
649 | eError = psDCInfo->psFuncTable->pfnOpenDCDevice(ui32DeviceID, | ||
650 | &psDCInfo->hExtDevice, | ||
651 | (PVRSRV_SYNC_DATA*)psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo->psSyncDataMemInfoKM->pvLinAddrKM); | ||
652 | if(eError != PVRSRV_OK) | ||
653 | { | ||
654 | PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenDCDeviceKM: Failed to open external DC device")); | ||
655 | psDCInfo->ui32RefCount--; | ||
656 | PVRSRVFreeSyncInfoKM(psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo); | ||
657 | return eError; | ||
658 | } | ||
659 | |||
660 | psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo->ui32RefCount++; | ||
661 | } | ||
662 | |||
663 | psDCPerContextInfo->psDCInfo = psDCInfo; | ||
664 | psDCPerContextInfo->hResItem = ResManRegisterRes(psPerProc->hResManContext, | ||
665 | RESMAN_TYPE_DISPLAYCLASS_DEVICE, | ||
666 | psDCPerContextInfo, | ||
667 | 0, | ||
668 | &CloseDCDeviceCallBack); | ||
669 | |||
670 | |||
671 | *phDeviceKM = (IMG_HANDLE)psDCPerContextInfo; | ||
672 | |||
673 | return PVRSRV_OK; | ||
674 | } | ||
675 | |||
676 | |||
677 | IMG_EXPORT | ||
678 | PVRSRV_ERROR PVRSRVEnumDCFormatsKM (IMG_HANDLE hDeviceKM, | ||
679 | IMG_UINT32 *pui32Count, | ||
680 | DISPLAY_FORMAT *psFormat) | ||
681 | { | ||
682 | PVRSRV_DISPLAYCLASS_INFO *psDCInfo; | ||
683 | |||
684 | if(!hDeviceKM || !pui32Count || !psFormat) | ||
685 | { | ||
686 | PVR_DPF((PVR_DBG_ERROR,"PVRSRVEnumDCFormatsKM: Invalid parameters")); | ||
687 | return PVRSRV_ERROR_INVALID_PARAMS; | ||
688 | } | ||
689 | |||
690 | psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM); | ||
691 | |||
692 | |||
693 | return psDCInfo->psFuncTable->pfnEnumDCFormats(psDCInfo->hExtDevice, pui32Count, psFormat); | ||
694 | } | ||
695 | |||
696 | |||
697 | |||
698 | IMG_EXPORT | ||
699 | PVRSRV_ERROR PVRSRVEnumDCDimsKM (IMG_HANDLE hDeviceKM, | ||
700 | DISPLAY_FORMAT *psFormat, | ||
701 | IMG_UINT32 *pui32Count, | ||
702 | DISPLAY_DIMS *psDim) | ||
703 | { | ||
704 | PVRSRV_DISPLAYCLASS_INFO *psDCInfo; | ||
705 | |||
706 | if(!hDeviceKM || !pui32Count || !psFormat) | ||
707 | { | ||
708 | PVR_DPF((PVR_DBG_ERROR,"PVRSRVEnumDCDimsKM: Invalid parameters")); | ||
709 | return PVRSRV_ERROR_INVALID_PARAMS; | ||
710 | } | ||
711 | |||
712 | psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM); | ||
713 | |||
714 | |||
715 | return psDCInfo->psFuncTable->pfnEnumDCDims(psDCInfo->hExtDevice, psFormat, pui32Count, psDim); | ||
716 | } | ||
717 | |||
718 | |||
719 | IMG_EXPORT | ||
720 | PVRSRV_ERROR PVRSRVGetDCSystemBufferKM (IMG_HANDLE hDeviceKM, | ||
721 | IMG_HANDLE *phBuffer) | ||
722 | { | ||
723 | PVRSRV_ERROR eError; | ||
724 | PVRSRV_DISPLAYCLASS_INFO *psDCInfo; | ||
725 | IMG_HANDLE hExtBuffer; | ||
726 | |||
727 | if(!hDeviceKM || !phBuffer) | ||
728 | { | ||
729 | PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetDCSystemBufferKM: Invalid parameters")); | ||
730 | return PVRSRV_ERROR_INVALID_PARAMS; | ||
731 | } | ||
732 | |||
733 | psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM); | ||
734 | |||
735 | |||
736 | eError = psDCInfo->psFuncTable->pfnGetDCSystemBuffer(psDCInfo->hExtDevice, &hExtBuffer); | ||
737 | if(eError != PVRSRV_OK) | ||
738 | { | ||
739 | PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetDCSystemBufferKM: Failed to get valid buffer handle from external driver")); | ||
740 | return eError; | ||
741 | } | ||
742 | |||
743 | |||
744 | psDCInfo->sSystemBuffer.sDeviceClassBuffer.pfnGetBufferAddr = psDCInfo->psFuncTable->pfnGetBufferAddr; | ||
745 | psDCInfo->sSystemBuffer.sDeviceClassBuffer.hDevMemContext = psDCInfo->hDevMemContext; | ||
746 | psDCInfo->sSystemBuffer.sDeviceClassBuffer.hExtDevice = psDCInfo->hExtDevice; | ||
747 | psDCInfo->sSystemBuffer.sDeviceClassBuffer.hExtBuffer = hExtBuffer; | ||
748 | |||
749 | psDCInfo->sSystemBuffer.psDCInfo = psDCInfo; | ||
750 | |||
751 | |||
752 | *phBuffer = (IMG_HANDLE)&(psDCInfo->sSystemBuffer); | ||
753 | |||
754 | return PVRSRV_OK; | ||
755 | } | ||
756 | |||
757 | |||
758 | IMG_EXPORT | ||
759 | PVRSRV_ERROR PVRSRVGetDCInfoKM (IMG_HANDLE hDeviceKM, | ||
760 | DISPLAY_INFO *psDisplayInfo) | ||
761 | { | ||
762 | PVRSRV_DISPLAYCLASS_INFO *psDCInfo; | ||
763 | PVRSRV_ERROR eError; | ||
764 | |||
765 | if(!hDeviceKM || !psDisplayInfo) | ||
766 | { | ||
767 | PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetDCInfoKM: Invalid parameters")); | ||
768 | return PVRSRV_ERROR_INVALID_PARAMS; | ||
769 | } | ||
770 | |||
771 | psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM); | ||
772 | |||
773 | |||
774 | eError = psDCInfo->psFuncTable->pfnGetDCInfo(psDCInfo->hExtDevice, psDisplayInfo); | ||
775 | if (eError != PVRSRV_OK) | ||
776 | { | ||
777 | return eError; | ||
778 | } | ||
779 | |||
780 | if (psDisplayInfo->ui32MaxSwapChainBuffers > PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS) | ||
781 | { | ||
782 | psDisplayInfo->ui32MaxSwapChainBuffers = PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS; | ||
783 | } | ||
784 | |||
785 | return PVRSRV_OK; | ||
786 | } | ||
787 | |||
788 | |||
789 | IMG_EXPORT | ||
790 | PVRSRV_ERROR PVRSRVDestroyDCSwapChainKM(IMG_HANDLE hSwapChainRef) | ||
791 | { | ||
792 | PVRSRV_ERROR eError; | ||
793 | PVRSRV_DC_SWAPCHAIN_REF *psSwapChainRef; | ||
794 | |||
795 | if(!hSwapChainRef) | ||
796 | { | ||
797 | PVR_DPF((PVR_DBG_ERROR,"PVRSRVDestroyDCSwapChainKM: Invalid parameters")); | ||
798 | return PVRSRV_ERROR_INVALID_PARAMS; | ||
799 | } | ||
800 | |||
801 | psSwapChainRef = hSwapChainRef; | ||
802 | |||
803 | eError = ResManFreeResByPtr(psSwapChainRef->hResItem); | ||
804 | |||
805 | return eError; | ||
806 | } | ||
807 | |||
808 | |||
809 | static PVRSRV_ERROR DestroyDCSwapChain(PVRSRV_DC_SWAPCHAIN *psSwapChain) | ||
810 | { | ||
811 | PVRSRV_ERROR eError; | ||
812 | PVRSRV_DISPLAYCLASS_INFO *psDCInfo = psSwapChain->psDCInfo; | ||
813 | IMG_UINT32 i; | ||
814 | |||
815 | |||
816 | |||
817 | if( psDCInfo->psDCSwapChainShared ) | ||
818 | { | ||
819 | if( psDCInfo->psDCSwapChainShared == psSwapChain ) | ||
820 | { | ||
821 | psDCInfo->psDCSwapChainShared = psSwapChain->psNext; | ||
822 | } | ||
823 | else | ||
824 | { | ||
825 | PVRSRV_DC_SWAPCHAIN *psCurrentSwapChain; | ||
826 | psCurrentSwapChain = psDCInfo->psDCSwapChainShared; | ||
827 | while( psCurrentSwapChain->psNext ) | ||
828 | { | ||
829 | if( psCurrentSwapChain->psNext != psSwapChain ) | ||
830 | { | ||
831 | psCurrentSwapChain = psCurrentSwapChain->psNext; | ||
832 | continue; | ||
833 | } | ||
834 | psCurrentSwapChain->psNext = psSwapChain->psNext; | ||
835 | break; | ||
836 | } | ||
837 | } | ||
838 | } | ||
839 | |||
840 | |||
841 | PVRSRVDestroyCommandQueueKM(psSwapChain->psQueue); | ||
842 | |||
843 | |||
844 | eError = psDCInfo->psFuncTable->pfnDestroyDCSwapChain(psDCInfo->hExtDevice, | ||
845 | psSwapChain->hExtSwapChain); | ||
846 | |||
847 | if (eError != PVRSRV_OK) | ||
848 | { | ||
849 | PVR_DPF((PVR_DBG_ERROR,"DestroyDCSwapChainCallBack: Failed to destroy DC swap chain")); | ||
850 | return eError; | ||
851 | } | ||
852 | |||
853 | |||
854 | for(i=0; i<psSwapChain->ui32BufferCount; i++) | ||
855 | { | ||
856 | if(psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo) | ||
857 | { | ||
858 | if (--psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->ui32RefCount == 0) | ||
859 | { | ||
860 | PVRSRVFreeSyncInfoKM(psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo); | ||
861 | } | ||
862 | } | ||
863 | } | ||
864 | |||
865 | OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DC_SWAPCHAIN), psSwapChain, IMG_NULL); | ||
866 | |||
867 | |||
868 | return eError; | ||
869 | } | ||
870 | |||
871 | |||
872 | static PVRSRV_ERROR DestroyDCSwapChainRefCallBack(IMG_PVOID pvParam, IMG_UINT32 ui32Param) | ||
873 | { | ||
874 | PVRSRV_DC_SWAPCHAIN_REF *psSwapChainRef = (PVRSRV_DC_SWAPCHAIN_REF *) pvParam; | ||
875 | PVRSRV_ERROR eError = PVRSRV_OK; | ||
876 | |||
877 | PVR_UNREFERENCED_PARAMETER(ui32Param); | ||
878 | |||
879 | if(--psSwapChainRef->psSwapChain->ui32RefCount == 0) | ||
880 | { | ||
881 | eError = DestroyDCSwapChain(psSwapChainRef->psSwapChain); | ||
882 | } | ||
883 | |||
884 | OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DC_SWAPCHAIN_REF), psSwapChainRef, IMG_NULL); | ||
885 | return eError; | ||
886 | } | ||
887 | |||
888 | static PVRSRV_DC_SWAPCHAIN* PVRSRVFindSharedDCSwapChainKM(PVRSRV_DISPLAYCLASS_INFO *psDCInfo, | ||
889 | IMG_UINT32 ui32SwapChainID) | ||
890 | { | ||
891 | PVRSRV_DC_SWAPCHAIN *psCurrentSwapChain; | ||
892 | |||
893 | for(psCurrentSwapChain = psDCInfo->psDCSwapChainShared; | ||
894 | psCurrentSwapChain; | ||
895 | psCurrentSwapChain = psCurrentSwapChain->psNext) | ||
896 | { | ||
897 | if(psCurrentSwapChain->ui32SwapChainID == ui32SwapChainID) | ||
898 | return psCurrentSwapChain; | ||
899 | } | ||
900 | return IMG_NULL; | ||
901 | } | ||
902 | |||
903 | static PVRSRV_ERROR PVRSRVCreateDCSwapChainRefKM(PVRSRV_PER_PROCESS_DATA *psPerProc, | ||
904 | PVRSRV_DC_SWAPCHAIN *psSwapChain, | ||
905 | PVRSRV_DC_SWAPCHAIN_REF **ppsSwapChainRef) | ||
906 | { | ||
907 | PVRSRV_DC_SWAPCHAIN_REF *psSwapChainRef = IMG_NULL; | ||
908 | |||
909 | |||
910 | if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP, | ||
911 | sizeof(PVRSRV_DC_SWAPCHAIN_REF), | ||
912 | (IMG_VOID **)&psSwapChainRef, IMG_NULL, | ||
913 | "Display Class Swapchain Reference") != PVRSRV_OK) | ||
914 | { | ||
915 | PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainRefKM: Failed psSwapChainRef alloc")); | ||
916 | return PVRSRV_ERROR_OUT_OF_MEMORY; | ||
917 | } | ||
918 | OSMemSet (psSwapChainRef, 0, sizeof(PVRSRV_DC_SWAPCHAIN_REF)); | ||
919 | |||
920 | |||
921 | psSwapChain->ui32RefCount++; | ||
922 | |||
923 | |||
924 | psSwapChainRef->psSwapChain = psSwapChain; | ||
925 | psSwapChainRef->hResItem = ResManRegisterRes(psPerProc->hResManContext, | ||
926 | RESMAN_TYPE_DISPLAYCLASS_SWAPCHAIN_REF, | ||
927 | psSwapChainRef, | ||
928 | 0, | ||
929 | &DestroyDCSwapChainRefCallBack); | ||
930 | *ppsSwapChainRef = psSwapChainRef; | ||
931 | |||
932 | return PVRSRV_OK; | ||
933 | } | ||
934 | |||
935 | |||
936 | IMG_EXPORT | ||
937 | PVRSRV_ERROR PVRSRVCreateDCSwapChainKM (PVRSRV_PER_PROCESS_DATA *psPerProc, | ||
938 | IMG_HANDLE hDeviceKM, | ||
939 | IMG_UINT32 ui32Flags, | ||
940 | DISPLAY_SURF_ATTRIBUTES *psDstSurfAttrib, | ||
941 | DISPLAY_SURF_ATTRIBUTES *psSrcSurfAttrib, | ||
942 | IMG_UINT32 ui32BufferCount, | ||
943 | IMG_UINT32 ui32OEMFlags, | ||
944 | IMG_HANDLE *phSwapChainRef, | ||
945 | IMG_UINT32 *pui32SwapChainID) | ||
946 | { | ||
947 | PVRSRV_DISPLAYCLASS_INFO *psDCInfo; | ||
948 | PVRSRV_DC_SWAPCHAIN *psSwapChain = IMG_NULL; | ||
949 | PVRSRV_DC_SWAPCHAIN_REF *psSwapChainRef = IMG_NULL; | ||
950 | PVRSRV_SYNC_DATA *apsSyncData[PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS]; | ||
951 | PVRSRV_QUEUE_INFO *psQueue = IMG_NULL; | ||
952 | PVRSRV_ERROR eError; | ||
953 | IMG_UINT32 i; | ||
954 | DISPLAY_INFO sDisplayInfo; | ||
955 | |||
956 | |||
957 | if(!hDeviceKM | ||
958 | || !psDstSurfAttrib | ||
959 | || !psSrcSurfAttrib | ||
960 | || !phSwapChainRef | ||
961 | || !pui32SwapChainID) | ||
962 | { | ||
963 | PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Invalid parameters")); | ||
964 | return PVRSRV_ERROR_INVALID_PARAMS; | ||
965 | } | ||
966 | |||
967 | if (ui32BufferCount > PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS) | ||
968 | { | ||
969 | PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Too many buffers")); | ||
970 | return PVRSRV_ERROR_TOOMANYBUFFERS; | ||
971 | } | ||
972 | |||
973 | if (ui32BufferCount < 2) | ||
974 | { | ||
975 | PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Too few buffers")); | ||
976 | return PVRSRV_ERROR_TOO_FEW_BUFFERS; | ||
977 | } | ||
978 | |||
979 | psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM); | ||
980 | |||
981 | if( ui32Flags & PVRSRV_CREATE_SWAPCHAIN_QUERY ) | ||
982 | { | ||
983 | |||
984 | psSwapChain = PVRSRVFindSharedDCSwapChainKM(psDCInfo, *pui32SwapChainID ); | ||
985 | if( psSwapChain ) | ||
986 | { | ||
987 | |||
988 | eError = PVRSRVCreateDCSwapChainRefKM(psPerProc, | ||
989 | psSwapChain, | ||
990 | &psSwapChainRef); | ||
991 | if( eError != PVRSRV_OK ) | ||
992 | { | ||
993 | PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Couldn't create swap chain reference")); | ||
994 | return eError; | ||
995 | } | ||
996 | |||
997 | *phSwapChainRef = (IMG_HANDLE)psSwapChainRef; | ||
998 | return PVRSRV_OK; | ||
999 | } | ||
1000 | PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: No shared SwapChain found for query")); | ||
1001 | return PVRSRV_ERROR_FLIP_CHAIN_EXISTS; | ||
1002 | } | ||
1003 | |||
1004 | |||
1005 | if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP, | ||
1006 | sizeof(PVRSRV_DC_SWAPCHAIN), | ||
1007 | (IMG_VOID **)&psSwapChain, IMG_NULL, | ||
1008 | "Display Class Swapchain") != PVRSRV_OK) | ||
1009 | { | ||
1010 | PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Failed psSwapChain alloc")); | ||
1011 | eError = PVRSRV_ERROR_OUT_OF_MEMORY; | ||
1012 | goto ErrorExit; | ||
1013 | } | ||
1014 | OSMemSet (psSwapChain, 0, sizeof(PVRSRV_DC_SWAPCHAIN)); | ||
1015 | |||
1016 | |||
1017 | eError = PVRSRVCreateCommandQueueKM(1024, &psQueue); | ||
1018 | if(eError != PVRSRV_OK) | ||
1019 | { | ||
1020 | PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Failed to create CmdQueue")); | ||
1021 | goto ErrorExit; | ||
1022 | } | ||
1023 | |||
1024 | |||
1025 | psSwapChain->psQueue = psQueue; | ||
1026 | |||
1027 | |||
1028 | for(i=0; i<ui32BufferCount; i++) | ||
1029 | { | ||
1030 | eError = PVRSRVAllocSyncInfoKM(IMG_NULL, | ||
1031 | psDCInfo->hDevMemContext, | ||
1032 | &psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo); | ||
1033 | if(eError != PVRSRV_OK) | ||
1034 | { | ||
1035 | PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Failed to alloc syninfo for psSwapChain")); | ||
1036 | goto ErrorExit; | ||
1037 | } | ||
1038 | |||
1039 | psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->ui32RefCount++; | ||
1040 | |||
1041 | |||
1042 | psSwapChain->asBuffer[i].sDeviceClassBuffer.pfnGetBufferAddr = psDCInfo->psFuncTable->pfnGetBufferAddr; | ||
1043 | psSwapChain->asBuffer[i].sDeviceClassBuffer.hDevMemContext = psDCInfo->hDevMemContext; | ||
1044 | psSwapChain->asBuffer[i].sDeviceClassBuffer.hExtDevice = psDCInfo->hExtDevice; | ||
1045 | |||
1046 | |||
1047 | psSwapChain->asBuffer[i].psDCInfo = psDCInfo; | ||
1048 | psSwapChain->asBuffer[i].psSwapChain = psSwapChain; | ||
1049 | |||
1050 | |||
1051 | apsSyncData[i] = (PVRSRV_SYNC_DATA*)psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->psSyncDataMemInfoKM->pvLinAddrKM; | ||
1052 | } | ||
1053 | |||
1054 | psSwapChain->ui32BufferCount = ui32BufferCount; | ||
1055 | psSwapChain->psDCInfo = psDCInfo; | ||
1056 | |||
1057 | #if defined(PDUMP) | ||
1058 | PDUMPCOMMENT("Allocate DC swap chain (SwapChainID == %u, BufferCount == %u)", | ||
1059 | *pui32SwapChainID, | ||
1060 | ui32BufferCount); | ||
1061 | PDUMPCOMMENT(" Src surface dimensions == %u x %u", | ||
1062 | psSrcSurfAttrib->sDims.ui32Width, | ||
1063 | psSrcSurfAttrib->sDims.ui32Height); | ||
1064 | PDUMPCOMMENT(" Dst surface dimensions == %u x %u", | ||
1065 | psDstSurfAttrib->sDims.ui32Width, | ||
1066 | psDstSurfAttrib->sDims.ui32Height); | ||
1067 | #endif | ||
1068 | |||
1069 | eError = psDCInfo->psFuncTable->pfnGetDCInfo(psDCInfo->hExtDevice, &sDisplayInfo); | ||
1070 | if (eError != PVRSRV_OK) | ||
1071 | { | ||
1072 | PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Failed to get DC info")); | ||
1073 | return eError; | ||
1074 | } | ||
1075 | |||
1076 | psSwapChain->ui32MinSwapInterval = sDisplayInfo.ui32MinSwapInterval; | ||
1077 | psSwapChain->ui32MaxSwapInterval = sDisplayInfo.ui32MaxSwapInterval; | ||
1078 | |||
1079 | |||
1080 | eError = psDCInfo->psFuncTable->pfnCreateDCSwapChain(psDCInfo->hExtDevice, | ||
1081 | ui32Flags, | ||
1082 | psDstSurfAttrib, | ||
1083 | psSrcSurfAttrib, | ||
1084 | ui32BufferCount, | ||
1085 | apsSyncData, | ||
1086 | ui32OEMFlags, | ||
1087 | &psSwapChain->hExtSwapChain, | ||
1088 | &psSwapChain->ui32SwapChainID); | ||
1089 | if(eError != PVRSRV_OK) | ||
1090 | { | ||
1091 | PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Failed to create 3rd party SwapChain")); | ||
1092 | PDUMPCOMMENT("Swapchain allocation failed."); | ||
1093 | goto ErrorExit; | ||
1094 | } | ||
1095 | |||
1096 | |||
1097 | eError = PVRSRVCreateDCSwapChainRefKM(psPerProc, | ||
1098 | psSwapChain, | ||
1099 | &psSwapChainRef); | ||
1100 | if( eError != PVRSRV_OK ) | ||
1101 | { | ||
1102 | PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Couldn't create swap chain reference")); | ||
1103 | PDUMPCOMMENT("Swapchain allocation failed."); | ||
1104 | goto ErrorExit; | ||
1105 | } | ||
1106 | |||
1107 | psSwapChain->ui32RefCount = 1; | ||
1108 | psSwapChain->ui32Flags = ui32Flags; | ||
1109 | |||
1110 | |||
1111 | if( ui32Flags & PVRSRV_CREATE_SWAPCHAIN_SHARED ) | ||
1112 | { | ||
1113 | if(! psDCInfo->psDCSwapChainShared ) | ||
1114 | { | ||
1115 | psDCInfo->psDCSwapChainShared = psSwapChain; | ||
1116 | } | ||
1117 | else | ||
1118 | { | ||
1119 | PVRSRV_DC_SWAPCHAIN *psOldHead = psDCInfo->psDCSwapChainShared; | ||
1120 | psDCInfo->psDCSwapChainShared = psSwapChain; | ||
1121 | psSwapChain->psNext = psOldHead; | ||
1122 | } | ||
1123 | } | ||
1124 | |||
1125 | |||
1126 | *pui32SwapChainID = psSwapChain->ui32SwapChainID; | ||
1127 | |||
1128 | |||
1129 | *phSwapChainRef= (IMG_HANDLE)psSwapChainRef; | ||
1130 | |||
1131 | return eError; | ||
1132 | |||
1133 | ErrorExit: | ||
1134 | |||
1135 | for(i=0; i<ui32BufferCount; i++) | ||
1136 | { | ||
1137 | if(psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo) | ||
1138 | { | ||
1139 | if (--psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->ui32RefCount == 0) | ||
1140 | { | ||
1141 | PVRSRVFreeSyncInfoKM(psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo); | ||
1142 | } | ||
1143 | } | ||
1144 | } | ||
1145 | |||
1146 | if(psQueue) | ||
1147 | { | ||
1148 | PVRSRVDestroyCommandQueueKM(psQueue); | ||
1149 | } | ||
1150 | |||
1151 | if(psSwapChain) | ||
1152 | { | ||
1153 | OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DC_SWAPCHAIN), psSwapChain, IMG_NULL); | ||
1154 | |||
1155 | } | ||
1156 | |||
1157 | return eError; | ||
1158 | } | ||
1159 | |||
1160 | |||
1161 | |||
1162 | |||
1163 | IMG_EXPORT | ||
1164 | PVRSRV_ERROR PVRSRVSetDCDstRectKM(IMG_HANDLE hDeviceKM, | ||
1165 | IMG_HANDLE hSwapChainRef, | ||
1166 | IMG_RECT *psRect) | ||
1167 | { | ||
1168 | PVRSRV_DISPLAYCLASS_INFO *psDCInfo; | ||
1169 | PVRSRV_DC_SWAPCHAIN *psSwapChain; | ||
1170 | |||
1171 | if(!hDeviceKM || !hSwapChainRef) | ||
1172 | { | ||
1173 | PVR_DPF((PVR_DBG_ERROR,"PVRSRVSetDCDstRectKM: Invalid parameters")); | ||
1174 | return PVRSRV_ERROR_INVALID_PARAMS; | ||
1175 | } | ||
1176 | |||
1177 | psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM); | ||
1178 | psSwapChain = ((PVRSRV_DC_SWAPCHAIN_REF*)hSwapChainRef)->psSwapChain; | ||
1179 | |||
1180 | return psDCInfo->psFuncTable->pfnSetDCDstRect(psDCInfo->hExtDevice, | ||
1181 | psSwapChain->hExtSwapChain, | ||
1182 | psRect); | ||
1183 | } | ||
1184 | |||
1185 | |||
1186 | IMG_EXPORT | ||
1187 | PVRSRV_ERROR PVRSRVSetDCSrcRectKM(IMG_HANDLE hDeviceKM, | ||
1188 | IMG_HANDLE hSwapChainRef, | ||
1189 | IMG_RECT *psRect) | ||
1190 | { | ||
1191 | PVRSRV_DISPLAYCLASS_INFO *psDCInfo; | ||
1192 | PVRSRV_DC_SWAPCHAIN *psSwapChain; | ||
1193 | |||
1194 | if(!hDeviceKM || !hSwapChainRef) | ||
1195 | { | ||
1196 | PVR_DPF((PVR_DBG_ERROR,"PVRSRVSetDCSrcRectKM: Invalid parameters")); | ||
1197 | return PVRSRV_ERROR_INVALID_PARAMS; | ||
1198 | } | ||
1199 | |||
1200 | psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM); | ||
1201 | psSwapChain = ((PVRSRV_DC_SWAPCHAIN_REF*)hSwapChainRef)->psSwapChain; | ||
1202 | |||
1203 | return psDCInfo->psFuncTable->pfnSetDCSrcRect(psDCInfo->hExtDevice, | ||
1204 | psSwapChain->hExtSwapChain, | ||
1205 | psRect); | ||
1206 | } | ||
1207 | |||
1208 | |||
1209 | IMG_EXPORT | ||
1210 | PVRSRV_ERROR PVRSRVSetDCDstColourKeyKM(IMG_HANDLE hDeviceKM, | ||
1211 | IMG_HANDLE hSwapChainRef, | ||
1212 | IMG_UINT32 ui32CKColour) | ||
1213 | { | ||
1214 | PVRSRV_DISPLAYCLASS_INFO *psDCInfo; | ||
1215 | PVRSRV_DC_SWAPCHAIN *psSwapChain; | ||
1216 | |||
1217 | if(!hDeviceKM || !hSwapChainRef) | ||
1218 | { | ||
1219 | PVR_DPF((PVR_DBG_ERROR,"PVRSRVSetDCDstColourKeyKM: Invalid parameters")); | ||
1220 | return PVRSRV_ERROR_INVALID_PARAMS; | ||
1221 | } | ||
1222 | |||
1223 | psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM); | ||
1224 | psSwapChain = ((PVRSRV_DC_SWAPCHAIN_REF*)hSwapChainRef)->psSwapChain; | ||
1225 | |||
1226 | return psDCInfo->psFuncTable->pfnSetDCDstColourKey(psDCInfo->hExtDevice, | ||
1227 | psSwapChain->hExtSwapChain, | ||
1228 | ui32CKColour); | ||
1229 | } | ||
1230 | |||
1231 | |||
1232 | IMG_EXPORT | ||
1233 | PVRSRV_ERROR PVRSRVSetDCSrcColourKeyKM(IMG_HANDLE hDeviceKM, | ||
1234 | IMG_HANDLE hSwapChainRef, | ||
1235 | IMG_UINT32 ui32CKColour) | ||
1236 | { | ||
1237 | PVRSRV_DISPLAYCLASS_INFO *psDCInfo; | ||
1238 | PVRSRV_DC_SWAPCHAIN *psSwapChain; | ||
1239 | |||
1240 | if(!hDeviceKM || !hSwapChainRef) | ||
1241 | { | ||
1242 | PVR_DPF((PVR_DBG_ERROR,"PVRSRVSetDCSrcColourKeyKM: Invalid parameters")); | ||
1243 | return PVRSRV_ERROR_INVALID_PARAMS; | ||
1244 | } | ||
1245 | |||
1246 | psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM); | ||
1247 | psSwapChain = ((PVRSRV_DC_SWAPCHAIN_REF*)hSwapChainRef)->psSwapChain; | ||
1248 | |||
1249 | return psDCInfo->psFuncTable->pfnSetDCSrcColourKey(psDCInfo->hExtDevice, | ||
1250 | psSwapChain->hExtSwapChain, | ||
1251 | ui32CKColour); | ||
1252 | } | ||
1253 | |||
1254 | |||
1255 | IMG_EXPORT | ||
1256 | PVRSRV_ERROR PVRSRVGetDCBuffersKM(IMG_HANDLE hDeviceKM, | ||
1257 | IMG_HANDLE hSwapChainRef, | ||
1258 | IMG_UINT32 *pui32BufferCount, | ||
1259 | IMG_HANDLE *phBuffer) | ||
1260 | { | ||
1261 | PVRSRV_DISPLAYCLASS_INFO *psDCInfo; | ||
1262 | PVRSRV_DC_SWAPCHAIN *psSwapChain; | ||
1263 | IMG_HANDLE ahExtBuffer[PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS]; | ||
1264 | PVRSRV_ERROR eError; | ||
1265 | IMG_UINT32 i; | ||
1266 | |||
1267 | if(!hDeviceKM || !hSwapChainRef || !phBuffer) | ||
1268 | { | ||
1269 | PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetDCBuffersKM: Invalid parameters")); | ||
1270 | return PVRSRV_ERROR_INVALID_PARAMS; | ||
1271 | } | ||
1272 | |||
1273 | psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM); | ||
1274 | psSwapChain = ((PVRSRV_DC_SWAPCHAIN_REF*)hSwapChainRef)->psSwapChain; | ||
1275 | |||
1276 | |||
1277 | eError = psDCInfo->psFuncTable->pfnGetDCBuffers(psDCInfo->hExtDevice, | ||
1278 | psSwapChain->hExtSwapChain, | ||
1279 | pui32BufferCount, | ||
1280 | ahExtBuffer); | ||
1281 | |||
1282 | PVR_ASSERT(*pui32BufferCount <= PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS); | ||
1283 | |||
1284 | |||
1285 | |||
1286 | |||
1287 | for(i=0; i<*pui32BufferCount; i++) | ||
1288 | { | ||
1289 | psSwapChain->asBuffer[i].sDeviceClassBuffer.hExtBuffer = ahExtBuffer[i]; | ||
1290 | phBuffer[i] = (IMG_HANDLE)&psSwapChain->asBuffer[i]; | ||
1291 | } | ||
1292 | |||
1293 | return eError; | ||
1294 | } | ||
1295 | |||
1296 | |||
1297 | IMG_EXPORT | ||
1298 | PVRSRV_ERROR PVRSRVSwapToDCBufferKM(IMG_HANDLE hDeviceKM, | ||
1299 | IMG_HANDLE hBuffer, | ||
1300 | IMG_UINT32 ui32SwapInterval, | ||
1301 | IMG_HANDLE hPrivateTag, | ||
1302 | IMG_UINT32 ui32ClipRectCount, | ||
1303 | IMG_RECT *psClipRect) | ||
1304 | { | ||
1305 | PVRSRV_ERROR eError; | ||
1306 | PVRSRV_DISPLAYCLASS_INFO *psDCInfo; | ||
1307 | PVRSRV_DC_BUFFER *psBuffer; | ||
1308 | PVRSRV_QUEUE_INFO *psQueue; | ||
1309 | DISPLAYCLASS_FLIP_COMMAND *psFlipCmd; | ||
1310 | IMG_UINT32 i; | ||
1311 | IMG_BOOL bAddReferenceToLast = IMG_TRUE; | ||
1312 | IMG_UINT16 ui16SwapCommandID = DC_FLIP_COMMAND; | ||
1313 | IMG_UINT32 ui32NumSrcSyncs = 1; | ||
1314 | PVRSRV_KERNEL_SYNC_INFO *apsSrcSync[2]; | ||
1315 | PVRSRV_COMMAND *psCommand; | ||
1316 | |||
1317 | if(!hDeviceKM || !hBuffer || !psClipRect) | ||
1318 | { | ||
1319 | PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBufferKM: Invalid parameters")); | ||
1320 | return PVRSRV_ERROR_INVALID_PARAMS; | ||
1321 | } | ||
1322 | |||
1323 | #if defined(SUPPORT_LMA) | ||
1324 | eError = PVRSRVPowerLock(KERNEL_ID, IMG_FALSE); | ||
1325 | if(eError != PVRSRV_OK) | ||
1326 | { | ||
1327 | return eError; | ||
1328 | } | ||
1329 | #endif | ||
1330 | |||
1331 | psBuffer = (PVRSRV_DC_BUFFER*)hBuffer; | ||
1332 | psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM); | ||
1333 | |||
1334 | |||
1335 | if(ui32SwapInterval < psBuffer->psSwapChain->ui32MinSwapInterval || | ||
1336 | ui32SwapInterval > psBuffer->psSwapChain->ui32MaxSwapInterval) | ||
1337 | { | ||
1338 | PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBufferKM: Invalid swap interval. Requested %u, Allowed range %u-%u", | ||
1339 | ui32SwapInterval, psBuffer->psSwapChain->ui32MinSwapInterval, psBuffer->psSwapChain->ui32MaxSwapInterval)); | ||
1340 | return PVRSRV_ERROR_INVALID_SWAPINTERVAL; | ||
1341 | } | ||
1342 | |||
1343 | #if defined(SUPPORT_CUSTOM_SWAP_OPERATIONS) | ||
1344 | |||
1345 | if(psDCInfo->psFuncTable->pfnQuerySwapCommandID != IMG_NULL) | ||
1346 | { | ||
1347 | psDCInfo->psFuncTable->pfnQuerySwapCommandID(psDCInfo->hExtDevice, | ||
1348 | psBuffer->psSwapChain->hExtSwapChain, | ||
1349 | psBuffer->sDeviceClassBuffer.hExtBuffer, | ||
1350 | hPrivateTag, | ||
1351 | &ui16SwapCommandID, | ||
1352 | &bAddReferenceToLast); | ||
1353 | |||
1354 | } | ||
1355 | |||
1356 | #endif | ||
1357 | |||
1358 | |||
1359 | psQueue = psBuffer->psSwapChain->psQueue; | ||
1360 | |||
1361 | |||
1362 | apsSrcSync[0] = psBuffer->sDeviceClassBuffer.psKernelSyncInfo; | ||
1363 | |||
1364 | |||
1365 | |||
1366 | if(bAddReferenceToLast && psBuffer->psSwapChain->psLastFlipBuffer && | ||
1367 | psBuffer != psBuffer->psSwapChain->psLastFlipBuffer) | ||
1368 | { | ||
1369 | apsSrcSync[1] = psBuffer->psSwapChain->psLastFlipBuffer->sDeviceClassBuffer.psKernelSyncInfo; | ||
1370 | |||
1371 | |||
1372 | |||
1373 | ui32NumSrcSyncs++; | ||
1374 | } | ||
1375 | |||
1376 | |||
1377 | eError = PVRSRVInsertCommandKM (psQueue, | ||
1378 | &psCommand, | ||
1379 | psDCInfo->ui32DeviceID, | ||
1380 | ui16SwapCommandID, | ||
1381 | 0, | ||
1382 | IMG_NULL, | ||
1383 | ui32NumSrcSyncs, | ||
1384 | apsSrcSync, | ||
1385 | sizeof(DISPLAYCLASS_FLIP_COMMAND) + (sizeof(IMG_RECT) * ui32ClipRectCount)); | ||
1386 | if(eError != PVRSRV_OK) | ||
1387 | { | ||
1388 | PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBufferKM: Failed to get space in queue")); | ||
1389 | goto Exit; | ||
1390 | } | ||
1391 | |||
1392 | |||
1393 | psFlipCmd = (DISPLAYCLASS_FLIP_COMMAND*)psCommand->pvData; | ||
1394 | |||
1395 | |||
1396 | psFlipCmd->hExtDevice = psDCInfo->hExtDevice; | ||
1397 | |||
1398 | |||
1399 | psFlipCmd->hExtSwapChain = psBuffer->psSwapChain->hExtSwapChain; | ||
1400 | |||
1401 | |||
1402 | psFlipCmd->hExtBuffer = psBuffer->sDeviceClassBuffer.hExtBuffer; | ||
1403 | |||
1404 | |||
1405 | psFlipCmd->hPrivateTag = hPrivateTag; | ||
1406 | |||
1407 | |||
1408 | psFlipCmd->ui32ClipRectCount = ui32ClipRectCount; | ||
1409 | |||
1410 | psFlipCmd->psClipRect = (IMG_RECT*)((IMG_UINT8*)psFlipCmd + sizeof(DISPLAYCLASS_FLIP_COMMAND)); | ||
1411 | |||
1412 | for(i=0; i<ui32ClipRectCount; i++) | ||
1413 | { | ||
1414 | psFlipCmd->psClipRect[i] = psClipRect[i]; | ||
1415 | } | ||
1416 | |||
1417 | |||
1418 | psFlipCmd->ui32SwapInterval = ui32SwapInterval; | ||
1419 | |||
1420 | |||
1421 | eError = PVRSRVSubmitCommandKM (psQueue, psCommand); | ||
1422 | if (eError != PVRSRV_OK) | ||
1423 | { | ||
1424 | PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBufferKM: Failed to submit command")); | ||
1425 | goto Exit; | ||
1426 | } | ||
1427 | |||
1428 | |||
1429 | |||
1430 | |||
1431 | |||
1432 | |||
1433 | |||
1434 | |||
1435 | |||
1436 | |||
1437 | LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) | ||
1438 | { | ||
1439 | if(PVRSRVProcessQueues(KERNEL_ID, IMG_FALSE) != PVRSRV_ERROR_PROCESSING_BLOCKED) | ||
1440 | { | ||
1441 | goto ProcessedQueues; | ||
1442 | } | ||
1443 | OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT); | ||
1444 | } END_LOOP_UNTIL_TIMEOUT(); | ||
1445 | |||
1446 | PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBufferKM: Failed to process queues")); | ||
1447 | |||
1448 | eError = PVRSRV_ERROR_FAILED_TO_PROCESS_QUEUE; | ||
1449 | goto Exit; | ||
1450 | |||
1451 | ProcessedQueues: | ||
1452 | |||
1453 | psBuffer->psSwapChain->psLastFlipBuffer = psBuffer; | ||
1454 | |||
1455 | Exit: | ||
1456 | |||
1457 | if(eError == PVRSRV_ERROR_CANNOT_GET_QUEUE_SPACE) | ||
1458 | { | ||
1459 | eError = PVRSRV_ERROR_RETRY; | ||
1460 | } | ||
1461 | |||
1462 | #if defined(SUPPORT_LMA) | ||
1463 | PVRSRVPowerUnlock(KERNEL_ID); | ||
1464 | #endif | ||
1465 | return eError; | ||
1466 | } | ||
1467 | |||
1468 | |||
1469 | IMG_EXPORT | ||
1470 | PVRSRV_ERROR PVRSRVSwapToDCSystemKM(IMG_HANDLE hDeviceKM, | ||
1471 | IMG_HANDLE hSwapChainRef) | ||
1472 | { | ||
1473 | PVRSRV_ERROR eError; | ||
1474 | PVRSRV_QUEUE_INFO *psQueue; | ||
1475 | PVRSRV_DISPLAYCLASS_INFO *psDCInfo; | ||
1476 | PVRSRV_DC_SWAPCHAIN *psSwapChain; | ||
1477 | PVRSRV_DC_SWAPCHAIN_REF *psSwapChainRef; | ||
1478 | DISPLAYCLASS_FLIP_COMMAND *psFlipCmd; | ||
1479 | IMG_UINT32 ui32NumSrcSyncs = 1; | ||
1480 | PVRSRV_KERNEL_SYNC_INFO *apsSrcSync[2]; | ||
1481 | PVRSRV_COMMAND *psCommand; | ||
1482 | IMG_BOOL bAddReferenceToLast = IMG_TRUE; | ||
1483 | IMG_UINT16 ui16SwapCommandID = DC_FLIP_COMMAND; | ||
1484 | |||
1485 | if(!hDeviceKM || !hSwapChainRef) | ||
1486 | { | ||
1487 | PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCSystemKM: Invalid parameters")); | ||
1488 | return PVRSRV_ERROR_INVALID_PARAMS; | ||
1489 | } | ||
1490 | |||
1491 | #if defined(SUPPORT_LMA) | ||
1492 | eError = PVRSRVPowerLock(KERNEL_ID, IMG_FALSE); | ||
1493 | if(eError != PVRSRV_OK) | ||
1494 | { | ||
1495 | return eError; | ||
1496 | } | ||
1497 | #endif | ||
1498 | |||
1499 | psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM); | ||
1500 | psSwapChainRef = (PVRSRV_DC_SWAPCHAIN_REF*)hSwapChainRef; | ||
1501 | psSwapChain = psSwapChainRef->psSwapChain; | ||
1502 | |||
1503 | |||
1504 | psQueue = psSwapChain->psQueue; | ||
1505 | |||
1506 | #if defined(SUPPORT_CUSTOM_SWAP_OPERATIONS) | ||
1507 | |||
1508 | if(psDCInfo->psFuncTable->pfnQuerySwapCommandID != IMG_NULL) | ||
1509 | { | ||
1510 | psDCInfo->psFuncTable->pfnQuerySwapCommandID(psDCInfo->hExtDevice, | ||
1511 | psSwapChain->hExtSwapChain, | ||
1512 | psDCInfo->sSystemBuffer.sDeviceClassBuffer.hExtBuffer, | ||
1513 | 0, | ||
1514 | &ui16SwapCommandID, | ||
1515 | &bAddReferenceToLast); | ||
1516 | |||
1517 | } | ||
1518 | |||
1519 | #endif | ||
1520 | |||
1521 | |||
1522 | apsSrcSync[0] = psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo; | ||
1523 | |||
1524 | |||
1525 | |||
1526 | if(bAddReferenceToLast && psSwapChain->psLastFlipBuffer) | ||
1527 | { | ||
1528 | |||
1529 | if (apsSrcSync[0] != psSwapChain->psLastFlipBuffer->sDeviceClassBuffer.psKernelSyncInfo) | ||
1530 | { | ||
1531 | apsSrcSync[1] = psSwapChain->psLastFlipBuffer->sDeviceClassBuffer.psKernelSyncInfo; | ||
1532 | |||
1533 | |||
1534 | |||
1535 | ui32NumSrcSyncs++; | ||
1536 | } | ||
1537 | } | ||
1538 | |||
1539 | |||
1540 | eError = PVRSRVInsertCommandKM (psQueue, | ||
1541 | &psCommand, | ||
1542 | psDCInfo->ui32DeviceID, | ||
1543 | ui16SwapCommandID, | ||
1544 | 0, | ||
1545 | IMG_NULL, | ||
1546 | ui32NumSrcSyncs, | ||
1547 | apsSrcSync, | ||
1548 | sizeof(DISPLAYCLASS_FLIP_COMMAND)); | ||
1549 | if(eError != PVRSRV_OK) | ||
1550 | { | ||
1551 | PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCSystemKM: Failed to get space in queue")); | ||
1552 | goto Exit; | ||
1553 | } | ||
1554 | |||
1555 | |||
1556 | psFlipCmd = (DISPLAYCLASS_FLIP_COMMAND*)psCommand->pvData; | ||
1557 | |||
1558 | |||
1559 | psFlipCmd->hExtDevice = psDCInfo->hExtDevice; | ||
1560 | |||
1561 | |||
1562 | psFlipCmd->hExtSwapChain = psSwapChain->hExtSwapChain; | ||
1563 | |||
1564 | |||
1565 | psFlipCmd->hExtBuffer = psDCInfo->sSystemBuffer.sDeviceClassBuffer.hExtBuffer; | ||
1566 | |||
1567 | |||
1568 | psFlipCmd->hPrivateTag = IMG_NULL; | ||
1569 | |||
1570 | |||
1571 | psFlipCmd->ui32ClipRectCount = 0; | ||
1572 | |||
1573 | psFlipCmd->ui32SwapInterval = 1; | ||
1574 | |||
1575 | |||
1576 | eError = PVRSRVSubmitCommandKM (psQueue, psCommand); | ||
1577 | if (eError != PVRSRV_OK) | ||
1578 | { | ||
1579 | PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCSystemKM: Failed to submit command")); | ||
1580 | goto Exit; | ||
1581 | } | ||
1582 | |||
1583 | |||
1584 | |||
1585 | |||
1586 | |||
1587 | |||
1588 | |||
1589 | |||
1590 | |||
1591 | LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) | ||
1592 | { | ||
1593 | if(PVRSRVProcessQueues(KERNEL_ID, IMG_FALSE) != PVRSRV_ERROR_PROCESSING_BLOCKED) | ||
1594 | { | ||
1595 | goto ProcessedQueues; | ||
1596 | } | ||
1597 | |||
1598 | OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT); | ||
1599 | } END_LOOP_UNTIL_TIMEOUT(); | ||
1600 | |||
1601 | PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCSystemKM: Failed to process queues")); | ||
1602 | eError = PVRSRV_ERROR_FAILED_TO_PROCESS_QUEUE; | ||
1603 | goto Exit; | ||
1604 | |||
1605 | ProcessedQueues: | ||
1606 | |||
1607 | psSwapChain->psLastFlipBuffer = &psDCInfo->sSystemBuffer; | ||
1608 | |||
1609 | eError = PVRSRV_OK; | ||
1610 | |||
1611 | Exit: | ||
1612 | |||
1613 | if(eError == PVRSRV_ERROR_CANNOT_GET_QUEUE_SPACE) | ||
1614 | { | ||
1615 | eError = PVRSRV_ERROR_RETRY; | ||
1616 | } | ||
1617 | |||
1618 | #if defined(SUPPORT_LMA) | ||
1619 | PVRSRVPowerUnlock(KERNEL_ID); | ||
1620 | #endif | ||
1621 | return eError; | ||
1622 | } | ||
1623 | |||
1624 | |||
1625 | static | ||
1626 | PVRSRV_ERROR PVRSRVRegisterSystemISRHandler (PFN_ISR_HANDLER pfnISRHandler, | ||
1627 | IMG_VOID *pvISRHandlerData, | ||
1628 | IMG_UINT32 ui32ISRSourceMask, | ||
1629 | IMG_UINT32 ui32DeviceID) | ||
1630 | { | ||
1631 | SYS_DATA *psSysData; | ||
1632 | PVRSRV_DEVICE_NODE *psDevNode; | ||
1633 | |||
1634 | PVR_UNREFERENCED_PARAMETER(ui32ISRSourceMask); | ||
1635 | |||
1636 | SysAcquireData(&psSysData); | ||
1637 | |||
1638 | |||
1639 | psDevNode = (PVRSRV_DEVICE_NODE*) | ||
1640 | List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList, | ||
1641 | &MatchDeviceKM_AnyVaCb, | ||
1642 | ui32DeviceID, | ||
1643 | IMG_TRUE); | ||
1644 | |||
1645 | if (psDevNode == IMG_NULL) | ||
1646 | { | ||
1647 | PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterSystemISRHandler: Failed to get psDevNode")); | ||
1648 | PVR_DBG_BREAK; | ||
1649 | return PVRSRV_ERROR_NO_DEVICENODE_FOUND; | ||
1650 | } | ||
1651 | |||
1652 | |||
1653 | psDevNode->pvISRData = (IMG_VOID*) pvISRHandlerData; | ||
1654 | |||
1655 | |||
1656 | psDevNode->pfnDeviceISR = pfnISRHandler; | ||
1657 | |||
1658 | return PVRSRV_OK; | ||
1659 | } | ||
1660 | |||
1661 | static | ||
1662 | IMG_VOID PVRSRVSetDCState_ForEachVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va) | ||
1663 | { | ||
1664 | PVRSRV_DISPLAYCLASS_INFO *psDCInfo; | ||
1665 | IMG_UINT32 ui32State; | ||
1666 | ui32State = va_arg(va, IMG_UINT32); | ||
1667 | |||
1668 | if (psDeviceNode->sDevId.eDeviceClass == PVRSRV_DEVICE_CLASS_DISPLAY) | ||
1669 | { | ||
1670 | psDCInfo = (PVRSRV_DISPLAYCLASS_INFO *)psDeviceNode->pvDevice; | ||
1671 | if (psDCInfo->psFuncTable->pfnSetDCState && psDCInfo->hExtDevice) | ||
1672 | { | ||
1673 | psDCInfo->psFuncTable->pfnSetDCState(psDCInfo->hExtDevice, ui32State); | ||
1674 | } | ||
1675 | } | ||
1676 | } | ||
1677 | |||
1678 | |||
1679 | IMG_VOID IMG_CALLCONV PVRSRVSetDCState(IMG_UINT32 ui32State) | ||
1680 | { | ||
1681 | SYS_DATA *psSysData; | ||
1682 | |||
1683 | SysAcquireData(&psSysData); | ||
1684 | |||
1685 | List_PVRSRV_DEVICE_NODE_ForEach_va(psSysData->psDeviceNodeList, | ||
1686 | &PVRSRVSetDCState_ForEachVaCb, | ||
1687 | ui32State); | ||
1688 | } | ||
1689 | |||
1690 | |||
1691 | IMG_EXPORT | ||
1692 | IMG_BOOL PVRGetDisplayClassJTable(PVRSRV_DC_DISP2SRV_KMJTABLE *psJTable) | ||
1693 | { | ||
1694 | psJTable->ui32TableSize = sizeof(PVRSRV_DC_DISP2SRV_KMJTABLE); | ||
1695 | psJTable->pfnPVRSRVRegisterDCDevice = &PVRSRVRegisterDCDeviceKM; | ||
1696 | psJTable->pfnPVRSRVRemoveDCDevice = &PVRSRVRemoveDCDeviceKM; | ||
1697 | psJTable->pfnPVRSRVOEMFunction = &SysOEMFunction; | ||
1698 | psJTable->pfnPVRSRVRegisterCmdProcList = &PVRSRVRegisterCmdProcListKM; | ||
1699 | psJTable->pfnPVRSRVRemoveCmdProcList = &PVRSRVRemoveCmdProcListKM; | ||
1700 | #if defined(SUPPORT_MISR_IN_THREAD) | ||
1701 | psJTable->pfnPVRSRVCmdComplete = &OSVSyncMISR; | ||
1702 | #else | ||
1703 | psJTable->pfnPVRSRVCmdComplete = &PVRSRVCommandCompleteKM; | ||
1704 | #endif | ||
1705 | psJTable->pfnPVRSRVRegisterSystemISRHandler = &PVRSRVRegisterSystemISRHandler; | ||
1706 | psJTable->pfnPVRSRVRegisterPowerDevice = &PVRSRVRegisterPowerDevice; | ||
1707 | #if defined(SUPPORT_CUSTOM_SWAP_OPERATIONS) | ||
1708 | psJTable->pfnPVRSRVFreeCmdCompletePacket = &PVRSRVFreeCommandCompletePacketKM; | ||
1709 | #endif | ||
1710 | |||
1711 | return IMG_TRUE; | ||
1712 | } | ||
1713 | |||
1714 | |||
1715 | |||
1716 | IMG_EXPORT | ||
1717 | PVRSRV_ERROR PVRSRVCloseBCDeviceKM (IMG_HANDLE hDeviceKM, | ||
1718 | IMG_BOOL bResManCallback) | ||
1719 | { | ||
1720 | PVRSRV_ERROR eError; | ||
1721 | PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *psBCPerContextInfo; | ||
1722 | |||
1723 | PVR_UNREFERENCED_PARAMETER(bResManCallback); | ||
1724 | |||
1725 | psBCPerContextInfo = (PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *)hDeviceKM; | ||
1726 | |||
1727 | |||
1728 | eError = ResManFreeResByPtr(psBCPerContextInfo->hResItem); | ||
1729 | |||
1730 | return eError; | ||
1731 | } | ||
1732 | |||
1733 | |||
1734 | static PVRSRV_ERROR CloseBCDeviceCallBack(IMG_PVOID pvParam, | ||
1735 | IMG_UINT32 ui32Param) | ||
1736 | { | ||
1737 | PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *psBCPerContextInfo; | ||
1738 | PVRSRV_BUFFERCLASS_INFO *psBCInfo; | ||
1739 | |||
1740 | PVR_UNREFERENCED_PARAMETER(ui32Param); | ||
1741 | |||
1742 | psBCPerContextInfo = (PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *)pvParam; | ||
1743 | psBCInfo = psBCPerContextInfo->psBCInfo; | ||
1744 | |||
1745 | psBCInfo->ui32RefCount--; | ||
1746 | if(psBCInfo->ui32RefCount == 0) | ||
1747 | { | ||
1748 | IMG_UINT32 i; | ||
1749 | |||
1750 | |||
1751 | psBCInfo->psFuncTable->pfnCloseBCDevice(psBCInfo->ui32DeviceID, psBCInfo->hExtDevice); | ||
1752 | |||
1753 | |||
1754 | for(i=0; i<psBCInfo->ui32BufferCount; i++) | ||
1755 | { | ||
1756 | if(psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo) | ||
1757 | { | ||
1758 | if (--psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->ui32RefCount == 0) | ||
1759 | { | ||
1760 | PVRSRVFreeSyncInfoKM(psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo); | ||
1761 | } | ||
1762 | } | ||
1763 | } | ||
1764 | |||
1765 | |||
1766 | if(psBCInfo->psBuffer) | ||
1767 | { | ||
1768 | OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_BC_BUFFER), psBCInfo->psBuffer, IMG_NULL); | ||
1769 | psBCInfo->psBuffer = IMG_NULL; | ||
1770 | } | ||
1771 | } | ||
1772 | |||
1773 | OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_BUFFERCLASS_PERCONTEXT_INFO), psBCPerContextInfo, IMG_NULL); | ||
1774 | |||
1775 | |||
1776 | return PVRSRV_OK; | ||
1777 | } | ||
1778 | |||
1779 | |||
1780 | IMG_EXPORT | ||
1781 | PVRSRV_ERROR PVRSRVOpenBCDeviceKM (PVRSRV_PER_PROCESS_DATA *psPerProc, | ||
1782 | IMG_UINT32 ui32DeviceID, | ||
1783 | IMG_HANDLE hDevCookie, | ||
1784 | IMG_HANDLE *phDeviceKM) | ||
1785 | { | ||
1786 | PVRSRV_BUFFERCLASS_INFO *psBCInfo; | ||
1787 | PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *psBCPerContextInfo; | ||
1788 | PVRSRV_DEVICE_NODE *psDeviceNode; | ||
1789 | SYS_DATA *psSysData; | ||
1790 | IMG_UINT32 i; | ||
1791 | PVRSRV_ERROR eError; | ||
1792 | |||
1793 | if(!phDeviceKM || !hDevCookie) | ||
1794 | { | ||
1795 | PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Invalid params")); | ||
1796 | return PVRSRV_ERROR_INVALID_PARAMS; | ||
1797 | } | ||
1798 | |||
1799 | SysAcquireData(&psSysData); | ||
1800 | |||
1801 | |||
1802 | psDeviceNode = (PVRSRV_DEVICE_NODE*) | ||
1803 | List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList, | ||
1804 | &MatchDeviceKM_AnyVaCb, | ||
1805 | ui32DeviceID, | ||
1806 | IMG_FALSE, | ||
1807 | PVRSRV_DEVICE_CLASS_BUFFER); | ||
1808 | if (!psDeviceNode) | ||
1809 | { | ||
1810 | PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: No devnode matching index %d", ui32DeviceID)); | ||
1811 | return PVRSRV_ERROR_NO_DEVICENODE_FOUND; | ||
1812 | } | ||
1813 | psBCInfo = (PVRSRV_BUFFERCLASS_INFO*)psDeviceNode->pvDevice; | ||
1814 | |||
1815 | |||
1816 | |||
1817 | |||
1818 | if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, | ||
1819 | sizeof(*psBCPerContextInfo), | ||
1820 | (IMG_VOID **)&psBCPerContextInfo, IMG_NULL, | ||
1821 | "Buffer Class per Context Info") != PVRSRV_OK) | ||
1822 | { | ||
1823 | PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Failed psBCPerContextInfo alloc")); | ||
1824 | return PVRSRV_ERROR_OUT_OF_MEMORY; | ||
1825 | } | ||
1826 | OSMemSet(psBCPerContextInfo, 0, sizeof(*psBCPerContextInfo)); | ||
1827 | |||
1828 | if(psBCInfo->ui32RefCount++ == 0) | ||
1829 | { | ||
1830 | BUFFER_INFO sBufferInfo; | ||
1831 | |||
1832 | psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevCookie; | ||
1833 | |||
1834 | |||
1835 | psBCInfo->hDevMemContext = (IMG_HANDLE)psDeviceNode->sDevMemoryInfo.pBMKernelContext; | ||
1836 | |||
1837 | |||
1838 | eError = psBCInfo->psFuncTable->pfnOpenBCDevice(ui32DeviceID, &psBCInfo->hExtDevice); | ||
1839 | if(eError != PVRSRV_OK) | ||
1840 | { | ||
1841 | PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Failed to open external BC device")); | ||
1842 | return eError; | ||
1843 | } | ||
1844 | |||
1845 | |||
1846 | eError = psBCInfo->psFuncTable->pfnGetBCInfo(psBCInfo->hExtDevice, &sBufferInfo); | ||
1847 | if(eError != PVRSRV_OK) | ||
1848 | { | ||
1849 | PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM : Failed to get BC Info")); | ||
1850 | return eError; | ||
1851 | } | ||
1852 | |||
1853 | |||
1854 | psBCInfo->ui32BufferCount = sBufferInfo.ui32BufferCount; | ||
1855 | |||
1856 | |||
1857 | |||
1858 | eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, | ||
1859 | sizeof(PVRSRV_BC_BUFFER) * sBufferInfo.ui32BufferCount, | ||
1860 | (IMG_VOID **)&psBCInfo->psBuffer, | ||
1861 | IMG_NULL, | ||
1862 | "Array of Buffer Class Buffer"); | ||
1863 | if(eError != PVRSRV_OK) | ||
1864 | { | ||
1865 | PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Failed to allocate BC buffers")); | ||
1866 | return eError; | ||
1867 | } | ||
1868 | OSMemSet (psBCInfo->psBuffer, | ||
1869 | 0, | ||
1870 | sizeof(PVRSRV_BC_BUFFER) * sBufferInfo.ui32BufferCount); | ||
1871 | |||
1872 | for(i=0; i<psBCInfo->ui32BufferCount; i++) | ||
1873 | { | ||
1874 | |||
1875 | eError = PVRSRVAllocSyncInfoKM(IMG_NULL, | ||
1876 | psBCInfo->hDevMemContext, | ||
1877 | &psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo); | ||
1878 | if(eError != PVRSRV_OK) | ||
1879 | { | ||
1880 | PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Failed sync info alloc")); | ||
1881 | goto ErrorExit; | ||
1882 | } | ||
1883 | |||
1884 | psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->ui32RefCount++; | ||
1885 | |||
1886 | |||
1887 | |||
1888 | |||
1889 | eError = psBCInfo->psFuncTable->pfnGetBCBuffer(psBCInfo->hExtDevice, | ||
1890 | i, | ||
1891 | psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->psSyncData, | ||
1892 | &psBCInfo->psBuffer[i].sDeviceClassBuffer.hExtBuffer); | ||
1893 | if(eError != PVRSRV_OK) | ||
1894 | { | ||
1895 | PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Failed to get BC buffers")); | ||
1896 | goto ErrorExit; | ||
1897 | } | ||
1898 | |||
1899 | |||
1900 | psBCInfo->psBuffer[i].sDeviceClassBuffer.pfnGetBufferAddr = psBCInfo->psFuncTable->pfnGetBufferAddr; | ||
1901 | psBCInfo->psBuffer[i].sDeviceClassBuffer.hDevMemContext = psBCInfo->hDevMemContext; | ||
1902 | psBCInfo->psBuffer[i].sDeviceClassBuffer.hExtDevice = psBCInfo->hExtDevice; | ||
1903 | } | ||
1904 | } | ||
1905 | |||
1906 | psBCPerContextInfo->psBCInfo = psBCInfo; | ||
1907 | psBCPerContextInfo->hResItem = ResManRegisterRes(psPerProc->hResManContext, | ||
1908 | RESMAN_TYPE_BUFFERCLASS_DEVICE, | ||
1909 | psBCPerContextInfo, | ||
1910 | 0, | ||
1911 | &CloseBCDeviceCallBack); | ||
1912 | |||
1913 | |||
1914 | *phDeviceKM = (IMG_HANDLE)psBCPerContextInfo; | ||
1915 | |||
1916 | return PVRSRV_OK; | ||
1917 | |||
1918 | ErrorExit: | ||
1919 | |||
1920 | |||
1921 | for(i=0; i<psBCInfo->ui32BufferCount; i++) | ||
1922 | { | ||
1923 | if(psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo) | ||
1924 | { | ||
1925 | if (--psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->ui32RefCount == 0) | ||
1926 | { | ||
1927 | PVRSRVFreeSyncInfoKM(psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo); | ||
1928 | } | ||
1929 | } | ||
1930 | } | ||
1931 | |||
1932 | |||
1933 | if(psBCInfo->psBuffer) | ||
1934 | { | ||
1935 | OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_BC_BUFFER), psBCInfo->psBuffer, IMG_NULL); | ||
1936 | psBCInfo->psBuffer = IMG_NULL; | ||
1937 | } | ||
1938 | |||
1939 | return eError; | ||
1940 | } | ||
1941 | |||
1942 | |||
1943 | |||
1944 | |||
1945 | IMG_EXPORT | ||
1946 | PVRSRV_ERROR PVRSRVGetBCInfoKM (IMG_HANDLE hDeviceKM, | ||
1947 | BUFFER_INFO *psBufferInfo) | ||
1948 | { | ||
1949 | PVRSRV_BUFFERCLASS_INFO *psBCInfo; | ||
1950 | PVRSRV_ERROR eError; | ||
1951 | |||
1952 | if(!hDeviceKM || !psBufferInfo) | ||
1953 | { | ||
1954 | PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetBCInfoKM: Invalid parameters")); | ||
1955 | return PVRSRV_ERROR_INVALID_PARAMS; | ||
1956 | } | ||
1957 | |||
1958 | psBCInfo = BCDeviceHandleToBCInfo(hDeviceKM); | ||
1959 | |||
1960 | eError = psBCInfo->psFuncTable->pfnGetBCInfo(psBCInfo->hExtDevice, psBufferInfo); | ||
1961 | |||
1962 | if(eError != PVRSRV_OK) | ||
1963 | { | ||
1964 | PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetBCInfoKM : Failed to get BC Info")); | ||
1965 | return eError; | ||
1966 | } | ||
1967 | |||
1968 | return PVRSRV_OK; | ||
1969 | } | ||
1970 | |||
1971 | |||
1972 | IMG_EXPORT | ||
1973 | PVRSRV_ERROR PVRSRVGetBCBufferKM (IMG_HANDLE hDeviceKM, | ||
1974 | IMG_UINT32 ui32BufferIndex, | ||
1975 | IMG_HANDLE *phBuffer) | ||
1976 | { | ||
1977 | PVRSRV_BUFFERCLASS_INFO *psBCInfo; | ||
1978 | |||
1979 | if(!hDeviceKM || !phBuffer) | ||
1980 | { | ||
1981 | PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetBCBufferKM: Invalid parameters")); | ||
1982 | return PVRSRV_ERROR_INVALID_PARAMS; | ||
1983 | } | ||
1984 | |||
1985 | psBCInfo = BCDeviceHandleToBCInfo(hDeviceKM); | ||
1986 | |||
1987 | if(ui32BufferIndex < psBCInfo->ui32BufferCount) | ||
1988 | { | ||
1989 | *phBuffer = (IMG_HANDLE)&psBCInfo->psBuffer[ui32BufferIndex]; | ||
1990 | } | ||
1991 | else | ||
1992 | { | ||
1993 | PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetBCBufferKM: Buffer index %d out of range (%d)", ui32BufferIndex,psBCInfo->ui32BufferCount)); | ||
1994 | return PVRSRV_ERROR_INVALID_PARAMS; | ||
1995 | } | ||
1996 | |||
1997 | return PVRSRV_OK; | ||
1998 | } | ||
1999 | |||
2000 | |||
2001 | IMG_EXPORT | ||
2002 | IMG_BOOL PVRGetBufferClassJTable(PVRSRV_BC_BUFFER2SRV_KMJTABLE *psJTable) | ||
2003 | { | ||
2004 | psJTable->ui32TableSize = sizeof(PVRSRV_BC_BUFFER2SRV_KMJTABLE); | ||
2005 | |||
2006 | psJTable->pfnPVRSRVRegisterBCDevice = &PVRSRVRegisterBCDeviceKM; | ||
2007 | psJTable->pfnPVRSRVScheduleDevices = &PVRSRVScheduleDevicesKM; | ||
2008 | psJTable->pfnPVRSRVRemoveBCDevice = &PVRSRVRemoveBCDeviceKM; | ||
2009 | |||
2010 | return IMG_TRUE; | ||
2011 | } | ||
2012 | |||