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

📄 mbx.c

📁 Lido PXA270平台开发板的最新BSP,包括源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
			We must round to the appropriate number of tiles
			and (if req'd) to nearest MT:
			MBX - nearest Macrotile
			MBXLite - nearest even tile
		*/
		eError = CalcTileDimensions(psDevInfo, 
									ps3DCtl, 
									ui32Width, 
									ui32Height);

		if(eError == PVRSRV_OK)
		{
			eError = Setup3DCtl(psDevInfo, psParamBuff, ps3DCtl, ui32AAFlags);
	
			if (eError == PVRSRV_OK)
			{
				/* Generate Unique ID from kernel address of structure */
				ps3DCtl->sSharedData.ui32UniqueID = (IMG_UINT32)ps3DCtl;
	
				/* Add to linked list of TARender infos. */
				ps3DCtl->psNext   = psParamBuff->ps3DCtlList;
				psParamBuff->ps3DCtlList = ps3DCtl;
	
				(*ppsTARenderInfo)->psSharedData =  &ps3DCtl->sSharedData;
				
				/* and setup tailptrs for user */
				(*ppsTARenderInfo)->pvTailPtrs = ps3DCtl->sSharedData.pvTailPtrsKM;

				/* Require resource manager to track resource */
				ps3DCtl->psResItem = ResManRegisterRes(( PRESMAN_ITEM)IMG_NULL, 
									                    RESMAN_TYPE_RENDERTARGET,
									                    psDevInfo, 
														(IMG_UINT32)*ppsTARenderInfo,
														RemoveRenderTargetCallBack, 
														RESMAN_AUTOFREE_LEV1);
				if (ps3DCtl->psResItem == IMG_NULL)
				{
					PVR_DPF((PVR_DBG_ERROR,"PVRSRVAddRenderTarget: Failed to register resource"));
					eError = PVRSRV_ERROR_GENERIC;
				}
			}
		}
	}

	return(eError);
}

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

 @Function	PVRSRVRemoveRenderTarget
 
 @Description 
 
 Removes a render target from the parameter buffer. Frees region headers and tail
 pointers.
 
 @Input    psDevData : 

 @Input    psInfo: 

 @Return   PVRSRV_ERROR  : 

******************************************************************************/
IMG_EXPORT PVRSRV_ERROR PVRSRVRemoveRenderTarget (PVRSRV_DEV_DATA *psDevData, PVRSRV_TARENDERINFO *psInfo)
{
	PVRSRV_ERROR 	eError;
	PVR3DIF_3DCTL	*ps3DCtl;
	
	ps3DCtl = (PVR3DIF_3DCTL *)psInfo->psSharedData;

	if(ps3DCtl->psResItem)
	{
		eError = ResManFreeResByPtr(ps3DCtl->psResItem);
	}
	else
	{	
		/* Resource not managed call the free callback directly */
		eError = RemoveRenderTargetCallBack(0,(IMG_PVOID)psDevData->psDevInfoKM, (IMG_UINT32)psInfo);
	}

	return(eError);	
}



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

 @Function	SetupHWRegs
 
 @Description 
 	Setup registers for event manager
  
 @Input    psDevInfo - devinfo
 @Input    ui32Offset - Offset from start of PB that EVM will manage
 
 @Return   none

******************************************************************************/
static IMG_VOID SetupHWRegs(PVRSRV_DEV_INFO *psDevInfo, IMG_UINT32 ui32Offset)
{
	PVR3DIF_PARAMBUFFER		*psParamBuffer = (PVR3DIF_PARAMBUFFER *)psDevInfo->sDeviceSpecific.s3D.hParamBuffer;
	IMG_PVOID				pvRegsBase = psDevInfo->sDevLocation.pvRegsBaseKM;
	PVRSRV_HWREG			*psRegs;
	IMG_UINT32				ui32ParamBase;
	IMG_UINT32				ui32NumBlocks;
	IMG_UINT32				ui32PageTableBase;
	IMG_UINT32				ui32StartPage;
	IMG_UINT32				ui32EndPage;
	volatile IMG_UINT32		ui32IntStatus;
	IMG_UINT32				ui32Orig;
	IMG_UINT32				i;

#ifdef SUPPORT_KYRO_AS_MBX_DEVICE
    /*
        Avoid "unreferenced local variable" warning.
    */
	ui32IntStatus = 0;
#endif
 
	ui32ParamBase = psParamBuffer->ParamDevVAddr.uiAddr;
	ui32NumBlocks = psParamBuffer->ui32NumBlocks;

	/*
		Calculate the required start-page, end-page, and pagetable address (an offset
		into FB)
	*/
	ui32PageTableBase = psParamBuffer->PageTableDevVAddr.uiAddr;
	ui32StartPage	= (ui32ParamBase + ui32Offset) / MBX1_TA_EVM_PAGETBL_GRAN;
	ui32EndPage		= ui32StartPage + ui32NumBlocks - 1;

	/*
		Setup parameter management regs
	*/
	psRegs = psParamBuffer->asHWRegs;
	i = 0;

	psRegs[i].ui32RegAddr  = MBX1_TAGLOBREG_EVM_PAGETBL_BASE;
	psRegs[i++].ui32RegVal = ui32PageTableBase;
	
	psRegs[i].ui32RegAddr  = MBX1_TAGLOBREG_EVM_LIST_START;
	psRegs[i++].ui32RegVal = ui32StartPage;
	
	psRegs[i].ui32RegAddr  = MBX1_TAGLOBREG_EVM_LIST_END;
	psRegs[i++].ui32RegVal = ui32EndPage;
	
	psRegs[i].ui32RegAddr  = MBX1_TAGLOBREG_EVM_INIT;
	psRegs[i++].ui32RegVal = 1;

	psRegs[i].ui32RegAddr  = MBX1_TAGLOBREG_OBJDATABASE;
	psRegs[i++].ui32RegVal = ui32ParamBase;

	psRegs[i].ui32RegAddr  = MBX1_GLOBREG_3D_ZL_BACKGROUND_TAG;
	psRegs[i++].ui32RegVal = MBX1_3DZLBG_TAG_OBJ_TEXTURED | 
							(8 << MBX1_3DZLBG_TAG_OBJ_MASK_SHIFT) |	  /* 8 is a Magic number from the programming guide */
							0;							/* 0 offset from Object base address - BGObj is at bottom of PB */
	/* save reg count */
	psParamBuffer->ui32HWRegCount = i;

	PVR_DPF((PVR_DBG_ERROR,"ui32PageTableBase = %x",ui32PageTableBase));
	PVR_DPF((PVR_DBG_ERROR,"ui32StartPage = %x",ui32StartPage));
	PVR_DPF((PVR_DBG_ERROR,"ui32EndPage = %x",ui32EndPage));
	PVR_DPF((PVR_DBG_ERROR,"ui32ParamBase = %x",ui32ParamBase));

	/*
		Initialise the EVM free-page list

		0) Enable 3D core
	    1) Disable EVM_DALLOC interrupt
		2) Write the required start, end and base address for the page-list
		3) Write to EVM_INIT
		4) Wait for EVM_DALLOC bit in the interrupt status word
		5) Reset the EVM_DALLOC interrupt
		6) Re-enable EVM_DALLOC interrupts
		7) Disable 3D core
	*/

	SysClearDeviceInterrupts(psDevInfo, pvRegsBase, MBX1_INT_EVM_DALLOC);
	PDUMPREG (IMG_NULL, PDUMPTAGS_REG_MBX, MBX1_GLOBREG_INT_CLEAR, MBX1_INT_EVM_DALLOC);

	/* Disable EVM_DALLOC interrupts */
	ui32Orig = SysDisableDeviceInterrupts(psDevInfo, pvRegsBase, MBX1_INT_EVM_DALLOC);

	/* write regs */
	WriteHWRegs(pvRegsBase, psParamBuffer->ui32HWRegCount, psRegs);
	PDUMPREGARRAY (IMG_NULL, PDUMPTAGS_REG_MBX, psRegs, psParamBuffer->ui32HWRegCount);		

#ifdef SUPPORT_KYRO_AS_MBX_DEVICE
	/* inform the 3dsim EVM init has started */
	REGWRITE3DSIM(MBX1_TAGLOBREG_EVM_INIT,1);
#endif

	/* Wait for EVM_DALLOC bit in the interrupt status word */
	do
	{
		ui32IntStatus = SysDecodeDeviceInterrupts(psDevInfo, pvRegsBase);
	} while ((ui32IntStatus & MBX1_INT_EVM_DALLOC) == 0);
	
	/* Reset the EVM_DALLOC interrupt */
	SysClearDeviceInterrupts(psDevInfo, pvRegsBase, MBX1_INT_EVM_DALLOC);
	PDUMPREG (IMG_NULL, PDUMPTAGS_REG_MBX, MBX1_GLOBREG_INT_CLEAR, MBX1_INT_EVM_DALLOC);

#ifdef SUPPORT_KYRO_AS_MBX_DEVICE
	/* inform the 3dsim Int's have been cleared */
	REGWRITE3DSIM(MBX1_GLOBREG_INT_CLEAR,MBX1_INT_EVM_DALLOC);
#endif


	/* Re-enable EVM_DALLOC interrupts */
	SysEnableDeviceInterrupts(psDevInfo, pvRegsBase, ui32Orig);
}


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

 @Function	BitInterleaveBA
 
 @Description 
 	Performs a bitwise Interleave of two 16-bit values A and B to
	form a 32-bit result, with the LSB of A forming the LSB of
	the result.
  
 @Input    wA		- 16-bit word to merge
 @Input    wB		- 16-bit word to merge
 
 @Return   result

******************************************************************************/
IMG_UINT32 BitInterleaveBA(IMG_UINT16 ui16Val1, IMG_UINT16 ui16Val2)
{
	IMG_UINT32	ui32Result;
	IMG_UINT32	ui32A, ui32B;
	IMG_UINT32	j;
	IMG_UINT32	i;
	
	ui32Result = 0;
	ui32A = (IMG_UINT32)ui16Val1;
	ui32B = (IMG_UINT32)ui16Val2;

	for	(i = 0x1, j = 0; i < 0x10000; i <<= 1)
	{
		ui32Result |= (ui32A & i) << j;
		j++;
		ui32Result |= (ui32B & i) << j;
	}

	return ui32Result;
}


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

 @Function	CalcMacrotileTileSize
 
 @Description 
		Calculates the appropriate macrotile dimension (in tiles)
		from a screen dimension (in tiles)
  
 @Input    number of tiles in given dimension
 
 @Return   number of tiles in given MT dimension

******************************************************************************/
static IMG_UINT32 CalcMacrotileTileSize(IMG_UINT32 ui32TileSize)
{
	IMG_UINT32	ui32MTTileSize;
	/*
		Pixels:
		-------
		Screen Size		Macrotile Size
		   <= 512			 64	
		   <= 1024			 128
		   <= 2048			 256
		Tiles:
		-------
		Screen Size		Macrotile Size
		   <= 512			 64	
		   <= 1024			 128
		   <= 2048			 256
	*/

	if (ui32TileSize <= MBX_MT_TILE_THRESHOLD_0)
	{
		ui32MTTileSize = MBX_MT_TILE_SIZE_0;
	}
	else if	(ui32TileSize <= MBX_MT_TILE_THRESHOLD_1)
	{
		ui32MTTileSize = MBX_MT_TILE_SIZE_1;
	}
	else if	(ui32TileSize <= MBX_MT_TILE_THRESHOLD_2)
	{
		ui32MTTileSize = MBX_MT_TILE_SIZE_2;
	}	
	else
	{
		PVR_DPF((PVR_DBG_ERROR,"CalcMacrotileTileSize: render target size too big"));
		ui32MTTileSize = 0;
	}

	return ui32MTTileSize;
}


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

 @Function	Setup3DCtl
 
 @Description 
		sets up 3d PB details
  
 @Input    psDevInfo
 @Input    psParamBuff
 @Input    ps3DCtl
 @Input    ui32AAFlags
 
 @Return   PVRSRV_ERROR

******************************************************************************/
static PVRSRV_ERROR Setup3DCtl(	PVRSRV_DEV_INFO *psDevInfo, 
								PVR3DIF_PARAMBUFFER *psParamBuff,
								PVR3DIF_3DCTL *ps3DCtl,
								IMG_UINT32 ui32AAFlags)
{
	IMG_UINT32	ui32TotalRegions;
	IMG_UINT32	ui32TotalTails;
	IMG_UINT32	ui32TotalTails1;
	IMG_UINT32	ui32TotalTails2;
	IMG_UINT32	ui32NumTilesX;
	IMG_UINT32	ui32NumTilesY;
	IMG_UINT32	ui32TailSize;
	IMG_VOID	*pvTailsLin;
	IMG_VOID	*pvContextLin;
	IMG_DEV_VIRTADDR TailPointerDevVAddr;
	IMG_DEV_VIRTADDR ContextDevVAddr;
	PVRSRV_ERROR eError = PVRSRV_ERROR_OUT_OF_MEMORY;
	IMG_UINT32	i, ui32AllocSize;

	/*
		Tile dimensions, as calc'ed by CalcTileDimensions
	*/
	ui32NumTilesX = ps3DCtl->sSharedData.ui32MTilesX * ps3DCtl->sSharedData.ui32XTilesPerMT;
	ui32NumTilesY = ps3DCtl->sSharedData.ui32MTilesY * ps3DCtl->sSharedData.ui32YTilesPerMT;

	/*
	 *	Allocate Complex Scene Information structs per MT
	 */
	ui32AllocSize = ps3DCtl->sSharedData.ui32MTilesX * ps3DCtl->sSharedData.ui32MTilesY * sizeof(PVR_CS_INFO);
	
	if(HostAllocMem( PVRSRV_HOST_NON_PAGEABLE_HEAP, 
					 ui32AllocSize, 
					 (IMG_VOID **)&ps3DCtl->psCSInfoMemKM,  0) != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR,"Unable to allocate psCSInfoMemKM"));
		goto ErrorExit;
	}
	HostMemSet((IMG_VOID *)ps3DCtl->psCSInfoMemKM, 0, ui32AllocSize);

	/* 
		Allocate tail-pointer space required

		NB:	Tail-pointer addressing is twiddled on MBX - the tail 
			pointer address is generated by interleaving the bits from
			a tile's X and Y tile-position (LSB = X-LSB). The largest
			possible tail-pointer address if therefore the bit-interleaved
			X and Y render-target tile dimensions.

			Additionally, the tail pointer data is accessed in blocks of
			8 DWORDs, so we must round-up the overall space to a multiple
			of this, to avoid the TA writing off the end of our tail-
			pointer data.
	*/
	ui32TotalTails1 = BitInterleaveBA((IMG_UINT16)ui32NumTilesX, (IMG_UINT16)ui32NumTilesY);
	ui32TotalTails2 = BitInterleaveBA((IMG_UINT16)ui32NumTilesY, (IMG_UINT16)ui32NumTilesX);
	
	if	(ui32TotalTails1 > ui32TotalTails2)
	{
		ui32TotalTails = ui32TotalTails1;
	}
	else
	{
		ui32TotalTails = ui32TotalTails2;
	}

	/*
		Calculate the space to allocate - each tail-pointer is 1 IMG_UINT32,
		and we must round the size up to a multiple of 8 DWORDs.

		NB:	Only 1 set of tail-pointer data is required, as the data 
			is only used by the TA (i.e. no simultaneous TA and 3D-core
			access)
	*/
	ui32TailSize = ui32TotalTails * sizeof(IMG_UINT32);
	ui32TailSize += 8*sizeof(IMG_UINT32) - 1;
	ui32TailSize &= ~(8*sizeof(IMG_UINT32) - 1);

	/* 
		Allocate memory for tail-pointers
		NB:	Only 1 set of tail-pointer data is required, as the data 
			is only used by the TA (i.e. no simultaneous TA and 3D-core
			access)
	*/
	eError = AllocStaticFBMem(	psDevInfo,
								0,
								ui32TailSize,
								MBX1_ADDRGRAN_TAILPTR,
								&pvTailsLin,
								&TailPointerDevVAddr);
								
	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR,"ERROR - Failed to alloc FB mem	 for TA/Render size related data !"));
		goto ErrorExit;
	}

	/* and be sure to initialise them */
	HostMemSet(pvTailsLin, 0, ui32TailSize);

	ps3DCtl->sSharedData.pvTailPtrsKM	 = pvTailsLin;
	ps3DCtl->sSharedData.TailPtrDevVAddr = TailPointerDevVAddr;
	ps3DCtl->sSharedData.ui32TailPtrSize = ui32TailSize;


	/*
		Allocate region-header space required
	*/
	ui32TotalRegions = ui32NumTilesX * ui32NumTilesY;

#if defined(FIX_HW_PRN_223) || defined(FIX_HW_PRN_251)	
	/* n.b. extra RH req'd to fix CS HW bug */
	ui32TotalRegions++;
#endif
	
	/*
		calculate what we can for the background object (U and V)
	*/
	CalcHWBGO3DCtl(&psDevInfo->sDeviceSpecific.s3D, ps3DCtl, ui32AAFlags);

	/*
		Allocate space to save and restore the TA and EVM context data

		We save data per macrotile with a maximum of 65 MTs inc. the global list
		TA saves 1 IMG_UINT32/MT -> 260bytes
		EVM saves 2 IMG_UINT32/MT -> 520bytes		
	*/

	eError = AllocStaticFBMem(	psDevInfo,
								0,
								MBX1_TACONTEXT_SIZE,
								MBX1_ADDRGRAN_TACONTEXT,
								&pvConte

⌨️ 快捷键说明

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