Beispiel #1
0
enum PVRSRV_ERROR PVRSRVGetDCInfoKM(void *hDeviceKM,
				struct DISPLAY_INFO *psDisplayInfo)
{
	struct PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
	enum PVRSRV_ERROR eError;

	if (!hDeviceKM || !psDisplayInfo) {
		PVR_DPF(PVR_DBG_ERROR,
			 "PVRSRVGetDCInfoKM: Invalid parameters");
		return PVRSRV_ERROR_INVALID_PARAMS;
	}

	psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);

	eError = psDCInfo->psFuncTable->pfnGetDCInfo(psDCInfo->hExtDevice,
							psDisplayInfo);
	if (eError != PVRSRV_OK)
		return eError;

	if (psDisplayInfo->ui32MaxSwapChainBuffers >
	    PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS) {
		psDisplayInfo->ui32MaxSwapChainBuffers =
		    PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS;
	}

	return PVRSRV_OK;
}
Beispiel #2
0
enum PVRSRV_ERROR PVRSRVGetDCBuffersKM(void *hDeviceKM, void *hSwapChain,
				      u32 *pui32BufferCount, void **phBuffer)
{
	struct PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
	struct PVRSRV_DC_SWAPCHAIN *psSwapChain;
	void *ahExtBuffer[PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS];
	enum PVRSRV_ERROR eError;
	u32 i;

	if (!hDeviceKM || !hSwapChain || !phBuffer) {
		PVR_DPF(PVR_DBG_ERROR,
			 "PVRSRVGetDCBuffersKM: Invalid parameters");
		return PVRSRV_ERROR_INVALID_PARAMS;
	}

	psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
	psSwapChain = (struct PVRSRV_DC_SWAPCHAIN *)hSwapChain;

	eError = psDCInfo->psFuncTable->pfnGetDCBuffers(psDCInfo->hExtDevice,
						psSwapChain->hExtSwapChain,
						pui32BufferCount, ahExtBuffer);

	PVR_ASSERT(*pui32BufferCount <= PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS);

	for (i = 0; i < *pui32BufferCount; i++) {
		psSwapChain->asBuffer[i].sDeviceClassBuffer.hExtBuffer =
								ahExtBuffer[i];
		phBuffer[i] = (void *)&psSwapChain->asBuffer[i];
	}

	return eError;
}
Beispiel #3
0
enum PVRSRV_ERROR PVRSRVEnumDCDimsKM(void *hDeviceKM,
				    struct DISPLAY_FORMAT *psFormat,
				    u32 *pui32Count, struct DISPLAY_DIMS *psDim)
{
	struct PVRSRV_DISPLAYCLASS_INFO *psDCInfo;

	if (!hDeviceKM || !pui32Count || !psFormat) {
		PVR_DPF(PVR_DBG_ERROR,
			 "PVRSRVEnumDCDimsKM: Invalid parameters");
		return PVRSRV_ERROR_INVALID_PARAMS;
	}

	psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);

	return psDCInfo->psFuncTable->pfnEnumDCDims(psDCInfo->hExtDevice,
						  psFormat, pui32Count, psDim);
}
Beispiel #4
0
enum PVRSRV_ERROR PVRSRVSetDCSrcColourKeyKM(void *hDeviceKM, void *hSwapChain,
					   u32 ui32CKColour)
{
	struct PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
	struct PVRSRV_DC_SWAPCHAIN *psSwapChain;

	if (!hDeviceKM || !hSwapChain) {
		PVR_DPF(PVR_DBG_ERROR,
			 "PVRSRVSetDCSrcColourKeyKM: Invalid parameters");
		return PVRSRV_ERROR_INVALID_PARAMS;
	}

	psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
	psSwapChain = (struct PVRSRV_DC_SWAPCHAIN *)hSwapChain;

	return psDCInfo->psFuncTable->pfnSetDCSrcColourKey(psDCInfo->hExtDevice,
				     psSwapChain->hExtSwapChain, ui32CKColour);
}
IMG_EXPORT
PVRSRV_ERROR PVRSRVEnumDCFormatsKM (IMG_HANDLE hDeviceKM,
									IMG_UINT32 *pui32Count,
									DISPLAY_FORMAT *psFormat)
{
	PVRSRV_DISPLAYCLASS_INFO *psDCInfo;

	if(!hDeviceKM || !pui32Count || !psFormat)
	{
		PVR_DPF((PVR_DBG_ERROR,"PVRSRVEnumDCFormatsKM: Invalid parameters"));
		return PVRSRV_ERROR_INVALID_PARAMS;
	}

	psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);

	
	return psDCInfo->psFuncTable->pfnEnumDCFormats(psDCInfo->hExtDevice, pui32Count, psFormat);
}
IMG_EXPORT
PVRSRV_ERROR PVRSRVSetDCDstRectKM(IMG_HANDLE	hDeviceKM,
								  IMG_HANDLE	hSwapChain,
								  IMG_RECT		*psRect)
{
	PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
	PVRSRV_DC_SWAPCHAIN *psSwapChain;

	if(!hDeviceKM || !hSwapChain)
	{
		PVR_DPF((PVR_DBG_ERROR,"PVRSRVSetDCDstRectKM: Invalid parameters"));
		return PVRSRV_ERROR_INVALID_PARAMS;
	}

	psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
	psSwapChain = (PVRSRV_DC_SWAPCHAIN*)hSwapChain;

	return psDCInfo->psFuncTable->pfnSetDCDstRect(psDCInfo->hExtDevice,
													psSwapChain->hExtSwapChain,
													psRect);
}
IMG_EXPORT
PVRSRV_ERROR PVRSRVGetDCBuffersKM(IMG_HANDLE	hDeviceKM,
								  IMG_HANDLE	hSwapChain,
								  IMG_UINT32	*pui32BufferCount,
								  IMG_HANDLE	*phBuffer)
{
	PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
	PVRSRV_DC_SWAPCHAIN *psSwapChain;
	IMG_HANDLE ahExtBuffer[PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS];
	PVRSRV_ERROR eError;
	IMG_UINT32 i;

	if(!hDeviceKM || !hSwapChain || !phBuffer)
	{
		PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetDCBuffersKM: Invalid parameters"));	
		return PVRSRV_ERROR_INVALID_PARAMS;
	}

	psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
	psSwapChain = (PVRSRV_DC_SWAPCHAIN*)hSwapChain;

	
	eError = psDCInfo->psFuncTable->pfnGetDCBuffers(psDCInfo->hExtDevice,
													psSwapChain->hExtSwapChain,
													pui32BufferCount,
													ahExtBuffer);

	PVR_ASSERT(*pui32BufferCount <= PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS);

	


	for(i=0; i<*pui32BufferCount; i++)
	{
		psSwapChain->asBuffer[i].sDeviceClassBuffer.hExtBuffer = ahExtBuffer[i];
		phBuffer[i] = (IMG_HANDLE)&psSwapChain->asBuffer[i];
	}

	return eError;
}
Beispiel #8
0
enum PVRSRV_ERROR PVRSRVGetDCSystemBufferKM(void *hDeviceKM, void **phBuffer)
{
	enum PVRSRV_ERROR eError;
	struct PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
	void *hExtBuffer;

	if (!hDeviceKM || !phBuffer) {
		PVR_DPF(PVR_DBG_ERROR,
			 "PVRSRVGetDCSystemBufferKM: Invalid parameters");
		return PVRSRV_ERROR_INVALID_PARAMS;
	}

	psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);

	eError =
	    psDCInfo->psFuncTable->pfnGetDCSystemBuffer(psDCInfo->hExtDevice,
							&hExtBuffer);
	if (eError != PVRSRV_OK) {
		PVR_DPF(PVR_DBG_ERROR, "PVRSRVGetDCSystemBufferKM: "
		     "Failed to get valid buffer handle from external driver");
		return eError;
	}

	psDCInfo->sSystemBuffer.sDeviceClassBuffer.pfnGetBufferAddr =
	    psDCInfo->psFuncTable->pfnGetBufferAddr;
	psDCInfo->sSystemBuffer.sDeviceClassBuffer.hDevMemContext =
	    psDCInfo->hDevMemContext;
	psDCInfo->sSystemBuffer.sDeviceClassBuffer.hExtDevice =
	    psDCInfo->hExtDevice;
	psDCInfo->sSystemBuffer.sDeviceClassBuffer.hExtBuffer = hExtBuffer;

	psDCInfo->sSystemBuffer.psDCInfo = psDCInfo;

	*phBuffer = (void *) &(psDCInfo->sSystemBuffer);

	return PVRSRV_OK;
}
Beispiel #9
0
enum PVRSRV_ERROR PVRSRVSwapToDCBufferKM(void *hDeviceKM, void *hBuffer,
					u32 ui32SwapInterval, void *hPrivateTag,
					u32 ui32ClipRectCount,
					struct IMG_RECT *psClipRect)
{
	enum PVRSRV_ERROR eError;
	struct PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
	struct PVRSRV_DC_BUFFER *psBuffer;
	struct PVRSRV_QUEUE_INFO *psQueue;
	struct DISPLAYCLASS_FLIP_COMMAND *psFlipCmd;
	u32 i;
	u32 ui32NumSrcSyncs = 1;
	struct PVRSRV_KERNEL_SYNC_INFO *apsSrcSync[2];
	struct PVRSRV_COMMAND *psCommand;

	if (!hDeviceKM || !hBuffer || !psClipRect) {
		PVR_DPF(PVR_DBG_ERROR,
			 "PVRSRVSwapToDCBufferKM: Invalid parameters");
		return PVRSRV_ERROR_INVALID_PARAMS;
	}

	psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
	psBuffer = (struct PVRSRV_DC_BUFFER *)hBuffer;

	psQueue = psBuffer->psSwapChain->psQueue;

	apsSrcSync[0] = psBuffer->sDeviceClassBuffer.psKernelSyncInfo;
	if (psBuffer->psSwapChain->psLastFlipBuffer &&
	    psBuffer != psBuffer->psSwapChain->psLastFlipBuffer) {
		apsSrcSync[1] =
		    psBuffer->psSwapChain->psLastFlipBuffer->sDeviceClassBuffer.
		    psKernelSyncInfo;
		ui32NumSrcSyncs++;
	}

	eError = PVRSRVInsertCommandKM(psQueue, &psCommand,
				      psDCInfo->ui32DeviceID, DC_FLIP_COMMAND,
				      0, NULL, ui32NumSrcSyncs, apsSrcSync,
				      sizeof(struct DISPLAYCLASS_FLIP_COMMAND) +
				      (sizeof(struct IMG_RECT) *
							   ui32ClipRectCount));
	if (eError != PVRSRV_OK) {
		PVR_DPF(PVR_DBG_ERROR,
			"PVRSRVSwapToDCBufferKM: Failed to get space in queue");
		goto Exit;
	}

	psFlipCmd = (struct DISPLAYCLASS_FLIP_COMMAND *)psCommand->pvData;
	psFlipCmd->hExtDevice = psDCInfo->hExtDevice;
	psFlipCmd->hExtSwapChain = psBuffer->psSwapChain->hExtSwapChain;
	psFlipCmd->hExtBuffer = psBuffer->sDeviceClassBuffer.hExtBuffer;
	psFlipCmd->hPrivateTag = hPrivateTag;
	psFlipCmd->ui32ClipRectCount = ui32ClipRectCount;
	psFlipCmd->psClipRect =
	    (struct IMG_RECT *)((u8 *) psFlipCmd +
			  sizeof(struct DISPLAYCLASS_FLIP_COMMAND));

	for (i = 0; i < ui32ClipRectCount; i++)
		psFlipCmd->psClipRect[i] = psClipRect[i];

	psFlipCmd->ui32SwapInterval = ui32SwapInterval;

	eError = PVRSRVSubmitCommandKM(psQueue, psCommand);
	if (eError != PVRSRV_OK) {
		PVR_DPF(PVR_DBG_ERROR,
			 "PVRSRVSwapToDCBufferKM: Failed to submit command");
		goto Exit;
	}

	LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) {
		if (PVRSRVProcessQueues(IMG_FALSE) !=
		    PVRSRV_ERROR_PROCESSING_BLOCKED) {
			goto ProcessedQueues;
		}
		OSWaitus(MAX_HW_TIME_US / WAIT_TRY_COUNT);
	}
	END_LOOP_UNTIL_TIMEOUT();

	PVR_DPF(PVR_DBG_ERROR,
		 "PVRSRVSwapToDCBufferKM: Failed to process queues");

	eError = PVRSRV_ERROR_GENERIC;
	goto Exit;

ProcessedQueues:

	psBuffer->psSwapChain->psLastFlipBuffer = psBuffer;

Exit:
	return eError;
}
Beispiel #10
0
enum PVRSRV_ERROR PVRSRVCreateDCSwapChainKM(
				struct PVRSRV_PER_PROCESS_DATA *psPerProc,
				void *hDeviceKM, u32 ui32Flags,
				struct DISPLAY_SURF_ATTRIBUTES *psDstSurfAttrib,
				struct DISPLAY_SURF_ATTRIBUTES *psSrcSurfAttrib,
				u32 ui32BufferCount, u32 ui32OEMFlags,
				void **phSwapChain, u32 *pui32SwapChainID)
{
	struct PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
	struct PVRSRV_DC_SWAPCHAIN *psSwapChain = NULL;
	struct PVRSRV_SYNC_DATA *apsSyncData[PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS];
	struct PVRSRV_QUEUE_INFO *psQueue = NULL;
	enum PVRSRV_ERROR eError;
	u32 i;

	if (!hDeviceKM || !psDstSurfAttrib || !psSrcSurfAttrib ||
	    !phSwapChain || !pui32SwapChainID) {
		PVR_DPF(PVR_DBG_ERROR,
			 "PVRSRVCreateDCSwapChainKM: Invalid parameters");
		return PVRSRV_ERROR_INVALID_PARAMS;
	}

	if (ui32BufferCount > PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS) {
		PVR_DPF(PVR_DBG_ERROR,
			 "PVRSRVCreateDCSwapChainKM: Too many buffers");
		return PVRSRV_ERROR_TOOMANYBUFFERS;
	}

	if (ui32BufferCount < 2) {
		PVR_DPF(PVR_DBG_ERROR,
			 "PVRSRVCreateDCSwapChainKM: Too few buffers");
		return PVRSRV_ERROR_TOO_FEW_BUFFERS;
	}

	psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);

	if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
		       sizeof(struct PVRSRV_DC_SWAPCHAIN),
		       (void **) &psSwapChain, NULL) != PVRSRV_OK) {
		PVR_DPF(PVR_DBG_ERROR,
			 "PVRSRVCreateDCSwapChainKM: Failed psSwapChain alloc");
		eError = PVRSRV_ERROR_OUT_OF_MEMORY;
		goto ErrorExit;
	}
	OSMemSet(psSwapChain, 0, sizeof(struct PVRSRV_DC_SWAPCHAIN));

	eError = PVRSRVCreateCommandQueueKM(1024, &psQueue);
	if (eError != PVRSRV_OK) {
		PVR_DPF(PVR_DBG_ERROR,
			"PVRSRVCreateDCSwapChainKM: Failed to create CmdQueue");
		goto ErrorExit;
	}

	psSwapChain->psQueue = psQueue;

	for (i = 0; i < ui32BufferCount; i++) {
		eError = PVRSRVAllocSyncInfoKM(NULL,
					       psDCInfo->hDevMemContext,
					       &psSwapChain->asBuffer[i].
						       sDeviceClassBuffer.
							      psKernelSyncInfo);
		if (eError != PVRSRV_OK) {
			PVR_DPF(PVR_DBG_ERROR, "PVRSRVCreateDCSwapChainKM: "
				"Failed to alloc syninfo for psSwapChain");
			goto ErrorExit;
		}

		psSwapChain->asBuffer[i].sDeviceClassBuffer.pfnGetBufferAddr =
		    psDCInfo->psFuncTable->pfnGetBufferAddr;
		psSwapChain->asBuffer[i].sDeviceClassBuffer.hDevMemContext =
		    psDCInfo->hDevMemContext;
		psSwapChain->asBuffer[i].sDeviceClassBuffer.hExtDevice =
		    psDCInfo->hExtDevice;

		psSwapChain->asBuffer[i].psDCInfo = psDCInfo;
		psSwapChain->asBuffer[i].psSwapChain = psSwapChain;

		apsSyncData[i] =
		    (struct PVRSRV_SYNC_DATA *)psSwapChain->asBuffer[i].
			    sDeviceClassBuffer.psKernelSyncInfo->
					psSyncDataMemInfoKM->pvLinAddrKM;
	}

	psSwapChain->ui32BufferCount = ui32BufferCount;
	psSwapChain->psDCInfo = psDCInfo;

	eError =
	    psDCInfo->psFuncTable->pfnCreateDCSwapChain(psDCInfo->hExtDevice,
						ui32Flags,
						psDstSurfAttrib,
						psSrcSurfAttrib,
						ui32BufferCount,
						apsSyncData,
						ui32OEMFlags,
						&psSwapChain->hExtSwapChain,
						pui32SwapChainID);
	if (eError != PVRSRV_OK) {
		PVR_DPF(PVR_DBG_ERROR, "PVRSRVCreateDCSwapChainKM: "
				"Failed to create 3rd party SwapChain");
		goto ErrorExit;
	}

	*phSwapChain = (void *) psSwapChain;

	psSwapChain->hResItem = ResManRegisterRes(psPerProc->hResManContext,
					  RESMAN_TYPE_DISPLAYCLASS_SWAPCHAIN,
					  psSwapChain, 0,
					  DestroyDCSwapChainCallBack);

	return eError;

ErrorExit:

	for (i = 0; i < ui32BufferCount; i++) {
		if (psSwapChain->asBuffer[i].sDeviceClassBuffer.
		    psKernelSyncInfo) {
			PVRSRVFreeSyncInfoKM(psSwapChain->asBuffer[i].
						     sDeviceClassBuffer.
							     psKernelSyncInfo);
		}
	}

	if (psQueue)
		PVRSRVDestroyCommandQueueKM(psQueue);

	if (psSwapChain) {
		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
			  sizeof(struct PVRSRV_DC_SWAPCHAIN), psSwapChain,
			  NULL);
	}

	return eError;
}
Beispiel #11
0
enum PVRSRV_ERROR PVRSRVSwapToDCSystemKM(void *hDeviceKM, void *hSwapChain)
{
	enum PVRSRV_ERROR eError;
	struct PVRSRV_QUEUE_INFO *psQueue;
	struct PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
	struct PVRSRV_DC_SWAPCHAIN *psSwapChain;
	struct DISPLAYCLASS_FLIP_COMMAND *psFlipCmd;
	IMG_BOOL bStart = IMG_FALSE;
	u32 uiStart = 0;
	u32 ui32NumSrcSyncs = 1;
	struct PVRSRV_KERNEL_SYNC_INFO *apsSrcSync[2];
	struct PVRSRV_COMMAND *psCommand;

	if (!hDeviceKM || !hSwapChain) {
		PVR_DPF(PVR_DBG_ERROR,
			 "PVRSRVSwapToDCSystemKM: Invalid parameters");
		return PVRSRV_ERROR_INVALID_PARAMS;
	}

	psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
	psSwapChain = (struct PVRSRV_DC_SWAPCHAIN *)hSwapChain;

	psQueue = psSwapChain->psQueue;

	apsSrcSync[0] =
	    psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo;
	if (psSwapChain->psLastFlipBuffer) {
		apsSrcSync[1] =
		    psSwapChain->psLastFlipBuffer->sDeviceClassBuffer.
		    psKernelSyncInfo;
		ui32NumSrcSyncs++;
	}

	eError = PVRSRVInsertCommandKM(psQueue, &psCommand,
				      psDCInfo->ui32DeviceID, DC_FLIP_COMMAND,
				      0, NULL, ui32NumSrcSyncs, apsSrcSync,
				      sizeof(struct DISPLAYCLASS_FLIP_COMMAND));
	if (eError != PVRSRV_OK) {
		PVR_DPF(PVR_DBG_ERROR, "PVRSRVSwapToDCSystemKM: "
			"Failed to get space in queue");
		goto Exit;
	}

	psFlipCmd = (struct DISPLAYCLASS_FLIP_COMMAND *)psCommand->pvData;
	psFlipCmd->hExtDevice = psDCInfo->hExtDevice;
	psFlipCmd->hExtSwapChain = psSwapChain->hExtSwapChain;
	psFlipCmd->hExtBuffer =
	    psDCInfo->sSystemBuffer.sDeviceClassBuffer.hExtBuffer;
	psFlipCmd->hPrivateTag = NULL;
	psFlipCmd->ui32ClipRectCount = 0;
	psFlipCmd->ui32SwapInterval = 1;

	eError = PVRSRVSubmitCommandKM(psQueue, psCommand);
	if (eError != PVRSRV_OK) {
		PVR_DPF(PVR_DBG_ERROR,
			 "PVRSRVSwapToDCSystemKM: Failed to submit command");
		goto Exit;
	}

	do {
		if (PVRSRVProcessQueues(KERNEL_ID, IMG_FALSE) !=
		    PVRSRV_ERROR_PROCESSING_BLOCKED)
			goto ProcessedQueues;

		if (bStart == IMG_FALSE) {
			uiStart = OSClockus();
			bStart = IMG_TRUE;
		}
		OSWaitus(MAX_HW_TIME_US / WAIT_TRY_COUNT);
	} while ((OSClockus() - uiStart) < MAX_HW_TIME_US);

	PVR_DPF(PVR_DBG_ERROR,
		 "PVRSRVSwapToDCSystemKM: Failed to process queues");
	eError = PVRSRV_ERROR_GENERIC;
	goto Exit;

ProcessedQueues:

	psSwapChain->psLastFlipBuffer = &psDCInfo->sSystemBuffer;

	eError = PVRSRV_OK;

Exit:
	return eError;
}
IMG_EXPORT
PVRSRV_ERROR PVRSRVSwapToDCSystemKM(IMG_HANDLE	hDeviceKM,
									IMG_HANDLE	hSwapChain)
{
	PVRSRV_ERROR eError;
	PVRSRV_QUEUE_INFO *psQueue;
	PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
	PVRSRV_DC_SWAPCHAIN *psSwapChain;
	DISPLAYCLASS_FLIP_COMMAND *psFlipCmd;
	IMG_UINT32 ui32NumSrcSyncs = 1;
	PVRSRV_KERNEL_SYNC_INFO *apsSrcSync[2];
	PVRSRV_COMMAND *psCommand;

	if(!hDeviceKM || !hSwapChain)
	{
		PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCSystemKM: Invalid parameters"));
		return PVRSRV_ERROR_INVALID_PARAMS;
	}

#if defined(SUPPORT_LMA)
	eError = PVRSRVPowerLock(KERNEL_ID, IMG_FALSE);
	if(eError != PVRSRV_OK)
	{
		return eError;
	}
#endif 
	
	psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
	psSwapChain = (PVRSRV_DC_SWAPCHAIN*)hSwapChain;

	
	psQueue = psSwapChain->psQueue;

	
	apsSrcSync[0] = psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo;
	if(psSwapChain->psLastFlipBuffer)
	{
		
		if (apsSrcSync[0] != psSwapChain->psLastFlipBuffer->sDeviceClassBuffer.psKernelSyncInfo)
		{
			apsSrcSync[1] = psSwapChain->psLastFlipBuffer->sDeviceClassBuffer.psKernelSyncInfo;
			ui32NumSrcSyncs++;			
		}
	}

	
	eError = PVRSRVInsertCommandKM (psQueue,
									&psCommand,
									psDCInfo->ui32DeviceID,
									DC_FLIP_COMMAND,
									0,
									IMG_NULL,
									ui32NumSrcSyncs,
									apsSrcSync,
									sizeof(DISPLAYCLASS_FLIP_COMMAND));
	if(eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCSystemKM: Failed to get space in queue"));
		goto Exit;
	}

	
	psFlipCmd = (DISPLAYCLASS_FLIP_COMMAND*)psCommand->pvData;

	
	psFlipCmd->hExtDevice = psDCInfo->hExtDevice;

	
	psFlipCmd->hExtSwapChain = psSwapChain->hExtSwapChain;

	
	psFlipCmd->hExtBuffer = psDCInfo->sSystemBuffer.sDeviceClassBuffer.hExtBuffer;

	
	psFlipCmd->hPrivateTag = IMG_NULL;

	
	psFlipCmd->ui32ClipRectCount = 0;

	psFlipCmd->ui32SwapInterval = 1;

	
	eError = PVRSRVSubmitCommandKM (psQueue, psCommand);
	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCSystemKM: Failed to submit command"));
		goto Exit;
	}

	






	LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
	{
		if(PVRSRVProcessQueues(KERNEL_ID, IMG_FALSE) != PVRSRV_ERROR_PROCESSING_BLOCKED)
		{
			goto ProcessedQueues;
		}

		OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT);
	} END_LOOP_UNTIL_TIMEOUT();

	PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCSystemKM: Failed to process queues"));
	eError = PVRSRV_ERROR_GENERIC;
	goto Exit;

ProcessedQueues:
	
	psSwapChain->psLastFlipBuffer = &psDCInfo->sSystemBuffer;

	eError = PVRSRV_OK;
	
Exit:
#if defined(SUPPORT_LMA)
	PVRSRVPowerUnlock(KERNEL_ID);
#endif	
	return eError;
}