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

📄 resources.c

📁 Lido PXA270平台开发板的最新BSP,包括源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/*!****************************************************************************
@File			resources.c

@Title			3D Scene management functions

@Author			Imagination Technologies

@date   		05/09/2003
 
@Copyright     	Copyright 2003-2004 by Imagination Technologies Limited.
                All rights reserved. No part of this software, either
                material or conceptual may be copied or distributed,
                transmitted, transcribed, stored in a retrieval system
                or translated into any human or computer language in any
                form by any means, electronic, mechanical, manual or
                other-wise, or disclosed to third parties without the
                express written permission of Imagination Technologies
                Limited, Unit 8, HomePark Industrial Estate,
                King's Langley, Hertfordshire, WD4 8LZ, U.K.

@Platform		generic

@Description	3D Scene management functions

@DoxygenVer		

******************************************************************************/

/******************************************************************************
Modifications :-

$Log: resources.c $
*****************************************************************************/

#include "img_defs.h"
#include "services.h"
#include "syscommon.h"
#include "pvr3dif.h"
#include "mbx13ddef.h"
#include "mbx12ddef.h"
#include "mbx1defs.h"
#include "pvr_debug.h"
#if defined(PVR_KERNEL)
#include "hostfunc.h"
#else
#include "hostfunc_um.h"
#endif
#include "sharedutils.h"
#include <stdlib.h>

#define HWCONTEXTID_ZERO	0
#define HWCONTEXTID_ONE		1
#define HWCONTEXTID_BUSY	1
#define HWCONTEXTID_FREE	0

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

 @Function	StopTA
 
 @Description 
 
 USER MODE FUNCTION
 Stops the TA synchronously. Called from PVRSRVAcquireTA()
  
 @Input    psDevInfo 			 : UM devinfo 
 
 @Input    psHWInfo 			 : HW Info structure

 @Input    bIgnoreStreamError 	 : Recovery from stream error - ignore when acquiring FIFO space
  
 @Input    bCompleteOnTerminate  : Set complete on terminate (for discarded scenes)

 @Return   PVRSRV_ERROR 

******************************************************************************/
static PVRSRV_ERROR StopTA (PVRSRV_DEV_INFO *psDevInfo, 
										 PVRSRV_HW_INFO *psHWInfo,
										 IMG_BOOL bIgnoreStreamError,
										 IMG_BOOL bCompleteOnTerminate,
										 PVRSRV_TARENDERINFO *psTARenderInfo)
{
	DEVICE3D *ps3D = &psDevInfo->sDeviceSpecific.s3D;
	PVRSRV_ERROR eError = PVRSRV_OK;
	IMG_UINT32 ui32TAConfig;
	
	/* wait for enough space to write the terminate */
	eError = PVRSRVAcquire3DFifoSpaceBlock (psDevInfo,
											psHWInfo,
											4);
	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR, "StopTA: Failed to acquire FIFO space"));
		goto ErrorExit;
	}								

	/* signal to ISR TAStopMode is ON */
	ps3D->bTAStopMode = IMG_TRUE;
	
	/*
		 TAconfig is r/m/w from many threads so we need acquire/release access API
	 	otherwise complex scene code will screw things up
	*/
	eError = HostLockResource(&ps3D->hTAConfigResource, IMG_TRUE);
	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR, "StopTA: Failed to acquire TAConfig access"));
		goto ErrorExit;
	}

	ui32TAConfig = ReadHWReg (psHWInfo->pvRegsBase, MBX1_TAGLOBREG_CONFIG);

	if(bCompleteOnTerminate)
	{
		WriteHWReg ( psHWInfo->pvRegsBase, MBX1_TAGLOBREG_CONFIG, ui32TAConfig | MBX1_TACONFIG_COMPLETEONTERM );
		PDUMPREG(psTARenderInfo->psPDContext,	PDUMPTAGS_REG_MBX, MBX1_TAGLOBREG_CONFIG, ui32TAConfig | MBX1_TACONFIG_COMPLETEONTERM);

	}
	else
	{
		WriteHWReg ( psHWInfo->pvRegsBase, MBX1_TAGLOBREG_CONFIG, ui32TAConfig & ~MBX1_TACONFIG_COMPLETEONTERM );
		PDUMPREG(psTARenderInfo->psPDContext,	PDUMPTAGS_REG_MBX, MBX1_TAGLOBREG_CONFIG, ui32TAConfig & ~MBX1_TACONFIG_COMPLETEONTERM);
	}

	
	/* write the terminate to the TA */
	PVRSRVWriteSlavePort (&psHWInfo->sDeviceSpecific.sMBX.sTASlavePort, MBX1_TAOBJTYPE_STREAMEND);
	PDUMPSP(psTARenderInfo->psPDContext, PDUMPTAGS_SP_MBX_DATA, MBX1_TAOBJTYPE_STREAMEND);	

	if(PollForValue ((volatile IMG_UINT32 *)&ps3D->bTAIdle,
							IMG_TRUE,
							0xFFFFFFFF,
							MAX_HW_TIME_US/WAIT_TRY_COUNT, 
							WAIT_TRY_COUNT) != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR, "StopTA: Failed to stop TA"));
		eError = PVRSRV_ERROR_TIMEOUT;
	}
	
	PDUMPPOL(psTARenderInfo->psPDContext, PDUMPTAGS_REG_MBX, MBX1_TAGLOBREG_INTSTATUS, MBX1_INT_TA_COMPLETE, MBX1_INT_TA_COMPLETE, 0, 10, 10000);
	PDUMPREG(psTARenderInfo->psPDContext,	PDUMPTAGS_REG_MBX, MBX1_GLOBREG_INT_CLEAR, MBX1_INT_TA_COMPLETE);
	
	/* signal to ISR TAStopMode is OFF */
	ps3D->bTAStopMode = IMG_FALSE;

	/* recover TAConfig */
	WriteHWReg ( psHWInfo->pvRegsBase, MBX1_TAGLOBREG_CONFIG, ui32TAConfig);
	PDUMPREG(psTARenderInfo->psPDContext,	PDUMPTAGS_REG_MBX, MBX1_TAGLOBREG_CONFIG, ui32TAConfig);

	
	eError = HostUnlockResource(&ps3D->hTAConfigResource);	
	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR, "StopTA: Failed to release TAConfig access"));
	}

ErrorExit:

	/*! @todo Check if this is correct/nice */
	/* reset the reserve */
	ps3D->ui32BytesReservedTA = 0;
	
	return eError;
}



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

 @Function	GetFreeHWContextID
 
 @Description 
 
 USER MODE FUNCTION
 returns a free context id. Called from ResetContext() and LoadContext()
  
 @Input    psDevInfo 			 : UM devinfo 
 
 @Return   a free id

******************************************************************************/

PVRSRV_ERROR GetFreeHWContextID (PVRSRV_DEV_INFO *psDevInfo, 
								   PVRSRV_HW_INFO *psHWInfo, 
								   IMG_UINT32 *puiRetID)
{
	DEVICE3D *ps3D = &psDevInfo->sDeviceSpecific.s3D;
	volatile IMG_UINT32 *pui32ContextIDState = ps3D->aui32HWContextIDState;
	IMG_UINT32 ui32ID = 0;
	IMG_BOOL bTimeout;
	IMG_BOOL bStart;
	IMG_UINT32 uiStart;

	/* 
		need to think about what to do here
		- we're less constrained if we assume there's just a driver thread and 
		a set of ISRs
		- do we even need eHWCONTEXTID lock - does the TA lock handle this
	*/
	bTimeout = IMG_TRUE;
	bStart = IMG_FALSE;
	uiStart = 0;
    do
	{
		/*
			atomic? no, if calling code protected by acquireTA() 
			Currently, ResetContext() and LoadContext(), the only functions 
			to call this code are both within acquireTA (post mutex acquire)
			- so OK?
		*/

		/* id == 0 */
		if (pui32ContextIDState[HWCONTEXTID_ZERO] == HWCONTEXTID_FREE)
		{
			pui32ContextIDState[HWCONTEXTID_ZERO] = HWCONTEXTID_BUSY;
			ui32ID = HWCONTEXTID_ZERO;
			bTimeout = IMG_FALSE;
			/* disable render to investigate performance */
			#if defined(DISABLE_HARDWARE_RENDER)
			pui32ContextIDState[HWCONTEXTID_ZERO] = HWCONTEXTID_FREE;
			#endif
			break;
		}
		/* id == 1 */
		if (pui32ContextIDState[HWCONTEXTID_ONE] == HWCONTEXTID_FREE)
		{
			pui32ContextIDState[HWCONTEXTID_ONE] = HWCONTEXTID_BUSY;
			ui32ID = HWCONTEXTID_ONE;
			bTimeout = IMG_FALSE;
			/* disable render to investigate performance */
			#if defined(DISABLE_HARDWARE_RENDER)
			pui32ContextIDState[HWCONTEXTID_ONE] = HWCONTEXTID_FREE;
			#endif
			break;
		}

		/* 
			@todo FIXME: need a timeout test fed back be 3DHW device code.
		 */

		/* If the 3D is already in progress, no need to kick the ISR */
		if(ps3D->b3DIdle && ps3D->b2DIdle)
		{
			SysKickCmdProc (psHWInfo->pui32KickerAddr);
		}

		/* We may relinquish if more than one 3D app is running */
		if(ps3D->ui32ParamBufferRefCount > 1)
		{
			HostReleaseThreadQuanta();
		}
		
		if (bStart == IMG_FALSE)
		{
			bStart = IMG_TRUE;
			uiStart = HostClockus();
		}
		HostWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT);
    } while ((HostClockus() - uiStart) < MAX_HW_TIME_US);

	if (bTimeout == IMG_TRUE)
	{
		PVR_DPF((PVR_DBG_ERROR, "GetFreeHWContextID: failed to get free hw context id"));
		return PVRSRV_ERROR_GENERIC;
	}
	
	/* write back ID */ 
	*puiRetID = ui32ID;

	return PVRSRV_OK;
}



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

 @Function	StoreContext
 
 @Description 
 
 USER MODE FUNCTION
 Stores a HW context. Called from PVRSRVAcquireTA().
  
 @Input    psDevInfo 			 : UM devinfo 
 
 @Input    psHWInfo 			 : HW Info structure

 @Return   PVRSRV_ERROR 

******************************************************************************/
static PVRSRV_ERROR IMG_CALLCONV StoreContext (PVRSRV_DEV_INFO		*psDevInfo, 
											   PVRSRV_HW_INFO		*psHWInfo,
											   PVRSRV_TARENDERINFO	*psTARenderInfo)
{
	DEVICE3D 				*ps3D = &psDevInfo->sDeviceSpecific.s3D;	
	PVRSRV_ERROR 			eError = PVRSRV_OK;
	PVRSRV_HWREG			psRegs[3];
	PPVRSRV_3DSHAREDDATA	psCurrentTargetSharedData = ps3D->psCurrentTARenderInfoUM->psSharedData;
	
	/*
		Set the context-base address and write to the context-store register
		to kick-off the store
	*/

	psRegs[0].ui32RegAddr = MBX1_TAGLOBREG_EVM_CONTEXT_FLUSH_ADDR;
	psRegs[0].ui32RegVal  = ps3D->LastEVMContextDevVAddr.uiAddr
						& MBX1_CONTEXT_FLUSH_BASE_ADDR_MASK;

	psRegs[1].ui32RegAddr = MBX1_TAGLOBREG_CONTEXT_BASE;
	psRegs[1].ui32RegVal  = ps3D->LastTAContextDevVAddr.uiAddr
						& MBX1_TA_CONTEXT_BASE_MASK;

	psRegs[2].ui32RegAddr = MBX1_TAGLOBREG_CONTEXT_STORE;
	psRegs[2].ui32RegVal  = 1;

	PDUMPREG(psTARenderInfo->psPDContext, PDUMPTAGS_REG_MBX, MBX1_GLOBREG_INT_CLEAR, MBX1_INT_TA_CONTEXT);		

	WriteHWRegs(psHWInfo->pvRegsBase, 3, psRegs);
	PDUMPREGARRAY(psTARenderInfo->psPDContext, PDUMPTAGS_REG_MBX, psRegs, 3);		

	/* Wait for the TA to finish storing the HW-context */
	if(PollForValue ((volatile IMG_UINT32 *)&ps3D->bTAContextInterrupt,
							IMG_TRUE,
							0xFFFFFFFF,
							MAX_HW_TIME_US/WAIT_TRY_COUNT, 
							WAIT_TRY_COUNT) != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR, "StoreContext: Failed to store"));
		eError = PVRSRV_ERROR_TIMEOUT;
	}

	/* reset bTAContextInterrupt boolean */
	ps3D->bTAContextInterrupt = IMG_FALSE;
	
	PDUMPPOL(psTARenderInfo->psPDContext, PDUMPTAGS_REG_MBX, MBX1_TAGLOBREG_INTSTATUS, MBX1_INT_TA_CONTEXT, MBX1_INT_TA_CONTEXT, 0, 10, 1000);
	PDUMPREG(psTARenderInfo->psPDContext, PDUMPTAGS_REG_MBX, MBX1_GLOBREG_INT_CLEAR, MBX1_INT_TA_CONTEXT);
	
	/* free the current hw context id*/
	FreeHWContextID(psDevInfo, psCurrentTargetSharedData->aui32HWContextID[psCurrentTargetSharedData->ui32CurrentRenderData]);

	return eError;
}


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

 @Function	LoadContext
 
 @Description 
 
 USER MODE FUNCTION
 loads a HW context. Called from PVRSRVAcquireTA()
  
 @Input    psDevInfo 			 : UM devinfo 
 
 @Input    psTARenderData		 : TA and 3D render info

 @Input    psHWInfo 			 : HW Info structure

 @Return   PVRSRV_ERROR

******************************************************************************/
static PVRSRV_ERROR IMG_CALLCONV LoadContext (PVRSRV_DEV_INFO		*psDevInfo, 
											  PVRSRV_TARENDERINFO	*psTARenderInfo,
											  PVRSRV_HW_INFO		*psHWInfo)
{
	DEVICE3D			*ps3D = &psDevInfo->sDeviceSpecific.s3D;	
	PVR3DIF_SHAREDDATA	*psSharedData = psTARenderInfo->psSharedData;
	PVRSRV_ERROR 		eError = PVRSRV_OK;
	PVRSRV_HWREG		sRegs[4];
	IMG_UINT32			ui32HWContextID;

	eError = GetFreeHWContextID(psDevInfo, psHWInfo, &ui32HWContextID);
	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR, "LoadContext: Failed to get free HW context ID"));
		return eError;
	}

	/* 
		store off record of what HWContextID we're using 
	*/
	psSharedData->aui32HWContextID[psSharedData->ui32CurrentRenderData] = ui32HWContextID;

	/*
		Set the context-base address and write to the context-store register
		to kick-off the store
	*/
	sRegs[0].ui32RegAddr = MBX1_TAGLOBREG_EVM_CONTEXT_FLUSH_ADDR;
	sRegs[0].ui32RegVal  = psSharedData->EVMContextDevVAddr.uiAddr
							& MBX1_CONTEXT_FLUSH_BASE_ADDR_MASK;

	sRegs[1].ui32RegAddr = MBX1_TAGLOBREG_CONTEXT_BASE;
	sRegs[1].ui32RegVal  = psSharedData->TAContextDevVAddr.uiAddr
							& MBX1_TA_CONTEXT_BASE_MASK;

	sRegs[2].ui32RegAddr = MBX1_TAGLOBREG_RENDER_ID;
	sRegs[2].ui32RegVal  = ui32HWContextID;
					
	sRegs[3].ui32RegAddr = MBX1_TAGLOBREG_CONTEXT_LOAD;
	sRegs[3].ui32RegVal  = 1;

	PDUMPREG(psTARenderInfo->psPDContext, PDUMPTAGS_REG_MBX, MBX1_GLOBREG_INT_CLEAR, MBX1_INT_TA_CONTEXT);		

	WriteHWRegs(psHWInfo->pvRegsBase, 4, sRegs);
	PDUMPREGARRAY(psTARenderInfo->psPDContext, PDUMPTAGS_REG_MBX, sRegs, 4);		

	/* Wait for the TA to finish loading the HW-context */
	if(PollForValue ((volatile IMG_UINT32 *)&ps3D->bTAContextInterrupt,
							IMG_TRUE,
							0xFFFFFFFF,
							MAX_HW_TIME_US/WAIT_TRY_COUNT, 
							WAIT_TRY_COUNT) != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR, "LoadContext: Failed to load"));
		eError = PVRSRV_ERROR_TIMEOUT;
	}

	/* reset bTAContextInterrupt boolean */
	ps3D->bTAContextInterrupt = IMG_FALSE;

	PDUMPPOL(psTARenderInfo->psPDContext, PDUMPTAGS_REG_MBX, MBX1_TAGLOBREG_INTSTATUS, MBX1_INT_TA_CONTEXT, MBX1_INT_TA_CONTEXT, 0, 10, 1000);
	PDUMPREG(psTARenderInfo->psPDContext, PDUMPTAGS_REG_MBX, MBX1_GLOBREG_INT_CLEAR, MBX1_INT_TA_CONTEXT);
	
	return eError;
}

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

 @Function	ResetContext
 
 @Description 
 
 USER MODE FUNCTION
 Resets a HW context. Called from PVRSRVAcquireTA()
  
 @Input    psDevInfo 			 : UM devinfo 
 
 @Input    psTARenderData		 : TA and 3D render info

 @Input    psHWInfo 			 : HW Info structure

 @Return   PVRSRV_ERROR

******************************************************************************/

⌨️ 快捷键说明

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