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

📄 tautils.c

📁 Lido PXA270平台开发板的最新BSP,包括源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
		
		NB:	must update the flags for the constants written, as we have 
			manually changed it flags
	*/
	FlagArrayUpdate((PFLAGARRAY)&sConstsWritten);

	FlagArraySetFlags((PFLAGARRAY)psStateCtlConstsSetup,
					  (PFLAGARRAY)&sConstsWritten);

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

}

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

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

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

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

 PARAMETERS	: psContext			- Current 3D rendering context
			  psInstsChanged	- VGP-instruction flags indicating which
								  instructions are to be written
			  psNewInsts		- HW state structure containing the new VGP
								  instruction data
			  bForceWrite		- Control to force instructions to be written
								  even if they are the same as the current
								  instructions
  
 RETURNS	: void
*****************************************************************************/
void TACSWriteVGPInstructions(LPD3DM_CONTEXT psContext,
						      PVGPINSTFLAGS  psInstsChanged,
						      PHWVGPCODE	 psNewInsts,
						      BOOL			 bForceWrite)
{
	PHWVGPCODE		psCurrInsts;
	PHWSTATECTL		psHWStateCtl;
	DWORD			pdwBlockData[(sizeof(HWVGPCODE)/sizeof(DWORD)) + 1];
	PVGPINSTFLAGS	psStateCtlInstsSetup;
	PVGPINSTFLAGS	psStateCtlInstsChanged;
	VGPINSTFLAGS	sInstsWritten;
	PDWORD			pdwDest;
	DWORD			dwLastInBlock;
	DWORD			i;

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

	psCurrInsts = &psContext->sCurrHWState.sVGPCode;
	psHWStateCtl = &psContext->sHWStateCtl;

	/*
		psStateCtlInstsChanged - flag-words specifying the instructions
								 marked as changed from the context state-
								 control data
		psStateCtlInstsSetup   - flag-words specifying the instructions
								 marked as previously setup (i.e. submitted
								 to the HW) from the context state-control
								 data
		psInstsWritten		   - flag-words indicating which instructions we 
								 need to write
	*/
	psStateCtlInstsChanged = &psHWStateCtl->sVGPInstsChanged;
	psStateCtlInstsSetup   = &psHWStateCtl->sVGPInstsSetup;
	sInstsWritten		   = *psInstsChanged;

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

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

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

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

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

		dwSetup = psStateCtlInstsSetup->pdwFlags[i];

		/*
			Process this group of instructions until we have handled all the
			changed ones.
		*/
		for(dwInstNum = i<<5, dwFlag = 0x1UL; dwLeft; dwFlag <<= 1, dwInstNum++)
		{
			PHWVGPINST	psNewInst;
			PHWVGPINST	psCurrInst;

			/*
				Skip instruction if it hasn't changed
			*/
			if(!(dwLeft & dwFlag))
			{
				continue;
			}

			/*
				Is the new value different from the current (if any)?
			*/
			psCurrInst = &psCurrInsts->psInsts[dwInstNum];
			psNewInst  = &psNewInsts->psInsts[dwInstNum];

			if(!(dwSetup & dwFlag)								||
				(psNewInst->word.dwLo ^ psCurrInst->word.dwLo)	|| 
				(psNewInst->word.dwHi ^ psCurrInst->word.dwHi))
			{
				D3DM_DPF((DPF_TA, "TACSWriteVGPInstructions: Instruction %d changed. Including in block", dwInstNum));
		
				/*
					Instruction changed or never written before. Must write.

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

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


					/* Add header to start of block */
					pdwBlockData[0] = MBX1_TAOBJTYPE_VGP_CODE | 
									  (dwFirstInBlock << MBX1_VGPCODE_STARTADDR_SHIFT) |
									  (dwLastInBlock << MBX1_VGPCODE_ENDADDR_SHIFT);

					dwDataSize += sizeof(DWORD);

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

					TACSWriteData(psContext, pdwBlockData, dwDataSize);

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

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

				/*
					Add this instruction to the current instruction-block
				*/
				*(PHWVGPINST)pdwDest = *psNewInst;
				*psCurrInst = *psNewInst;
				pdwDest += sizeof(HWVGPINST) / sizeof(DWORD);

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

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

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

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

		/* Add header to start of block	*/
		pdwBlockData[0] = MBX1_TAOBJTYPE_VGP_CODE | 
						  (dwFirstInBlock << MBX1_VGPCODE_STARTADDR_SHIFT) |
						  (dwLastInBlock << MBX1_VGPCODE_ENDADDR_SHIFT);

		dwDataSize += sizeof(DWORD);

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

		TACSWriteData(psContext, pdwBlockData, dwDataSize);
	}

	/*
		Record which instructions we have just written-out
		
		NB:	must update the flags for the instructions written, as we have 
			manually changed it's flags
	*/
	FlagArrayUpdate((PFLAGARRAY)&sInstsWritten);

	FlagArraySetFlags((PFLAGARRAY)psStateCtlInstsSetup,
					  (PFLAGARRAY)&sInstsWritten);
}
/*****************************************************************************
 FUNCTION	: UpdateVGPInstructions
    
 PURPOSE	: Updates the VGP-code required for the next primitive, and
			  submits any changes to the HW.

 PARAMETERS	: psContext	- Current 3D rendering context
  
 RETURNS	: void
*****************************************************************************/
IMG_VOID UpdateVGPInstructions(LPD3DM_CONTEXT psContext)
{
	PHWSTATECTL		psHWStateCtl;
	PVGPINSTFLAGS	psInstsChanged;

	psHWStateCtl = &psContext->sHWStateCtl;

	/*
		Any constants in this bank changed?
	*/
	psInstsChanged = &psHWStateCtl->sVGPInstsChanged;
	if(psInstsChanged->dwUsed)
	{
		PHWVGPCODE	psNewInsts;

		D3DM_DPF((DPF_TA, "UpdateVGPInstructions: updating instructions"));

		/*
			Submit the changed instructions (only written if different 
			to current values)
		*/
		psNewInsts = &psContext->sHWState.sVGPCode;

		TACSWriteVGPInstructions(psContext,
								 psInstsChanged,
								 psNewInsts,
								 FALSE);

		/*
			Reset the instruction 'state-changed' flags (since all changed 
			instructions have been output)
		*/
		FlagArrayClearFlagRange((PFLAGARRAY)psInstsChanged,
								0,
								psInstsChanged->dwSize - 1);
	}
}

#endif /* SUPPORT_VGP */

/*********************************************************************************
 End of VGP Specific
*********************************************************************************/

/*********************************************************************************
 Function	 : TACSWriteData

 Description : Low-level routine to output a given block of data to the
			   TA control-stream slave port.
 
 Parameters	 : psContext	- Current 3D rendering context
			   pvData		- The data to write
			   dwDataSize	- The amount of data to write (in bytes)

 Return		 : void
*********************************************************************************/
void TACSWriteData(LPD3DM_CONTEXT psContext, PVOID pvData, DWORD dwDataSize)
{
	PVRSRV_DEV_INFO			*psDevInfo;
	PVRSRV_DEV_DATA			*psDevData;
	PVRSRV_DEV_LOCATION		*psDevLoc; 
	DWORD					dwDataLeft;
	PVOID					*pvRegBase;
	DWORD					*pdwData;
	DWORD					dwBytesObtained = 0;
	DWORD					dwAmountToWrite;

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

	PROFILE_START_FUNC(TACS_WRITE_DATA);

	psDevData			= &psContext->sDevData;
	psDevInfo			= GetDevInfo(psContext);
	pvRegBase			= GetRegisterBase(psContext);
	psDevLoc			= &psDevInfo->sDevLocation;

	/* convert from bytes to DWORDs */
	dwDataLeft	= (dwDataSize + 3) >> 2;
	pdwData		= (DWORD*)pvData;

	while(dwDataLeft)
	{
		/* Obtain available fifo space if we have none */
		if(psContext->dwAllocatedFifoSpaceDWORDS == 0)
		{

			PVRSRVAcquire3DFifoSpace (psDevData->psDevInfoUM,
									&psContext->sHWInfo,
									&dwBytesObtained);

			psContext->dwAllocatedFifoSpaceDWORDS = dwBytesObtained >> 2;

		}


		/* Calculate how many DWORDs we should write */
		if(psContext->dwAllocatedFifoSpaceDWORDS > dwDataLeft)
		{
			dwAmountToWrite = dwDataLeft;
		}
		else
		{
			dwAmountToWrite = psContext->dwAllocatedFifoSpaceDWORDS;
		}

		
		D3DM_DPF((DPF_TA, "TACSWriteData: Writing %d bytes from 0x%8.8lX", (dwAmountToWrite <<2), pvData));

		/* Batch write as much data as we can*/
		PVRSRVWriteSlavePortBatch(&psContext->sHWInfo.sDeviceSpecific.sMBX.sTASlavePort,
								  pdwData,
								  (dwAmountToWrite<<2));

		dwDataLeft								-= dwAmountToWrite;
		psContext->dwAllocatedFifoSpaceDWORDS	-= dwAmountToWrite;
		PVRSRVRelease3DFifoSpace(psDevData->psDevInfoUM, (dwAmountToWrite << 2));

		/* Dump SP writes */
		PDUMPSPBATCH(psContext->psPDContext, PDUMPTAGS_SP_MBX_DATA, pdwData, dwAmountToWrite);

		/* Update our data pointer */
		pdwData			+= dwAmountToWrite;

	}
	/* Signal that we've sent some data to the TA */
	psContext->psCurrentRenderTarget->sDescription.sSurface.bSceneTADataSent = TRUE;

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

	PROFILE_STOP_FUNC(TACS_WRITE_DATA);
}

/*********************************************************************************
 Function	 : TACSWriteTermDWORD

 Description : Low-level routine to write a DWORD to the slave-port terminate
			   address
 
 Parameters	 : psContext	- Current 3D rendering context
			   dwValue		- The value to write

 Return		 : void
*********************************************************************************/
void TACSWriteTermDWORD(LPD3DM_CONTEXT psContext, DWORD dwValue)
{
	PVRSRV_DEV_INFO			*psDevInfo;
	PVRSRV_DEV_DATA			*psDevData;
	PVRSRV_DEV_LOCATION		*psDevLoc; 
	PVOID					*pvRegBase;
	DWORD					dwBytesObtained;

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

	PROFILE_START_FUNC(TACS_WRITE_TERM_DWORD);

	psDevData				= &psContext->sDevData;
	psDevInfo				= GetDevInfo(psContext);
	pvRegBase				= GetRegisterBase(psContext);
	psDevLoc				= &psDevInfo->sDevLocation;
	dwBytesObtained			= 0;

	/* Aquire FIFO space if required */
	if(psContext->dwAllocatedFifoSpaceDWORDS == 0)
	{

		while(!dwBytesObtained)
		{
			PVRSRVAcquire3DFifoSpace (psDevData->psDevInfoUM,
									&psContext->sHWInfo,
									&dwBytesObtained);
		}

		psContext->dwAllocatedFifoSpaceDWORDS = dwBytesObtained >> 2;
	}

	/* Write the DWORD and update space count */
	PVRSRVWriteSlavePort(&psContext->sHWInfo.sDeviceSpecific.sMBX.sTAControlSlavePort, dwValue);
	psContext->dwAllocatedFifoSpaceDWORDS--;
	PVRSRVRelease3DFifoSpace(psDevData->psDevInfoUM, 4 /*bytes*/);

	/* Pdump SP Dword write */
	PDUMPSP(psContext->psPDContext, PDUMPTAGS_SP_MBX_TERM, dwValue);

	PROFILE_STOP_FUNC(TACS_WRITE_TERM_DWORD);

}

/*****************************************************************************
 End of file (tautils)
*****************************************************************************/

⌨️ 快捷键说明

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