📄 mbx.c
字号:
@Description
If this is the last reference to the parameter buffer, it will be destroyed.
@Input psDevData :
@Return PVRSRV_ERROR :
******************************************************************************/
IMG_EXPORT PVRSRV_ERROR PVRSRVDestroyParameterBuffer(PVRSRV_DEV_DATA *psDevData)
{
return ResManFreeResByCriteria(RESMAN_CRITERIA_RESTYPE | RESMAN_CRITERIA_FREEONCE, RESMAN_TYPE_PARAMBUFF, 0, 0, 0);
}
/*!
******************************************************************************
@Function RemoveRenderTargetCleanUp
@Description
RT clean-up code
@Input psDevInfo
@Input psInfo
@Return PVRSRV_ERROR
******************************************************************************/
static PVRSRV_ERROR RemoveRenderTargetCleanUp(PVRSRV_DEV_INFO *psDevInfo, PVRSRV_TARENDERINFO *psInfo)
{
PVRSRV_ERROR eError = PVRSRV_OK;
DEVICE3D *ps3D = &psDevInfo->sDeviceSpecific.s3D;
if(ps3D->ui32Last3DCtlID == psInfo->psSharedData->ui32UniqueID)
{
ps3D->LastEVMContextDevVAddr.uiAddr = 0;
ps3D->LastTAContextDevVAddr.uiAddr = 0;
ps3D->bLastContextMidScene = IMG_FALSE;
ps3D->ui32Last3DCtlID = 0;
ps3D->ui32LastTilesX = 0;
ps3D->ui32LastTilesY = 0;
}
if ((psInfo->psSharedData->aui32ContextStatus[psInfo->psSharedData->ui32CurrentRenderData] == PVR3DIF_3DCTL_PREPARING)
|| (psInfo->psSharedData->aui32ContextStatus[psInfo->psSharedData->ui32CurrentRenderData] == PVR3DIF_3DCTL_CS_PREPARING))
{
IMG_PVOID *pvRegsBase = psDevInfo->sDevLocation.pvRegsBaseKM;
PVR3DIF_PARAMBUFFER *psParamBuffer = (PVR3DIF_PARAMBUFFER *)ps3D->hParamBuffer;
PVRSRV_QUEUE_INFO *psQueue;
PVR3DIF_3DCTL *ps3DCtl;
SYS_DATA *psSysData;
RENDERSYNCS *psRenderSyncs;
BLTSYNCS *psBlitSyncs;
IMG_UINT32 ui3DCtlCount = 0;
IMG_UINT32 i;
/*
At this point SW / HW state could be corrupted.
- Enable dummy processing mode
- if any commands are `in process' assume they are broken
and call their respective complete functions
- command processor now calls the pfnDummyProc functions
to clean-up
*/
eError = SysAcquireData(&psSysData);
if (eError != PVRSRV_OK)
{
return eError;
}
/* block processing of any more commands */
ps3D->b3DIdle = IMG_FALSE;/* render */
eError = HostLockResource(&ps3D->h2DSlaveportResource, IMG_TRUE); /* blit */
if (eError != PVRSRV_OK)
{
return eError;
}
psRenderSyncs = ps3D->hRenderSync;
psBlitSyncs = ps3D->hBlitSync;
/* signal to all other contexts to stop HW accesses */
ps3DCtl = psParamBuffer->ps3DCtlList;
while (ps3DCtl)
{
ps3DCtl->sSharedData.bSceneInvalidated = IMG_TRUE;
ps3DCtl = ps3DCtl->psNext;
ui3DCtlCount++;
}
/* deal with active commands */
if(psRenderSyncs->bInUse || psBlitSyncs->bInUse)
{
/* wait some time for these to complete */
HostWaitus(MAX_HW_TIME_US);
if(psRenderSyncs->bInUse)
{
psRenderSyncs->bPartialRender = IMG_FALSE;
psRenderSyncs->bUpdatePrimary = IMG_FALSE;
ps3D->bRestartTA = IMG_FALSE;
Handle3DComplete(psDevInfo);
}
if(psBlitSyncs->bInUse)
{
psBlitSyncs->bUpdatePrimary = IMG_FALSE;
Handle2DSync(psDevInfo);
}
}
/*
Now reset HW
*/
SysDeviceReset(psSysData, psDevInfo);
/*
If not already freed free the region headers
*/
psInfo->psSharedData->aui32ContextStatus[0] = PVR3DIF_3DCTL_FREE;
psInfo->psSharedData->aui32ContextStatus[1] = PVR3DIF_3DCTL_FREE;
/*
fifo state clean-up
*/
ps3D->ui32BytesFreeTAFifo = 0;
ps3D->ui32BytesReservedTA = 0;
ps3D->ui32BytesReserved2d = 0;
eError = HostReleaseMutex(&ps3D->hMutexTAFifoSpace);
if (eError != PVRSRV_OK)
{
return eError;
}
/*
Slaveport details
*/
ps3D->ui32BytesFreeTAFifo = 0;
ps3D->ui32BytesReservedTA = 0;
ps3D->ui32BytesReserved2d = 0;
eError = HostUnlockResource(&ps3D->h2DSlaveportResource);
if (eError != PVRSRV_OK)
{
return eError;
}
/*
TA details
*/
ps3D->bTAStopMode = IMG_FALSE;
ps3D->bTAIdle = IMG_TRUE;
ps3D->bRestartTA = IMG_FALSE;
eError = HostUnlockResource(&ps3D->hTAConfigResource);
if (eError != PVRSRV_OK)
{
return eError;
}
eError = HostUnlockResource(&ps3D->hTAResource);
if (eError != PVRSRV_OK)
{
return eError;
}
/*
context details
*/
ps3D->aui32HWContextIDState[0] = 0;
ps3D->aui32HWContextIDState[1] = 0;
ps3D->bTAContextInterrupt = IMG_FALSE;
/*
discard scene details
*/
ps3D->bBlock3DProcessing = IMG_FALSE;
ps3D->bEVMDAlloc = IMG_FALSE;
ps3D->bTATimeOut = IMG_FALSE;
/****************************************************
ASYNCHRONOUS CLEAN-UP
****************************************************/
/*
render resources
*/
ps3D->bEnablePartialRender = IMG_FALSE;
ps3D->bEVMDAlloc = IMG_FALSE;
ps3D->b3DIdle = IMG_TRUE;
ps3D->bRenderComplete = IMG_FALSE;
HostMemSet(ps3D->hRenderSync, 0, sizeof(RENDERSYNCS));
/*
blit resources
*/
HostMemSet(ps3D->hBlitSync, 0, sizeof(BLTSYNCS));
/*
general command state clean-up
*/
/****************************************************
HW RECOVERY
****************************************************/
/*
re-enable the device
*/
if(psDevInfo->pfnInitDevice != IMG_NULL)
{
eError = psDevInfo->pfnInitDevice (psDevInfo);
if (eError != PVRSRV_OK)
{
return eError;
}
}
if(ui3DCtlCount > 1)
{
/* if other contexts present we need to silently re-enable the parameter buffer */
WriteHWRegs(pvRegsBase, psParamBuffer->ui32HWRegCount, psParamBuffer->asHWRegs);
eError = PollForValueKM ((volatile IMG_UINT32 *)&ps3D->bEVMDAlloc,
IMG_TRUE,
0xFFFFFFFF,
MAX_HW_TIME_US/WAIT_TRY_COUNT,
WAIT_TRY_COUNT);
if (eError != PVRSRV_OK)
{
return eError;
}
/* and clear the flag */
ps3D->bEVMDAlloc = IMG_FALSE;
}
/*
start dummy processing
*/
psSysData->bDummyProcessing = IMG_TRUE;
for (i=0; i<WAIT_TRY_COUNT; i++)
{
IMG_BOOL bQueuesEmpty;
bQueuesEmpty = IMG_TRUE;
psQueue = psSysData->psQueueList;
while(psQueue)
{
if (psQueue->ui32ReadOffset != psQueue->ui32WriteOffset)
{
bQueuesEmpty = IMG_FALSE;
}
SysKickCmdProc (psSysData->pui32KickerAddr);
HostWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT);
psQueue = psQueue->psNextKM;
}
if(bQueuesEmpty)
{
break;
}
}
if(i==WAIT_TRY_COUNT)
{
return PVRSRV_ERROR_GENERIC;
}
/* stop dummy processing */
psSysData->bDummyProcessing = IMG_FALSE;
}
return eError;
}
/*!
******************************************************************************
@Function RemoveRenderTargetCallBack
@Description
RT clean-up code
@Input ui32ProcessID - process id
@Input pvParam - data packet
@Input ui32Param - packet size
@Return PVRSRV_ERROR
******************************************************************************/
static PVRSRV_ERROR RemoveRenderTargetCallBack (IMG_UINT32 ui32ProcessID,
IMG_PVOID pvParam,
IMG_UINT32 ui32Param)
{
PVRSRV_DEV_INFO *psDevInfo = (PVRSRV_DEV_INFO *)pvParam;/*! @todo should really have a holding structure */
PVRSRV_TARENDERINFO *psInfo = (PVRSRV_TARENDERINFO *)ui32Param;/*! @todo should really have a holding structure */
PVR3DIF_PARAMBUFFER *psParamBuffer;
PVR3DIF_3DCTL *psThis;
PVR3DIF_3DCTL *psPrev;
PVR3DIF_3DCTL *ps3DCtl;
SYS_DATA *psSysData;
IMG_UINT i;
PVRSRV_ERROR eError;
eError = SysAcquireData(&psSysData);
if (eError != PVRSRV_OK)
{
return eError;
}
ps3DCtl = (PVR3DIF_3DCTL *)psInfo->psSharedData;
/* @todo FIXME: don't need any sleeps here - need test for 3DHW timeout flag */
for (i=0; (i<WAIT_TRY_COUNT)
&& ((ps3DCtl->sSharedData.aui32ContextStatus[0] != PVR3DIF_3DCTL_FREE) ||
(ps3DCtl->sSharedData.aui32ContextStatus[1] != PVR3DIF_3DCTL_FREE)); i++)
{
SysKickCmdProc (psSysData->pui32KickerAddr);
HostWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT);
}
if (i == WAIT_TRY_COUNT)
{
PVR_DPF((PVR_DBG_WARNING,"RemoveRenderTargetCallBack: region headers never became free - assume OK to deallocate"));
}
eError = RemoveRenderTargetCleanUp(psDevInfo, psInfo);
if (eError != PVRSRV_OK)
{
return eError;
}
psParamBuffer = (PVR3DIF_PARAMBUFFER *)psDevInfo->sDeviceSpecific.s3D.hParamBuffer;
psPrev = 0;
/* Find entry in linked list.. */
psThis = psParamBuffer->ps3DCtlList;
while(psThis)
{
if (psThis == ps3DCtl)
{
break;
}
psPrev = psThis;
psThis = psThis->psNext;
}
/* Go away if we've been given a dicky thang to remove. */
if (!psThis)
{
PVR_DPF((PVR_DBG_ERROR,"Invalid 3DCtl - can't be removed from render target!"));
return PVRSRV_ERROR_INVALID_PARAMS;
}
/*
Free the space allocated for TA context load/store, region
headers, tail-pointers and the HW background object
*/
FreeStaticFBMem(psDevInfo, ps3DCtl->pvTAContextKM);
FreeStaticFBMem(psDevInfo, ps3DCtl->pvEVMContextKM);
FreeStaticFBMem(psDevInfo, ps3DCtl->sSharedData.pvTailPtrsKM);
/* free region headers */
FreeStaticFBMem(psDevInfo, ps3DCtl->apvRgnHeadersKM[0]);
FreeStaticFBMem(psDevInfo, ps3DCtl->apvRgnHeadersKM[1]);
HostFreeMem(PVRSRV_HOST_NON_PAGEABLE_HEAP, ps3DCtl->psCSInfoMemKM);
/* Remove entry from linked list. */
if (psPrev)
{
psPrev->psNext = ps3DCtl->psNext;
}
else
{
psParamBuffer->ps3DCtlList = ps3DCtl->psNext;
}
/* Free host memory. */
HostFreeMem(PVRSRV_HOST_NON_PAGEABLE_HEAP, ps3DCtl);
HostFreeMem(PVRSRV_HOST_NON_PAGEABLE_HEAP, psInfo);
return PVRSRV_OK;
}
/*!
******************************************************************************
@Function PVRSRVAddRenderTarget
@Description
Adds a render target to the parameter buffer. Creates region headers and tail
pointers appropriate to the render target size.
@Input psDevData :
@Input ui32Width: In pixels.
@Input ui32Height: In pixels.
@Input ui32Flags: Anti aliasing flags
@Output *ppsTARenderInfo:
@Return PVRSRV_ERROR :
******************************************************************************/
IMG_EXPORT PVRSRV_ERROR PVRSRVAddRenderTarget (PVRSRV_DEV_DATA *psDevData, IMG_UINT32 ui32Width,
IMG_UINT32 ui32Height, IMG_UINT32 ui32AAFlags, PVRSRV_TARENDERINFO **ppsTARenderInfo)
{
PVRSRV_ERROR eError = PVRSRV_OK;
PVRSRV_DEV_INFO *psDevInfo = psDevData->psDevInfoKM;
PVR3DIF_PARAMBUFFER *psParamBuff = (PVR3DIF_PARAMBUFFER *)psDevInfo->sDeviceSpecific.s3D.hParamBuffer;
PVR3DIF_3DCTL *ps3DCtl;
if(ui32AAFlags & PVRSRV_ADDRENDERTARGET_AAX)
ui32Width <<= 1;
if(ui32AAFlags & PVRSRV_ADDRENDERTARGET_AAY)
ui32Height <<= 1;
/* OK, alloc mem for Host side structures... */
if(HostAllocMem( PVRSRV_HOST_NON_PAGEABLE_HEAP,
sizeof(PVRSRV_TARENDERINFO),
(IMG_VOID **)ppsTARenderInfo, 0) != PVRSRV_OK)
{
PVR_DPF((PVR_DBG_ERROR,"ERROR - Failed to alloc host mem for UM TA RenderInfo !"));
return PVRSRV_ERROR_OUT_OF_MEMORY;
}
/* setup kernel pointer (overwritten by glue in a bridged system) */
(*ppsTARenderInfo)->psTARenderInfoKM = *ppsTARenderInfo;
if(HostAllocMem( PVRSRV_HOST_NON_PAGEABLE_HEAP,
sizeof(PVR3DIF_3DCTL),
(IMG_VOID **)&ps3DCtl, 0) != PVRSRV_OK)
{
PVR_DPF((PVR_DBG_ERROR,"ERROR - Failed to alloc host mem for 3D Control structure !"));
eError = PVRSRV_ERROR_OUT_OF_MEMORY;
}
else
{
/* zero structure */
HostMemSet(ps3DCtl, 0, sizeof(PVR3DIF_3DCTL));
ps3DCtl->sSharedData.ui32UniqueID = 0;
ps3DCtl->sSharedData.ui32AAFlags = ui32AAFlags;
/*
We are given pixel dimensions of the render target
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -