1 /**********************************************************************
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
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.
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.
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.
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
25 ******************************************************************************/
27 #include "services_headers.h"
28 #include "buffer_manager.h"
29 #include "kernelbuffer.h"
30 #include "pvr_bridge_km.h"
32 PVRSRV_ERROR AllocateDeviceID(SYS_DATA * psSysData, IMG_UINT32 * pui32DevID);
33 PVRSRV_ERROR FreeDeviceID(SYS_DATA * psSysData, IMG_UINT32 ui32DevID);
35 typedef struct PVRSRV_DC_SRV2DISP_KMJTABLE_TAG *PPVRSRV_DC_SRV2DISP_KMJTABLE;
37 typedef struct PVRSRV_DC_BUFFER_TAG {
39 PVRSRV_DEVICECLASS_BUFFER sDeviceClassBuffer;
41 struct PVRSRV_DISPLAYCLASS_INFO_TAG *psDCInfo;
42 struct PVRSRV_DC_SWAPCHAIN_TAG *psSwapChain;
45 typedef struct PVRSRV_DC_SWAPCHAIN_TAG {
46 IMG_HANDLE hExtSwapChain;
47 PVRSRV_QUEUE_INFO *psQueue;
48 PVRSRV_DC_BUFFER asBuffer[PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS];
49 IMG_UINT32 ui32BufferCount;
50 PVRSRV_DC_BUFFER *psLastFlipBuffer;
51 struct PVRSRV_DISPLAYCLASS_INFO_TAG *psDCInfo;
53 } PVRSRV_DC_SWAPCHAIN;
55 typedef struct PVRSRV_DISPLAYCLASS_INFO_TAG {
56 IMG_UINT32 ui32RefCount;
57 IMG_UINT32 ui32DeviceID;
58 IMG_HANDLE hExtDevice;
59 PPVRSRV_DC_SRV2DISP_KMJTABLE psFuncTable;
60 IMG_HANDLE hDevMemContext;
61 PVRSRV_DC_BUFFER sSystemBuffer;
62 } PVRSRV_DISPLAYCLASS_INFO;
64 typedef struct PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO_TAG {
65 PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
66 PRESMAN_ITEM hResItem;
67 } PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO;
69 typedef struct PVRSRV_BC_SRV2BUFFER_KMJTABLE_TAG
70 *PPVRSRV_BC_SRV2BUFFER_KMJTABLE;
72 typedef struct PVRSRV_BC_BUFFER_TAG {
74 PVRSRV_DEVICECLASS_BUFFER sDeviceClassBuffer;
76 struct PVRSRV_BUFFERCLASS_INFO_TAG *psBCInfo;
79 typedef struct PVRSRV_BUFFERCLASS_INFO_TAG {
80 IMG_UINT32 ui32RefCount;
81 IMG_UINT32 ui32DeviceID;
82 IMG_HANDLE hExtDevice;
83 PPVRSRV_BC_SRV2BUFFER_KMJTABLE psFuncTable;
84 IMG_HANDLE hDevMemContext;
86 IMG_UINT32 ui32BufferCount;
87 PVRSRV_BC_BUFFER *psBuffer;
89 } PVRSRV_BUFFERCLASS_INFO;
91 typedef struct PVRSRV_BUFFERCLASS_PERCONTEXT_INFO_TAG {
92 PVRSRV_BUFFERCLASS_INFO *psBCInfo;
94 } PVRSRV_BUFFERCLASS_PERCONTEXT_INFO;
96 static PVRSRV_DISPLAYCLASS_INFO *DCDeviceHandleToDCInfo(IMG_HANDLE hDeviceKM)
98 PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *psDCPerContextInfo;
100 psDCPerContextInfo = (PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *) hDeviceKM;
102 return psDCPerContextInfo->psDCInfo;
105 static PVRSRV_BUFFERCLASS_INFO *BCDeviceHandleToBCInfo(IMG_HANDLE hDeviceKM)
107 PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *psBCPerContextInfo;
109 psBCPerContextInfo = (PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *) hDeviceKM;
111 return psBCPerContextInfo->psBCInfo;
115 PVRSRV_ERROR PVRSRVEnumerateDCKM(PVRSRV_DEVICE_CLASS DeviceClass,
116 IMG_UINT32 * pui32DevCount,
117 IMG_UINT32 * pui32DevID)
119 PVRSRV_DEVICE_NODE *psDeviceNode;
120 IMG_UINT ui32DevCount = 0;
123 if (SysAcquireData(&psSysData) != PVRSRV_OK) {
124 PVR_DPF((PVR_DBG_ERROR,
125 "PVRSRVEnumerateDCKM: Failed to get SysData"));
126 return PVRSRV_ERROR_GENERIC;
129 psDeviceNode = psSysData->psDeviceNodeList;
130 while (psDeviceNode) {
131 if ((psDeviceNode->sDevId.eDeviceClass == DeviceClass)
132 && (psDeviceNode->sDevId.eDeviceType ==
133 PVRSRV_DEVICE_TYPE_EXT)) {
137 psDeviceNode->sDevId.ui32DeviceIndex;
140 psDeviceNode = psDeviceNode->psNext;
144 *pui32DevCount = ui32DevCount;
145 } else if (pui32DevID == IMG_NULL) {
146 PVR_DPF((PVR_DBG_ERROR,
147 "PVRSRVEnumerateDCKM: Invalid parameters"));
148 return (PVRSRV_ERROR_INVALID_PARAMS);
154 PVRSRV_ERROR PVRSRVRegisterDCDeviceKM(PVRSRV_DC_SRV2DISP_KMJTABLE * psFuncTable,
155 IMG_UINT32 * pui32DeviceID)
157 PVRSRV_DISPLAYCLASS_INFO *psDCInfo = IMG_NULL;
158 PVRSRV_DEVICE_NODE *psDeviceNode;
161 if (SysAcquireData(&psSysData) != PVRSRV_OK) {
162 PVR_DPF((PVR_DBG_ERROR,
163 "PVRSRVRegisterDCDeviceKM: Failed to get SysData"));
164 return PVRSRV_ERROR_GENERIC;
167 if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
169 (IMG_VOID **) & psDCInfo, IMG_NULL) != PVRSRV_OK) {
170 PVR_DPF((PVR_DBG_ERROR,
171 "PVRSRVRegisterDCDeviceKM: Failed psDCInfo alloc"));
172 return PVRSRV_ERROR_OUT_OF_MEMORY;
174 OSMemSet(psDCInfo, 0, sizeof(*psDCInfo));
176 if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
177 sizeof(PVRSRV_DC_SRV2DISP_KMJTABLE),
178 (IMG_VOID **) & psDCInfo->psFuncTable,
179 IMG_NULL) != PVRSRV_OK) {
180 PVR_DPF((PVR_DBG_ERROR,
181 "PVRSRVRegisterDCDeviceKM: Failed psFuncTable alloc"));
184 OSMemSet(psDCInfo->psFuncTable, 0, sizeof(PVRSRV_DC_SRV2DISP_KMJTABLE));
186 *psDCInfo->psFuncTable = *psFuncTable;
188 if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
189 sizeof(PVRSRV_DEVICE_NODE),
190 (IMG_VOID **) & psDeviceNode, IMG_NULL) != PVRSRV_OK) {
191 PVR_DPF((PVR_DBG_ERROR,
192 "PVRSRVRegisterDCDeviceKM: Failed psDeviceNode alloc"));
195 OSMemSet(psDeviceNode, 0, sizeof(PVRSRV_DEVICE_NODE));
197 psDeviceNode->pvDevice = (IMG_VOID *) psDCInfo;
198 psDeviceNode->ui32pvDeviceSize = sizeof(*psDCInfo);
199 psDeviceNode->ui32RefCount = 1;
200 psDeviceNode->sDevId.eDeviceType = PVRSRV_DEVICE_TYPE_EXT;
201 psDeviceNode->sDevId.eDeviceClass = PVRSRV_DEVICE_CLASS_DISPLAY;
202 psDeviceNode->psSysData = psSysData;
204 AllocateDeviceID(psSysData, &psDeviceNode->sDevId.ui32DeviceIndex);
205 psDCInfo->ui32DeviceID = psDeviceNode->sDevId.ui32DeviceIndex;
207 *pui32DeviceID = psDeviceNode->sDevId.ui32DeviceIndex;
210 SysRegisterExternalDevice(psDeviceNode);
212 psDeviceNode->psNext = psSysData->psDeviceNodeList;
213 psSysData->psDeviceNodeList = psDeviceNode;
219 if (psDCInfo->psFuncTable) {
220 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
221 sizeof(PVRSRV_DC_SRV2DISP_KMJTABLE),
222 psDCInfo->psFuncTable, IMG_NULL);
225 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DISPLAYCLASS_INFO),
228 return PVRSRV_ERROR_OUT_OF_MEMORY;
231 PVRSRV_ERROR PVRSRVRemoveDCDeviceKM(IMG_UINT32 ui32DevIndex)
234 PVRSRV_DEVICE_NODE **ppsDeviceNode, *psDeviceNode;
235 PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
237 if (SysAcquireData(&psSysData) != PVRSRV_OK) {
238 PVR_DPF((PVR_DBG_ERROR,
239 "PVRSRVRemoveDCDeviceKM: Failed to get SysData"));
240 return PVRSRV_ERROR_GENERIC;
243 ppsDeviceNode = &psSysData->psDeviceNodeList;
244 while (*ppsDeviceNode) {
245 switch ((*ppsDeviceNode)->sDevId.eDeviceClass) {
246 case PVRSRV_DEVICE_CLASS_DISPLAY:
248 if ((*ppsDeviceNode)->sDevId.ui32DeviceIndex ==
259 ppsDeviceNode = &((*ppsDeviceNode)->psNext);
262 PVR_DPF((PVR_DBG_ERROR,
263 "PVRSRVRemoveDCDeviceKM: requested device %d not present",
266 return PVRSRV_ERROR_GENERIC;
270 psDeviceNode = *ppsDeviceNode;
271 *ppsDeviceNode = psDeviceNode->psNext;
273 SysRemoveExternalDevice(psDeviceNode);
275 psDCInfo = (PVRSRV_DISPLAYCLASS_INFO *) psDeviceNode->pvDevice;
276 PVR_ASSERT(psDCInfo->ui32RefCount == 0);
277 FreeDeviceID(psSysData, ui32DevIndex);
278 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DC_SRV2DISP_KMJTABLE),
279 psDCInfo->psFuncTable, IMG_NULL);
280 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DISPLAYCLASS_INFO),
282 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DEVICE_NODE),
283 psDeviceNode, IMG_NULL);
287 PVRSRV_ERROR PVRSRVRegisterBCDeviceKM(PVRSRV_BC_SRV2BUFFER_KMJTABLE *
288 psFuncTable, IMG_UINT32 * pui32DeviceID)
290 PVRSRV_BUFFERCLASS_INFO *psBCInfo = IMG_NULL;
291 PVRSRV_DEVICE_NODE *psDeviceNode;
294 if (SysAcquireData(&psSysData) != PVRSRV_OK) {
295 PVR_DPF((PVR_DBG_ERROR,
296 "PVRSRVRegisterBCDeviceKM: Failed to get SysData"));
297 return PVRSRV_ERROR_GENERIC;
300 if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
302 (IMG_VOID **) & psBCInfo, IMG_NULL) != PVRSRV_OK) {
303 PVR_DPF((PVR_DBG_ERROR,
304 "PVRSRVRegisterBCDeviceKM: Failed psBCInfo alloc"));
305 return PVRSRV_ERROR_OUT_OF_MEMORY;
307 OSMemSet(psBCInfo, 0, sizeof(*psBCInfo));
309 if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
310 sizeof(PVRSRV_BC_SRV2BUFFER_KMJTABLE),
311 (IMG_VOID **) & psBCInfo->psFuncTable,
312 IMG_NULL) != PVRSRV_OK) {
313 PVR_DPF((PVR_DBG_ERROR,
314 "PVRSRVRegisterBCDeviceKM: Failed psFuncTable alloc"));
317 OSMemSet(psBCInfo->psFuncTable, 0,
318 sizeof(PVRSRV_BC_SRV2BUFFER_KMJTABLE));
320 *psBCInfo->psFuncTable = *psFuncTable;
322 if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
323 sizeof(PVRSRV_DEVICE_NODE),
324 (IMG_VOID **) & psDeviceNode, IMG_NULL) != PVRSRV_OK) {
325 PVR_DPF((PVR_DBG_ERROR,
326 "PVRSRVRegisterBCDeviceKM: Failed psDeviceNode alloc"));
329 OSMemSet(psDeviceNode, 0, sizeof(PVRSRV_DEVICE_NODE));
331 psDeviceNode->pvDevice = (IMG_VOID *) psBCInfo;
332 psDeviceNode->ui32pvDeviceSize = sizeof(*psBCInfo);
333 psDeviceNode->ui32RefCount = 1;
334 psDeviceNode->sDevId.eDeviceType = PVRSRV_DEVICE_TYPE_EXT;
335 psDeviceNode->sDevId.eDeviceClass = PVRSRV_DEVICE_CLASS_BUFFER;
336 psDeviceNode->psSysData = psSysData;
338 AllocateDeviceID(psSysData, &psDeviceNode->sDevId.ui32DeviceIndex);
339 psBCInfo->ui32DeviceID = psDeviceNode->sDevId.ui32DeviceIndex;
341 *pui32DeviceID = psDeviceNode->sDevId.ui32DeviceIndex;
344 psDeviceNode->psNext = psSysData->psDeviceNodeList;
345 psSysData->psDeviceNodeList = psDeviceNode;
351 if (psBCInfo->psFuncTable) {
352 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
353 sizeof(PVRSRV_BC_SRV2BUFFER_KMJTABLE),
354 psBCInfo->psFuncTable, IMG_NULL);
357 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_BUFFERCLASS_INFO),
360 return PVRSRV_ERROR_OUT_OF_MEMORY;
363 PVRSRV_ERROR PVRSRVRemoveBCDeviceKM(IMG_UINT32 ui32DevIndex)
366 PVRSRV_DEVICE_NODE **ppsDevNode, *psDevNode;
367 PVRSRV_BUFFERCLASS_INFO *psBCInfo;
369 if (SysAcquireData(&psSysData) != PVRSRV_OK) {
370 PVR_DPF((PVR_DBG_ERROR,
371 "PVRSRVRemoveBCDeviceKM: Failed to get SysData"));
372 return PVRSRV_ERROR_GENERIC;
375 ppsDevNode = &psSysData->psDeviceNodeList;
376 while (*ppsDevNode) {
377 switch ((*ppsDevNode)->sDevId.eDeviceClass) {
378 case PVRSRV_DEVICE_CLASS_BUFFER:
380 if ((*ppsDevNode)->sDevId.ui32DeviceIndex ==
391 ppsDevNode = &(*ppsDevNode)->psNext;
394 PVR_DPF((PVR_DBG_ERROR,
395 "PVRSRVRemoveBCDeviceKM: requested device %d not present",
398 return PVRSRV_ERROR_GENERIC;
402 psDevNode = *(ppsDevNode);
403 *ppsDevNode = psDevNode->psNext;
405 FreeDeviceID(psSysData, ui32DevIndex);
406 psBCInfo = (PVRSRV_BUFFERCLASS_INFO *) psDevNode->pvDevice;
407 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
408 sizeof(PVRSRV_BC_SRV2BUFFER_KMJTABLE), psBCInfo->psFuncTable,
410 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_BUFFERCLASS_INFO),
412 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DEVICE_NODE),
413 psDevNode, IMG_NULL);
418 PVRSRV_ERROR PVRSRVCloseDCDeviceKM(IMG_HANDLE hDeviceKM,
419 IMG_BOOL bResManCallback)
422 PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *psDCPerContextInfo;
424 PVR_UNREFERENCED_PARAMETER(bResManCallback);
426 psDCPerContextInfo = (PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *) hDeviceKM;
428 eError = ResManFreeResByPtr(psDCPerContextInfo->hResItem);
433 static PVRSRV_ERROR CloseDCDeviceCallBack(IMG_PVOID pvParam,
434 IMG_UINT32 ui32Param)
436 PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *psDCPerContextInfo;
437 PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
439 PVR_UNREFERENCED_PARAMETER(ui32Param);
441 psDCPerContextInfo = (PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *) pvParam;
442 psDCInfo = psDCPerContextInfo->psDCInfo;
444 psDCInfo->ui32RefCount--;
445 if (psDCInfo->ui32RefCount == 0) {
447 psDCInfo->psFuncTable->pfnCloseDCDevice(psDCInfo->hExtDevice);
449 PVRSRVFreeSyncInfoKM(psDCInfo->sSystemBuffer.sDeviceClassBuffer.
452 psDCInfo->hDevMemContext = IMG_NULL;
453 psDCInfo->hExtDevice = IMG_NULL;
456 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
457 sizeof(PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO),
458 psDCPerContextInfo, IMG_NULL);
464 PVRSRV_ERROR PVRSRVOpenDCDeviceKM(PVRSRV_PER_PROCESS_DATA * psPerProc,
465 IMG_UINT32 ui32DeviceID,
466 IMG_HANDLE hDevCookie,
467 IMG_HANDLE * phDeviceKM)
469 PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
470 PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *psDCPerContextInfo;
471 PVRSRV_DEVICE_NODE *psDeviceNode;
475 PVR_DPF((PVR_DBG_ERROR,
476 "PVRSRVOpenDCDeviceKM: Invalid params"));
477 return PVRSRV_ERROR_GENERIC;
480 if (SysAcquireData(&psSysData) != PVRSRV_OK) {
481 PVR_DPF((PVR_DBG_ERROR,
482 "PVRSRVOpenDCDeviceKM: Failed to get SysData"));
483 return PVRSRV_ERROR_GENERIC;
486 psDeviceNode = psSysData->psDeviceNodeList;
487 while (psDeviceNode) {
488 if ((psDeviceNode->sDevId.eDeviceClass ==
489 PVRSRV_DEVICE_CLASS_DISPLAY)
490 && (psDeviceNode->sDevId.ui32DeviceIndex == ui32DeviceID)) {
493 (PVRSRV_DISPLAYCLASS_INFO *) psDeviceNode->pvDevice;
496 psDeviceNode = psDeviceNode->psNext;
499 PVR_DPF((PVR_DBG_ERROR,
500 "PVRSRVOpenDCDeviceKM: no devnode matching index %d",
503 return PVRSRV_ERROR_GENERIC;
507 if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
508 sizeof(*psDCPerContextInfo),
509 (IMG_VOID **) & psDCPerContextInfo,
510 IMG_NULL) != PVRSRV_OK) {
511 PVR_DPF((PVR_DBG_ERROR,
512 "PVRSRVOpenDCDeviceKM: Failed psDCPerContextInfo alloc"));
513 return PVRSRV_ERROR_OUT_OF_MEMORY;
515 OSMemSet(psDCPerContextInfo, 0, sizeof(*psDCPerContextInfo));
517 if (psDCInfo->ui32RefCount++ == 0) {
520 psDeviceNode = (PVRSRV_DEVICE_NODE *) hDevCookie;
521 PVR_ASSERT(psDeviceNode != IMG_NULL);
523 psDCInfo->hDevMemContext =
524 (IMG_HANDLE) psDeviceNode->sDevMemoryInfo.pBMKernelContext;
526 eError = PVRSRVAllocSyncInfoKM(IMG_NULL,
527 (IMG_HANDLE) psDeviceNode->
528 sDevMemoryInfo.pBMKernelContext,
529 &psDCInfo->sSystemBuffer.
532 if (eError != PVRSRV_OK) {
533 PVR_DPF((PVR_DBG_ERROR,
534 "PVRSRVOpenDCDeviceKM: Failed sync info alloc"));
535 psDCInfo->ui32RefCount--;
539 eError = psDCInfo->psFuncTable->pfnOpenDCDevice(ui32DeviceID,
547 psSyncDataMemInfoKM->
549 if (eError != PVRSRV_OK) {
550 PVR_DPF((PVR_DBG_ERROR,
551 "PVRSRVOpenDCDeviceKM: Failed to open external DC device"));
552 psDCInfo->ui32RefCount--;
553 PVRSRVFreeSyncInfoKM(psDCInfo->sSystemBuffer.
560 psDCPerContextInfo->psDCInfo = psDCInfo;
561 psDCPerContextInfo->hResItem =
562 ResManRegisterRes(psPerProc->hResManContext,
563 RESMAN_TYPE_DISPLAYCLASS_DEVICE,
564 psDCPerContextInfo, 0, CloseDCDeviceCallBack);
566 *phDeviceKM = (IMG_HANDLE) psDCPerContextInfo;
572 PVRSRV_ERROR PVRSRVEnumDCFormatsKM(IMG_HANDLE hDeviceKM,
573 IMG_UINT32 * pui32Count,
574 DISPLAY_FORMAT * psFormat)
576 PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
578 if (!hDeviceKM || !pui32Count || !psFormat) {
579 PVR_DPF((PVR_DBG_ERROR,
580 "PVRSRVEnumDCFormatsKM: Invalid parameters"));
581 return PVRSRV_ERROR_INVALID_PARAMS;
584 psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
586 return psDCInfo->psFuncTable->pfnEnumDCFormats(psDCInfo->hExtDevice,
587 pui32Count, psFormat);
591 PVRSRV_ERROR PVRSRVEnumDCDimsKM(IMG_HANDLE hDeviceKM,
592 DISPLAY_FORMAT * psFormat,
593 IMG_UINT32 * pui32Count,
594 DISPLAY_DIMS * psDim)
596 PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
598 if (!hDeviceKM || !pui32Count || !psFormat) {
599 PVR_DPF((PVR_DBG_ERROR,
600 "PVRSRVEnumDCDimsKM: Invalid parameters"));
601 return PVRSRV_ERROR_INVALID_PARAMS;
604 psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
606 return psDCInfo->psFuncTable->pfnEnumDCDims(psDCInfo->hExtDevice,
607 psFormat, pui32Count,
612 PVRSRV_ERROR PVRSRVGetDCSystemBufferKM(IMG_HANDLE hDeviceKM,
613 IMG_HANDLE * phBuffer)
616 PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
617 IMG_HANDLE hExtBuffer;
619 if (!hDeviceKM || !phBuffer) {
620 PVR_DPF((PVR_DBG_ERROR,
621 "PVRSRVGetDCSystemBufferKM: Invalid parameters"));
622 return PVRSRV_ERROR_INVALID_PARAMS;
625 psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
628 psDCInfo->psFuncTable->pfnGetDCSystemBuffer(psDCInfo->hExtDevice,
630 if (eError != PVRSRV_OK) {
631 PVR_DPF((PVR_DBG_ERROR,
632 "PVRSRVGetDCSystemBufferKM: Failed to get valid buffer handle from external driver"));
636 psDCInfo->sSystemBuffer.sDeviceClassBuffer.pfnGetBufferAddr =
637 psDCInfo->psFuncTable->pfnGetBufferAddr;
638 psDCInfo->sSystemBuffer.sDeviceClassBuffer.hDevMemContext =
639 psDCInfo->hDevMemContext;
640 psDCInfo->sSystemBuffer.sDeviceClassBuffer.hExtDevice =
641 psDCInfo->hExtDevice;
642 psDCInfo->sSystemBuffer.sDeviceClassBuffer.hExtBuffer = hExtBuffer;
644 psDCInfo->sSystemBuffer.psDCInfo = psDCInfo;
646 *phBuffer = (IMG_HANDLE) & (psDCInfo->sSystemBuffer);
652 PVRSRV_ERROR PVRSRVGetDCInfoKM(IMG_HANDLE hDeviceKM,
653 DISPLAY_INFO * psDisplayInfo)
655 PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
658 if (!hDeviceKM || !psDisplayInfo) {
659 PVR_DPF((PVR_DBG_ERROR,
660 "PVRSRVGetDCInfoKM: Invalid parameters"));
661 return PVRSRV_ERROR_INVALID_PARAMS;
664 psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
667 psDCInfo->psFuncTable->pfnGetDCInfo(psDCInfo->hExtDevice,
669 if (eError != PVRSRV_OK) {
673 if (psDisplayInfo->ui32MaxSwapChainBuffers >
674 PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS) {
675 psDisplayInfo->ui32MaxSwapChainBuffers =
676 PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS;
682 IMG_EXPORT PVRSRV_ERROR PVRSRVDestroyDCSwapChainKM(IMG_HANDLE hSwapChain)
685 PVRSRV_DC_SWAPCHAIN *psSwapChain;
688 PVR_DPF((PVR_DBG_ERROR,
689 "PVRSRVDestroyDCSwapChainKM: Invalid parameters"));
690 return PVRSRV_ERROR_INVALID_PARAMS;
693 psSwapChain = hSwapChain;
695 eError = ResManFreeResByPtr(psSwapChain->hResItem);
700 static PVRSRV_ERROR DestroyDCSwapChainCallBack(IMG_PVOID pvParam,
701 IMG_UINT32 ui32Param)
704 PVRSRV_DC_SWAPCHAIN *psSwapChain = pvParam;
705 PVRSRV_DISPLAYCLASS_INFO *psDCInfo = psSwapChain->psDCInfo;
708 PVR_UNREFERENCED_PARAMETER(ui32Param);
710 PVRSRVDestroyCommandQueueKM(psSwapChain->psQueue);
713 psDCInfo->psFuncTable->pfnDestroyDCSwapChain(psDCInfo->hExtDevice,
717 if (eError != PVRSRV_OK) {
718 PVR_DPF((PVR_DBG_ERROR,
719 "DestroyDCSwapChainCallBack: Failed to destroy DC swap chain"));
723 for (i = 0; i < psSwapChain->ui32BufferCount; i++) {
724 if (psSwapChain->asBuffer[i].sDeviceClassBuffer.
726 PVRSRVFreeSyncInfoKM(psSwapChain->asBuffer[i].
732 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DC_SWAPCHAIN),
733 psSwapChain, IMG_NULL);
739 PVRSRV_ERROR PVRSRVCreateDCSwapChainKM(PVRSRV_PER_PROCESS_DATA * psPerProc,
740 IMG_HANDLE hDeviceKM,
741 IMG_UINT32 ui32Flags,
742 DISPLAY_SURF_ATTRIBUTES *
744 DISPLAY_SURF_ATTRIBUTES *
746 IMG_UINT32 ui32BufferCount,
747 IMG_UINT32 ui32OEMFlags,
748 IMG_HANDLE * phSwapChain,
749 IMG_UINT32 * pui32SwapChainID)
751 PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
752 PVRSRV_DC_SWAPCHAIN *psSwapChain = IMG_NULL;
753 PVRSRV_SYNC_DATA *apsSyncData[PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS];
754 PVRSRV_QUEUE_INFO *psQueue = IMG_NULL;
760 || !psSrcSurfAttrib || !phSwapChain || !pui32SwapChainID) {
761 PVR_DPF((PVR_DBG_ERROR,
762 "PVRSRVCreateDCSwapChainKM: Invalid parameters"));
763 return PVRSRV_ERROR_INVALID_PARAMS;
766 if (ui32BufferCount > PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS) {
767 PVR_DPF((PVR_DBG_ERROR,
768 "PVRSRVCreateDCSwapChainKM: Too many buffers"));
769 return PVRSRV_ERROR_TOOMANYBUFFERS;
772 if (ui32BufferCount < 2) {
773 PVR_DPF((PVR_DBG_ERROR,
774 "PVRSRVCreateDCSwapChainKM: Too few buffers"));
775 return PVRSRV_ERROR_TOO_FEW_BUFFERS;
778 psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
780 if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
781 sizeof(PVRSRV_DC_SWAPCHAIN),
782 (IMG_VOID **) & psSwapChain, IMG_NULL) != PVRSRV_OK) {
783 PVR_DPF((PVR_DBG_ERROR,
784 "PVRSRVCreateDCSwapChainKM: Failed psSwapChain alloc"));
785 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
788 OSMemSet(psSwapChain, 0, sizeof(PVRSRV_DC_SWAPCHAIN));
790 eError = PVRSRVCreateCommandQueueKM(1024, &psQueue);
791 if (eError != PVRSRV_OK) {
792 PVR_DPF((PVR_DBG_ERROR,
793 "PVRSRVCreateDCSwapChainKM: Failed to create CmdQueue"));
797 psSwapChain->psQueue = psQueue;
799 for (i = 0; i < ui32BufferCount; i++) {
800 eError = PVRSRVAllocSyncInfoKM(IMG_NULL,
801 psDCInfo->hDevMemContext,
802 &psSwapChain->asBuffer[i].
805 if (eError != PVRSRV_OK) {
806 PVR_DPF((PVR_DBG_ERROR,
807 "PVRSRVCreateDCSwapChainKM: Failed to alloc syninfo for psSwapChain"));
811 psSwapChain->asBuffer[i].sDeviceClassBuffer.pfnGetBufferAddr =
812 psDCInfo->psFuncTable->pfnGetBufferAddr;
813 psSwapChain->asBuffer[i].sDeviceClassBuffer.hDevMemContext =
814 psDCInfo->hDevMemContext;
815 psSwapChain->asBuffer[i].sDeviceClassBuffer.hExtDevice =
816 psDCInfo->hExtDevice;
818 psSwapChain->asBuffer[i].psDCInfo = psDCInfo;
819 psSwapChain->asBuffer[i].psSwapChain = psSwapChain;
822 (PVRSRV_SYNC_DATA *) psSwapChain->asBuffer[i].
823 sDeviceClassBuffer.psKernelSyncInfo->psSyncDataMemInfoKM->
827 psSwapChain->ui32BufferCount = ui32BufferCount;
828 psSwapChain->psDCInfo = psDCInfo;
831 psDCInfo->psFuncTable->pfnCreateDCSwapChain(psDCInfo->hExtDevice,
841 if (eError != PVRSRV_OK) {
842 PVR_DPF((PVR_DBG_ERROR,
843 "PVRSRVCreateDCSwapChainKM: Failed to create 3rd party SwapChain"));
847 *phSwapChain = (IMG_HANDLE) psSwapChain;
849 psSwapChain->hResItem = ResManRegisterRes(psPerProc->hResManContext,
850 RESMAN_TYPE_DISPLAYCLASS_SWAPCHAIN,
853 DestroyDCSwapChainCallBack);
859 for (i = 0; i < ui32BufferCount; i++) {
860 if (psSwapChain->asBuffer[i].sDeviceClassBuffer.
862 PVRSRVFreeSyncInfoKM(psSwapChain->asBuffer[i].
869 PVRSRVDestroyCommandQueueKM(psQueue);
873 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DC_SWAPCHAIN),
874 psSwapChain, IMG_NULL);
881 PVRSRV_ERROR PVRSRVSetDCDstRectKM(IMG_HANDLE hDeviceKM,
882 IMG_HANDLE hSwapChain, IMG_RECT * psRect)
884 PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
885 PVRSRV_DC_SWAPCHAIN *psSwapChain;
887 if (!hDeviceKM || !hSwapChain) {
888 PVR_DPF((PVR_DBG_ERROR,
889 "PVRSRVSetDCDstRectKM: Invalid parameters"));
890 return PVRSRV_ERROR_INVALID_PARAMS;
893 psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
894 psSwapChain = (PVRSRV_DC_SWAPCHAIN *) hSwapChain;
896 return psDCInfo->psFuncTable->pfnSetDCDstRect(psDCInfo->hExtDevice,
898 hExtSwapChain, psRect);
902 PVRSRV_ERROR PVRSRVSetDCSrcRectKM(IMG_HANDLE hDeviceKM,
903 IMG_HANDLE hSwapChain, IMG_RECT * psRect)
905 PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
906 PVRSRV_DC_SWAPCHAIN *psSwapChain;
908 if (!hDeviceKM || !hSwapChain) {
909 PVR_DPF((PVR_DBG_ERROR,
910 "PVRSRVSetDCSrcRectKM: Invalid parameters"));
911 return PVRSRV_ERROR_INVALID_PARAMS;
914 psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
915 psSwapChain = (PVRSRV_DC_SWAPCHAIN *) hSwapChain;
917 return psDCInfo->psFuncTable->pfnSetDCSrcRect(psDCInfo->hExtDevice,
919 hExtSwapChain, psRect);
923 PVRSRV_ERROR PVRSRVSetDCDstColourKeyKM(IMG_HANDLE hDeviceKM,
924 IMG_HANDLE hSwapChain,
925 IMG_UINT32 ui32CKColour)
927 PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
928 PVRSRV_DC_SWAPCHAIN *psSwapChain;
930 if (!hDeviceKM || !hSwapChain) {
931 PVR_DPF((PVR_DBG_ERROR,
932 "PVRSRVSetDCDstColourKeyKM: Invalid parameters"));
933 return PVRSRV_ERROR_INVALID_PARAMS;
936 psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
937 psSwapChain = (PVRSRV_DC_SWAPCHAIN *) hSwapChain;
939 return psDCInfo->psFuncTable->pfnSetDCDstColourKey(psDCInfo->hExtDevice,
946 PVRSRV_ERROR PVRSRVSetDCSrcColourKeyKM(IMG_HANDLE hDeviceKM,
947 IMG_HANDLE hSwapChain,
948 IMG_UINT32 ui32CKColour)
950 PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
951 PVRSRV_DC_SWAPCHAIN *psSwapChain;
953 if (!hDeviceKM || !hSwapChain) {
954 PVR_DPF((PVR_DBG_ERROR,
955 "PVRSRVSetDCSrcColourKeyKM: Invalid parameters"));
956 return PVRSRV_ERROR_INVALID_PARAMS;
959 psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
960 psSwapChain = (PVRSRV_DC_SWAPCHAIN *) hSwapChain;
962 return psDCInfo->psFuncTable->pfnSetDCSrcColourKey(psDCInfo->hExtDevice,
969 PVRSRV_ERROR PVRSRVGetDCBuffersKM(IMG_HANDLE hDeviceKM,
970 IMG_HANDLE hSwapChain,
971 IMG_UINT32 * pui32BufferCount,
972 IMG_HANDLE * phBuffer)
974 PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
975 PVRSRV_DC_SWAPCHAIN *psSwapChain;
976 IMG_HANDLE ahExtBuffer[PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS];
980 if (!hDeviceKM || !hSwapChain || !phBuffer) {
981 PVR_DPF((PVR_DBG_ERROR,
982 "PVRSRVGetDCBuffersKM: Invalid parameters"));
983 return PVRSRV_ERROR_INVALID_PARAMS;
986 psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
987 psSwapChain = (PVRSRV_DC_SWAPCHAIN *) hSwapChain;
989 eError = psDCInfo->psFuncTable->pfnGetDCBuffers(psDCInfo->hExtDevice,
995 PVR_ASSERT(*pui32BufferCount <= PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS);
997 for (i = 0; i < *pui32BufferCount; i++) {
998 psSwapChain->asBuffer[i].sDeviceClassBuffer.hExtBuffer =
1000 phBuffer[i] = (IMG_HANDLE) & psSwapChain->asBuffer[i];
1007 PVRSRV_ERROR PVRSRVSwapToDCBufferKM(IMG_HANDLE hDeviceKM,
1009 IMG_UINT32 ui32SwapInterval,
1010 IMG_HANDLE hPrivateTag,
1011 IMG_UINT32 ui32ClipRectCount,
1012 IMG_RECT * psClipRect)
1014 PVRSRV_ERROR eError;
1015 PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
1016 PVRSRV_DC_BUFFER *psBuffer;
1017 PVRSRV_QUEUE_INFO *psQueue;
1018 DISPLAYCLASS_FLIP_COMMAND *psFlipCmd;
1020 IMG_BOOL bStart = IMG_FALSE;
1021 IMG_UINT32 uiStart = 0;
1022 IMG_UINT32 ui32NumSrcSyncs = 1;
1023 PVRSRV_KERNEL_SYNC_INFO *apsSrcSync[2];
1024 PVRSRV_COMMAND *psCommand;
1026 if (!hDeviceKM || !hBuffer || !psClipRect) {
1027 PVR_DPF((PVR_DBG_ERROR,
1028 "PVRSRVSwapToDCBufferKM: Invalid parameters"));
1029 return PVRSRV_ERROR_INVALID_PARAMS;
1031 #if defined(SUPPORT_LMA)
1032 eError = PVRSRVPowerLock(KERNEL_ID, IMG_FALSE);
1033 if (eError != PVRSRV_OK) {
1038 psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
1039 psBuffer = (PVRSRV_DC_BUFFER *) hBuffer;
1041 psQueue = psBuffer->psSwapChain->psQueue;
1043 apsSrcSync[0] = psBuffer->sDeviceClassBuffer.psKernelSyncInfo;
1044 if (psBuffer->psSwapChain->psLastFlipBuffer &&
1045 psBuffer != psBuffer->psSwapChain->psLastFlipBuffer) {
1047 psBuffer->psSwapChain->psLastFlipBuffer->sDeviceClassBuffer.
1052 eError = PVRSRVInsertCommandKM(psQueue,
1054 psDCInfo->ui32DeviceID,
1060 sizeof(DISPLAYCLASS_FLIP_COMMAND) +
1061 (sizeof(IMG_RECT) * ui32ClipRectCount));
1062 if (eError != PVRSRV_OK) {
1063 PVR_DPF((PVR_DBG_ERROR,
1064 "PVRSRVSwapToDCBufferKM: Failed to get space in queue"));
1068 psFlipCmd = (DISPLAYCLASS_FLIP_COMMAND *) psCommand->pvData;
1070 psFlipCmd->hExtDevice = psDCInfo->hExtDevice;
1072 psFlipCmd->hExtSwapChain = psBuffer->psSwapChain->hExtSwapChain;
1074 psFlipCmd->hExtBuffer = psBuffer->sDeviceClassBuffer.hExtBuffer;
1076 psFlipCmd->hPrivateTag = hPrivateTag;
1078 psFlipCmd->ui32ClipRectCount = ui32ClipRectCount;
1080 psFlipCmd->psClipRect =
1081 (IMG_RECT *) ((IMG_UINT8 *) psFlipCmd +
1082 sizeof(DISPLAYCLASS_FLIP_COMMAND));
1084 for (i = 0; i < ui32ClipRectCount; i++) {
1085 psFlipCmd->psClipRect[i] = psClipRect[i];
1088 psFlipCmd->ui32SwapInterval = ui32SwapInterval;
1090 eError = PVRSRVSubmitCommandKM(psQueue, psCommand);
1091 if (eError != PVRSRV_OK) {
1092 PVR_DPF((PVR_DBG_ERROR,
1093 "PVRSRVSwapToDCBufferKM: Failed to submit command"));
1098 if (PVRSRVProcessQueues(KERNEL_ID, IMG_FALSE) !=
1099 PVRSRV_ERROR_PROCESSING_BLOCKED) {
1100 goto ProcessedQueues;
1103 if (bStart == IMG_FALSE) {
1104 uiStart = OSClockus();
1107 OSWaitus(MAX_HW_TIME_US / WAIT_TRY_COUNT);
1108 } while ((OSClockus() - uiStart) < MAX_HW_TIME_US);
1110 PVR_DPF((PVR_DBG_ERROR,
1111 "PVRSRVSwapToDCBufferKM: Failed to process queues"));
1113 eError = PVRSRV_ERROR_GENERIC;
1118 psBuffer->psSwapChain->psLastFlipBuffer = psBuffer;
1121 #if defined(SUPPORT_LMA)
1122 PVRSRVPowerUnlock(KERNEL_ID);
1128 PVRSRV_ERROR PVRSRVSwapToDCSystemKM(IMG_HANDLE hDeviceKM,
1129 IMG_HANDLE hSwapChain)
1131 PVRSRV_ERROR eError;
1132 PVRSRV_QUEUE_INFO *psQueue;
1133 PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
1134 PVRSRV_DC_SWAPCHAIN *psSwapChain;
1135 DISPLAYCLASS_FLIP_COMMAND *psFlipCmd;
1136 IMG_BOOL bStart = IMG_FALSE;
1137 IMG_UINT32 uiStart = 0;
1138 IMG_UINT32 ui32NumSrcSyncs = 1;
1139 PVRSRV_KERNEL_SYNC_INFO *apsSrcSync[2];
1140 PVRSRV_COMMAND *psCommand;
1142 if (!hDeviceKM || !hSwapChain) {
1143 PVR_DPF((PVR_DBG_ERROR,
1144 "PVRSRVSwapToDCSystemKM: Invalid parameters"));
1145 return PVRSRV_ERROR_INVALID_PARAMS;
1147 #if defined(SUPPORT_LMA)
1148 eError = PVRSRVPowerLock(KERNEL_ID, IMG_FALSE);
1149 if (eError != PVRSRV_OK) {
1154 psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
1155 psSwapChain = (PVRSRV_DC_SWAPCHAIN *) hSwapChain;
1157 psQueue = psSwapChain->psQueue;
1160 psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo;
1161 if (psSwapChain->psLastFlipBuffer) {
1163 psSwapChain->psLastFlipBuffer->sDeviceClassBuffer.
1168 eError = PVRSRVInsertCommandKM(psQueue,
1170 psDCInfo->ui32DeviceID,
1176 sizeof(DISPLAYCLASS_FLIP_COMMAND));
1177 if (eError != PVRSRV_OK) {
1178 PVR_DPF((PVR_DBG_ERROR,
1179 "PVRSRVSwapToDCSystemKM: Failed to get space in queue"));
1183 psFlipCmd = (DISPLAYCLASS_FLIP_COMMAND *) psCommand->pvData;
1185 psFlipCmd->hExtDevice = psDCInfo->hExtDevice;
1187 psFlipCmd->hExtSwapChain = psSwapChain->hExtSwapChain;
1189 psFlipCmd->hExtBuffer =
1190 psDCInfo->sSystemBuffer.sDeviceClassBuffer.hExtBuffer;
1192 psFlipCmd->hPrivateTag = IMG_NULL;
1194 psFlipCmd->ui32ClipRectCount = 0;
1196 psFlipCmd->ui32SwapInterval = 1;
1198 eError = PVRSRVSubmitCommandKM(psQueue, psCommand);
1199 if (eError != PVRSRV_OK) {
1200 PVR_DPF((PVR_DBG_ERROR,
1201 "PVRSRVSwapToDCSystemKM: Failed to submit command"));
1206 if (PVRSRVProcessQueues(KERNEL_ID, IMG_FALSE) !=
1207 PVRSRV_ERROR_PROCESSING_BLOCKED) {
1208 goto ProcessedQueues;
1211 if (bStart == IMG_FALSE) {
1212 uiStart = OSClockus();
1215 OSWaitus(MAX_HW_TIME_US / WAIT_TRY_COUNT);
1216 } while ((OSClockus() - uiStart) < MAX_HW_TIME_US);
1218 PVR_DPF((PVR_DBG_ERROR,
1219 "PVRSRVSwapToDCSystemKM: Failed to process queues"));
1220 eError = PVRSRV_ERROR_GENERIC;
1225 psSwapChain->psLastFlipBuffer = &psDCInfo->sSystemBuffer;
1230 #if defined(SUPPORT_LMA)
1231 PVRSRVPowerUnlock(KERNEL_ID);
1236 PVRSRV_ERROR PVRSRVRegisterSystemISRHandler(PFN_ISR_HANDLER pfnISRHandler,
1237 IMG_VOID * pvISRHandlerData,
1238 IMG_UINT32 ui32ISRSourceMask,
1239 IMG_UINT32 ui32DeviceID)
1241 SYS_DATA *psSysData;
1242 PVRSRV_DEVICE_NODE *psDevNode;
1244 PVR_UNREFERENCED_PARAMETER(ui32ISRSourceMask);
1246 if (SysAcquireData(&psSysData) != PVRSRV_OK) {
1247 PVR_DPF((PVR_DBG_ERROR,
1248 "PVRSRVRegisterSystemISRHandler: Failed to get SysData"));
1249 return PVRSRV_ERROR_GENERIC;
1252 psDevNode = psSysData->psDeviceNodeList;
1254 if (psDevNode->sDevId.ui32DeviceIndex == ui32DeviceID) {
1257 psDevNode = psDevNode->psNext;
1260 psDevNode->pvISRData = (IMG_VOID *) pvISRHandlerData;
1262 psDevNode->pfnDeviceISR = pfnISRHandler;
1267 IMG_VOID IMG_CALLCONV PVRSRVSetDCState(IMG_UINT32 ui32State)
1269 PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
1270 PVRSRV_DEVICE_NODE *psDeviceNode;
1271 SYS_DATA *psSysData;
1273 if (SysAcquireData(&psSysData) != PVRSRV_OK) {
1274 PVR_DPF((PVR_DBG_ERROR,
1275 "PVRSRVSetDCState: Failed to get SysData"));
1279 psDeviceNode = psSysData->psDeviceNodeList;
1280 while (psDeviceNode != IMG_NULL) {
1281 if (psDeviceNode->sDevId.eDeviceClass ==
1282 PVRSRV_DEVICE_CLASS_DISPLAY) {
1284 (PVRSRV_DISPLAYCLASS_INFO *) psDeviceNode->pvDevice;
1285 if (psDCInfo->psFuncTable->pfnSetDCState
1286 && psDCInfo->hExtDevice) {
1287 psDCInfo->psFuncTable->pfnSetDCState(psDCInfo->
1292 psDeviceNode = psDeviceNode->psNext;
1297 IMG_BOOL PVRGetDisplayClassJTable(PVRSRV_DC_DISP2SRV_KMJTABLE * psJTable)
1299 psJTable->ui32TableSize = sizeof(PVRSRV_DC_DISP2SRV_KMJTABLE);
1300 psJTable->pfnPVRSRVRegisterDCDevice = PVRSRVRegisterDCDeviceKM;
1301 psJTable->pfnPVRSRVRemoveDCDevice = PVRSRVRemoveDCDeviceKM;
1302 psJTable->pfnPVRSRVOEMFunction = SysOEMFunction;
1303 psJTable->pfnPVRSRVRegisterCmdProcList = PVRSRVRegisterCmdProcListKM;
1304 psJTable->pfnPVRSRVRemoveCmdProcList = PVRSRVRemoveCmdProcListKM;
1305 psJTable->pfnPVRSRVCmdComplete = PVRSRVCommandCompleteKM;
1306 psJTable->pfnPVRSRVRegisterSystemISRHandler =
1307 PVRSRVRegisterSystemISRHandler;
1308 psJTable->pfnPVRSRVRegisterPowerDevice = PVRSRVRegisterPowerDevice;
1314 PVRSRV_ERROR PVRSRVCloseBCDeviceKM(IMG_HANDLE hDeviceKM,
1315 IMG_BOOL bResManCallback)
1317 PVRSRV_ERROR eError;
1318 PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *psBCPerContextInfo;
1320 PVR_UNREFERENCED_PARAMETER(bResManCallback);
1322 psBCPerContextInfo = (PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *) hDeviceKM;
1324 eError = ResManFreeResByPtr(psBCPerContextInfo->hResItem);
1329 static PVRSRV_ERROR CloseBCDeviceCallBack(IMG_PVOID pvParam,
1330 IMG_UINT32 ui32Param)
1332 PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *psBCPerContextInfo;
1333 PVRSRV_BUFFERCLASS_INFO *psBCInfo;
1335 PVR_UNREFERENCED_PARAMETER(ui32Param);
1337 psBCPerContextInfo = (PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *) pvParam;
1338 psBCInfo = psBCPerContextInfo->psBCInfo;
1340 psBCInfo->ui32RefCount--;
1341 if (psBCInfo->ui32RefCount == 0) {
1344 psBCInfo->psFuncTable->pfnCloseBCDevice(psBCInfo->hExtDevice);
1346 for (i = 0; i < psBCInfo->ui32BufferCount; i++) {
1347 if (psBCInfo->psBuffer[i].sDeviceClassBuffer.
1349 PVRSRVFreeSyncInfoKM(psBCInfo->psBuffer[i].
1355 if (psBCInfo->psBuffer) {
1356 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
1357 sizeof(PVRSRV_BC_BUFFER) *
1358 psBCInfo->ui32BufferCount, psBCInfo->psBuffer,
1363 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
1364 sizeof(PVRSRV_BUFFERCLASS_PERCONTEXT_INFO),
1365 psBCPerContextInfo, IMG_NULL);
1371 PVRSRV_ERROR PVRSRVOpenBCDeviceKM(PVRSRV_PER_PROCESS_DATA * psPerProc,
1372 IMG_UINT32 ui32DeviceID,
1373 IMG_HANDLE hDevCookie,
1374 IMG_HANDLE * phDeviceKM)
1376 PVRSRV_BUFFERCLASS_INFO *psBCInfo;
1377 PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *psBCPerContextInfo;
1378 PVRSRV_DEVICE_NODE *psDeviceNode;
1379 SYS_DATA *psSysData;
1381 PVRSRV_ERROR eError;
1382 BUFFER_INFO sBufferInfo;
1385 PVR_DPF((PVR_DBG_ERROR,
1386 "PVRSRVOpenBCDeviceKM: Invalid params"));
1387 return PVRSRV_ERROR_GENERIC;
1390 if (SysAcquireData(&psSysData) != PVRSRV_OK) {
1391 PVR_DPF((PVR_DBG_ERROR,
1392 "PVRSRVOpenBCDeviceKM: Failed to get SysData"));
1393 return PVRSRV_ERROR_GENERIC;
1396 psDeviceNode = psSysData->psDeviceNodeList;
1397 while (psDeviceNode) {
1398 if ((psDeviceNode->sDevId.eDeviceClass ==
1399 PVRSRV_DEVICE_CLASS_BUFFER)
1400 && (psDeviceNode->sDevId.ui32DeviceIndex == ui32DeviceID)) {
1403 (PVRSRV_BUFFERCLASS_INFO *) psDeviceNode->pvDevice;
1406 psDeviceNode = psDeviceNode->psNext;
1409 PVR_DPF((PVR_DBG_ERROR,
1410 "PVRSRVOpenBCDeviceKM: No devnode matching index %d",
1413 return PVRSRV_ERROR_GENERIC;
1417 if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
1418 sizeof(*psBCPerContextInfo),
1419 (IMG_VOID **) & psBCPerContextInfo,
1420 IMG_NULL) != PVRSRV_OK) {
1421 PVR_DPF((PVR_DBG_ERROR,
1422 "PVRSRVOpenBCDeviceKM: Failed psBCPerContextInfo alloc"));
1423 return PVRSRV_ERROR_OUT_OF_MEMORY;
1425 OSMemSet(psBCPerContextInfo, 0, sizeof(*psBCPerContextInfo));
1427 if (psBCInfo->ui32RefCount++ == 0) {
1428 psDeviceNode = (PVRSRV_DEVICE_NODE *) hDevCookie;
1429 PVR_ASSERT(psDeviceNode != IMG_NULL);
1431 psBCInfo->hDevMemContext =
1432 (IMG_HANDLE) psDeviceNode->sDevMemoryInfo.pBMKernelContext;
1435 psBCInfo->psFuncTable->pfnOpenBCDevice(&psBCInfo->
1437 if (eError != PVRSRV_OK) {
1438 PVR_DPF((PVR_DBG_ERROR,
1439 "PVRSRVOpenBCDeviceKM: Failed to open external BC device"));
1444 psBCInfo->psFuncTable->pfnGetBCInfo(psBCInfo->hExtDevice,
1446 if (eError != PVRSRV_OK) {
1447 PVR_DPF((PVR_DBG_ERROR,
1448 "PVRSRVOpenBCDeviceKM : Failed to get BC Info"));
1452 psBCInfo->ui32BufferCount = sBufferInfo.ui32BufferCount;
1454 eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
1455 sizeof(PVRSRV_BC_BUFFER) *
1456 sBufferInfo.ui32BufferCount,
1457 (IMG_VOID **) & psBCInfo->psBuffer,
1459 if (eError != PVRSRV_OK) {
1460 PVR_DPF((PVR_DBG_ERROR,
1461 "PVRSRVOpenBCDeviceKM: Failed to allocate BC buffers"));
1464 OSMemSet(psBCInfo->psBuffer,
1466 sizeof(PVRSRV_BC_BUFFER) *
1467 sBufferInfo.ui32BufferCount);
1469 for (i = 0; i < psBCInfo->ui32BufferCount; i++) {
1471 eError = PVRSRVAllocSyncInfoKM(IMG_NULL,
1472 psBCInfo->hDevMemContext,
1473 &psBCInfo->psBuffer[i].
1476 if (eError != PVRSRV_OK) {
1477 PVR_DPF((PVR_DBG_ERROR,
1478 "PVRSRVOpenBCDeviceKM: Failed sync info alloc"));
1483 psBCInfo->psFuncTable->pfnGetBCBuffer(psBCInfo->
1494 if (eError != PVRSRV_OK) {
1495 PVR_DPF((PVR_DBG_ERROR,
1496 "PVRSRVOpenBCDeviceKM: Failed to get BC buffers"));
1500 psBCInfo->psBuffer[i].sDeviceClassBuffer.
1502 psBCInfo->psFuncTable->pfnGetBufferAddr;
1503 psBCInfo->psBuffer[i].sDeviceClassBuffer.
1504 hDevMemContext = psBCInfo->hDevMemContext;
1505 psBCInfo->psBuffer[i].sDeviceClassBuffer.hExtDevice =
1506 psBCInfo->hExtDevice;
1510 psBCPerContextInfo->psBCInfo = psBCInfo;
1511 psBCPerContextInfo->hResItem =
1512 ResManRegisterRes(psPerProc->hResManContext,
1513 RESMAN_TYPE_BUFFERCLASS_DEVICE,
1514 psBCPerContextInfo, 0, CloseBCDeviceCallBack);
1516 *phDeviceKM = (IMG_HANDLE) psBCPerContextInfo;
1522 for (i = 0; i < psBCInfo->ui32BufferCount; i++) {
1523 if (psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo) {
1524 PVRSRVFreeSyncInfoKM(psBCInfo->psBuffer[i].
1530 if (psBCInfo->psBuffer) {
1531 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
1532 sizeof(PVRSRV_BC_BUFFER) *
1533 sBufferInfo.ui32BufferCount, psBCInfo->psBuffer,
1541 PVRSRV_ERROR PVRSRVGetBCInfoKM(IMG_HANDLE hDeviceKM,
1542 BUFFER_INFO * psBufferInfo)
1544 PVRSRV_BUFFERCLASS_INFO *psBCInfo;
1545 PVRSRV_ERROR eError;
1547 if (!hDeviceKM || !psBufferInfo) {
1548 PVR_DPF((PVR_DBG_ERROR,
1549 "PVRSRVGetBCInfoKM: Invalid parameters"));
1550 return PVRSRV_ERROR_INVALID_PARAMS;
1553 psBCInfo = BCDeviceHandleToBCInfo(hDeviceKM);
1556 psBCInfo->psFuncTable->pfnGetBCInfo(psBCInfo->hExtDevice,
1559 if (eError != PVRSRV_OK) {
1560 PVR_DPF((PVR_DBG_ERROR,
1561 "PVRSRVGetBCInfoKM : Failed to get BC Info"));
1569 PVRSRV_ERROR PVRSRVGetBCBufferKM(IMG_HANDLE hDeviceKM,
1570 IMG_UINT32 ui32BufferIndex,
1571 IMG_HANDLE * phBuffer)
1573 PVRSRV_BUFFERCLASS_INFO *psBCInfo;
1575 if (!hDeviceKM || !phBuffer) {
1576 PVR_DPF((PVR_DBG_ERROR,
1577 "PVRSRVGetBCBufferKM: Invalid parameters"));
1578 return PVRSRV_ERROR_INVALID_PARAMS;
1581 psBCInfo = BCDeviceHandleToBCInfo(hDeviceKM);
1583 if (ui32BufferIndex < psBCInfo->ui32BufferCount) {
1584 *phBuffer = (IMG_HANDLE) & psBCInfo->psBuffer[ui32BufferIndex];
1586 PVR_DPF((PVR_DBG_ERROR,
1587 "PVRSRVGetBCBufferKM: Buffer index %d out of range (%d)",
1588 ui32BufferIndex, psBCInfo->ui32BufferCount));
1589 return PVRSRV_ERROR_INVALID_PARAMS;
1596 IMG_BOOL PVRGetBufferClassJTable(PVRSRV_BC_BUFFER2SRV_KMJTABLE * psJTable)
1598 psJTable->ui32TableSize = sizeof(PVRSRV_BC_BUFFER2SRV_KMJTABLE);
1600 psJTable->pfnPVRSRVRegisterBCDevice = PVRSRVRegisterBCDeviceKM;
1601 psJTable->pfnPVRSRVRemoveBCDevice = PVRSRVRemoveBCDeviceKM;