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

📄 tautils.c

📁 Lido PXA270平台开发板的最新BSP,包括源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/******************************************************************************
<module>
* Name         : tautils.c
* Title        : D3DM primcopy routines
* Author(s)    : Imagination Technologies
* Created      : 18 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  : DrawPrimitive Entry Point for processing D3DMobile DP Commands, 
*				 and DP Operation Handlers
*
* Platform     : Windows CE
*
</module>
 $Log: tautils.c $
********************************************************************************/
#include "context.h"

/*****************************************************************************
 FUNCTION	: CalcTARegionClip
    
 PURPOSE	: Forms an appropriate TA region-clip control word to clip-to
			  a given pixel-area

 PARAMETERS	: psContext		- Current 3D rendering context
			  psRect		- The pixel-area to clip to
			  
 RETURNS	: TA region clip control word.
*****************************************************************************/
DWORD CalcTARegionClip(LPD3DM_CONTEXT psContext, LPD3DMRECT psRect)
{
	DEVICE3D	*ps3DDevice;
	DWORD		dwRegionClip;
	DWORD		dwLeft, dwRight, dwTop, dwBottom;
	DWORD		dwX1, dwX2, dwY1, dwY2;

	ps3DDevice			= &GetDevInfo(psContext)->sDeviceSpecific.s3D;
	dwX1				= psRect->x1;
	dwX2				= psRect->x2;
	dwY1				= psRect->y1;
	dwY2				= psRect->y2;

	/* Double size if Antialiasing enabled (covers 4x regions) */
	if(psContext->dwFlags & D3DM_CONTEXT_SWFLAGS_SUPERSAMPLEX)
	{
		dwX1 *= 2;
		dwX2 *= 2;
	}

	if(psContext->dwFlags & D3DM_CONTEXT_SWFLAGS_SUPERSAMPLEY)
	{
		dwY1 *= 2;
		dwY2 *= 2;
	}

	/*
		Round down TA region clip rect (top and left) to nearest tile 
		granularity boundaries outside viewport rectangle.
	*/
	RoundToTileGranBoundary(psContext, FALSE, dwX1, dwY1, NULL, NULL, &dwLeft, &dwTop);

	/*
		Round up TA region clip rect (right and bottom) to nearest tile 
		granularity boundaries outside viewport rectangle.
	*/
	RoundToTileGranBoundary(psContext, TRUE, dwX2, dwY2, NULL, NULL, &dwRight, &dwBottom);


	/*
		Region clip isn't specified in tiles, rather 16 pixel units.
		For MBX this is our pseudo tile size, got from the product
		of tile size and tile granularity
	*/
	dwLeft		/= ps3DDevice->ui32TileXGran;
	dwRight		/= ps3DDevice->ui32TileXGran;
	dwTop		/= ps3DDevice->ui32TileYGran;
	dwBottom	/= ps3DDevice->ui32TileYGran;
		
	/*
		Setup region-clip word to clip everything outside the calculated 
		tile-region
	*/
	dwRegionClip = MBX1_TASTATERGNCLIP_CLIPOUTSIDE;

	dwRegionClip |= (dwLeft << MBX1_TASTATERGNCLIP_LEFTCLIPSHIFT) & 
					(~MBX1_TASTATERGNCLIP_LEFTCLIPCLRMASK);

	dwRegionClip |= (dwRight << MBX1_TASTATERGNCLIP_RIGHTCLIPSHIFT) & 
					(~MBX1_TASTATERGNCLIP_RIGHTCLIPCLRMASK);

	dwRegionClip |= (dwTop << MBX1_TASTATERGNCLIP_TOPCLIPSHIFT) & 
					(~MBX1_TASTATERGNCLIP_TOPCLIPCLRMASK);

	dwRegionClip |= (dwBottom << MBX1_TASTATERGNCLIP_BOTTOMCLIPSHIFT) & 
					(~MBX1_TASTATERGNCLIP_BOTTOMCLIPCLRMASK);

	return dwRegionClip;
}

/*****************************************************************************
 FUNCTION	: UpdateTACtlAnd3DState
    
 PURPOSE	: Updates the TA/3D control state required for the next primitive,
			  and submits any changes to the HW.

 PARAMETERS	: psContext	- Current 3D rendering context
  
 RETURNS	: void
*****************************************************************************/
void UpdateTACtlAnd3DState(LPD3DM_CONTEXT psContext)
{
	PHWTACTL3DSTATE		psHWTACtl3DState;
	PHWSTATECTL			psHWStateCtl;
	PTRANSIENT_STATE	psTState;
	DWORD				dwStateChanged;
	DWORD				i;

	D3DM_DPF((DPF_ENTRY, "->UpdateTACtlAnd3DState"));

	psTState			= &psContext->sTState;
	psHWTACtl3DState	= &psContext->sHWState.sTACtl3DState;
	psHWStateCtl		= &psContext->sHWStateCtl;
	dwStateChanged		= psHWStateCtl->dwTACtl3DStateChanged;
								  
	D3DM_DPF((DPF_TA, "UpdateTACtlAnd3DState: Change flags 0x%8.8lX", dwStateChanged));

	/*
		Perform any final 'pre-primitive' processing of the HW-state for each
		texture-stage, and determine the overall HW pass and layer counts
		required
	*/
	for	(i = 0; i < MBX1_MAXTEXTURE_LAYERS; i++)
	{
		PMBX1_TSPLAYER_STATE	psTSPLState;
		LPD3DM_SURFACE			psSurfData;

		/* Stop if this layer is not enabled	*/
		if(!(psContext->dwFlags & (D3DM_CONTEXT_SWFLAGS_LAYER0ENABLED << i)))
		{
			break;
		}

		psTSPLState = &psHWTACtl3DState->sTSPLState[i];
		psSurfData	= psTState->sLState[i].psSurfData;

		/* Add stride into parameters if texture hasn't been blitted to */
		if(psSurfData)
		{
			if(!(psSurfData->dwFlags & D3DM_SURFACE_FLAGS_TWIDDLED)) 
			{
				DWORD	dwStridePixel;
				DWORD	dwStride;

				/*
					Get Pixel stride from current top level map.
					This should always be correc teven when mipmapping is disabled
				*/
				dwStridePixel = psSurfData->sDescription.sTexture.psMapDetails->psCurrentTopLevel->dwStridePixel;
	
				/*
					NB:	MBX1 stride is in terms of 8-pixels
						surface-data stride is in pixels
				*/
				dwStride = (DWORD)dwStridePixel >> 3;
		
				/* Write stride into layer-words 1 and 2 */
				psTSPLState->dwLCtl1 &= ~MBX1_TSPPL1_TEXSTRIDE_LSB;
				psTSPLState->dwLCtl1 |= (dwStride << MBX1_TSPPL1_TEXSTRIDE_LSBSHIFT) &
									    MBX1_TSPPL1_TEXSTRIDE_LSB;

				psTSPLState->dwLCtl2 &= MBX1_TSPPL2_TEXSTRIDECLRMASK;
				psTSPLState->dwLCtl2 |= (dwStride << (MBX1_TSPPL2_TEXSTRIDESHIFT - 1)) & 
									    (~MBX1_TSPPL2_TEXSTRIDECLRMASK);

				/*
					Flag that this layer has potentially changed
				*/
				dwStateChanged |= MBX1_TASTATEPRES_LAYER0CTL << i;
			}
		}
	}

	/* Submit the new state (only written if different to current state) */
	TACSWriteTACtlAnd3DState(psContext, 
							 dwStateChanged, 
							 psHWTACtl3DState, 
							 FALSE);

	/*
		Reset the TA-ctl/3D-state 'state-changed' flags (since all changed
		state has now been output)
	*/
	psHWStateCtl->dwTACtl3DStateChanged = 0;

	D3DM_DPF((DPF_EXIT, "<-UpdateTACtlAnd3DState"));
}

/*****************************************************************************
 FUNCTION	: TACSWriteTACtlAnd3DState
    
 PURPOSE	: Writes a TA-control and 3D-state block to the TA control stream

PARAMETERS	: psContext				- Current 3D rendering context
			  dwStateChanged		- State presence flags indicating which
									  states are to be written (see 
									  MBX1_TASTATEPRES_xxx flags)
			  psNewTACtl3DState		- HW-state structure containing the new
									  TA-ctl/3D-state to write
			  bForceWrite			- Control to force state to be written
									  even if it is the same as the current
									  state-data.
   
 RETURNS	: void
*****************************************************************************/
void TACSWriteTACtlAnd3DState(LPD3DM_CONTEXT	psContext, 
							  DWORD				dwStateChanged,
							  PHWTACTL3DSTATE	psNewTACtl3DState,
							  BOOL				bForceWrite)
{
	PHWSTATECTL		psHWStateCtl;
	DWORD			pdwBlockData[(sizeof(HWTACTL3DSTATE)/sizeof(DWORD)) + 1];
	PDWORD			pdwDest;
	PDWORD			pdwCurrState;
	PDWORD			pdwNewState;
	DWORD			dwStateSetup;
	DWORD			dwStateLeft;
	DWORD			dwStateToWrite;
	DWORD			dwState;
	DWORD			i;
	static DWORD	pdwStateSizes[] = 
	{
		1,		/* ISP/TSP state			= 1 DWORD */
		1,		/* TSP per-object state		= 1 DWORD */
		3,		/* TSP layer 0 state		= 3 DWORDs */
		3,		/* TSP layer 1 state		= 3 DWORDs */
		1,		/* TA region-clip			= 1 DWORD */
		1,		/* VGP input-format			= 1 DWORD */
		1,		/* TA fixed-point format	= 1 DWORD */
		6,		/* VGP viewport transform	= 6 DWORDs */
		1,		/* VGP W-clamp value		= 1 DWORD */
	};
	#if defined(DEBUG) || defined(D3DM_RETAIL_DBGOUT)
	static PSTR	ppszStateName[] = 
	{
		"ISP/TSP word",
		"TSP word",
		"TSP Layer 0 state",
		"TSP Layer 1 state",
		"TA region clip word",
		"VGP input-def word",
		"TA input-format word",
		"viewport transform",
		"W-clamp value"
	};
	#endif /*#if defined(DEBUG) || defined(D3DM_RETAIL_DBGOUT)*/

	D3DM_DPF((DPF_ENTRY, "->TACSWriteTACtlAnd3DState"));

#if !defined(SUPPORT_VGP) && !defined (SUPPORT_VGP_LITE)
	/*
        Mask out VGP-related states.
    */
    dwStateChanged &= ~ (MBX1_TASTATEPRES_VGP_IFDEFINITION |
                         MBX1_TASTATEPRES_VGP_VIEWPORTTRANS |
                         MBX1_TASTATEPRES_VGP_WCLAMPVAL);
#endif /* #if !defined(SUPPORT_VGP) */

	/* Do nothing if no state needs changing */
	dwStateChanged &= ~MBX1_TASTATEPRES_CLRMASK;
	if(!dwStateChanged)
	{
		D3DM_DPF((DPF_TA,"TACSWriteTACtlAnd3DState: No new-state flags set. Doing nothing!"));
		return;
	}

	D3DM_DPF((DPF_TA, "TACSWriteTACtlAnd3DState: New-state flags 0x%8.8lX", dwStateChanged));

	psHWStateCtl = &psContext->sHWStateCtl;

	/*
		dwStateSetup   - which state has already been setup
		dwStateToWrite - which state we may need to write
		dwStateLeft    - which state we still have to process
	*/
	dwStateSetup	= psHWStateCtl->dwTACtl3DStateSetup & (~MBX1_TASTATEPRES_CLRMASK);
	dwStateToWrite	= dwStateChanged;
	dwStateLeft		= dwStateChanged;

	/*
		If forcing the state to be output, remove the new state from the
		state already setup. This disables the comparison between the new 
		and current values for this state, so that it always gets written.
	*/
	if(bForceWrite)
	{
		dwStateSetup &= ~dwStateChanged;
	}

	/*
		Setup where we will be copying the state from and to

		NB:	Leave the first DWORD in the block-data free for the header	
	*/
	pdwCurrState = (PDWORD)&psContext->sCurrHWState.sTACtl3DState;
	pdwNewState	 = (PDWORD)psNewTACtl3DState;
	pdwDest		 = &pdwBlockData[1];

	/*
		Check each state in turn to see if we need to write it, stopping once
		all the changed state has been considered.
	*/
	dwState = MBX1_TASTATEPRES_ISPCTL;
	i = 0;

	while(dwStateLeft)
	{
		DWORD dwStateSize;

		dwStateSize = pdwStateSizes[i];

		/* Has this state changed? */
		if(dwStateLeft & dwState)
		{
			BOOL bCopyState;

			/*
				Offset the state read/write pointers so that the switch-based
				compare/copy code works.
			*/
			pdwNewState  -= 6 - dwStateSize;
			pdwCurrState -= 6 - dwStateSize;

			/*
				Do we need to copy the new state? Copy if it has not been
				written before, or it is different from the current state.
			*/
			bCopyState = TRUE;

			if(dwStateSetup & dwState)
			{
				/*
					Compare current and new state
				*/
				switch(dwStateSize)
				{
					case 6:  if (pdwNewState[0] ^ pdwCurrState[0]) break;
					case 5:  if (pdwNewState[1] ^ pdwCurrState[1]) break;
					case 4:  if (pdwNewState[2] ^ pdwCurrState[2]) break;
					case 3:  if (pdwNewState[3] ^ pdwCurrState[3]) break;
					case 2:  if (pdwNewState[4] ^ pdwCurrState[4]) break;
					case 1:  if (pdwNewState[5] ^ pdwCurrState[5]) break;
					default: bCopyState = FALSE;
				}
			}
			
			if(bCopyState)
			{
				D3DM_DPF((DPF_TA, "TACSWriteTACtlAnd3DState: Need to send %hs. Adding to state-block", ppszStateName[i]));

				/*
					Copy the new state into the state block to write, and into 
					the current state data.
				*/
				pdwDest -= 6 - dwStateSize;
				switch (dwStateSize)
				{
					case 6: pdwCurrState[0] = pdwDest[0] = pdwNewState[0];
					case 5: pdwCurrState[1] = pdwDest[1] = pdwNewState[1];
					case 4: pdwCurrState[2] = pdwDest[2] = pdwNewState[2];
					case 3: pdwCurrState[3] = pdwDest[3] = pdwNewState[3];
					case 2: pdwCurrState[4] = pdwDest[4] = pdwNewState[4];
					case 1: pdwCurrState[5] = pdwDest[5] = pdwNewState[5];
				}
				pdwDest += 6;
			}
			else
			{
				D3DM_DPF((DPF_TA, "TACSWriteTACtlAnd3DState: %hs unchanged, not adding in state-block", ppszStateName[i]));

				/*
					State not copied. Removed from the state we have to 
					write at the end.
				*/
				dwStateToWrite ^= dwState;				
			}

			/*
				Move to the data for the next state (note the offset to
				these pointers above)
			*/
			pdwNewState  += 6;
			pdwCurrState += 6;

			/* Remove this state from the ones we have to deal with */
			dwStateLeft ^= dwState;
		}
		else
		{
			/*
				State not changed. Skip the data for this state
			*/
			pdwNewState  += dwStateSize;
			pdwCurrState += dwStateSize;
		}

		/* Move onto next state to test */
		dwState <<= 1;
		i++;
	}

	/* If we have some state to write, do so */
	if(dwStateToWrite)
	{
		DWORD	dwBlockSize;

		D3DM_DPF((DPF_TA, "TACSWriteTACtlAnd3DState: Writing block with flags 0x%8.8lX", dwStateToWrite));

		/* Add header to start of block	*/
		pdwBlockData[0] = MBX1_TAOBJTYPE_STATE | dwStateToWrite;

		/* Output the block	*/
		DBG_DECODETACTL3DSTATEBLOCK(psContext, pdwBlockData);

		dwBlockSize = (pdwDest - pdwBlockData) * sizeof(DWORD);
		TACSWriteData(psContext, pdwBlockData, dwBlockSize);
	}

	/* Record which state we have just written out	*/
	psHWStateCtl->dwTACtl3DStateSetup |= dwStateToWrite;

	D3DM_DPF((DPF_EXIT, "<-TACSWriteTACtlAnd3DState"));
}		

/*********************************************************************************
 VGP Specific
*********************************************************************************/

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

/*****************************************************************************
 FUNCTION	: UpdateVGPControlState
    
 PURPOSE	: Updates the VGP-control state required for the next primitive,
			  and submits any changes to the HW.

 PARAMETERS	: psContext	- Current 3D rendering context
  
 RETURNS	: void
*****************************************************************************/
void UpdateVGPControlState(LPD3DM_CONTEXT psContext)
{
	PHWVGPCONTROL	psNewVGPControlState;
	PHWSTATECTL		psHWStateCtl;
	DWORD			dwStateChanged;
	
	D3DM_DPF((DPF_ENTRY, "->UpdateVGPControlState"));
	
	psHWStateCtl   = &psContext->sHWStateCtl;
	dwStateChanged = psHWStateCtl->dwVGPCtlStateChanged;

	/* Quit if nothing's changed */
	if(!dwStateChanged)
	{
		D3DM_DPF((DPF_TA,"UpdateVGPControlState: no update required (no state changed)"));
		return;
	}

	D3DM_DPF((DPF_TA,"UpdateVGPControlState: Change flags 0x%8.8lX", dwStateChanged));

	/*
		Submit the new VGP-control state (only written if different to
		current state)
	*/
	psNewVGPControlState = &psContext->sHWState.sVGPControl;

⌨️ 快捷键说明

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