📄 resources.c
字号:
/* read fifo space from HW */
//FIXME: make this inline
/* disable TA to investigate performance */
#if !defined(DISABLE_HARDWARE_TA)
ui32FifoBytes = (MBX1_SP_FIFO_DWSIZE - MBX_EXTRACT_FIFO_COUNT(ReadHWReg(psHWInfo->pvRegsBase, MBX1_GLOBREG_INT_STATUS))) << 2;
#else
ui32FifoBytes = (MBX1_SP_FIFO_DWSIZE - MBX_EXTRACT_FIFO_COUNT(ReadHWReg(psHWInfo->pvRegsBase, MBX1_GLOBREG_INT_STATUS) & ~MBX1_INT_TA_FREEVCOUNT_MASK)) << 2;
#endif
/* set bytes available for 2D port */
//FIXME: should we include reserve on 3D port in case other 3DFifo functions use cached value?
//ps3D->ui32BytesFreeTAFifo = ui32FifoBytes;
if (ui32FifoBytes <= ui32ReserveBytes)
{
ui32FifoBytes = 0;
}
else
{
/* Minus the reserve */
ui32FifoBytes -= ui32ReserveBytes;
/* Clamp to maximum space available to a single port */
if (ui32FifoBytes > MBX1_SP_FIFO_MAXALLOWEDBYTES)
{
ui32FifoBytes = MBX1_SP_FIFO_MAXALLOWEDBYTES;
}
}
/* set reserve for 3D port */
ps3D->ui32BytesReservedTA = ui32FifoBytes;
/* return the bytes available to 3d port */
*pui32BytesObtained = ui32FifoBytes;
ErrorHandler:
if (HostReleaseMutex(phMutex) != PVRSRV_OK)
{
PVR_DPF((PVR_DBG_ERROR,"PVRSRVAcquire3DFifoSpace: HostReleaseMutex failed"));
}
return eError;
}
/*!
******************************************************************************
@Function PVRSRVAcquire3DFifoSpaceBlock
@Description
USER AND KERNEL MODE FUNCTION
Attempts to acquire space in the SlavePort FIFO. Called from
display driver, 3D driver and ISRs
This provides flow control for the slaveports.
On return, the number of bytes that can be written is returned in pui32BytesObtained.
@Input psDevInfo : UM devdata
@Input psHWInfo : HW Info
@Output *ui32BytesRequired : required bytes in FIFO
@Return PVRSRV_ERROR :
******************************************************************************/
IMG_EXPORT
PVRSRV_ERROR IMG_CALLCONV PVRSRVAcquire3DFifoSpaceBlock (PVRSRV_DEV_INFO *psDevInfo,
PVRSRV_HW_INFO *psHWInfo,
IMG_UINT32 ui32BytesRequired)
{
PVRSRV_ERROR eError;
DEVICE3D *ps3D = &psDevInfo->sDeviceSpecific.s3D;
PVRSRV_MUTEX_HANDLE *phMutex = &ps3D->hMutexTAFifoSpace;
volatile IMG_UINT32 *pui32ReserveBytes = &ps3D->ui32BytesReserved2d;
IMG_UINT32 ui32FifoBytes = 0;
IMG_UINT32 i;
IMG_BOOL bTimeout;
IMG_BOOL bStart;
IMG_UINT32 uiStart;
eError = HostAcquireMutex (phMutex, IMG_TRUE);
if (eError != PVRSRV_OK)
{
PVR_DPF((PVR_DBG_ERROR,"PVRSRVAcquire3DFifoSpaceBlock: failed to acquire the FIFO resource"));
return eError;
}
#ifdef DEBUG
/* check appropriate resources have previously been acquired */
if (HostIsResourceLocked(&ps3D->hTAResource) == IMG_FALSE)
{
PVR_DPF((PVR_DBG_ERROR,"PVRSRVAcquire3DFifoSpaceBlock: TA and/or TA slaveport is not locked"));
eError = PVRSRV_ERROR_GENERIC;
goto ErrorHandler; /* we need to release FIFO mutex */
}
if ((ui32BytesRequired > (MBX1_SP_FIFO_DWSIZE<<2)) /* fifo limit */
|| ((ui32BytesRequired & 0x3) != 0)) /* only request 4byte units */
{
PVR_DPF((PVR_DBG_ERROR,"PVRSRVAcquire3DFifoSpaceBlock: invalid ui32BytesRequired value"));
eError = PVRSRV_ERROR_INVALID_PARAMS;
goto ErrorHandler; /* we need to release FIFO mutex */
}
#endif
bTimeout = IMG_TRUE;
bStart = IMG_FALSE;
uiStart = 0;
i = 0;
do
{
/* read fifo space from HW */
//FIXME: make this inline
/* disable TA to investigate performance */
#if !defined(DISABLE_HARDWARE_TA)
ui32FifoBytes = (MBX1_SP_FIFO_DWSIZE - MBX_EXTRACT_FIFO_COUNT(ReadHWReg(psHWInfo->pvRegsBase, MBX1_GLOBREG_INT_STATUS))) << 2;
#else
ui32FifoBytes = (MBX1_SP_FIFO_DWSIZE - MBX_EXTRACT_FIFO_COUNT(ReadHWReg(psHWInfo->pvRegsBase, MBX1_GLOBREG_INT_STATUS) & ~MBX1_INT_TA_FREEVCOUNT_MASK)) << 2;
#endif
/* set bytes available for 2D port */
//FIXME: should we include reserve on 3D port in case other 3DFifo functions use cached value?
//ps3D->ui32BytesFreeTAFifo = ui32FifoBytes;
/* Don't even consider ending if we've less then the reserve */
if (ui32FifoBytes >= *pui32ReserveBytes)
{
/* Now subtract the reserve */
ui32FifoBytes -= *pui32ReserveBytes;
/*
Don't need to clamp to MBX1_SP_FIFO_MAXALLOWEDBYTES as we only
need to make sure we have what was requested.
*/
if (ui32FifoBytes >= ui32BytesRequired)
{
bTimeout = IMG_FALSE;
break;
}
}
/*
we have to handle thread starvation and block this thread
if we fail to acquire the lock after some number of tries
*/
if (bStart == IMG_FALSE)
{
bStart = IMG_TRUE;
uiStart = HostClockus();
}
if (i > 100)
{
/* check for stream errors after 100 passes */
if (ps3D->bTAStreamErrorInterrupt)
{
PVR_DPF((PVR_DBG_ERROR,"PVRSRVAcquire3DFifoSpaceBlock: got stream error"));
eError = PVRSRV_ERROR_STREAM_ERROR;
goto ErrorHandler; /* we need to release FIFO mutex */
}
HostWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT);
/* does another thread have space reserved? */
if(*pui32ReserveBytes > 0)
{
#if !defined(PVR_KERNEL)
HostReleaseThreadQuanta();
#endif
}
}
i++;
} while ((HostClockus() - uiStart) < MAX_HW_TIME_US);
if (bTimeout == IMG_TRUE)
{
PVR_DPF((PVR_DBG_ERROR,"PVRSRVAcquire3DFifoSpaceBlock: Failed to get space in FIFO"));
eError = PVRSRV_ERROR_GENERIC;
goto ErrorHandler; /* we need to release FIFO mutex */
}
/* set reserve for 3D port */
ps3D->ui32BytesReservedTA = ui32BytesRequired;
ErrorHandler:
if (HostReleaseMutex(phMutex) != PVRSRV_OK)
{
PVR_DPF((PVR_DBG_ERROR,"PVRSRVAcquire3DFifoSpaceBlock: HostReleaseMutex failed"));
}
return eError;
}
/*!
******************************************************************************
@Function PVRSRVAcquire2DFifoSpace
@Description
USER AND KERNEL MODE FUNCTION
Attempts to acquire space in the SlavePort FIFO. Called from
display driver, 3D driver and ISRs
This provides flow control for the slaveports.
On return, the number of bytes that can be written is returned in pui32BytesObtained.
@Input psDevInfo : UM devdata
@Input psHWInfo : HW Info
@Output *pui32BytesObtained : free bytes in FIFO
@Return PVRSRV_ERROR :
******************************************************************************/
IMG_EXPORT
PVRSRV_ERROR IMG_CALLCONV PVRSRVAcquire2DFifoSpace (PVRSRV_DEV_INFO *psDevInfo,
IMG_VOID *pvRegsBase,
IMG_UINT32 *pui32BytesObtained)
{
PVRSRV_ERROR eError;
DEVICE3D *ps3D = &psDevInfo->sDeviceSpecific.s3D;
PVRSRV_MUTEX_HANDLE *phMutex = &ps3D->hMutexTAFifoSpace;
IMG_UINT32 ui32ReserveBytes;
IMG_UINT32 ui32FifoBytes;
eError = HostAcquireMutex (phMutex, IMG_TRUE);
if (eError != PVRSRV_OK)
{
PVR_DPF((PVR_DBG_ERROR,"PVRSRVAcquire2DFifoSpace: failed to acquire the FIFO resource"));
return eError;
}
#ifdef DEBUG
/* check appropriate resources have previously been acquired */
if (HostIsResourceLocked(&ps3D->h2DSlaveportResource) == IMG_FALSE)
{
PVR_DPF((PVR_DBG_ERROR,"PVRSRVAcquire2DFifoSpace: TA and/or TA slaveport is not locked"));
eError = PVRSRV_ERROR_GENERIC;
goto ErrorHandler; /* we need to release FIFO mutex */
}
#endif
/* set up temporary for reserve TA */
ui32ReserveBytes = ps3D->ui32BytesReservedTA;
/* read fifo space from HW */
//FIXME: make this inline
ui32FifoBytes = (MBX1_SP_FIFO_DWSIZE - MBX_EXTRACT_FIFO_COUNT(ReadHWReg(pvRegsBase, MBX1_GLOBREG_INT_STATUS))) << 2;
/* set bytes available for 3D port */
//FIXME: should we include reserve on 2D port in case other 2DFifo functions use cached value?
//ps3D->ui32BytesFreeTAFifo = ui32FifoBytes;
if (ui32FifoBytes <= ui32ReserveBytes)
{
ui32FifoBytes = 0;
}
else
{
/* Minus the reserve */
ui32FifoBytes -= ui32ReserveBytes;
/* Clamp to maximum space available to a single port */
if (ui32FifoBytes > MBX1_SP_FIFO_MAXALLOWEDBYTES)
{
ui32FifoBytes = MBX1_SP_FIFO_MAXALLOWEDBYTES;
}
}
/* set reserve for 2D port */
ps3D->ui32BytesReserved2d = ui32FifoBytes;
/* return the bytes available to 2d port */
*pui32BytesObtained = ui32FifoBytes;
#if DEBUG
ErrorHandler:
#endif /*DEBUG*/
if (HostReleaseMutex(phMutex) != PVRSRV_OK)
{
PVR_DPF((PVR_DBG_ERROR,"PVRSRVAcquire2DFifoSpace: HostReleaseMutex failed"));
}
return eError;
}
/*!
******************************************************************************
@Function PVRSRVAcquire2DFifoSpaceBlock
@Description
USER AND KERNEL MODE FUNCTION
Attempts to acquire space in the SlavePort FIFO. Called from
display driver, 3D driver and ISRs
This provides flow control for the slaveports.
On return, the number of bytes that can be written is returned in pui32BytesObtained.
@Input psDevInfo : UM devdata
@Input psHWInfo : HW Info
@Output *ui32BytesRequired : required bytes in FIFO
@Return PVRSRV_ERROR :
******************************************************************************/
IMG_EXPORT
PVRSRV_ERROR IMG_CALLCONV PVRSRVAcquire2DFifoSpaceBlock (PVRSRV_DEV_INFO *psDevInfo,
IMG_VOID *pvRegsBase,
IMG_UINT32 ui32BytesRequired)
{
PVRSRV_ERROR eError;
DEVICE3D *ps3D = &psDevInfo->sDeviceSpecific.s3D;
PVRSRV_MUTEX_HANDLE *phMutex = &ps3D->hMutexTAFifoSpace;
volatile IMG_UINT32 *pui32ReserveBytes = &ps3D->ui32BytesReservedTA;
IMG_UINT32 ui32FifoBytes = 0;
IMG_UINT32 i;
IMG_BOOL bTimeout;
IMG_BOOL bStart;
IMG_UINT32 uiStart;
eError = HostAcquireMutex (phMutex, IMG_TRUE);
if (eError != PVRSRV_OK)
{
PVR_DPF((PVR_DBG_ERROR,"PVRSRVAcquire2DFifoSpaceBlock: failed to acquire the FIFO resource"));
return eError;
}
#ifdef DEBUG
/* check appropriate resources have previously been acquired */
if (HostIsResourceLocked(&ps3D->h2DSlaveportResource) == IMG_FALSE)
{
PVR_DPF((PVR_DBG_ERROR,"PVRSRVAcquire2DFifoSpaceBlock: TA and/or TA slaveport is not locked"));
eError = PVRSRV_ERROR_GENERIC;
goto ErrorHandler; /* we need to release FIFO mutex */
}
if ((ui32BytesRequired > (MBX1_SP_FIFO_DWSIZE<<2)) /* fifo limit */
|| ((ui32BytesRequired & 0x3) != 0)) /* only request 4byte units */
{
PVR_DPF((PVR_DBG_ERROR,"PVRSRVAcquire2DFifoSpaceBlock: invalid ui32BytesRequired value"));
eError = PVRSRV_ERROR_INVALID_PARAMS;
goto ErrorHandler; /* we need to release FIFO mutex */
}
#endif
bTimeout = IMG_TRUE;
bStart = IMG_FALSE;
uiStart = 0;
i = 0;
do
{
/* read fifo space from HW */
//FIXME: make this inline
ui32FifoBytes = (MBX1_SP_FIFO_DWSIZE - MBX_EXTRACT_FIFO_COUNT(ReadHWReg(pvRegsBase, MBX1_GLOBREG_INT_STATUS))) << 2;
/* set bytes available for 3D port */
//FIXME: should we include reserve on 2D port in case other 2DFifo functions use cached value?
//ps3D->ui32BytesFreeTAFifo = ui32FifoBytes;
/* Don't even consider ending if we've less then the reserve */
if (ui32FifoBytes >= *pui32ReserveBytes)
{
/* Now subtract the reserve */
ui32FifoBytes -= *pui32ReserveBytes;
/*
Don't need to clamp to MBX1_SP_FIFO_MAXALLOWEDBYTES as we only
need to make sure we have what was requested.
*/
if (ui32FifoBytes >= ui32BytesRequired)
{
bTimeout = IMG_FALSE;
break;
}
}
/*
we have to handle thread starvation and block this thread
if we fail to acquire the lock after some number of tries
*/
if (bStart == IMG_FALSE)
{
bStart = IMG_TRUE;
uiStart = HostClockus();
}
if (i > 100)
{
HostWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT);
/* does another thread have space reserved? */
if(*pui32ReserveBytes > 0)
{
#if !defined(PVR_KERNEL)
HostReleaseThreadQuanta();
#endif
}
}
i++;
} while ((HostClockus() - uiStart) < MAX_HW_TIME_US);
if (bTimeout == IMG_TRUE)
{
PVR_DPF((PVR_DBG_ERROR,"PVRSRVAcquire2DFifoSpaceBlock: Failed to get space in FIFO"));
eError = PVRSRV_ERROR_GENERIC;
goto ErrorHandler; /* we need to release FIFO mutex */
}
/* set reserve for 2D port */
ps3D->ui32BytesReserved2d = ui32BytesRequired;
ErrorHandler:
if (HostReleaseMutex(phMutex) != PVRSRV_OK)
{
PVR_DPF((PVR_DBG_ERROR,"PVRSRVAcquire2DFifoSpaceBlock: HostReleaseMutex failed"));
}
return eError;
}
/*!
******************************************************************************
@Function PVRSRVRelease2DFifoSpace
@Description
Utlity: Releases FIFO space reserved for a given port. If this function is not called
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -