aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/pvr/deviceclass.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/pvr/deviceclass.c')
-rw-r--r--drivers/gpu/pvr/deviceclass.c2012
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
37PVRSRV_ERROR AllocateDeviceID(SYS_DATA *psSysData, IMG_UINT32 *pui32DevID);
38PVRSRV_ERROR FreeDeviceID(SYS_DATA *psSysData, IMG_UINT32 ui32DevID);
39
40#if defined(SUPPORT_MISR_IN_THREAD)
41void OSVSyncMISR(IMG_HANDLE, IMG_BOOL);
42#endif
43
44#if defined(SUPPORT_CUSTOM_SWAP_OPERATIONS)
45IMG_VOID PVRSRVFreeCommandCompletePacketKM(IMG_HANDLE hCmdCookie,
46 IMG_BOOL bScheduleMISR);
47#endif
48typedef struct PVRSRV_DC_SRV2DISP_KMJTABLE_TAG *PPVRSRV_DC_SRV2DISP_KMJTABLE;
49
50typedef 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
59typedef 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
76typedef 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
83typedef 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
95typedef struct PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO_TAG
96{
97 PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
98 PRESMAN_ITEM hResItem;
99} PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO;
100
101
102typedef struct PVRSRV_BC_SRV2BUFFER_KMJTABLE_TAG *PPVRSRV_BC_SRV2BUFFER_KMJTABLE;
103
104typedef 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
113typedef 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
127typedef struct PVRSRV_BUFFERCLASS_PERCONTEXT_INFO_TAG
128{
129 PVRSRV_BUFFERCLASS_INFO *psBCInfo;
130 IMG_HANDLE hResItem;
131} PVRSRV_BUFFERCLASS_PERCONTEXT_INFO;
132
133
134static 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
144static 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
153static 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
175IMG_EXPORT
176PVRSRV_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
207static
208PVRSRV_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
298ErrorExit:
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
312static 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
371static
372PVRSRV_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
457ErrorExit:
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
472static 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
531IMG_EXPORT
532PVRSRV_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
549static 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
582IMG_EXPORT
583PVRSRV_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
677IMG_EXPORT
678PVRSRV_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
698IMG_EXPORT
699PVRSRV_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
719IMG_EXPORT
720PVRSRV_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
758IMG_EXPORT
759PVRSRV_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
789IMG_EXPORT
790PVRSRV_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
809static 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
872static 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
888static 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
903static 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
936IMG_EXPORT
937PVRSRV_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
1133ErrorExit:
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
1163IMG_EXPORT
1164PVRSRV_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
1186IMG_EXPORT
1187PVRSRV_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
1209IMG_EXPORT
1210PVRSRV_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
1232IMG_EXPORT
1233PVRSRV_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
1255IMG_EXPORT
1256PVRSRV_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
1297IMG_EXPORT
1298PVRSRV_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
1451ProcessedQueues:
1452
1453 psBuffer->psSwapChain->psLastFlipBuffer = psBuffer;
1454
1455Exit:
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
1469IMG_EXPORT
1470PVRSRV_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
1605ProcessedQueues:
1606
1607 psSwapChain->psLastFlipBuffer = &psDCInfo->sSystemBuffer;
1608
1609 eError = PVRSRV_OK;
1610
1611Exit:
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
1625static
1626PVRSRV_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
1661static
1662IMG_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
1679IMG_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
1691IMG_EXPORT
1692IMG_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
1716IMG_EXPORT
1717PVRSRV_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
1734static 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
1780IMG_EXPORT
1781PVRSRV_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
1918ErrorExit:
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
1945IMG_EXPORT
1946PVRSRV_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
1972IMG_EXPORT
1973PVRSRV_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
2001IMG_EXPORT
2002IMG_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