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

📄 tautils.c

📁 Lido PXA270平台开发板的最新BSP,包括源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	TACSWriteVGPControlState(psContext, 
							 dwStateChanged,
							 psNewVGPControlState,
							 FALSE);

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

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

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

 PARAMETERS	: psContext	- Current 3D rendering context
  
 RETURNS	: void
*****************************************************************************/
void UpdateVGPConstants(LPD3DM_CONTEXT psContext)
{
	PVGPCONSTFLAGS	psConstsChanged;
	PHWSTATECTL		psHWStateCtl;

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

	psHWStateCtl = &psContext->sHWStateCtl;

	/* Any constants in this bank changed? */
	psConstsChanged = &psHWStateCtl->sVGPConstsChanged;
	if(psConstsChanged->dwUsed)
	{
		PHWVGPCONSTANTS	psNewConsts;

		D3DM_DPF((DPF_TA, "UpdateVGPConstants: updating constants"));

		/*
			Submit the changed constants (only written if different to
			current values)
		*/
		psNewConsts = &psContext->sHWState.sVGPConsts;

		TACSWriteVGPConstants(psContext,
							  psConstsChanged,
							  psNewConsts,
							  FALSE);

		/*
			Reset the constant 'state-changed' flags (since all changed 
			constants have been output)
		*/
		FlagArrayClearFlagRange((PFLAGARRAY)psConstsChanged, 
								0, 
								psConstsChanged->dwSize - 1);
	}
	else
	{
		D3DM_DPF((DPF_TA, "UpdateVGPConstants: No constants changed."));
	}

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

/*****************************************************************************
 FUNCTION	: TACSWriteVGPControlState
    
 PURPOSE	: Writes a VGP-control block to the TA control stream

 PARAMETERS	: psContext			- Current 3D rendering context
			  dwStateChanged	- Section-definition presence flags indicating
								  which definitions are to be written (see
								  MBX1_VGPCONTROL_SECTIONxDEF_ENABLE flags)
			  psNewVGPControl	- HW-state structure containing the new
								  section-definitions to be written
			  bForceWrite		- Control to force state to be written
								  even if it is the same as the current
								  state-data.
			  
 RETURNS	: void
*****************************************************************************/
void TACSWriteVGPControlState(LPD3DM_CONTEXT	psContext,
							  DWORD				dwStateChanged,
							  PHWVGPCONTROL		psNewVGPControl,
							  BOOL				bForceWrite)
{
	PHWVGPCONTROL	psCurrVGPControl;
	PHWSTATECTL		psHWStateCtl;
	PDWORD			pdwNewSectionDef;
	PDWORD			pdwCurrSectionDef;
	DWORD			pdwBlockData[(sizeof(HWVGPCONTROL)/sizeof(DWORD)) + 1];
	DWORD			dwStateSetup;
	DWORD			dwStateLeft;
	DWORD			dwStateToWrite;
	PDWORD			pdwDest;
	DWORD			i;

	D3DM_DPF((DPF_ENTRY, "->TACSWriteVGPControlState")

	/* Do nothing if no section definitions are present	*/
	dwStateChanged &= ~MBX1_VGPCONTROL_SECTIONENABLECLRMASK;
	if(!dwStateChanged)
	{
		D3DM_DPF((DPF_TA, "TACSWriteVGPControlState: No flags set. Doing nothing"));
		return;
	}

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

	psCurrVGPControl	= &psContext->sCurrHWState.sVGPControl;
	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->dwVGPCtlStateSetup & 
						(~MBX1_VGPCONTROL_SECTIONENABLECLRMASK);
	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;
	}

	/* Leave the first DWORD in the block-data free for the header */
	pdwDest = &pdwBlockData[1];

	/*
		Loop through all section-definitions, adding those that need to be
		written to the state-block data
	*/
	pdwNewSectionDef  = psNewVGPControl->pdwSectionDef;
	pdwCurrSectionDef = psCurrVGPControl->pdwSectionDef;

	for(i = 0; i < MBX1_VGPCODE_SECTION_COUNT; i++)
	{
		DWORD	dwSectionPresFlag;

		/* Include this section-definition?	*/
		dwSectionPresFlag = MBX1_VGPCONTROL_SECTION0DEF_ENABLE << i;
		if(dwStateLeft & dwSectionPresFlag)
		{
			/* Is the new value different from the current (if any)? */
			if((!(dwStateSetup & dwSectionPresFlag)) ||	(*pdwNewSectionDef ^ *pdwCurrSectionDef))
			{
				D3DM_DPF((DPF_TA, "TACSWriteVGPControlState: VGP section-def %d changed. Including in block", i));
		
				/* Changed or never written before. Add to state-block */
				*pdwDest			= *pdwNewSectionDef;
				*pdwCurrSectionDef	= *pdwNewSectionDef;
				pdwDest++;
			}
			else
			{
				D3DM_DPF((DPF_TA, "TACSWriteVGPControlState: VGP section-def %d unchanged. Removing from block", i));
		
				/* Same as current. Remove from state to write */
				dwStateToWrite ^= dwSectionPresFlag;
			}

			/* Write the state-block if we have handled all the changed state now */
			dwStateLeft ^= dwSectionPresFlag;
			if(!dwStateLeft)
			{
				break;
			}
		}

		/* Move to next section-definition */
		pdwNewSectionDef++;
		pdwCurrSectionDef++;
	}

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

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

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

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

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

	/*	Record which state we have written */
	psHWStateCtl->dwVGPCtlStateSetup |= dwStateToWrite;

	D3DM_DPF((DPF_EXIT, "<-TACSWriteVGPControlState"));

}

/*****************************************************************************
 FUNCTION	: TACSWriteVGPConstants
    
 PURPOSE	: Writes VGP-constants to the TA control-stream, updating the
			  context state-control data accordingly.

			  NB: This routine can write arbitrary constants as specified
				  by the flags-array psConstsChanged. A single flag bit is
				  used for each constant, arranged in increasing order 
				  (LSB->MSB), with 32 constants per DWORD of flags. A set 
				  flag-bit indicates that the constant should be written.
				  Only constants specified in these flags-words will be 
				  considered for writing.

				  Similar flags in the context state-control data (representing
				  the constants that have been already written) are updated to
				  include the constants actually sent to the HW. These are
				  maintained to indicate which constants in the context's
				  'current' hardware-state data are up-to-data and thus
				  valid. This routine will not sent constant where the new
				  value is identical to the current. Constants that have not
				  been sent previously will always be sent.

				  This routine is fastest when sending small contiguous 
				  groups of constants. The slowest case is probably where
				  all constants have been sent before and every-other
				  constant is to be written - an unlikely case.

 PARAMETERS	: psContext			- Current 3D rendering context
			  psConstsChanged	- VGP-constant flags indicating which constants
								  are to be written
			  psNewConsts		- HW state structure containing the new VGP
								  constant data
			  bForceWrite		- Control to force constants to be written
								  even if they are the same as the current
								  constants.
  
 RETURNS	: void
*****************************************************************************/
void TACSWriteVGPConstants(LPD3DM_CONTEXT	psContext,
						   PVGPCONSTFLAGS	psConstsChanged,
						   PHWVGPCONSTANTS	psNewConsts,
						   BOOL				bForceWrite)
{
	PHWVGPCONSTANTS psCurrConsts;
	PHWSTATECTL		psHWStateCtl;
	DWORD			pdwBlockData[(sizeof(HWVGPCONSTANTS)/sizeof(DWORD)) + 1];
	PVGPCONSTFLAGS	psStateCtlConstsSetup;
	VGPCONSTFLAGS	sConstsWritten;
	PDWORD			pdwDest;
	DWORD			dwLastInBlock;
	DWORD			i;

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

	/* Do nothing if no constants have changed */
	if(!psConstsChanged->dwUsed)
	{
		D3DM_DPF((DPF_TA, "TACSWriteVGPConstants: No flags set. Doing nothing"));
		return;
	}

	#if defined(DEBUG)
	for(i = 0; i < (MBX1_VGPCONSTANTS_CONST_COUNT/(sizeof(DWORD)*8)); i++)
	{
		if(psConstsChanged->dwUsed & (1L << i))
		{
			D3DM_DPF((DPF_TA, "TACSWriteVGPConstants: constants %d-%d changed: 0x%8.8lX", i*32, i*32+31, psConstsChanged->pdwFlags[i]));
		}
	}
	#endif /* #if defined(DEBUG) */

	psCurrConsts = &psContext->sCurrHWState.sVGPConsts;
	psHWStateCtl = &psContext->sHWStateCtl;

	/*
		psStateCtlConstsSetup   - flag-words specifying the constants marked
								  as previously setup (i.e. submitted to the 
								  HW) from the context state-control data

		sConstsWritten			- flag-words indicating which constants we 
								  need to write
	*/
	psStateCtlConstsSetup = &psHWStateCtl->sVGPConstsSetup;
	sConstsWritten		  = *psConstsChanged;

	/*
		If forcing the state to be output, remove the new constants from 
		the constants already setup. This disables the comparison between the
		new and current values for them, so that they always gets written.
	*/
	if(bForceWrite)
	{
		FlagArrayClearFlags((PFLAGARRAY)psStateCtlConstsSetup,
							(PFLAGARRAY)psConstsChanged);
	}

	/*
		Initialise the block-data pointer ready to start a new block of
		constants - remembering to leave a DWORD for the header.
	*/
	pdwDest = &pdwBlockData[1];

	/*
		Initialise the last constant in the current block to ensures that
		the current block (which will be empty) is not written when the 
		first constant is added to it.
	*/
	dwLastInBlock = MBX1_VGPCONSTANTS_CONST_COUNT;

	/*
		Loop through all constants, adding those that need to be written to
		the constant-block data
	*/
	for(i = 0; i < (MBX1_VGPCONSTANTS_CONST_COUNT/(sizeof(DWORD)*8)); i++)
	{
		DWORD	dwSetup;
		DWORD	dwLeft;
		DWORD	dwFlag;
		DWORD	dwConstNum;

		/* Skip this group of constants if we have none to process in it */
		dwLeft = psConstsChanged->pdwFlags[i];
		if(!dwLeft)
		{
			continue;
		}

		dwSetup = psStateCtlConstsSetup->pdwFlags[i];

		/*
			Process this group of constants until we have handled all the
			changed ones.
		*/
		dwConstNum = i << 5;
		for	(dwFlag = 0x1UL; dwLeft; dwFlag <<= 1, dwConstNum++)
		{
			PHWVGPCONST	psNewConst;
			PHWVGPCONST	psCurrConst;

			/*
				Has this constant changed?
			*/
			if(dwLeft & dwFlag)
			{
				/* Is the new value different from the current (if any)? */
				psCurrConst = &psCurrConsts->psConsts[dwConstNum];
				psNewConst  = &psNewConsts->psConsts[dwConstNum];

				if((!(dwSetup & dwFlag))							  ||
				   (psNewConst->e[0].dwVal ^ psCurrConst->e[0].dwVal) ||
				   (psNewConst->e[1].dwVal ^ psCurrConst->e[1].dwVal) ||
				   (psNewConst->e[2].dwVal ^ psCurrConst->e[2].dwVal) ||
				   (psNewConst->e[3].dwVal ^ psCurrConst->e[3].dwVal))
				{
					D3DM_DPF((DPF_TA, "TACSWriteVGPConstants: Constant %d changed. Including in block", dwConstNum));
			
					/*
						Constant changed or never written before. Must write.

						If the new constant is not contiguous with those already
						copied into the current constant-block, we cannot add it
						to that block. Must write the current block of constants
						and start a new-one.
					*/
					if(dwConstNum > (dwLastInBlock + 1))
					{
						DWORD	dwFirstInBlock;
						DWORD	dwDataSize;

						/*
							Determine the range of constants in this block
						*/
						dwDataSize = (pdwDest - pdwBlockData - 1) * sizeof(DWORD);
						dwFirstInBlock = dwLastInBlock - (dwDataSize/sizeof(HWVGPCONST) - 1);

						#if defined(DEBUG)
						if	(dwFirstInBlock == dwLastInBlock)
						{
							D3DM_DPF((DPF_TA, "TACSWriteVGPConstants: Writing constant %d", dwFirstInBlock));
						}
						else
						{
							D3DM_DPF((DPF_TA, "TACSWriteVGPConstants: Writing constants %d to %d", dwFirstInBlock, dwLastInBlock));
						}
						#endif /* #if defined(DEBUG) */

						/* Add header to start of block	*/
						pdwBlockData[0] = MBX1_TAOBJTYPE_VGP_CONSTANTS | 
										  (dwFirstInBlock << MBX1_VGPCONSTANTS_STARTADDR_SHIFT) |
										  (dwLastInBlock << MBX1_VGPCONSTANTS_ENDADDR_SHIFT);

						dwDataSize += sizeof(DWORD);

						/* Output the block-data */
						DBG_DECODEVGPCONSTANTSBLOCK(psContext, pdwBlockData);

						TACSWriteData(psContext, pdwBlockData, dwDataSize);

						/*
							Reset the block-data pointer ready to start a new
							block of constants - remembering to leave a DWORD
							for the header.
						*/
						pdwDest = &pdwBlockData[1];

						/*
							Initialise the last constant in the current block
							to ensures that the current block (which will be 
							empty) is not written when the first constant is 
							added to it.
						*/
						dwLastInBlock = MBX1_VGPCONSTANTS_CONST_COUNT;
					}

					/* Add this constant to the current constant-block */
					*(PHWVGPCONST)pdwDest	= *psNewConst;
					*psCurrConst			= *psNewConst;
					pdwDest					+= sizeof(HWVGPCONST) / sizeof(DWORD);

					/*
						Record that this constant is the last one in the current
						block of constants to write
					*/
					dwLastInBlock = dwConstNum;
				}
				else
				{
					D3DM_DPF((DPF_TA, "TACSWriteVGPConstants: Constant %d unchanged", dwConstNum));
			
					/* Same as current. Remove from constants written */
					sConstsWritten.pdwFlags[i] ^= dwFlag;
				}

				/* Remove this constant from the ones left to handle */
				dwLeft ^= dwFlag;
			}
		}
	}

	/* Write the final block of constants (if any) */
	if(dwLastInBlock < MBX1_VGPCONSTANTS_CONST_COUNT)
	{
		DWORD	dwFirstInBlock;
		DWORD	dwDataSize;

		/* Determine the range of constants in this block */
		dwDataSize		= (pdwDest - pdwBlockData - 1) * sizeof(DWORD);
		dwFirstInBlock	= dwLastInBlock - (dwDataSize/sizeof(HWVGPCONST) - 1);

		#if defined(DEBUG)
		if(dwFirstInBlock == dwLastInBlock)
		{
			D3DM_DPF((DPF_TA, "TACSWriteVGPConstants: Writing constant %d", dwFirstInBlock));
		}
		else
		{
			D3DM_DPF((DPF_TA, "TACSWriteVGPConstants: Writing constants %d to %d", dwFirstInBlock, dwLastInBlock));
		}
		#endif /* #if defined(DEBUG) */

		/* Add header to start of block	*/
		pdwBlockData[0] = MBX1_TAOBJTYPE_VGP_CONSTANTS | 
						  (dwFirstInBlock << MBX1_VGPCONSTANTS_STARTADDR_SHIFT) |
						  (dwLastInBlock << MBX1_VGPCONSTANTS_ENDADDR_SHIFT);

		dwDataSize += sizeof(DWORD);

		/* Output the block-data */
		DBG_DECODEVGPCONSTANTSBLOCK(psContext, pdwBlockData);

		TACSWriteData(psContext, pdwBlockData, dwDataSize);
	}

	/*
		Record which constants we have just written-out

⌨️ 快捷键说明

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