📄 pvrsrv.c
字号:
return 1;
/*! @todo How big are the pixels of the pal format? */
/*
case PVRSRV_PIXEL_FORMAT_PAL12 :
return ;
case PVRSRV_PIXEL_FORMAT_PAL4 :
return ;
case PVRSRV_PIXEL_FORMAT_PAL2 :
return ;
case PVRSRV_PIXEL_FORMAT_PAL1 :
return ;
*/
case PVRSRV_PIXEL_FORMAT_ARGB1555 :
return 2;
case PVRSRV_PIXEL_FORMAT_ARGB4444 :
return 2;
case PVRSRV_PIXEL_FORMAT_ARGB8888 :
return 4;
case PVRSRV_PIXEL_FORMAT_ABGR8888 :
return 4;
case PVRSRV_PIXEL_FORMAT_YV12 :
return 4;
case PVRSRV_PIXEL_FORMAT_I420 :
return 4;
case PVRSRV_PIXEL_FORMAT_DXT1 :
return 8;
default:
/* Unknown format */
return 0;
}
}
/*!
******************************************************************************
@Function PVRSRVQueryPrimary
@Description
Queries the primary surface, obtaining the current dimensions of the surface.
This function MUST NEVER return a handle of an active primary surface.
@Input *psDevData : Must refer to a display device
@Output *psPrimaryQuery : Pointer to return structure
@Return PVRSRV_OK : Success
PVRSRV_ERROR_INVALID_PARAMS : Parameters passed are invalid
PVRSRV_ERROR_NO_PRIMARY : No primary surface has been acquired
******************************************************************************/
IMG_EXPORT
PVRSRV_ERROR IMG_CALLCONV PVRSRVQueryPrimary( PVRSRV_DEV_DATA *psDevData,
PVRSRV_PRIMARY_SURF_INFO *psPrimaryQuery)
{
PVRSRV_PRIMARY_SURF *psPrimSurf;
if ((psDevData == IMG_NULL) || (psPrimaryQuery == IMG_NULL))
{
return PVRSRV_ERROR_INVALID_PARAMS;
}
/* Check to see whether we've been passed a display device or not */
if (psDevData->psDevInfoKM->sDevId.eDeviceClass != PVRSRV_DEVICE_CLASS_DISPLAY)
{
PVR_DPF((PVR_DBG_ERROR, "%s: Device does not have flip capabilities", "PVRSRVQueryPrimary"));
return PVRSRV_ERROR_INVALID_PARAMS;
}
psPrimSurf = &(psDevData->psDevInfoKM->sDeviceSpecific.sDisplay.sPrimarySurface);
if (psPrimSurf->bValid == IMG_FALSE)
{
/* Note that the debug message below is set to PVR_DBG_MESSAGE as
* the level rather than PVR_DBG_ERROR as it's perfectly acceptable
* to call the function when no primary surface exists.
*/
PVR_DPF((PVR_DBG_MESSAGE, "%s: There is no primary surface yet", "PVRSRVQueryPrimary"));
return PVRSRV_ERROR_NO_PRIMARY;
}
psPrimaryQuery->ui32PixelWidth = psPrimSurf->ui32PixelWidth;
psPrimaryQuery->ui32PixelHeight = psPrimSurf->ui32PixelHeight;
psPrimaryQuery->ui32ByteStride = psPrimSurf->ui32ByteStride;
psPrimaryQuery->ePixelFormat = psPrimSurf->ePixelFormat;
PVR_DPF((PVR_DBG_MESSAGE, "%s: Primary surface queried successfully", "PVRSRVQueryPrimary"));
PVR_DPF((PVR_DBG_MESSAGE, "%s: Returning %d x %d (stride=0x%x; pixel format=%d)", "PVRSRVQueryPrimary",
psPrimaryQuery->ui32PixelWidth, psPrimaryQuery->ui32PixelHeight, psPrimaryQuery->ui32ByteStride, psPrimaryQuery->ePixelFormat));
return PVRSRV_OK;
}
/*!
******************************************************************************
@Function DestroyPrimaryCallBack
@Description
Destroy the specified primary surface.
@Input *psDevData :
@Input *psPrimSurf :
@Return PVRSRV_ERROR :
******************************************************************************/
static PVRSRV_ERROR DestroyPrimaryCallBack(IMG_UINT32 ui32ProcessID, IMG_PVOID pvParam, IMG_UINT32 ui32Param)
{
PVRSRV_DEV_DATA *psDevData = (PVRSRV_DEV_DATA *)pvParam;/*! @todo should really have a holding structure */
PVRSRV_PRIMARY_SURF *psPrimSurf = (PVRSRV_PRIMARY_SURF *)ui32Param;/*! @todo should really have a holding structure */
PVRSRV_ERROR eError = PVRSRV_OK ;
if(!psDevData)
{
PVR_DPF((PVR_DBG_ERROR,"Invalid DevData"));
return PVRSRV_ERROR_INVALID_PARAMS;
}
psPrimSurf->i32RefCountKM--;
if (psPrimSurf->i32RefCountKM == 0)
{
eError = PVRSRVFreeDeviceMem(psDevData, psPrimSurf->psMemInfo);
psPrimSurf->bValid = IMG_FALSE;
}
return eError;
}
/*!
******************************************************************************
@Function PVRSRVAcquirePrimary
@Description
Acquires the primary surface. If the surface does not exist (i.e. on first
call), the surface is created.
@Input *psDevData : Must refer to a display device
ui32Flags : Surface flags
uiPixelWidth : Width of the primary surface in pixels
uiPixelHeight : Height of the primary surface in pixels
ePixelFormat : Pixel format of the primary surface
@Output **ppsPrimarySurf : Pointer to a returned pointer containing the
surface
@Return PVRSRV_OK : Success
PVRSRV_ERROR_INVALID_PARAMS : Parameters passed are invalid
PVRSRV_ERROR_NO_PRIMARY : No primary surface has been acquired
PVRSRV_ERROR_NO_MEMORY : Insufficient memory to create surface
PVRSRV_ERROR_GENERIC : An unknown error occurred
******************************************************************************/
IMG_EXPORT
PVRSRV_ERROR IMG_CALLCONV PVRSRVAcquirePrimary( PVRSRV_DEV_DATA *psDevData,
IMG_UINT32 ui32Flags,
IMG_UINT32 uiPixelWidth,
IMG_UINT32 uiPixelHeight,
PVRSRV_PIXEL_FORMAT ePixelFormat,
PVRSRV_PRIMARY_SURF **ppsPrimarySurf)
{
PVRSRV_PRIMARY_SURF *psPrimSurf;
if ((psDevData == IMG_NULL) || (ppsPrimarySurf == IMG_NULL))
{
return PVRSRV_ERROR_INVALID_PARAMS;
}
/* Check to see whether we've been passed a display device or not */
if (psDevData->psDevInfoKM->sDevId.eDeviceClass != PVRSRV_DEVICE_CLASS_DISPLAY)
{
PVR_DPF((PVR_DBG_ERROR, "%s: Device does not have flip capabilities", "PVRSRVAcquirePrimary"));
return PVRSRV_ERROR_INVALID_PARAMS;
}
/* See whether the primary surface exists... */
psPrimSurf = &(psDevData->psDevInfoKM->sDeviceSpecific.sDisplay.sPrimarySurface);
if (psPrimSurf->bValid)
{
/* If it does, we can only acquire it if the width/height/format
* values match (PVRSRVQueryPrimary can be called to obtain these)
*/
if ((uiPixelWidth != psPrimSurf->ui32PixelWidth) || (uiPixelHeight != psPrimSurf->ui32PixelHeight) || (ePixelFormat != psPrimSurf->ePixelFormat))
{
PVR_DPF((PVR_DBG_ERROR, "%s: Cannot acquire primary surface as passed values don't match existing values", "PVRSRVAcquirePrimary"));
PVR_DPF((PVR_DBG_ERROR, " [existing: %dx%d (%d), passed: %dx%d (%d)",
psPrimSurf->ui32PixelWidth, psPrimSurf->ui32PixelHeight, psPrimSurf->ePixelFormat,
uiPixelWidth, uiPixelHeight, ePixelFormat));
return PVRSRV_ERROR_GENERIC;
}
/* Providing everything is okay, we don't actually need to do
* anything except increment our usage counter for the surface.
*/
PVR_DPF((PVR_DBG_MESSAGE, "%s: Using previously acquired primary surface (0x%08x)", "PVRSRVAcquirePrimary", psPrimSurf));
psPrimSurf->i32RefCountKM++;
*ppsPrimarySurf = psPrimSurf;
}
else
{
/* If the surface doesn't exist, we're the first to acquire it so
* we must also create it.
*/
IMG_UINT32 uiBytesPerPixel = CalcBytesPerPixel(ePixelFormat);
IMG_UINT32 uiByteStride = uiPixelWidth * uiBytesPerPixel;
IMG_UINT32 ui32RequiredBufferSize = uiPixelHeight * uiByteStride;
PVRSRV_ERROR eError;
PVR_DPF((PVR_DBG_MESSAGE, "%s: First call - creating the primary surface", "PVRSRVAcquirePrimary"));
eError = PVRSRVAllocDeviceMem( psDevData,
ui32Flags,
ui32RequiredBufferSize,
MBX1_TSPPL2_TEXADDRALIGNSIZE, /*FIXME :need to base this on render requirement*/
&(psPrimSurf->psMemInfo));
if (eError == PVRSRV_OK)
{
psPrimSurf->ui32ByteStride = uiByteStride;
psPrimSurf->ui32PixelWidth = uiPixelWidth;
psPrimSurf->ui32PixelHeight = uiPixelHeight;
psPrimSurf->ePixelFormat = ePixelFormat;
psPrimSurf->i32RefCountKM = 1;
psPrimSurf->psPrimSurfKM = psPrimSurf;
*ppsPrimarySurf = psPrimSurf;
/* Register the primary surface with the resource manager so
* that if all Services clients exit with never freeing the
* surface, it will be done automatically.
*/
if(ResManRegisterRes( (PRESMAN_ITEM)IMG_NULL,
RESMAN_TYPE_PRIMSURF,
psDevData,
(IMG_UINT32)psPrimSurf,
DestroyPrimaryCallBack,
RESMAN_AUTOFREE_LEV2) == IMG_NULL)
{
PVR_DPF((PVR_DBG_ERROR, "%s: Failed to register resource", "PVRSRVAcquirePrimary"));
PVRSRVFreeDeviceMem(psDevData, psPrimSurf->psMemInfo);
*ppsPrimarySurf = IMG_NULL;
return PVRSRV_ERROR_GENERIC;
}
/* We now have a valid primary surface, so mark it as such */
psPrimSurf->bValid = IMG_TRUE;
}
else
{
PVR_DPF((PVR_DBG_ERROR, "%s: Failed to allocate device memory for primary surface", "PVRSRVAcquirePrimary"));
*ppsPrimarySurf = IMG_NULL;
return PVRSRV_ERROR_OUT_OF_MEMORY;
}
}
PVR_DPF((PVR_DBG_MESSAGE, "%s: Primary surface acquired", "PVRSRVAcquirePrimary"));
return PVRSRV_OK;
}
/*!
******************************************************************************
@Function PVRSRVReleasePrimary
@Description
Releases a previously acquired primary surface.
@Input *psDevData : Must refer to a display device
*psPrimarySurf : Pointer to the primary surface to release
@Output -- none --
@Return PVRSRV_OK : success
PVRSRV_ERROR_INVALID_PARAMS : parameters passed are invalid
PVRSRV_ERROR_NO_PRIMARY : no primary surface has been acquired
******************************************************************************/
IMG_EXPORT
PVRSRV_ERROR IMG_CALLCONV PVRSRVReleasePrimary( PVRSRV_DEV_DATA *psDevData,
PVRSRV_PRIMARY_SURF *psPrimarySurf)
{
if ((psDevData == IMG_NULL) || (psPrimarySurf == IMG_NULL))
{
return PVRSRV_ERROR_INVALID_PARAMS;
}
/* Check to see whether we've been passed a display device or not */
if (psDevData->psDevInfoKM->sDevId.eDeviceClass != PVRSRV_DEVICE_CLASS_DISPLAY)
{
PVR_DPF((PVR_DBG_ERROR, "%s: Device does not have flip capabilities", "PVRSRVReleasePrimary"));
return PVRSRV_ERROR_INVALID_PARAMS;
}
return ResManFreeResByCriteria(RESMAN_CRITERIA_RESTYPE | RESMAN_CRITERIA_FREEONCE, RESMAN_TYPE_PRIMSURF, 0, 0, 0);
}
/*!
******************************************************************************
@Function PVRSRVRegisterPrimary
@Description
Register a primary surface which has already been created (e.g. by the Wince GPE driver)
@Input *psDevData : Must refer to a display device
sPrimSurf : Contains info about the surface being registered
@Output :
@Return PVRSRV_ERROR :
******************************************************************************/
IMG_EXPORT PVRSRV_ERROR IMG_CALLCONV PVRSRVRegisterPrimary(PVRSRV_DEV_DATA *psDevData,
PVRSRV_PRIMARY_SURF sPrimSurf)
{
PVRSRV_ERROR eError = PVRSRV_OK;
PVRSRV_PRIMARY_SURF *psPrimSurf;
psPrimSurf = &(psDevData->psDevInfoKM->sDeviceSpecific.sDisplay.sPrimarySurface);
/* Is the primary already there? */
if(!psPrimSurf->bValid)
{
psPrimSurf->i32RefCountKM = 1;
}
psPrimSurf->ePixelFormat = sPrimSurf.ePixelFormat;
psPrimSurf->ui32ByteStride = sPrimSurf.ui32ByteStride;
psPrimSurf->ui32PixelWidth = sPrimSurf.ui32PixelWidth;
psPrimSurf->ui32PixelHeight = sPrimSurf.ui32PixelHeight;
psPrimSurf->psPrimSurfKM = psPrimSurf;
psPrimSurf->psMemInfo=sPrimSurf.psMemInfo;
if(ResManRegisterRes(( PRESMAN_ITEM)IMG_NULL,
RESMAN_TYPE_PRIMSURF,
psDevData,
(IMG_UINT32)psPrimSurf,
DestroyPrimaryCallBack,
RESMAN_AUTOFREE_LEV2)== IMG_NULL)
{
/*
n.b. we don't test the return value because it's OK to fail
if this is called by the GWES
*/
PVR_DPF((PVR_DBG_ERROR,"Register primary with resman failed"));
PVR_DPF((PVR_DBG_ERROR,"Probably the (WINCE)GWES, which hasn't connected to the resman"));
}
psPrimSurf->bValid = IMG_TRUE;
return eError;
}
/*!
******************************************************************************
@Function PVRSRVGetHWInfo
@Description
Gets linear pointers to FB, Registers, slaveports etc
@Input psDevData :
@Output psHWInfo :
@Return PVRSRV_ERROR :
******************************************************************************/
PVRSRV_ERROR IMG_CALLCONV PVRSRVGetHWInfo( PVRSRV_DEV_DATA *psDevData,
PVRSRV_HW_INFO *psHWInfo)
{
PVRSRV_DEV_LOCATION *psDevLocation = IMG_NULL;
if ((psDevData == IMG_NULL) || (psHWInfo == IMG_NULL))
{
return PVRSRV_ERROR_INVALID_PARAMS;
}
psDevLocation = &(psDevData->psDevInfoKM->sDevLocation);
psHWInfo->pvRegsBase = psDevLocation->pvRegsBaseKM;
psHWInfo->pui32KickerAddr = psDevData->psDevInfoKM->pui32KickerAddrKM;
psHWInfo->pvSOCRegsBase = psDevLocation->pvSOCRegsBaseKM;
/* Fill on device type specific mappings */
switch(psDevData->psDevInfoKM->sDevId.eDeviceType)
{
case PVRSRV_DEVICE_TYPE_MBX1:
case PVRSRV_DEVICE_TYPE_MBX1_LITE:
{
psHWInfo->sDeviceSpecific.sMBX.sTASlavePort.pvData =
psDevLocation->sDeviceSpecific.sMBX.sTASlavePort.pvData;
psHWInfo->sDeviceSpecific.sMBX.sTASlavePort.ui32DataRange =
psDevLocation->sDeviceSpecific.sMBX.sTASlavePort.ui32DataRange;
psHWInfo->sDeviceSpecific.sMBX.sTASlavePort.pui32Offset =
&psDevData->psDevInfoKM->sDeviceSpecific.s3D.ui32TASlavePortOffset;
psHWInfo->sDeviceSpecific.sMBX.s2DSlavePort.pvData =
psDevLocation->sDeviceSpecific.sMBX.s2DSlavePort.pvData;
psHWInfo->sDeviceSpecific.sMBX.s2DSlavePort.ui32DataRange =
psDevLocation->sDeviceSpecific.sMBX.s2DSlavePort.ui32DataRange;
psHWInfo->sDeviceSpecific.sMBX.s2DSlavePort.pui32Offset =
&psDevData->psDevInfoKM->sDeviceSpecific.s3D.ui322DSlavePortOffset;
psHWInfo->sDeviceSpecific.sMBX.sTAControlSlavePort.pvData =
psDevLocation->sDeviceSpecific.sMBX.sTAControlSlavePort.pvData;
psHWInfo->sDeviceSpecific.sMBX.sTAControlSlavePort.ui32DataRange =
psDevLocation->sDeviceSpecific.sMBX.sTAControlSlavePort.ui32DataRange;
psHWInfo->sDeviceSpecific.sMBX.sTAControlSlavePort.pui32Offset =
&psDevData->psDevInfoKM->sDeviceSpecific.s3D.ui32TAControlSlavePortOffset;
}
break;
#if defined(SUPPORT_DEVCLASS_MPEG)
case PVRSRV_DEVICE_TYPE_M24VA:
{
IMG_PVOID pvSlavePortBase;
pvSlavePortBase = psDevLocation->sDeviceSpecific.sM24VA.pvSPLinearBase;
psHWInfo->sDeviceSpecific.sM24VA.pvSPLinearBase = pvSlavePortBase;
psHWInfo->sDeviceSpecific.sM24VA.pvSPCmd = (IMG_UINT32*)((IMG_UINT32)pvSlavePortBase
+ M24VA_SP_CMD_OFFSET);
psHWInfo->sDeviceSpecific.sM24VA.pvSPIDCT = (IMG_UINT32*)((IMG_UINT32)pvSlavePortBase
+ M24VA_SP_IDCT_OFFSET);
}
break;
#endif
case PVRSRV_DEVICE_TYPE_JDISPLAY:
case PVRSRV_DEVICE_TYPE_PDP:
case PVRSRV_DEVICE_TYPE_CRTC:
break;
default:
PVR_DPF((PVR_DBG_ERROR, "PVRSRVAcquireDeviceData : Attempted to set up HWInfo info for an unknown device type."));
return PVRSRV_ERROR_INVALID_DEVICE;
}
return PVRSRV_OK;
}
/*!
******************************************************************************
@Function PollForValueKM
@Description
Polls for a value to match a masked read of sysmem
@Input pui32LinMemAddr : CPU linear address of the mem to poll
@Input ui32Value : req'd value
@Input ui32Mask : Mask
@Input ui32Waitus : wait between tries (us)
@Input ui32Tries : number of tries
@Return PVRSRV_ERROR :
******************************************************************************/
IMG_EXPORT
PVRSRV_ERROR PollForValueKM ( volatile IMG_UINT32* pui32LinMemAddr,
IMG_UINT32 ui32Value,
IMG_UINT32 ui32Mask,
IMG_UINT32 ui32Waitus,
IMG_UINT32 ui32Tries)
{
while(ui32Tries--)
{
if((*pui32LinMemAddr & ui32Mask) == ui32Value)
{
return PVRSRV_OK;
}
HostWaitus(ui32Waitus);
}
return PVRSRV_ERROR_GENERIC;
}
/*!
******************************************************************************
@Function PVRSRVGetFBStats
@Description
Gets total and available frame buffer memory
@Output pui32Total
@Output pui32Available
@Return PVRSRV_ERROR :
******************************************************************************/
PVRSRV_ERROR PVRSRVGetFBStats(PVRSRV_DEV_DATA *psDevData,
IMG_UINT32 *pui32Total,
IMG_UINT32 *pui32Available)
{
IMG_UINT32 ui32Total;
IMG_UINT32 ui32Available;
/* External Dev memory */
if(BM_ContiguousStatistics(0,
pui32Total,
pui32Available) != IMG_TRUE)
{
return PVRSRV_ERROR_GENERIC;
}
/* Internal Dev memory */
if(BM_ContiguousStatistics(1,
&ui32Total,
&ui32Available) != IMG_TRUE)
{
return PVRSRV_ERROR_GENERIC;
}
*pui32Total += ui32Total;
*pui32Available += ui32Available;
return PVRSRV_OK;
}
/*--------------------------------- end of file ------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -