⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mbx.c

📁 Lido PXA270平台开发板的最新BSP,包括源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
 @Description 
 
 If this is the last reference to the parameter buffer, it will be destroyed.
 
 @Input    psDevData : 

 @Return   PVRSRV_ERROR  : 

******************************************************************************/
IMG_EXPORT PVRSRV_ERROR PVRSRVDestroyParameterBuffer(PVRSRV_DEV_DATA *psDevData)
{
	return ResManFreeResByCriteria(RESMAN_CRITERIA_RESTYPE | RESMAN_CRITERIA_FREEONCE, RESMAN_TYPE_PARAMBUFF, 0, 0, 0);
}

/*!
******************************************************************************

 @Function	RemoveRenderTargetCleanUp
 
 @Description 
 	RT clean-up code
  
 @Input    psDevInfo
 @Input    psInfo
 
 @Return   PVRSRV_ERROR 

******************************************************************************/
static PVRSRV_ERROR RemoveRenderTargetCleanUp(PVRSRV_DEV_INFO *psDevInfo, PVRSRV_TARENDERINFO *psInfo)
{
	PVRSRV_ERROR	eError = PVRSRV_OK;
	DEVICE3D		*ps3D = &psDevInfo->sDeviceSpecific.s3D;

	if(ps3D->ui32Last3DCtlID == psInfo->psSharedData->ui32UniqueID)
	{
		ps3D->LastEVMContextDevVAddr.uiAddr = 0;
		ps3D->LastTAContextDevVAddr.uiAddr = 0;
		ps3D->bLastContextMidScene = IMG_FALSE;
		ps3D->ui32Last3DCtlID = 0;
		ps3D->ui32LastTilesX = 0;
		ps3D->ui32LastTilesY = 0;
	}

	if ((psInfo->psSharedData->aui32ContextStatus[psInfo->psSharedData->ui32CurrentRenderData] == PVR3DIF_3DCTL_PREPARING)
	||	(psInfo->psSharedData->aui32ContextStatus[psInfo->psSharedData->ui32CurrentRenderData] == PVR3DIF_3DCTL_CS_PREPARING))
	{
	    IMG_PVOID			*pvRegsBase = psDevInfo->sDevLocation.pvRegsBaseKM;
    	PVR3DIF_PARAMBUFFER	*psParamBuffer = (PVR3DIF_PARAMBUFFER *)ps3D->hParamBuffer;
		PVRSRV_QUEUE_INFO	*psQueue;
		PVR3DIF_3DCTL		*ps3DCtl;
		SYS_DATA			*psSysData;
		RENDERSYNCS			*psRenderSyncs;
		BLTSYNCS			*psBlitSyncs;
		IMG_UINT32			ui3DCtlCount = 0;
		IMG_UINT32			i;


		/*
			At this point SW / HW state could be corrupted.
			- Enable dummy processing mode
			- if any commands are `in process' assume they are broken
				and call their respective complete functions
			- command processor now calls the pfnDummyProc functions
			to clean-up
		*/
		eError = SysAcquireData(&psSysData);
		if (eError != PVRSRV_OK)
		{
			return eError;
		}
		
		/* block processing of any more commands */
		ps3D->b3DIdle = IMG_FALSE;/* render */
		eError = HostLockResource(&ps3D->h2DSlaveportResource, IMG_TRUE);	/* blit */
		if (eError != PVRSRV_OK)
		{
			return eError;
		}

		psRenderSyncs = ps3D->hRenderSync;
		psBlitSyncs  = ps3D->hBlitSync;

		/* signal to all other contexts to stop HW accesses */
		ps3DCtl = psParamBuffer->ps3DCtlList;
		while (ps3DCtl)
		{
			ps3DCtl->sSharedData.bSceneInvalidated = IMG_TRUE;
			ps3DCtl = ps3DCtl->psNext;
			ui3DCtlCount++;
		}

		/* deal with active commands */
		if(psRenderSyncs->bInUse || psBlitSyncs->bInUse)
		{
			/* wait some time for these to complete */
			HostWaitus(MAX_HW_TIME_US);
			if(psRenderSyncs->bInUse)
			{
				psRenderSyncs->bPartialRender = IMG_FALSE;
				psRenderSyncs->bUpdatePrimary = IMG_FALSE;
				ps3D->bRestartTA = IMG_FALSE;
				Handle3DComplete(psDevInfo);
			}
			if(psBlitSyncs->bInUse)
			{
				psBlitSyncs->bUpdatePrimary = IMG_FALSE;
				Handle2DSync(psDevInfo);
			}
		}


		/*
			Now reset HW
		*/
		SysDeviceReset(psSysData, psDevInfo);

		/*
			If not already freed free the region headers
		*/
		psInfo->psSharedData->aui32ContextStatus[0] = PVR3DIF_3DCTL_FREE;
		psInfo->psSharedData->aui32ContextStatus[1] = PVR3DIF_3DCTL_FREE;

		/*
			fifo state clean-up
		*/
		ps3D->ui32BytesFreeTAFifo = 0; 
		ps3D->ui32BytesReservedTA = 0; 
		ps3D->ui32BytesReserved2d = 0;
		eError = HostReleaseMutex(&ps3D->hMutexTAFifoSpace);
		if (eError != PVRSRV_OK)
		{
			return eError;
		}

		/*
			Slaveport details
		*/
		ps3D->ui32BytesFreeTAFifo = 0; 
		ps3D->ui32BytesReservedTA = 0; 
		ps3D->ui32BytesReserved2d = 0;
		eError = HostUnlockResource(&ps3D->h2DSlaveportResource);
		if (eError != PVRSRV_OK)
		{
			return eError;
		}

		/*
			TA details
		*/
		ps3D->bTAStopMode = IMG_FALSE;
		ps3D->bTAIdle = IMG_TRUE;
		ps3D->bRestartTA = IMG_FALSE;
		eError = HostUnlockResource(&ps3D->hTAConfigResource);
		if (eError != PVRSRV_OK)
		{
			return eError;
		}		
		
		eError = HostUnlockResource(&ps3D->hTAResource);
		if (eError != PVRSRV_OK)
		{
			return eError;
		}
		/*
			context details
		*/
		ps3D->aui32HWContextIDState[0] = 0;
		ps3D->aui32HWContextIDState[1] = 0;
		ps3D->bTAContextInterrupt = IMG_FALSE;
		/*
			discard scene details
		*/
		ps3D->bBlock3DProcessing = IMG_FALSE;
		ps3D->bEVMDAlloc = IMG_FALSE;
		ps3D->bTATimeOut = IMG_FALSE;

		/****************************************************
			ASYNCHRONOUS CLEAN-UP 
		****************************************************/

		/*
			render resources
		*/
		ps3D->bEnablePartialRender = IMG_FALSE;
		ps3D->bEVMDAlloc = IMG_FALSE;
		ps3D->b3DIdle = IMG_TRUE;
		ps3D->bRenderComplete = IMG_FALSE;
		HostMemSet(ps3D->hRenderSync, 0, sizeof(RENDERSYNCS));

		/*
			blit resources
		*/
		HostMemSet(ps3D->hBlitSync, 0, sizeof(BLTSYNCS));

		/*
			general command state clean-up
		*/


		/****************************************************
			HW RECOVERY 
		****************************************************/

		/* 
			re-enable the device 
		*/
		if(psDevInfo->pfnInitDevice != IMG_NULL)
		{
			eError = psDevInfo->pfnInitDevice (psDevInfo);
			if (eError != PVRSRV_OK)
			{
				return eError;
			}
		}

		if(ui3DCtlCount > 1)
		{
			/* if other contexts present we need to silently re-enable the parameter buffer */
			WriteHWRegs(pvRegsBase, psParamBuffer->ui32HWRegCount, psParamBuffer->asHWRegs);
			eError = PollForValueKM ((volatile IMG_UINT32 *)&ps3D->bEVMDAlloc,
									IMG_TRUE,
									0xFFFFFFFF,
									MAX_HW_TIME_US/WAIT_TRY_COUNT,
									WAIT_TRY_COUNT);
			if (eError != PVRSRV_OK)
			{
				return eError;
			}
			/* and clear the flag */
			ps3D->bEVMDAlloc = IMG_FALSE;			
		}

		/* 
			start dummy processing 
		*/
		psSysData->bDummyProcessing = IMG_TRUE;
		for (i=0; i<WAIT_TRY_COUNT; i++)
		{
			IMG_BOOL bQueuesEmpty;
			
			bQueuesEmpty = IMG_TRUE;
			
			psQueue = psSysData->psQueueList;	
			while(psQueue)
			{		
				if (psQueue->ui32ReadOffset != psQueue->ui32WriteOffset)
				{
					bQueuesEmpty = IMG_FALSE;
				}
				
				SysKickCmdProc (psSysData->pui32KickerAddr);
				
				HostWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT);

				psQueue = psQueue->psNextKM;	
			}
			if(bQueuesEmpty)
			{
				break;
			}
		}
		
		if(i==WAIT_TRY_COUNT)
		{
			return PVRSRV_ERROR_GENERIC;
		}

		/* stop dummy processing */
		psSysData->bDummyProcessing = IMG_FALSE;
	}

	return eError;
}



/*!
******************************************************************************

 @Function	RemoveRenderTargetCallBack
 
 @Description 
 	RT clean-up code
  
 @Input    ui32ProcessID - process id
 @Input    pvParam - data packet
 @Input    ui32Param - packet size
 
 @Return   PVRSRV_ERROR 

******************************************************************************/
static PVRSRV_ERROR RemoveRenderTargetCallBack (IMG_UINT32	ui32ProcessID, 
												IMG_PVOID	pvParam, 
												IMG_UINT32	ui32Param)
{
	PVRSRV_DEV_INFO 	*psDevInfo = (PVRSRV_DEV_INFO *)pvParam;/*! @todo should really have a holding structure */
	PVRSRV_TARENDERINFO *psInfo = (PVRSRV_TARENDERINFO *)ui32Param;/*! @todo should really have a holding structure */
	PVR3DIF_PARAMBUFFER	*psParamBuffer;
	PVR3DIF_3DCTL		*psThis;
	PVR3DIF_3DCTL		*psPrev;
	PVR3DIF_3DCTL		*ps3DCtl;
	SYS_DATA			*psSysData;
	IMG_UINT			i;
	PVRSRV_ERROR		eError;

	eError = SysAcquireData(&psSysData);
	if (eError != PVRSRV_OK)
	{
		return eError;
	}
	
	ps3DCtl = (PVR3DIF_3DCTL *)psInfo->psSharedData;

	/* @todo FIXME: don't need any sleeps here - need test for 3DHW timeout flag */
	for (i=0; (i<WAIT_TRY_COUNT)
		&&	((ps3DCtl->sSharedData.aui32ContextStatus[0] != PVR3DIF_3DCTL_FREE) ||
			 (ps3DCtl->sSharedData.aui32ContextStatus[1] != PVR3DIF_3DCTL_FREE)); i++)
	{
		SysKickCmdProc (psSysData->pui32KickerAddr);
		HostWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT);
	}

	if (i == WAIT_TRY_COUNT)
	{
		PVR_DPF((PVR_DBG_WARNING,"RemoveRenderTargetCallBack: region headers never became free - assume OK to deallocate"));
	}

	eError = RemoveRenderTargetCleanUp(psDevInfo, psInfo);
	if (eError != PVRSRV_OK)
	{
		return eError;
	}
	
	psParamBuffer = (PVR3DIF_PARAMBUFFER *)psDevInfo->sDeviceSpecific.s3D.hParamBuffer;
	psPrev = 0;

	/* Find entry in linked list.. */
	psThis = psParamBuffer->ps3DCtlList;

	while(psThis)
	{
		if (psThis == ps3DCtl)
		{
			break;
		}

		psPrev = psThis;
		psThis = psThis->psNext;
	}

	/* Go away if we've been given a dicky thang to remove. */
	if (!psThis)
	{
		PVR_DPF((PVR_DBG_ERROR,"Invalid 3DCtl - can't be removed from render target!"));
		return PVRSRV_ERROR_INVALID_PARAMS;
	}

	/*
		Free the space allocated for TA context load/store, region
		headers, tail-pointers and the HW background object
	*/

	FreeStaticFBMem(psDevInfo, ps3DCtl->pvTAContextKM);
	FreeStaticFBMem(psDevInfo, ps3DCtl->pvEVMContextKM);
	FreeStaticFBMem(psDevInfo, ps3DCtl->sSharedData.pvTailPtrsKM);

	/* free region headers */	
	FreeStaticFBMem(psDevInfo, ps3DCtl->apvRgnHeadersKM[0]);	
	FreeStaticFBMem(psDevInfo, ps3DCtl->apvRgnHeadersKM[1]);	

	HostFreeMem(PVRSRV_HOST_NON_PAGEABLE_HEAP, ps3DCtl->psCSInfoMemKM);	

	/* Remove entry from linked list. */
	if (psPrev)
	{
		psPrev->psNext = ps3DCtl->psNext;
	}
	else
	{
		psParamBuffer->ps3DCtlList = ps3DCtl->psNext;
	}

	/* Free host memory. */
	HostFreeMem(PVRSRV_HOST_NON_PAGEABLE_HEAP, ps3DCtl);	
	HostFreeMem(PVRSRV_HOST_NON_PAGEABLE_HEAP, psInfo);	

	return PVRSRV_OK;
}


/*!
******************************************************************************

 @Function	PVRSRVAddRenderTarget
 
 @Description 
 
 Adds a render target to the parameter buffer. Creates region headers and tail
 pointers appropriate to the render target size.
 
 @Input    psDevData : 

 @Input    ui32Width: In pixels.

 @Input    ui32Height:  In pixels.

 @Input    ui32Flags:  Anti aliasing flags

 @Output   *ppsTARenderInfo: 

 @Return   PVRSRV_ERROR  : 

******************************************************************************/
IMG_EXPORT PVRSRV_ERROR PVRSRVAddRenderTarget (PVRSRV_DEV_DATA *psDevData, IMG_UINT32 ui32Width, 
							   IMG_UINT32 ui32Height, IMG_UINT32 ui32AAFlags, PVRSRV_TARENDERINFO **ppsTARenderInfo)
{
	PVRSRV_ERROR eError = PVRSRV_OK;
	PVRSRV_DEV_INFO *psDevInfo = psDevData->psDevInfoKM;
	PVR3DIF_PARAMBUFFER *psParamBuff = (PVR3DIF_PARAMBUFFER *)psDevInfo->sDeviceSpecific.s3D.hParamBuffer;
	PVR3DIF_3DCTL *ps3DCtl;

	if(ui32AAFlags & PVRSRV_ADDRENDERTARGET_AAX)
		ui32Width <<= 1;

	if(ui32AAFlags & PVRSRV_ADDRENDERTARGET_AAY)
		ui32Height <<= 1;

	/* OK, alloc mem for Host side structures... */
	if(HostAllocMem( PVRSRV_HOST_NON_PAGEABLE_HEAP, 
					 sizeof(PVRSRV_TARENDERINFO), 
					 (IMG_VOID **)ppsTARenderInfo, 0) != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR,"ERROR - Failed to alloc host mem for UM TA RenderInfo !"));
		return PVRSRV_ERROR_OUT_OF_MEMORY;
	}
	/* setup kernel pointer (overwritten by glue in a bridged system) */
	(*ppsTARenderInfo)->psTARenderInfoKM = *ppsTARenderInfo;

	if(HostAllocMem( PVRSRV_HOST_NON_PAGEABLE_HEAP, 
					 sizeof(PVR3DIF_3DCTL), 
					 (IMG_VOID **)&ps3DCtl,  0) != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR,"ERROR - Failed to alloc host mem for 3D Control structure !"));
		eError = PVRSRV_ERROR_OUT_OF_MEMORY;
	}
	else
	{
		/* zero structure */
		HostMemSet(ps3DCtl, 0, sizeof(PVR3DIF_3DCTL));

		ps3DCtl->sSharedData.ui32UniqueID   = 0;
		ps3DCtl->sSharedData.ui32AAFlags = ui32AAFlags;

		/*
			We are given pixel dimensions of the render target

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -