Beispiel #1
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;
}
Beispiel #2
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;
}
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;
}