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

📄 complexscene.c

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

@Title			complex scene handling

@Author			Imagination Technologies

@date   		3 / 11 / 03
 
@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		MBX generic

@Description	complex scene handling code

@DoxygenVer		

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

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

$Log: complexscene.c $
*****************************************************************************/

#include "services_headers.h"
#include "mbx.h"
#include "mbx13ddef.h"
#include "mbx1defs.h"

typedef IMG_UINT32 MBX1_TA_TAILPTR;

#if defined(FIX_HW_PRN_264_MBXLITE)

IMG_VOID InsertOpaqueObject(DEVICE3D *ps3D, MBX1_REGION_ENTRY *psRegionHdr, 
							IMG_UINT32 ui32XTilesPerMT, IMG_UINT32 ui32YTilesPerMT)
{
	IMG_UINT32 i;
	IMG_VOID *pvParamLinBase = ((struct _PVR3DIF_PARAMBUFFER_ *)ps3D->hParamBuffer)->pvParamLinBaseKM;

	/*
		Here we append every pointer list with the special object
	*/
	for(i=0; i<ui32XTilesPerMT*ui32YTilesPerMT; i++)
	{
		if ((psRegionHdr[i].ui32Header & MBX1_RH_EMPTY_TILE) == 0)
		{
			/* find the last entry */
			IMG_DEV_VIRTADDR	PBDevAddr = ((struct _PVR3DIF_PARAMBUFFER_ *)ps3D->hParamBuffer)->ParamDevVAddr;
			IMG_UINT32			ui32ObjPtrVal;
			IMG_UINT32			ui32ObjPtrOffset = (psRegionHdr[i].ui32ListPtr & MBX1_OBJPTR_LINKADDRESS_MASK) - PBDevAddr.uiAddr;
			
			while (IMG_TRUE)
			{
				/* read back current ptr value */
				ui32ObjPtrVal = *(IMG_UINT32*)((IMG_UINT32)pvParamLinBase + ui32ObjPtrOffset);
	
				if ((ui32ObjPtrVal & MBX1_OBJPTR_LISTEND) == MBX1_OBJPTR_LISTEND)
				{
					*(IMG_UINT32*)((IMG_UINT32)pvParamLinBase + ui32ObjPtrOffset) = ps3D->ui32SpecialListPtr | MBX1_OBJPTR_LINK;
					break;
				}
				else if ((ui32ObjPtrVal & MBX1_OBJPTR_LINK) == MBX1_OBJPTR_LINK)
				{
					/* link pointer */
					ui32ObjPtrOffset =	(ui32ObjPtrVal & MBX1_OBJPTR_LINKADDRESS_MASK) - PBDevAddr.uiAddr;
				}
				else
				{
					/* advance ptr */
					ui32ObjPtrOffset += 4;
				}
			}
		}
	}	
}

#elif defined(FIX_HW_PRN_264_MBX)

IMG_VOID ContextStoreLoad(PVRSRV_DEV_INFO *psDevInfo, DEVICE3D *ps3D)
{
	IMG_UINT32 ui32Orig;
	IMG_PVOID pvRegsBase = psDevInfo->sDevLocation.pvRegsBaseKM;
	PVRSRV_HWREG	psRegs[3];
	volatile IMG_UINT32 ui32IStatus = 0;
#if defined (FIX_HW_PRN_327)
	IMG_UINT32 i=0;
#endif	
	/*
		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;


	/* Disable TA_CONTEXT interrupts */
	ui32Orig = SysDisableDeviceInterrupts(psDevInfo, pvRegsBase, MBX1_INT_TA_CONTEXT);
	SysClearDeviceInterrupts(psDevInfo, pvRegsBase, MBX1_INT_TA_CONTEXT);

	WriteHWRegs(pvRegsBase, 3, psRegs);

	/* FIXME: need to have timeout clause here */
	do
	{
		ui32IStatus = ReadHWReg(pvRegsBase, MBX1_GLOBREG_INT_STATUS);
	} while((ui32IStatus & MBX1_INT_TA_CONTEXT) == 0);

	SysClearDeviceInterrupts(psDevInfo, pvRegsBase, MBX1_INT_TA_CONTEXT);

#if defined (FIX_HW_PRN_327)
	for (i = 0; i < MBX1HW327_TA_CONTEXT_STORE_DELAY; ++i)
	{
		ui32IStatus = ReadHWReg(pvRegsBase, MBX1_GLOBREG_INT_STATUS);
	}
#endif

	psRegs[0].ui32RegAddr = MBX1_TAGLOBREG_CONTEXT_LOAD;
	psRegs[0].ui32RegVal  = 1;

	WriteHWRegs(pvRegsBase, 1, psRegs);

	/* FIXME: need to have timeout clause here */
	do
	{
		ui32IStatus = ReadHWReg(pvRegsBase, MBX1_GLOBREG_INT_STATUS);
	} while((ui32IStatus & MBX1_INT_TA_CONTEXT) == 0);

	SysClearDeviceInterrupts(psDevInfo, pvRegsBase, MBX1_INT_TA_CONTEXT);

	/* Restore interrupts */
	SysEnableDeviceInterrupts(psDevInfo, pvRegsBase, ui32Orig);
}

IMG_VOID InsertOpaqueObjectTPC(DEVICE3D *ps3D, PVR3DIF_3DCTL *ps3DCtl, 
							   IMG_UINT32 ui32TileIndexX, IMG_UINT32 ui32TileIndexY)
{
	IMG_UINT32 ui32XIndex, ui32YIndex;
	IMG_UINT32 ui32XTilesMax, ui32YTilesMax;
	IMG_UINT32 ui32TailPtrCacheOffset = 0;
	IMG_UINT32 ui32TailPointerCacheVal = 0;
	IMG_UINT32 *pui32TailPtr= IMG_NULL;
	IMG_UINT32 *pui32ObjectPointer= IMG_NULL;
	IMG_DEV_VIRTADDR sParamLinBase = ((struct _PVR3DIF_PARAMBUFFER_ *)ps3D->hParamBuffer)->ParamDevVAddr;
	IMG_VOID *pvParamLinBase = ((struct _PVR3DIF_PARAMBUFFER_ *)ps3D->hParamBuffer)->pvParamLinBaseKM;

	ui32XTilesMax = ui32TileIndexX + ps3DCtl->sSharedData.ui32XTilesPerMT;
	ui32YTilesMax = ui32TileIndexY + ps3DCtl->sSharedData.ui32YTilesPerMT;

	if(ui32XTilesMax > ps3DCtl->sSharedData.ui32TilesX)
		ui32XTilesMax = ps3DCtl->sSharedData.ui32TilesX;

	if(ui32YTilesMax > ps3DCtl->sSharedData.ui32TilesY)
		ui32YTilesMax = ps3DCtl->sSharedData.ui32TilesY;

	for (ui32YIndex = ui32TileIndexY; ui32YIndex < ui32YTilesMax; ++ui32YIndex)
	{
		for (ui32XIndex = ui32TileIndexX; ui32XIndex < ui32XTilesMax; ++ui32XIndex)
		{
			ui32TailPtrCacheOffset = BitInterleaveBA((IMG_UINT16)ui32YIndex, (IMG_UINT16)ui32XIndex) * sizeof(MBX1_TA_TAILPTR);

			pui32TailPtr = (IMG_UINT32 *) ((IMG_UINT8 *)ps3DCtl->sSharedData.pvTailPtrsKM + ui32TailPtrCacheOffset);
			
			ui32TailPointerCacheVal = *pui32TailPtr;

			if(ui32TailPointerCacheVal != 0) /* Tile is non empty */
			{
				IMG_UINT32 ui32ObjectPointerOffset = 
					((ui32TailPointerCacheVal & MBX1_TA_TAILPTR_ADDR_MASK) << 2) - sParamLinBase.uiAddr;

				pui32ObjectPointer = (IMG_UINT32 *)((IMG_UINT8 *)pvParamLinBase + ui32ObjectPointerOffset);

				if (((ui32TailPointerCacheVal & MBX1_TA_TAILPTR_FIRST_ADDRINDEX_MASK) >> MBX1_TA_TAILPTR_FIRST_ADDRINDEX_SHIFT) != 
					(ui32TailPointerCacheVal & MBX1_TA_TAILPTR_LAST_ADDRINDEX_MASK))
				{
					/* Space left in block => Insert object pointer and terminate word */
					*pui32ObjectPointer++ = ps3D->ui32SpecialObjectPointer;
					*pui32ObjectPointer++ = MBX1_OBJPTR_LISTEND;

				}
				else
				{
					*pui32ObjectPointer++ = (ps3D->ui32SpecialListPtr & MBX1_OBJPTR_LINKADDRESS_MASK) | MBX1_OBJPTR_LINK;
				}
			}
		}
	}
}

	/* Clear tail pointer cache */
	
IMG_VOID ClearTPC(DEVICE3D *ps3D, PVR3DIF_3DCTL *ps3DCtl, 
							   IMG_UINT32 ui32TileIndexX, IMG_UINT32 ui32TileIndexY)
{
	/*
	// This code exploits the fact that macrotile sizes are powers
	// of two, allowing the the least significant bits to be ignored
	// when determining whether an address lies within a macrotile.
	// The fact that the addresses are twiddled is just an extra
	// detail handled by twiddling the masks before using them on
	// the addresses.
	*/
	IMG_UINT32 ui32TailPtrCacheOffset = BitInterleaveBA((IMG_UINT16)ui32TileIndexY, (IMG_UINT16)ui32TileIndexX) * sizeof(MBX1_TA_TAILPTR);

	if(ps3DCtl->sSharedData.ui32XTilesPerMT == ps3DCtl->sSharedData.ui32YTilesPerMT)
	{
		IMG_VOID *pvTailPtr = (IMG_VOID *) ((IMG_UINT8 *)ps3DCtl->sSharedData.pvTailPtrsKM + ui32TailPtrCacheOffset);
		HostMemSet(pvTailPtr, 0, sizeof(MBX1_TA_TAILPTR) * ps3DCtl->sSharedData.ui32XTilesPerMT * ps3DCtl->sSharedData.ui32YTilesPerMT);
	}
	else
	{
		IMG_UINT32 ui32Offset;
		IMG_UINT16 ui16TileIndexXMax = (IMG_UINT16) (ui32TileIndexX + ps3DCtl->sSharedData.ui32XTilesPerMT);
		IMG_UINT16 ui16TileIndexYMax = (IMG_UINT16) (ui32TileIndexY + ps3DCtl->sSharedData.ui32YTilesPerMT);
		IMG_UINT32 ui32MaxOffset = BitInterleaveBA(ui16TileIndexYMax, ui16TileIndexXMax) * sizeof(MBX1_TA_TAILPTR);
		IMG_UINT16 ui16MTXMask = (IMG_UINT16) (~(ps3DCtl->sSharedData.ui32XTilesPerMT - 1) & 0xFFFF);
		IMG_UINT16 ui16MTYMask = (IMG_UINT16) (~(ps3DCtl->sSharedData.ui32YTilesPerMT - 1) & 0xFFFF);
		IMG_UINT32 ui32OffsetMask = BitInterleaveBA(ui16MTYMask, ui16MTXMask) * sizeof(MBX1_TA_TAILPTR); 
		IMG_UINT32 *pui32TailPtr;

		for(ui32Offset = ui32TailPtrCacheOffset; ui32Offset < ui32MaxOffset; /* */)
		{
			if((ui32Offset & ui32OffsetMask) == ui32TailPtrCacheOffset)
			{
				/* We're in the macrotile */
				pui32TailPtr = (IMG_UINT32 *) ((IMG_UINT8 *)ps3DCtl->sSharedData.pvTailPtrsKM + ui32Offset);

				*pui32TailPtr = 0;

				ui32Offset += sizeof(MBX1_TA_TAILPTR);
			}
			else
			{
				/*
				// We're outside a macrotile.  The minimum offset needed
				// to move back into the macrotile is the minimum size of
				// a (square) macrotile.
				*/
				ui32Offset += (MBX_MT_TILE_SIZE_0 * MBX_MT_TILE_SIZE_0 * sizeof(MBX1_TA_TAILPTR));
			}

		}
	}

}
#endif


#if defined(FIX_HW_PRN_223) || defined(FIX_HW_PRN_251)
/* If bIsPartialRender is set, then psRegionHdr points to the first region in the macrotile. 
	Otherwise it is ignored */
IMG_VOID AddCoveredLastTile(DEVICE3D *ps3D, PVR3DIF_3DCTL *ps3DCtl, 
							MBX1_REGION_ENTRY *psRegionHdr, IMG_BOOL bIsPartialRender)
{
	MBX1_REGION_ENTRY 	*psRH;
	
	if(bIsPartialRender)
	{
		psRH = &psRegionHdr[(ps3DCtl->sSharedData.ui32XTilesPerMT * ps3DCtl->sSharedData.ui32YTilesPerMT) - 1];
	}
	else
	{
		IMG_UINT32 ui32TotalTiles = ps3DCtl->sSharedData.ui32MTilesX * 
									ps3DCtl->sSharedData.ui32XTilesPerMT * 
									ps3DCtl->sSharedData.ui32MTilesY * 
									ps3DCtl->sSharedData.ui32YTilesPerMT;

		psRH = &psRegionHdr[ui32TotalTiles - 1];
	}

	if(psRH->ui32Header & MBX1_RH_EMPTY_TILE)
	{
		psRH->ui32Header &= ~MBX1_RH_EMPTY_TILE;
		psRH->ui32ListPtr = ps3D->ui32SpecialListPtr;

⌨️ 快捷键说明

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