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

📄 clear.c

📁 Lido PXA270平台开发板的最新BSP,包括源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/******************************************************************************
<module>
* Name         : clear.c
* Title        : D3DM Clear routines
* 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  : D3DM Clear routines
*
* Platform     : Windows CE
*
</module>
********************************************************************************/

#include "context.h"


/*****************************************************************************
 Structures
*****************************************************************************/
typedef struct _TEXTUREDRECT_
{
	LPD3DM_CONTEXT	psContext;
	D3DMRECT		sSrcRect;
	D3DMRECT		sDestRect;
	DWORD			dwFillDepth;
	DWORD			dwFillRHW;
	float			fUScale;
	float			fVScale;
	BOOL			bFullScreenClip;
}
TEXTUREDRECT, *PTEXTUREDRECT;

/*****************************************************************************
############################### CLEARS:#######################################
*****************************************************************************/


/*****************************************************************************
 FUNCTION	: ClearRectangle
    
 PURPOSE	: Used to render a rectangle for supporting Clear2.

 PARAMETERS	: psContext		- A 3D rendering context
			  psRect		- The position and size of the required clear-
							  object (ignored if bFullscreen is TRUE)
			  dwFillColour	- The base (diffuse) colour to use for the clear-
							  object
			  dwFillDepth	- The depth (Z) value to use for the clear-object
			  dwFillRHW		- The RHW value to use for the clear objecr
			  bFullScreen	- TRUE if the object should be created to cover
							  the entire current render-target surface

 RETURNS	: None.
*****************************************************************************/
void ClearRectangle(LPD3DM_CONTEXT 	psContext, 
					LPD3DMRECT 		psRect, 
					DWORD 			dwFillColour, 
					DWORD 			dwFillDepth, 
					DWORD 			dwFillRHW,
					BOOL			bFullScreen)
{
	PHWSTATE			psHWState;
	PHWSTATECTL			psHWStateCtl;
	LPD3DM_SURFACE		psRenderTarget;
	DWORD				adwVertex[20], *pdwVertex;
	DWORD				dwTAPrimCtl;
#if defined (SUPPORT_VGP) || defined (SUPPORT_VGP_LITE)
	DWORD				dwVGPClipCtl;
    DWORD				dwFVFCode;
	DWORD				dwTnLFlags;
	VSIFDEF				sVSIFDef;
#endif
	DWORD				dwWidth, dwHeight;
	NTV_TYPE			ntvX1, ntvX2, ntvY1, ntvY2;
	DEVICE3D			*p3DDevice;
	PVR3DIF_SHAREDDATA	*p3DSharedData;

	p3DDevice		 = &(GetDevInfo(psContext)->sDeviceSpecific.s3D);
	psHWState		 = &psContext->sHWState;			
	psHWStateCtl	 = &psContext->sHWStateCtl;
	psRenderTarget	 = psContext->psCurrentRenderTarget;

	p3DSharedData	 = psRenderTarget->sDescription.sSurface.psTARenderInfo->psSharedData;

	/*
		Setup appropriate primitive block-header controls
	*/
	dwTAPrimCtl = MBX1_TAPRIM_NONPERSPCORRECT |
				  MBX1_TAPRIM_ZBIAS_MODEINCREASING |
				  (0 << MBX1_TAPRIM_ZBIAS_SHIFT) |
				  MBX1_TAPRIM_CULLMODENONE |
                  (psContext->dwTAPrimCtl & MBX1_TAPRIM_WBUFFERING_ENABLE);

#if defined (SUPPORT_VGP) || defined (SUPPORT_VGP_LITE)

    /* Set up the FVF code and TnL flags for pass through shader */
    dwFVFCode = D3DMFVF_XYZRHW_FLOAT |
			    D3DMFVF_DIFFUSE;

	dwTnLFlags = PVRD3DTNL_FLAGS_DIFFUSE_PRESENT;

	/*
		Configure the FVF passthough-shader for the FVF we require
	*/
	VSIFDefSetupForFVF(psContext, &sVSIFDef, dwFVFCode, 5<<2);

	/* set up the pass-through vertex-shader for this clear data type */
	VGPTNLSetUpPassThroughShader(psContext, dwTnLFlags);

	/* Ensure our VGP instructions are up to date before sending anything */
	UpdateVGPInstructions(psContext);

	/* Update the vertex-copy data */
	SetupVertexCopyData(psContext, &sVSIFDef);

	/* update Interface Def HW State */
	psContext->sHWState.sTACtl3DState.dwVGPIFDef = sVSIFDef.dwVGPIFDef;
	psContext->sHWStateCtl.dwTACtl3DStateChanged |= MBX1_TASTATEPRES_VGP_IFDEFINITION;

	/*
		Write out all the HW-state that has just changed as a result of
		loading the passthrough shader
	*/
	TACSWriteTACtlAnd3DState(psContext,
							 MBX1_TASTATEPRES_VGP_IFDEFINITION,
							 &psHWState->sTACtl3DState,
							 FALSE);

	TACSWriteVGPControlState(psContext,
							 psHWStateCtl->dwVGPCtlStateChanged,
							 &psHWState->sVGPControl,
							 FALSE);

	/*
		Reset the VGP-control 'state-changed' flags (since all changed 
		state has now been output)
	*/
	psHWStateCtl->dwVGPCtlStateChanged = 0;

	/*
		Disable stuff in the VGP-clip control word that isn't required in
		this case (since we are suppying already transformed (i.e. in
		screen-space) vertices.
	*/
	dwVGPClipCtl = psContext->dwVGPClipCtl;

	dwVGPClipCtl &= ~(MBX1_VGPCLIPCTL_CLIPPLANES_MASK |
					  MBX1_VGPCLIPCTL_VIEWPORTTRANS_ENABLE |
					  MBX1_VGPCLIPCTL_STARTSECTION_MASK);
#endif

	/*
		Calculate width and height rounded up to next tile boundary.
		MACROTILE * TILESPERMACROTILE * PIXELSINTTILE
		- FIXME:MAY BREAK IN ANTI-ALIAS!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
	*/
	dwWidth  = p3DSharedData->ui32XTilesPerMT * 
			   p3DSharedData->ui32MTilesX	  * 
			   p3DDevice->ui32PixelsInTileX;

	dwHeight = p3DSharedData->ui32YTilesPerMT *
			   p3DSharedData->ui32MTilesY	  * 
			   p3DDevice->ui32PixelsInTileY;

	/*
		Begin a new vertex-strip
	*/
	TACSWritePrimHdr(psContext, dwTAPrimCtl, MBX1_TAOBJTYPE_VERTEXFACESTRIP);

#if defined (SUPPORT_VGP) || defined (SUPPORT_VGP_LITE)
	TACSWriteVGPClipWord(psContext, dwVGPClipCtl);
#endif

	ntvX1 = LONG_AS_NTV(psRect->x1);
	ntvY1 = LONG_AS_NTV(psRect->y1);

	/*
		Are we fullscreen?
	*/
	if	(bFullScreen)
	{
		/*
			If dest rectangle is full-rendersurface,
			send single triangle scaled up in size to cover
			full screen.
		*/
		D3DM_DPF((DPF_MESSAGE, "full render srf clear - sending single tri"));

		ntvX2 = Add(ntvX1, LONG_AS_NTV(2 * dwWidth));
		ntvY2 = Add(ntvY1, LONG_AS_NTV(2 * dwHeight));
	}
	else
	{
		/*
			If dest rectangle is smaller than full-rendersurface,
			send two-triangle quad as normal.
		*/
		D3DM_DPF((DPF_MESSAGE, "not full render srf clear - sending 2-tri quad"));

		ntvX2 = LONG_AS_NTV(psRect->x2);
		ntvY2 = LONG_AS_NTV(psRect->y2);

		/*
			Increase full-surface blits to next tilesize up.
		*/
		if	(psRect->x2 == (int) psRenderTarget->dwWidth)
		{
			ntvX2 = LONG_AS_NTV(dwWidth);
		}
		if	(psRect->y2 == (int) psRenderTarget->dwHeight)
		{
			ntvY2 = LONG_AS_NTV(dwHeight);
		}
	}

	/*
		init scratch ptr
	*/
	pdwVertex = adwVertex;

	/*
		Setup vertex data for 2 triangles using 4 vertices.
	*/
    *pdwVertex++ = TO_ULONG(ntvX1);
    *pdwVertex++ = TO_ULONG(ntvY2);
	*pdwVertex++ = dwFillDepth;
	*pdwVertex++ = dwFillRHW;
    *pdwVertex++ = dwFillColour;

    *pdwVertex++ = TO_ULONG(ntvX1);
    *pdwVertex++ = TO_ULONG(ntvY1);
	*pdwVertex++ = dwFillDepth;
	*pdwVertex++ = dwFillRHW;
    *pdwVertex++ = dwFillColour;

	if	(!bFullScreen)
	{
	    *pdwVertex++ = TO_ULONG(ntvX2);
	    *pdwVertex++ = TO_ULONG(ntvY2);
		*pdwVertex++ = dwFillDepth;
		*pdwVertex++ = dwFillRHW;
		*pdwVertex++ = dwFillColour;
	}

	*pdwVertex++ = TO_ULONG(ntvX2);
	*pdwVertex++ = TO_ULONG(ntvY1);
	*pdwVertex++ = dwFillDepth;
	*pdwVertex++ = dwFillRHW;
    *pdwVertex++ = dwFillColour;


#if defined (SUPPORT_VGP) || defined (SUPPORT_VGP_LITE)

	CopySelect(psContext,
			  (IMG_UINT8 *)adwVertex, 
			  bFullScreen ? 4 : 3, 
			  &sVSIFDef);

#else

	TACSWriteData(psContext, (PVOID)adwVertex, (pdwVertex-adwVertex)<<2);

#endif

	TACSWriteLastPrim(psContext);

#if defined (SUPPORT_VGP) || defined (SUPPORT_VGP_LITE)

	/* update Interface Def HW State */
	if(psContext->psVertexSource)
	{
		psContext->sHWState.sTACtl3DState.dwVGPIFDef = psContext->psVertexSource->sVSIFDef.dwVGPIFDef;
		psContext->sHWStateCtl.dwTACtl3DStateChanged |= MBX1_TASTATEPRES_VGP_IFDEFINITION;
	}


#endif /* #if defined(SUPPORT_VGP) */
}



/*****************************************************************************
 FUNCTION	: SendClear
    
 PURPOSE	: Handles clears for the draw-prim2 op.

 PARAMETERS	: psContext		- D3D context
			  dwFlags		- The type of clear to perform
			  dwFillColour	- The colour to use when clearing the target
			  fFillDepth	- The depth to use when clearing the depth-buffer
			  dwNumRects	- The number of rects at lpRects
			  psRects		- An array of dwNumRects rectangles
			  bFullScreen	- Whether it is fullscreen or not
			  
 RETURNS	: void
*****************************************************************************/
void SendClear(	LPD3DM_CONTEXT	psContext,
				DWORD			dwFlags,
				DWORD			dwFillColour,
				float			fFillDepth,
				DWORD			dwNumRects,
				LPD3DMRECT		psRects,
				DWORD			dwFSFlags)
{
	LPD3DMRECT		psRect;
	HWTACTL3DSTATE	sTACtl3DState;
	DWORD			dwStateChanged = 0;
	DWORD			dwDepth;
	DWORD			dwRHW;
	DWORD			i;
	NTV_TYPE		ntvD3DM_One = D3DM_One, ntvFillDepth;

	D3DM_DPF((DPF_MESSAGE, "SendClear: flags %#8.8lX",dwFlags));

	/*
		Check if we have someting to do
	*/
	if((!dwNumRects) ||	(!(dwFlags & (D3DMCLEAR_ZBUFFER | D3DMCLEAR_TARGET))))
	{
		return;
	}

	PDUMPSTRING(psContext->psPDContext, "--Clear Object");

	/*
		Get the rectangle.
	*/
	psRect = psRects;

#if defined(FIX_HW_PRN_145)
	/*
		Setup TA-Ctl/3D state as required.
	*/
	sTACtl3DState.dwISPTSPCtl = MBX1_ISPTSPCTL_SRCBLENDONE			|
								MBX1_ISPTSPCTL_DESTBLENDZERO		|
								MBX1_ISPTSPCTL_BLENDOPMODEFOGNONE	|
								MBX1_ISPTSPCTL_CKDISABLE			|
								(0 << MBX1_ISPTSPCTL_NUMPASSESSHIFT)|
								(0 << MBX1_ISPTSPCTL_UVCOUNTSHIFT)	|
								MBX1_ISPTSPCTL_OBJTYPE_OPAQUE		|
								MBX1_ISPTSPCTL_DCMPMODEALWAYS		|
								MBX1_ISPTSPCTL_VTXORDERSTRIP;

#else

	sTACtl3DState.dwISPTSPCtl = MBX1_ISPTSPCTL_SRCBLENDONE			|
								MBX1_ISPTSPCTL_DESTBLENDZERO		|
								MBX1_ISPTSPCTL_LOGICALOPDISABLE		|
								MBX1_ISPTSPCTL_CKDISABLE			|
								(0 << MBX1_ISPTSPCTL_NUMPASSESSHIFT)|
								(0 << MBX1_ISPTSPCTL_UVCOUNTSHIFT)	|
								MBX1_ISPTSPCTL_OBJTYPE_OPAQUE		|
								MBX1_ISPTSPCTL_DCMPMODEALWAYS		|
								MBX1_ISPTSPCTL_VTXORDERSTRIP;
#endif

	sTACtl3DState.dwTSPObjCtl = MBX1_TSPOBJ_ACMPMODEALWAYS;

#if defined (SUPPORT_VGP) || defined (SUPPORT_VGP_LITE)

	sTACtl3DState.dwFPFormat = psContext->dwNativeFPFormat;
	dwStateChanged = MBX1_TASTATEPRES_FP_INPUTFORMAT;

#endif

	dwStateChanged |=  (MBX1_TASTATEPRES_ISPCTL	| 
					    MBX1_TASTATEPRES_TSPCTL);

	/*
		Disable tag-writes if not clearing the render-target
	*/
	if	(!(dwFlags & D3DMCLEAR_TARGET))
	{
		sTACtl3DState.dwISPTSPCtl |= MBX1_ISPTSPCTL_TAGWDISABLE;
	}

	/*
		Disable depth-writes if not clearing the depth-buffer
	*/
	if	(!(dwFlags & D3DMCLEAR_ZBUFFER))
	{
		sTACtl3DState.dwISPTSPCtl |= MBX1_ISPTSPCTL_DWDISABLE;
	}

	/*
		Set the required TA-ctl/3D state
	*/
	TACSWriteTACtlAnd3DState(psContext, 
							 dwStateChanged,
							 &sTACtl3DState,
							 FALSE);

	/*
		Record which state we have changed
	*/
	psContext->sHWStateCtl.dwTACtl3DStateChanged |= dwStateChanged;

	/*
		zbuffer depthclears - default case - put depth clear 0-1 value into z
							  and rhw = 1.0 for correct untextured shading
	*/
	ntvFillDepth = FL2NTV(fFillDepth);
	dwDepth = TO_ULONG(ntvFillDepth);
	dwRHW   = TO_ULONG(ntvD3DM_One);

	/*
		Depth clears - all handled as W-buffered.
	*/
	if(dwFlags & D3DMCLEAR_ZBUFFER)
	{
		/*
			Fix for Rogue Squadron, that changes Wnear and Wfar midscene.
			We put background at infinity hence use min float as RHW
		*/
		if	(fFillDepth > 0.9999f)
		{
			/* Min float */
			fFillDepth = 1.1754944e-038f; 
		}
		else
		{
			D3DM_DPF((DPF_MESSAGE, "wbuffered clear depth %#8.8lX",FLOAT_TO_LONG(fFillDepth)));
			
			/*
				Clear depth is normalised W value between 0 -> 1,
				(eye space - post projection, pre-perspective divide), 
				with 0.0 at near clip depth & 1.0 at far clip.
				=> must use WNear & WFar to scale clear W (depth) to
				original range between WNear & WFar.
				(wnear & wfar values are the same as the near/far clip depths used to
				construct the projection matrix, where wnear < wfar)
			*/
			fFillDepth = (fFillDepth * (NTV2FL(psContext->sTState.WFar) - NTV2FL(psContext->sTState.WNear))) + 
					 NTV2FL(psContext->sTState.WNear);

			D3DM_DPF((DPF_MESSAGE, "       scaled depth %#8.8lX", FLOAT_TO_LONG(fFillDepth)));

			/*
				Now we must convert it to rhw (= 1 / Wscaled),
				so its in the same space as the 3d data.
				(The TA will take rhw in each vtx and put it
				into the z field of each vtx output to core 3d,
				for depth comparison)
			*/
			if(fFillDepth == 0.0f)
			{
				/* 
					Instead of divide by zero, return max float value #
				*/
				fFillDepth = FLT_MAX;
			}
			else
			{
				fFillDepth = NTV2FL(Div(D3DM_One, FL2NTV(fFillDepth)));
			}
		}		
		D3DM_DPF((DPF_MESSAGE, "          rhw = 1/w %#8.8lX", FLOAT_TO_LONG(fFillDepth)));

		ntvFillDepth = FL2NTV(fFillDepth);
		dwRHW = TO_ULONG(ntvFillDepth);
	}

	/*
		Go through each rectangle.
	*/
	for (i = 0; i < dwNumRects ; i++)
	{
		/*
			Are we fullscreen?
		*/
		if	(dwFSFlags & (0x1 << i))
		{
			D3DM_DPF((DPF_MESSAGE, "full render srf clear"));
			
			/*

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -