📄 surface.c
字号:
/******************************************************************************
<module>
* Name : Surface.c
* Title : D3DM Surface Callbacks
* Author(s) : Imagination Technologies
* Created : 2 March 2004
*
* Copyright : 2004 by Imagination Technologies Limited.
* All rights reserved. No part of this software, either
* material or conceptual may be copied or distributed,
* transmitted, transcribed, stored in a retrieval system
* or translated into any human or computer language in any
* form by any means, electronic, mechanical, manual or
* other-wise, or disclosed to third parties without the
* express written permission of Imagination Technologies
* Limited, Unit 8, HomePark Industrial Estate,
* King's Langley, Hertfordshire, WD4 8LZ, U.K.
*
* Description : Entry Points for D3DMobile surface callbacks.
*
* Platform : Windows CE
*
</module>
********************************************************************************/
#include "context.h"
/*----------------------------------------------------------------------------
<function>
FUNCTION: FillInCommonDetails
PURPOSE: Fills in Surface details from surface description
PARAMETERS: In: psSurface - Surface to fill in
In: pcsd - surface creation data
RETURNS:
</function>
------------------------------------------------------------------------------*/
VOID FillInCommonDetails(LPD3DM_SURFACE psSurface, D3DM_CREATESURFACE_DATA *pcsd, BOOL bSwitchDim)
{
/* Fill in common surface details */
psSurface->psContext = (LPD3DM_CONTEXT) pcsd->nContextId;
psSurface->eSurfaceType = pcsd->SurfaceType;
psSurface->dwUsage = pcsd->SurfaceDesc.Usage;
psSurface->eFormat = pcsd->SurfaceDesc.Format;
psSurface->eMultiSampleType = pcsd->SurfaceDesc.MultiSampleType;
psSurface->dwStridePixel = bSwitchDim ? pcsd->SurfaceDesc.Height : pcsd->SurfaceDesc.Width;/* assume contiguous by default */
psSurface->dwWidth = bSwitchDim ? pcsd->SurfaceDesc.Height : pcsd->SurfaceDesc.Width;
psSurface->dwHeight = bSwitchDim ? pcsd->SurfaceDesc.Width : pcsd->SurfaceDesc.Height;
}
/*****************************************************************************
FUNCTION : ZLSAlloc
PURPOSE : Creates ZLS videomemory buffer plus system memory
depth buffer for app/HW to read from & write into.
PARAMETERS : psContext
RETURNS : BOOL
*****************************************************************************/
IMG_BOOL ZLSAlloc(LPD3DM_CONTEXT psContext)
{
PPVRSRV_MEM_INFO psMemInfo;
DWORD dwAllocSize;
DWORD dwBytesPerPixel;
DWORD dwPixelWidth;
DWORD dwPixelHeight;
PVR3DIF_SHAREDDATA *psSharedData;
DEVICE3D *ps3D;
ps3D = &GetDevInfo(psContext)->sDeviceSpecific.s3D;
psSharedData = psContext->psCurrentRenderTarget->sDescription.sSurface.psTARenderInfo->psSharedData;
D3DM_DPF((DPF_MESSAGE, "ZLSAlloc"));
dwBytesPerPixel = psContext->psCurrentDepthBuffer->dwBpp >> 3;
dwPixelWidth = psSharedData->ui32XTilesPerMT * psSharedData->ui32MTilesX * ps3D->ui32PixelsInTileX;
dwPixelHeight = psSharedData->ui32YTilesPerMT * psSharedData->ui32MTilesY * ps3D->ui32PixelsInTileY;
psContext->psCurrentDepthBuffer->dwWidth = dwPixelWidth;
psContext->psCurrentDepthBuffer->dwHeight = dwPixelHeight;
dwAllocSize = dwPixelWidth * dwBytesPerPixel * dwPixelHeight;
if(D3DMAllocDeviceMem (&psContext->sDevData,
0,
dwAllocSize,
MBX1_ZBASEADDR_ALIGNSIZE,
&psMemInfo) != PVRSRV_OK)
{
D3DM_DPF((DPF_ERROR, "ZLSAlloc - Failed to allocate surface memory..."));
return FALSE;
}
/* Store to the depth buffer */
psContext->psCurrentDepthBuffer->psMemInfo = psMemInfo;
PDUMPREGISTERTEX(psContext->psPDContext, psMemInfo);
return TRUE;
}
/*----------------------------------------------------------------------------
<function>
FUNCTION: CreateFrontBuffer
PURPOSE: Creates a D3D mobile front buffer and acquires necessary hardware
resources
PARAMETERS: In: pcsd - surface creation data
RETURNS:
</function>
------------------------------------------------------------------------------*/
VOID CreateFrontBuffer(D3DM_CREATESURFACE_DATA *pcsd)
{
/***************************
* PRIMARY *
***************************/
LPD3DM_SURFACE psSurface = NULL;
LPD3DM_CONTEXT psContext = (LPD3DM_CONTEXT)pcsd->nContextId;
PVR_DEVFORMAT *psDevFormat = NULL;
D3DMFRONTBUFFER_DESC *psFrontbufferDesc = &pcsd->FrontDesc;
IMG_BOOL bFlipCoords = (psContext->dwRotationAngle == 90 ||
psContext->dwRotationAngle == 270);
/* Allocate the surface structure */
psSurface = D3DMAllocate(sizeof(D3DM_SURFACE));
if(psSurface == NULL)
{
D3DM_DPF((DPF_ERROR, "CreateFrontBuffer:Insufficient system memory to create surface"));
pcsd->rval = D3DMERR_DRIVERINTERNALERROR;
return;
}
memset(psSurface, 0, sizeof(D3DM_SURFACE));
/* Obtain current rendering context */
psSurface->psContext = psContext;
/* Get format descriptor for current display mode format */
psDevFormat = GetFormatDescriptorPVR(psContext->psPrimSurfData->ePixelFormat);
if(psDevFormat == NULL || !(psDevFormat->sD3DDevFormat.TypeFlags & D3DMRTYPEFLAG_FRONTBUFFER))
{
D3DM_DPF((DPF_ERROR, "CreateFrontBuffer:No D3DM Format matches display mode"));
pcsd->rval = D3DMERR_DRIVERINTERNALERROR;
goto error_exit;
}
/* Write back primary stats */
if(ValidatePoolType(pcsd->SurfaceType, D3DMPOOL_SYSTEMMEM))
pcsd->SurfaceDesc.Pool = D3DMPOOL_SYSTEMMEM;
else
pcsd->SurfaceDesc.Pool = D3DMPOOL_VIDEOMEM;
pcsd->SurfaceDesc.Format = psDevFormat->sD3DDevFormat.Format;
pcsd->SurfaceDesc.Width = bFlipCoords ? psContext->psPrimSurfData->ui32PixelHeight : psContext->psPrimSurfData->ui32PixelWidth;
pcsd->SurfaceDesc.Height = bFlipCoords ? psContext->psPrimSurfData->ui32PixelWidth : psContext->psPrimSurfData->ui32PixelHeight;
pcsd->SurfaceDesc.Size = psContext->psPrimSurfData->ui32ByteStride *
psContext->psPrimSurfData->ui32PixelHeight;
/* Fill in common surface details */
psSurface->eSurfaceType = pcsd->SurfaceType;
psSurface->eFormat = psDevFormat->sD3DDevFormat.Format;
psSurface->dwBpp = psDevFormat->dwBpp;
psSurface->eMultiSampleType = pcsd->SurfaceDesc.MultiSampleType;
psSurface->dwWidth = psContext->psPrimSurfData->ui32PixelWidth;
psSurface->dwHeight = psContext->psPrimSurfData->ui32PixelHeight;
psSurface->dwStrideByte = psContext->psPrimSurfData->ui32ByteStride;
psSurface->dwStridePixel = (psContext->psPrimSurfData->ui32ByteStride << 3) / psDevFormat->dwBpp;
/* Wrap the primary surf memory */
psSurface->psMemInfo = psContext->psPrimSurfData->psMemInfo;
/* Set the surface as current display surface for the context */
psContext->psCurrentDisplay = psSurface;
/* Store as Primary */
psContext->sChain.psPrimary = psSurface;
if(psContext->SwapEffect == D3DMSWAPEFFECT_FLIP)
{
DWORD dwAAFlags;
/* We are creating the primary as part of a flip chain so create renderinfo now */
/* this is a render target */
psSurface->dwUsage = D3DMUSAGE_RENDERTARGET;
/* 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, "CreateFrontBuffer:Failed to Connect render target"));
pcsd->rval = D3DMERR_DRIVERINTERNALERROR;
goto error_exit;
}
}
/* Store the hardware format */
psSurface->sDescription.sSurface.ePVRFormat = psContext->psPrimSurfData->ePixelFormat;
/* Record the surface pointer as surface ID */
pcsd->nSurfaceId = (ULONG) psSurface;
/* Record number of back buffers */
psContext->sChain.dwTotalBackBuffers = psFrontbufferDesc->TotalBackBuffers;
pcsd->rval = D3DM_OK;
return;
error_exit:
/* clean up and exit */
if(psSurface->sDescription.sSurface.psTARenderInfo)
D3DMDisconnectRenderTarget(psContext, psSurface);
D3DMFree(psSurface);
}
/*----------------------------------------------------------------------------
<function>
FUNCTION: CreateBackBuffer
PURPOSE: Creates a D3D mobile back buffer and acquires necessary hardware
resources
PARAMETERS: In: pcsd - surface creation data
RETURNS:
</function>
------------------------------------------------------------------------------*/
VOID CreateBackBuffer(D3DM_CREATESURFACE_DATA *pcsd)
{
/***************************
* BACKBUFFER *
***************************/
LPD3DM_SURFACE psTarget;
LPD3DM_SURFACE psSurface = NULL;
LPD3DM_CONTEXT psContext = (LPD3DM_CONTEXT) pcsd->nContextId;
PVR_DEVFORMAT *psDevFormat = NULL;
DWORD dwSize;
D3DMBACKBUFFER_DESC *psBackbufferDesc = &pcsd->BackDesc;
DWORD dwAAFlags;
DWORD i;
DWORD dwMemFlags = 0;
PVRSRV_ERROR eError;
BOOL bRenderInfoCreated = FALSE;
BOOL bSwitchDimensions = FALSE;
dwAAFlags = 0;
/* Allocate the surface structure */
psSurface = D3DMAllocate(sizeof(D3DM_SURFACE));
if(psSurface == NULL)
{
D3DM_DPF((DPF_ERROR, "CreateBackBuffer: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_BACKBUFFER))
{
D3DM_DPF((DPF_ERROR ,"CreateBackBuffer:Unsupported Render target format requested"));
pcsd->rval = D3DMERR_DRIVERUNSUPPORTED;
goto error_exit;
}
/* Validate memory pool */
if(!ValidatePoolType(pcsd->SurfaceType, pcsd->SurfaceDesc.Pool))
{
D3DM_DPF((DPF_ERROR ,"CreateBackBuffer:Unsupported memory pool requested"));
pcsd->rval = D3DMERR_DRIVERUNSUPPORTED;
goto error_exit;
}
/* Catch rotated cases */
switch(psContext->dwRotationAngle)
{
case 90:
case 270:
{
bSwitchDimensions = TRUE;
break;
}
default:
break;
}
/* Fill in some data */
FillInCommonDetails(psSurface, pcsd, bSwitchDimensions);
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 *
psSurface->dwHeight;
if(psContext->SwapEffect == D3DMSWAPEFFECT_FLIP)
{
/* Flip chain so mark surface as flippable */
dwMemFlags |= PVRSRV_MEMFLG_FLIPPABLE;
/* Copy Renderinfo */
psSurface->sDescription.sSurface.psTARenderInfo =
psContext->sChain.psPrimary->sDescription.sSurface.psTARenderInfo;
/* We'll still need a command queue for this surface's render commands */
if(PVRSRVCreateCommandQueue(&psContext->sDevData,
D3DM_COMMANDQUEUE_SIZE,
&psSurface->sDescription.sSurface.psQueue) != PVRSRV_OK)
{
D3DM_DPF((DPF_ERROR, "CreateBackBuffer:Failed to create command queue!"));
pcsd->rval = D3DMERR_DRIVERINTERNALERROR;
goto error_exit;
}
}
else if(psContext->sChain.dwSuppliedBackBuffers == 0)
{
/* We're not flipping and there's no swap chain renderinfo yet so create it */
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, "CreateBackBuffer:Failed to Connect render target"));
pcsd->rval = D3DMERR_DRIVERINTERNALERROR;
goto error_exit;
}
bRenderInfoCreated = TRUE;
}
else
{
/* We're not flipping, but we've already created the renderinfo */
for(i=0;i<MAX_FLIP_SURFACES-1;i++)
{
psTarget = psContext->sChain.psBackBuffers[i];
if(psTarget)
{
psSurface->sDescription.sSurface.psTARenderInfo =
psTarget->sDescription.sSurface.psTARenderInfo;
break;
}
}
/* We'll still need a command queue for this surface's render commands */
if(PVRSRVCreateCommandQueue(&psContext->sDevData,
D3DM_COMMANDQUEUE_SIZE,
&psSurface->sDescription.sSurface.psQueue) != PVRSRV_OK)
{
D3DM_DPF((DPF_ERROR, "CreateBackBuffer:Failed to create command queue!"));
pcsd->rval = D3DMERR_DRIVERINTERNALERROR;
goto error_exit;
}
}
/* Create render target */
if((eError = D3DMAllocDeviceMem(&psContext->sDevData,
dwMemFlags,
dwSize,
MBX1_TSPPL2_TEXADDRALIGNSIZE,
&psSurface->psMemInfo)) != PVRSRV_OK)
{
D3DM_DPF((DPF_ERROR,"CreateBackBuffer:Failed to allocate surface memory"));
if(eError == PVRSRV_ERROR_OUT_OF_MEMORY)
pcsd->rval = D3DMERR_MEMORYPOOLEMPTY;
else
pcsd->rval = D3DMERR_DRIVERINTERNALERROR;
goto error_exit;
}
/* Add to our RT list */
psContext->sChain.psBackBuffers[psBackbufferDesc->BackBuffer] = psSurface;
psContext->sChain.dwSuppliedBackBuffers++;
/* Write back the surface size value */
pcsd->SurfaceDesc.Size = dwSize;
/* Record the surface pointer as surface ID */
pcsd->nSurfaceId = (ULONG) psSurface;
/* now link up the swap chain */
if (psContext->sChain.dwSuppliedBackBuffers == psContext->sChain.dwTotalBackBuffers)
{
LPD3DM_SURFACE psSurf;
IMG_UINT32 i;
/* make the primary the current surface */
psContext->sChain.psCurrentBuffer = psContext->sChain.psPrimary;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -