📄 surface.c
字号:
psSurf = psContext->sChain.psCurrentBuffer;
for(i=0; i<psContext->sChain.dwSuppliedBackBuffers; i++)
{
psSurf->psNext = psContext->sChain.psBackBuffers[i];
/* advance surface */
psSurf = psSurf->psNext;
}
/* and wrap back to primary */
psContext->sChain.psBackBuffers[i-1]->psNext = psContext->sChain.psCurrentBuffer;
/* advance to next surface to stop advancing to the same surface first time round */
psContext->sChain.psCurrentBuffer = psContext->sChain.psCurrentBuffer->psNext;
}
pcsd->rval = D3DM_OK;
return;
error_exit:
/* clean up and exit */
if(psSurface->sDescription.sSurface.psTARenderInfo && bRenderInfoCreated)
D3DMDisconnectRenderTarget(psContext, psSurface);
if(psSurface->psMemInfo)
D3DMFreeDeviceMem(&psContext->sDevData, psSurface->psMemInfo);
D3DMFree(psSurface);
}
/*----------------------------------------------------------------------------
<function>
FUNCTION: CreateSurface
PURPOSE: Creates a D3D mobile surface and acquires necessary hardware
resources
PARAMETERS: In: pcsd - surface creation data
RETURNS:
</function>
------------------------------------------------------------------------------*/
VOID CreateSurface(D3DM_CREATESURFACE_DATA *pcsd)
{
/***************************
* IMAGE_SURFACE *
***************************/
LPD3DM_SURFACE psSurface = NULL;
LPD3DM_CONTEXT psContext;
PVR_DEVFORMAT *psDevFormat = NULL;
DWORD dwSize;
PVRSRV_ERROR eError;
psContext = (LPD3DM_CONTEXT) pcsd->nContextId;
/* Allocate the surface structure */
psSurface = D3DMAllocate(sizeof(D3DM_SURFACE));
if(psSurface == NULL)
{
D3DM_DPF((DPF_ERROR, "CreateSurface:Insufficient system memory to create surface"));
pcsd->rval = D3DMERR_DRIVERINTERNALERROR;
return;
}
memset(psSurface, 0, sizeof(D3DM_SURFACE));
/* Get format descriptor */
psDevFormat = GetFormatDescriptorD3DM(psContext, pcsd->SurfaceDesc.Format);
/* Check for supported format */
if(psDevFormat == NULL || !(psDevFormat->sD3DDevFormat.TypeFlags & D3DMRTYPEFLAG_SURFACE))
{
D3DM_DPF((DPF_ERROR ,"CreateSurface:Unsupported Image Surface format requested"));
pcsd->rval = D3DMERR_DRIVERUNSUPPORTED;
goto error_exit;
}
/* Validate memory pool */
if(!ValidatePoolType(pcsd->SurfaceType, pcsd->SurfaceDesc.Pool))
{
D3DM_DPF((DPF_ERROR ,"CreateSurface:Unsupported memory pool requested"));
pcsd->rval = D3DMERR_DRIVERUNSUPPORTED;
goto error_exit;
}
/* Fill in some data */
FillInCommonDetails(psSurface, pcsd, FALSE);
psSurface->dwBpp = psDevFormat->dwBpp;
psSurface->dwStridePixel = (psSurface->dwWidth + (MBX1_TEXSTRIDE_PIXEL_GRAN - 1))
& ~(MBX1_TEXSTRIDE_PIXEL_GRAN - 1);
psSurface->dwStrideByte = (psSurface->dwStridePixel * psSurface->dwBpp) >> 3;
/* Calculate render target size in bytes */
dwSize = psSurface->dwStrideByte *
pcsd->SurfaceDesc.Height;
/* Create surface */
if((eError = D3DMAllocDeviceMem(&psContext->sDevData,
0,
dwSize,
MBX1_TSPPL2_TEXADDRALIGNSIZE,
&psSurface->psMemInfo)) != PVRSRV_OK)
{
D3DM_DPF((DPF_ERROR,"CreateSurface:Failed to allocate surface memory"));
if(eError == PVRSRV_ERROR_OUT_OF_MEMORY)
pcsd->rval = D3DMERR_MEMORYPOOLEMPTY;
else
pcsd->rval = D3DMERR_DRIVERINTERNALERROR;
goto error_exit;
}
/* We are creating a rendertarget so create renderinfo */
if(pcsd->SurfaceDesc.Usage & D3DMUSAGE_RENDERTARGET)
{
DWORD dwAAFlags;
LPD3DM_SURFACE psTemp;
/* Set up AA Flags */
dwAAFlags = SetUpAntialias(pcsd->SurfaceDesc.MultiSampleType, psContext);
/* Connect the render target to the services */
if(D3DMConnectRenderTarget(psContext, psSurface, dwAAFlags, D3DM_DEFAULT_PB_PAGES) != PVRSRV_OK)
{
D3DM_DPF((DPF_ERROR, "CreateSurface:Failed to Connect render target"));
pcsd->rval = D3DMERR_DRIVERINTERNALERROR;
goto error_exit;
}
psTemp = psContext->psNonChainRenderTargets;
if(psTemp)
{
/* Add to non chain RT List */
while(psTemp->psNext != NULL)
{
psTemp = psTemp->psNext;
}
psTemp->psNext = psSurface;
}
else
{
psContext->psNonChainRenderTargets = psSurface;
}
}
/* Write back the surface size value */
pcsd->SurfaceDesc.Size = dwSize;
/* Record the surface pointer as surface ID */
pcsd->nSurfaceId = (ULONG) psSurface;
pcsd->rval = D3DM_OK;
return;
error_exit:
/* clean up and exit */
if(psSurface->sDescription.sSurface.psTARenderInfo)
D3DMDisconnectRenderTarget(psContext, psSurface);
if(psSurface->psMemInfo)
D3DMFreeDeviceMem(&psContext->sDevData, psSurface->psMemInfo);
D3DMFree(psSurface);
}
/*----------------------------------------------------------------------------
<function>
FUNCTION: CreateDepthBuffer
PURPOSE: Creates a D3D mobile Depth buffer
PARAMETERS: In: pcsd - surface creation data
RETURNS:
</function>
------------------------------------------------------------------------------*/
VOID CreateDepthBuffer(D3DM_CREATESURFACE_DATA *pcsd)
{
/***************************
* Z-BUFFER *
***************************/
DWORD dwForceZ = 0;
CHAR szTemp[128];
LPD3DM_SURFACE psSurface = NULL;
LPD3DM_CONTEXT psContext;
PVR_DEVFORMAT *psDevFormat = NULL;
psContext = (LPD3DM_CONTEXT) pcsd->nContextId;
/* Allocate the surface structure */
psSurface = D3DMAllocate(sizeof(D3DM_SURFACE));
if(psSurface == NULL)
{
D3DM_DPF((DPF_ERROR, "CreateSurface:Insufficient system memory to create surface"));
pcsd->rval = D3DMERR_DRIVERINTERNALERROR;
return;
}
memset(psSurface, 0, sizeof(D3DM_SURFACE));
/* Get format descriptor */
psDevFormat = GetFormatDescriptorD3DM(psContext, pcsd->SurfaceDesc.Format);
/* Check for supported format */
if(psDevFormat == NULL || !(psDevFormat->sD3DDevFormat.TypeFlags & D3DMRTYPEFLAG_DEPTHSTENCIL))
{
D3DM_DPF((DPF_ERROR ,"CreateDepthBuffer:Unsupported Depth Buffer format requested"));
pcsd->rval = D3DMERR_DRIVERUNSUPPORTED;
goto error_exit;
}
/* Fill in some data */
FillInCommonDetails(psSurface, pcsd, FALSE);
psSurface->dwBpp = psDevFormat->dwBpp;
psSurface->dwStrideByte = (((psSurface->dwWidth * psSurface->dwBpp) >> 3)
+ MBX1_FBLINESTRIDE_ALIGNMASK) & ~MBX1_FBLINESTRIDE_ALIGNMASK;
psSurface->dwStridePixel = (psSurface->dwStrideByte << 3) / psSurface->dwBpp;
/* Validate memory pool */
if(!ValidatePoolType(pcsd->SurfaceType, pcsd->SurfaceDesc.Pool))
{
D3DM_DPF((DPF_ERROR ,"CreateDepthBuffer:Unsupported memory pool requested"));
pcsd->rval = D3DMERR_DRIVERUNSUPPORTED;
goto error_exit;
}
/* Check if we are forcing Zbuffer creation */
sprintf(szTemp, "%s%s", POWERVR_REG_ROOT, D3DM_REGAPPHINTCOMMON_ROOT);
D3DMGetAppHint(0, szTemp, "ForceExternalZBuffer", &dwForceZ);
/*
Flag the Z-Buffer for creation now if required.
It will be created when the corresponding render target is set.
*/
if((psContext->sRegData.dwFlags & D3DMREG_COMPLEX_SCENE) || dwForceZ)
{
psSurface->dwFlags |= D3DM_SURFACE_FLAGS_CREATE_Z_BUFFER;
}
/* Write back the surface size value */
pcsd->SurfaceDesc.Size = (psSurface->dwWidth * psSurface->dwHeight * psSurface->dwBpp) >> 3;
/* Record the surface pointer as surface ID */
pcsd->nSurfaceId = (ULONG) psSurface;
return;
error_exit:
/* clean up and exit */
if(psSurface->psMemInfo)
D3DMFreeDeviceMem(&psContext->sDevData, psSurface->psMemInfo);
D3DMFree(psSurface);
pcsd->rval = D3DM_OK;
}
/*----------------------------------------------------------------------------
<function>
FUNCTION: CreateVBuffer
PURPOSE: Creates a D3D mobile Vertex buffer
PARAMETERS: In: pcsd - surface creation data
RETURNS:
</function>
------------------------------------------------------------------------------*/
VOID CreateVBuffer(D3DM_CREATESURFACE_DATA *pcsd)
{
D3DMVERTEXBUFFER_DESC *psVertexDesc = &pcsd->VertexDesc;
LPD3DM_VBUFFER psBuffer = NULL;
LPD3DM_CONTEXT psContext = (LPD3DM_CONTEXT) pcsd->nContextId;
/* Validate FVF */
if(!ValidateFVF(psVertexDesc->FVF))
{
D3DM_DPF((DPF_ERROR ,"CreateVBuffer:Unsupported FVF passed in"));
pcsd->rval = D3DMERR_DRIVERUNSUPPORTED;
return;
}
/* Validate memory pool */
if(!ValidatePoolType(pcsd->SurfaceType, pcsd->SurfaceDesc.Pool))
{
D3DM_DPF((DPF_ERROR ,"CreateVBuffer:Unsupported memory pool requested"));
pcsd->rval = D3DMERR_DRIVERUNSUPPORTED;
return;
}
/* Create Vertex buffer Object */
psBuffer = D3DMAllocate(sizeof(D3DM_VBUFFER));
if(psBuffer == NULL)
{
D3DM_DPF((DPF_ERROR, "CreateVBuffer:Insufficient system memory to create Buffer"));
pcsd->rval = D3DMERR_DRIVERINTERNALERROR;
return;
}
memset(psBuffer, 0, sizeof(D3DM_VBUFFER));
/* Copy Buffer Data */
psBuffer->dwFVFFlags = psVertexDesc->FVF;
psBuffer->dwSizeDW = psVertexDesc->Size >> 2; /* As DWORD's */
psBuffer->dwStrideDW = GetVertexSizeBytes(psBuffer->dwFVFFlags) >> 2;
/* Create Memory buffer */
psBuffer->pvVertexData = D3DMAllocate(psVertexDesc->Size);
if(psBuffer->pvVertexData == NULL)
{
D3DM_DPF((DPF_ERROR, "CreateVBuffer:Insufficient system memory to create Buffer"));
D3DMFree(psBuffer);
pcsd->rval = D3DMERR_DRIVERINTERNALERROR;
return;
}
memset(psBuffer->pvVertexData, 0, psVertexDesc->Size);
#if defined (SUPPORT_VGP) || defined (SUPPORT_VGP_LITE)
/* Set up VGP input format definition */
VSIFDefSetupForFVF(psContext, &psBuffer->sVSIFDef, psBuffer->dwFVFFlags, (psBuffer->dwStrideDW << 2));
#endif
psBuffer->eSurfaceType = pcsd->SurfaceType;
psBuffer->dwUsage = psVertexDesc->Usage;
/* Record the buffer pointer as surface ID */
pcsd->nSurfaceId = (ULONG) psBuffer;
pcsd->rval = D3DM_OK;
}
/*----------------------------------------------------------------------------
<function>
FUNCTION: CreateIBuffer
PURPOSE: Creates a D3D mobile Index buffer
PARAMETERS: In: pcsd - surface creation data
RETURNS:
</function>
------------------------------------------------------------------------------*/
VOID CreateIBuffer(D3DM_CREATESURFACE_DATA *pcsd)
{
D3DMINDEXBUFFER_DESC *psIndexDesc = &pcsd->IndexDesc;
LPD3DM_IBUFFER psBuffer = NULL;
/* Validate memory pool */
if(!ValidatePoolType(pcsd->SurfaceType, pcsd->SurfaceDesc.Pool))
{
D3DM_DPF((DPF_ERROR ,"CreateIBuffer:Unsupported memory pool requested"));
pcsd->rval = D3DMERR_DRIVERUNSUPPORTED;
return;
}
/* Create Vertex buffer Object */
psBuffer = D3DMAllocate(sizeof(D3DM_IBUFFER));
if(psBuffer == NULL)
{
D3DM_DPF((DPF_ERROR, "CreateIBuffer:Insufficient system memory to create Buffer"));
pcsd->rval = D3DMERR_DRIVERINTERNALERROR;
return;
}
memset(psBuffer, 0, sizeof(D3DM_IBUFFER));
/* Copy Buffer Data */
psBuffer->eFormat = psIndexDesc->Format;
psBuffer->dwSizeByte = psIndexDesc->Size;
psBuffer->dwStrideByte = (psBuffer->eFormat == D3DMFMT_INDEX32) ? 4 : 2;
/* Create Memory buffer */
psBuffer->pvIndexData = D3DMAllocate(psIndexDesc->Size);
if(psBuffer->pvIndexData == NULL)
{
D3DM_DPF((DPF_ERROR, "CreateIBuffer:Insufficient system memory to create Buffer"));
D3DMFree(psBuffer);
pcsd->rval = D3DMERR_DRIVERINTERNALERROR;
return;
}
memset(psBuffer->pvIndexData, 0, psIndexDesc->Size);
psBuffer->eSurfaceType = pcsd->SurfaceType;
psBuffer->dwUsage = psIndexDesc->Usage;
/* Record the buffer pointer as surface ID */
pcsd->nSurfaceId = (ULONG) psBuffer;
pcsd->rval = D3DM_OK;
}
/*----------------------------------------------------------------------------
<function>
FUNCTION: DestroyFrontBuffer
PURPOSE: Destroys a front buffer
PARAMETERS: In: pcsd - surface creation data
RETURNS:
</function>
------------------------------------------------------------------------------*/
VOID DestroyFrontBuffer(D3DM_DESTROYSURFACE_DATA *pdsd)
{
/***************************
* PRIMARY *
***************************/
LPD3DM_SURFACE psSurface = (LPD3DM_SURFACE) pdsd->nSurfaceId;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -