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