📄 complexscene.c
字号:
/*!****************************************************************************
@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 + -