⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 surface.c

📁 Lido PXA270平台开发板的最新BSP,包括源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/******************************************************************************
<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 + -