📄 mbx.c
字号:
******************************************************************************/
IMG_UINT32 GetHWTextureSize(IMG_UINT32 ui32TexSize, IMG_UINT32 *pui32RoundedUpTexSize)
{
IMG_UINT32 ui32TexWidth = 1;
/* find the bounding texture sizes (power of 2) */
while(ui32TexWidth < ui32TexSize)
{
ui32TexWidth <<= 1;
}
if(pui32RoundedUpTexSize)
{
*pui32RoundedUpTexSize = ui32TexWidth;
}
switch (ui32TexWidth)
{
case 2048 :
return MBX1_TSPPL1_TSIZE2048;
case 1024 :
return MBX1_TSPPL1_TSIZE1024;
case 512 :
return MBX1_TSPPL1_TSIZE512;
case 256 :
return MBX1_TSPPL1_TSIZE256;
case 128 :
return MBX1_TSPPL1_TSIZE128;
case 64 :
return MBX1_TSPPL1_TSIZE64;
case 32 :
return MBX1_TSPPL1_TSIZE32;
case 16 :
return MBX1_TSPPL1_TSIZE16;
case 8 :
return MBX1_TSPPL1_TSIZE8;
default:
PVR_DPF((PVR_DBG_ERROR,"GetHWTextureSize: invalid texture width"));
PVR_ASSERT(0);
return 0;
}
}
/*!
******************************************************************************
@Function Init3DDeviceInfo
@Description
Allocates and sets up the 3d device devinfo
@Input ppsDevInfo : KM devinfo
@Input psDevId : dev. identifier
@Return PVRSRV_ERROR
******************************************************************************/
PVRSRV_ERROR Init3DDeviceInfo(PVRSRV_DEV_INFO **ppsDevInfo,
PVRSRV_DEVICE_IDENTIFIER *psDevId)
{
PVRSRV_DEV_INFO *psDevInfo;
DEVICE3D *psDevice;
PVRSRV_DEV_LOCATION *psDevLocation;
PVRSRV_ERROR eError = PVRSRV_OK;
IMG_VOID *pvLinBase;
/* Allocate device control block */
if(HostAllocMem( PVRSRV_HOST_NON_PAGEABLE_HEAP,
sizeof(PVRSRV_DEV_INFO),
(IMG_VOID **)&psDevInfo, 0) != PVRSRV_OK)
{
PVR_DPF((PVR_DBG_ERROR,"Init3DDeviceInfo : Failed to alloc memory for DevInfo"));
return (PVRSRV_ERROR_OUT_OF_MEMORY);
}
HostMemSet (psDevInfo, 0, sizeof(PVRSRV_DEV_INFO));
/* copy psDevId into new psDevInfo */
psDevInfo->sDevId = *psDevId;
psDevice = &psDevInfo->sDeviceSpecific.s3D;
/* setup some device details */
switch(psDevInfo->sDevId.eDeviceType)
{
case PVRSRV_DEVICE_TYPE_MBX1:
{
psDevice->ui32PixelsInTileX = MBX1_ISPREGION_SIZEX;
psDevice->ui32PixelsInTileY = MBX1_ISPREGION_SIZEY;
psDevice->ui32TileXGran = 1;
psDevice->ui32TileYGran = 1;
}
break;
case PVRSRV_DEVICE_TYPE_MBX1_LITE:
{
psDevice->ui32PixelsInTileX = MBX1_ISPREGION_SIZEX;
psDevice->ui32PixelsInTileY = MBX1_ISPREGION_SIZEY;
psDevice->ui32TileXGran = 2;
psDevice->ui32TileYGran = 1;
}
break;
default:
{
PVR_DPF((PVR_DBG_ERROR,"Init3DDeviceInfo : Invalid device"));
return PVRSRV_ERROR_INVALID_DEVICE;
}
}
/* init structure */
psDevice->bTAIdle = IMG_TRUE;
psDevice->b3DIdle = IMG_TRUE;
#if defined(SUPPORT_3D_BLIT)
/* Reset blit Ctl handles */
psDevice->h3DBlitCtl = IMG_NULL;
/* Reset blit Ctl handles */
psDevice->hOvl3DBlitCtl = IMG_NULL;
#endif
/* allocate render command sync structures */
if(HostAllocMem( PVRSRV_HOST_NON_PAGEABLE_HEAP,
sizeof(RENDERSYNCS),
(IMG_VOID **)&psDevice->hRenderSync, 0) != PVRSRV_OK)
{
PVR_DPF((PVR_DBG_ERROR,"Init3DDeviceInfo : Failed to alloc memory for psDevice->hRenderSync"));
return (PVRSRV_ERROR_OUT_OF_MEMORY);
}
HostMemSet (psDevice->hRenderSync, 0, sizeof(RENDERSYNCS));
/* allocate blit command sync structures */
if(HostAllocMem( PVRSRV_HOST_NON_PAGEABLE_HEAP,
sizeof(BLTSYNCS),
(IMG_VOID **)&psDevice->hBlitSync, 0) != PVRSRV_OK)
{
PVR_DPF((PVR_DBG_ERROR,"Init3DDeviceInfo : Failed to alloc memory for psDevice->hBlitSync"));
return (PVRSRV_ERROR_OUT_OF_MEMORY);
}
HostMemSet (psDevice->hBlitSync, 0, sizeof(BLTSYNCS));
eError = HostCreateResource(&psDevice->hTAResource);
if (eError != PVRSRV_OK)
{
PVR_DPF((PVR_DBG_ERROR,"Init3DDeviceInfo: Failed to create resource !"));
return PVRSRV_ERROR_INIT_FAILURE;
}
eError = HostCreateResource(&psDevice->hTAConfigResource);
if (eError != PVRSRV_OK)
{
PVR_DPF((PVR_DBG_ERROR,"Init3DDeviceInfo: Failed to create resource !"));
return PVRSRV_ERROR_INIT_FAILURE;
}
eError = HostCreateResource(&psDevice->h2DSlaveportResource);
if (eError != PVRSRV_OK)
{
PVR_DPF((PVR_DBG_ERROR,"Init3DDeviceInfo: Failed to create resource !"));
return PVRSRV_ERROR_INIT_FAILURE;
}
eError = HostCreateMutex(&psDevice->hMutexTAFifoSpace);
if (eError != PVRSRV_OK)
{
PVR_DPF((PVR_DBG_ERROR,"Init3DDeviceInfo: Failed to create mutex !"));
return PVRSRV_ERROR_INIT_FAILURE;
}
eError = HostCreateMutex(&psDevInfo->hClockGateMutex);
if (eError != PVRSRV_OK)
{
PVR_DPF((PVR_DBG_ERROR,"Init3DDeviceInfo: Failed to create mutex !"));
return PVRSRV_ERROR_INIT_FAILURE;
}
/* setup the DevLocation */
eError = SysFindLocation(psDevInfo);
if (eError != PVRSRV_OK)
{
PVR_DPF((PVR_DBG_ERROR,"Init3DDeviceInfo: Failed to find device !"));
return PVRSRV_ERROR_INIT_FAILURE;
}
/* save pointer de-refs */
psDevLocation = &psDevInfo->sDevLocation;
/* Map Regs */
pvLinBase = HostMapPhysToLin(ENV_SysPAddrToCpuPAddr(psDevLocation->sRegsPhysBase),
psDevLocation->ui32RegSize,
CACHETYPE_UNCACHED | EXTRA_CACHETYPE_SHARED);
if (pvLinBase == (IMG_CPU_VIRTADDR)0)
{
PVR_DPF((PVR_DBG_ERROR,"Init3DDeviceInfo : Failed to map in regs\n"));
return PVRSRV_ERROR_BAD_MAPPING;
}
psDevLocation->pvRegsBaseKM = pvLinBase;
/* If this is a kicker device, setup the address */
if(psDevInfo->sDevId.bIsKickerDevice)
{
SYS_DATA *psSysData;
if(SysAcquireData(&psSysData) != PVRSRV_OK)
{
return PVRSRV_ERROR_GENERIC;
}
psSysData->pui32KickerAddr = (IMG_PVOID)((IMG_UINT32)pvLinBase+MBX1_GLOBREG_INT_STATUS);
}
/* Map SOC Registers */
if(psDevLocation->sSOCRegsPhysBase.uiAddr)
{
pvLinBase = HostMapPhysToLin(ENV_SysPAddrToCpuPAddr(psDevLocation->sSOCRegsPhysBase),
psDevLocation->ui32SOCRegSize,
CACHETYPE_UNCACHED | EXTRA_CACHETYPE_SHARED);
if (pvLinBase == (IMG_CPU_VIRTADDR)0)
{
PVR_DPF((PVR_DBG_ERROR,"Init3DDeviceInfo : Failed to map in SOC regs\n"));
return PVRSRV_ERROR_BAD_MAPPING;
}
psDevLocation->pvSOCRegsBaseKM = pvLinBase;
PVRSRVSetupMetricTimers(psDevInfo);
}
else
{
psDevLocation->pvSOCRegsBaseKM = 0;
}
/* map Slave ports */
if (psDevLocation->sDeviceSpecific.sMBX.sTASlavePort.sPhysBase.uiAddr)
{
/* Individual mappings per slaveport - allows more fine-grained control. */
/* TA Data port */
pvLinBase = HostMapPhysToLin(
psDevLocation->sDeviceSpecific.sMBX.sTASlavePort.sPhysBase,
psDevLocation->sDeviceSpecific.sMBX.sTASlavePort.ui32DataRange,
CACHETYPE_WRITECOMBINED | EXTRA_CACHETYPE_SHARED
);
/* Check slave port allocation was ok */
if (pvLinBase == (IMG_CPU_VIRTADDR)0)
{
PVR_DPF((PVR_DBG_ERROR,"Init3DDeviceInfo : Failed to map in Slave port memory\n"));
return PVRSRV_ERROR_BAD_MAPPING;
}
psDevLocation->sDeviceSpecific.sMBX.sTASlavePort.pvData = pvLinBase;
psDevLocation->sDeviceSpecific.sMBX.sTASlavePort.pui32Offset = &psDevice->ui32TASlavePortOffset;
/* 2D Data port */
pvLinBase = HostMapPhysToLin(
psDevLocation->sDeviceSpecific.sMBX.s2DSlavePort.sPhysBase,
psDevLocation->sDeviceSpecific.sMBX.s2DSlavePort.ui32DataRange,
CACHETYPE_WRITECOMBINED | EXTRA_CACHETYPE_SHARED
);
/* Check slave port allocation was ok */
if (pvLinBase == (IMG_CPU_VIRTADDR)0)
{
PVR_DPF((PVR_DBG_ERROR,"Init3DDeviceInfo : Failed to map in Slave port memory\n"));
return PVRSRV_ERROR_BAD_MAPPING;
}
psDevLocation->sDeviceSpecific.sMBX.s2DSlavePort.pvData = pvLinBase;
psDevLocation->sDeviceSpecific.sMBX.s2DSlavePort.pui32Offset = &psDevice->ui322DSlavePortOffset;
/*
* TA Terminate port - must be non-write combined and non-cached, to ensure write-combiners are
* flushed and the terminate does not go out of order
*/
pvLinBase = HostMapPhysToLin(
psDevLocation->sDeviceSpecific.sMBX.sTAControlSlavePort.sPhysBase,
psDevLocation->sDeviceSpecific.sMBX.sTAControlSlavePort.ui32DataRange,
CACHETYPE_UNCACHED | EXTRA_CACHETYPE_SHARED
);
/* Check slave port allocation was ok */
if (pvLinBase == (IMG_CPU_VIRTADDR)0)
{
PVR_DPF((PVR_DBG_ERROR,"Init3DDeviceInfo : Failed to map in Slave port memory\n"));
return PVRSRV_ERROR_BAD_MAPPING;
}
psDevLocation->sDeviceSpecific.sMBX.sTAControlSlavePort.pvData = pvLinBase;
psDevLocation->sDeviceSpecific.sMBX.sTAControlSlavePort.pui32Offset = &psDevice->ui32TAControlSlavePortOffset;
}
else
{
/*
if we have a physical address of 0 coming down assume we have no HW
Therefore, we'll be pdumping and/or 2d/3d sim'ing all of which
require no slaveport FIFO storage
*/
pvLinBase = (IMG_CPU_VIRTADDR)0;
}
#ifdef SIM_DEVICE
{
IMG_UINT32 ui32HighLinBase;
/*
when we use Kyro to sim' MBX we need real Kyro regs
and dummy mbx regs for the integrated 3d sim
*/
if(HostAllocMem( PVRSRV_HOST_NON_PAGEABLE_HEAP,
DEVICE_REG_SIZE,
(IMG_VOID **)&ui32HighLinBase, 0) != PVRSRV_OK)
{
PVR_DPF((PVR_DBG_ERROR,"Init3DDeviceInfo : Failed to alloc memory for dummy mbx regs"));
return PVRSRV_ERROR_OUT_OF_MEMORY;
}
psDevLocation->sDeviceSpecific.sMBX.ui32MBXRegsLinBase = ui32HighLinBase;
}
#endif
/* identify the actual MBX core */
if( IdentifyDevice( psDevInfo ) != PVRSRV_OK )
{
return PVRSRV_ERROR_INVALID_DEVICE;
}
/*
install device functions
*/
psDevInfo->pfnInitDevice = DevInitMBX;
psDevInfo->pfnDeInitDevice = DevDeInitMBX;
psDevInfo->pfnDeviceISR = MBXIsr;
psDevInfo->pfnProcessCommands = DevProcessCommandsMBX;
psDevInfo->pfnDummyProcessCommands = DevDummyProcessCommandsMBX;
#ifdef SUPPORT_POWER_STATE
psDevInfo->pfnSetPowerState = DevPowerStateMBX;
#endif
/* return the new devinfo */
*ppsDevInfo = psDevInfo;
return eError;
}
/*!
******************************************************************************
@Function DeInit3DDeviceInfo
@Description
Allocates and sets up the 3d device devinfo
@Input psDevInfo : KM devinfo
@Return PVRSRV_ERROR
******************************************************************************/
PVRSRV_ERROR DeInit3DDeviceInfo(PVRSRV_DEV_INFO *psDevInfo)
{
PVRSRV_DEV_LOCATION *psDevLocation;
DEVICE3D *psDevice = &psDevInfo->sDeviceSpecific.s3D;
PVRSRV_ERROR eError = PVRSRV_OK;
/* deallocate render command sync structures */
HostFreeMem(PVRSRV_HOST_NON_PAGEABLE_HEAP, psDevice->hRenderSync);
/* deallocate blit command sync structures */
HostFreeMem(PVRSRV_HOST_NON_PAGEABLE_HEAP, psDevice->hBlitSync);
/* call into host specific functions to destroy blocking objects */
eError = HostDestroyResource(&psDevice->hTAResource);
if (eError != PVRSRV_OK)
{
return eError;
}
eError = HostDestroyResource(&psDevice->hTAConfigResource);
if (eError != PVRSRV_OK)
{
return eError;
}
eError = HostDestroyResource(&psDevice->h2DSlaveportResource);
if (eError != PVRSRV_OK)
{
return eError;
}
eError = HostDestroyMutex(&psDevice->hMutexTAFifoSpace);
if (eError != PVRSRV_OK)
{
return eError;
}
eError = HostDestroyMutex(&psDevInfo->hClockGateMutex);
if (eError != PVRSRV_OK)
{
return eError;
}
/* save pointer de-refs */
psDevLocation = &psDevInfo->sDevLocation;
/* UnMap Regs */
HostUnMapPhysToLin (psDevLocation->pvRegsBaseKM, psDevLocation->ui32RegSize);
/* UnMap Slaveports */
if (psDevLocation->sDeviceSpecific.sMBX.sTASlavePort.sPhysBase.uiAddr)
{
HostUnMapPhysToLin (psDevLocation->sDeviceSpecific.sMBX.sTASlavePort.pvData,
psDevLocation->sDeviceSpecific.sMBX.sTASlavePort.ui32DataRange);
HostUnMapPhysToLin (psDevLocation->sDeviceSpecific.sMBX.s2DSlavePort.pvData,
psDevLocation->sDeviceSpecific.sMBX.s2DSlavePort.ui32DataRange);
HostUnMapPhysToLin (psDevLocation->sDeviceSpecific.sMBX.sTAControlSlavePort.pvData,
psDevLocation->sDeviceSpecific.sMBX.sTAControlSlavePort.ui32DataRange);
}
#ifdef SIM_DEVICE
/*
when we use Kyro to sim' MBX we need real Kyro regs
and dummy mbx regs for the integrated 3d sim
*/
HostFreeMem(PVRSRV_HOST_NON_PAGEABLE_HEAP, psDevLocation->ui32MBXRegsLinBase);
#endif
/* And left until as late as possible (for the metrics) do the SOC regs */
if(psDevLocation->pvSOCRegsBaseKM)
{
PVRSRVOutputMetricTotals();
HostUnMapPhysToLin (psDevLocation->pvSOCRegsBaseKM, psDevLocation->ui32SOCRegSize);
}
/* DeAllocate devinfo */
HostFreeMem(PVRSRV_HOST_NON_PAGEABLE_HEAP, psDevInfo);
return eError;
}
/*!
******************************************************************************
@Function Enable3DDevice
@Description
Enables a 3d device
@Input psDevInfo : KM devinfo
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -