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

📄 vgplite.c

📁 Lido PXA270平台开发板的最新BSP,包括源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*****************************************************************************
 Name			: vgp.c
 
 Title			: VGP lite specific functions
 
 C Author 		: Imagination Technologies
 
 Created  		: 22/4/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, HomePark
				  Industrial Estate, King's Langley, Hertfordshire,
				  WD4 8LZ, U.K.

 Description 	: VGP lite specific functions
   
 Program Type	: 32-bit DLL

 Version	 	: $Revision: 1.2 $

 Modifications	:

 $Log: vgplite.c $

  Initial revision
 
*****************************************************************************/

#include "context.h"

#if defined(SUPPORT_VGP_LITE)

/*****************************************************************************
*	Include code sections
*****************************************************************************/
#include "vgpsections.c"
/*****************************************************************************/

/*****************************************************************************
 FUNCTION	: VGPTNLUpdateFFTNLShader
    
 PURPOSE	: Configures the fixed-function TNL vertex-shader according the
			  the current TN: requirements and state

 PARAMETERS	: psContext	- The current 3D rendering context
			  
 RETURNS	: void
****************************************************************************/
void VGPTNLUpdateFFTNLShader(LPD3DM_CONTEXT psContext)
{
	PTRANSIENT_STATE	psTState;
	PSWTNLSTATE			psSWTNLState;
	DWORD				dwTNLFlags;
	DWORD				dwTNLFlags2;
	DWORD				dwSectionModFlags;
	DWORD				dwRSFlags;
	DWORD				dwSectionStart;
	DWORD				dwSectionEnd;
	DWORD				dwSectionsToEnable;
	DWORD				dwTcCount;
	DWORD				dwBaseInstruction;
	DWORD				dwCurrentInstruction;
	DWORD				i;
	HWVGPINST			*pInstBuffer;

	pInstBuffer			= (HWVGPINST*) &psContext->sHWState.sVGPCode;
	psTState			= &psContext->sTState;
	psSWTNLState		= &psTState->sSWTNLState;
	dwTNLFlags			= psSWTNLState->dwTNLFlags;
	dwTNLFlags2			= psSWTNLState->dwTNLFlags2;
	dwSectionModFlags	= psSWTNLState->dwSectionModFlags;
	dwRSFlags			= psTState->dwRSFlags;

	/* Start by disabling all sections */
	DisableSections(0xFFFFFFFF, psContext);
	dwSectionsToEnable = 0;

	/* Enable Position section */
	dwSectionsToEnable |= 1 << VGPTNL_SECTIONORD_POSITION;

	if(dwSectionModFlags & (1 << VGPTNL_SECTIONORD_POSITION))
	{
		if(psContext->sTState.sSWTNLState.dwSectionModFlags & PVRD3DTNL_FLAGS_PASSTHROUGH_LOADED)
		{
			PVSINSTRANGE psExeRange = &psContext->sTState.sSWTNLState.psPTSectionMods[VGPTNL_SECTIONORD_POSITION].sExeRange;

			/* The only change is the passthrough has been loaded, so we only need replace 1 instruction */
			pInstBuffer[psExeRange->dwFirst] = 
				psContext->sTState.sSWTNLState.psPTSectionMods[VGPTNL_SECTIONORD_POSITION].psInstructions[0];

			/* Set executable range */
			SetSectionExeRange(VGPTNL_SECTIONORD_POSITION,
							   psExeRange->dwFirst, 
							   psExeRange->dwLast,
							   psContext);

			/* Flag modified instructions */
			FlagArraySetFlagRange((PFLAGARRAY)&psContext->sHWStateCtl.sVGPInstsChanged, 
								   psExeRange->dwFirst, 
								   psExeRange->dwFirst);
		}
		else
		{
			/* Get position section first instruction address */
			dwBaseInstruction = psContext->ppsFFTNLSections[VGPTNL_SECTIONORD_POSITION]->sConfig.sLoadRange.dwFirst;
			dwCurrentInstruction = dwBaseInstruction;

			/* 
				Setup the position section. Available sections: -

				psPositionPassthruSection			- Pass through input to output
				psPositionZBiasPassthruSection		- Add Z bias to Z and store in R0
				psPositionWBiasPassthruSection		- Add Z bias to W and store in R0
				psPositionTransformSection			- Transform postition and store in R0
				psPositionZBiasSection				- Add inverse VPTTrans of Z bias to Z (from R0) store in R0
				psPositionWBiasSection				- Add 1/(1/W + Z-bias) to W (from R0) store in R0
				psPositionViewPortTransformSection	- Does VPort transform for procvert mode
				psPositionOutputSection				- Move R0 to outputs
				psPositionClipSection				- Set front and rear clips
			*/
			if((psContext->psVertexSource->dwFVFFlags & D3DMFVF_POSITION_MASK) ==D3DMFVF_XYZRHW_FIXED ||
			   (psContext->psVertexSource->dwFVFFlags & D3DMFVF_POSITION_MASK) ==D3DMFVF_XYZRHW_FLOAT)
			{
				if(dwRSFlags & TSTATE_RSFLAGS_DEPTHBIAS)
				{
					if(psContext->dwTAPrimCtl & MBX1_TAPRIM_WBUFFERING_ENABLE)
					{
						/* Add Zbias to W */
						for(i = 0; i < INSTCOUNT(psPositionWBiasPassthruSection); i++)
						{
							pInstBuffer[dwCurrentInstruction++] = psPositionWBiasPassthruSection[i];
						}
					}
					else
					{
						/* Add Zbias to Z */
						for(i = 0; i < INSTCOUNT(psPositionZBiasPassthruSection); i++)
						{
							pInstBuffer[dwCurrentInstruction++] = psPositionZBiasPassthruSection[i];
						}
					}

					/* Copy to outputs */
					pInstBuffer[dwCurrentInstruction++] = psPositionOutputSection[0];
				}
				else
				{
					/* Pass inputs to outputs */
					pInstBuffer[dwCurrentInstruction++] = psPositionPassthruSection[0];
				}
			}
			else
			{
				/* Add position transform */
				for(i = 0; i < INSTCOUNT(psPositionTransformSection); i++)
				{
					pInstBuffer[dwCurrentInstruction++] = psPositionTransformSection[i];
				}

				/* Check for Depth bias */
				if(dwRSFlags & TSTATE_RSFLAGS_DEPTHBIAS)
				{
					if(psContext->dwTAPrimCtl & MBX1_TAPRIM_WBUFFERING_ENABLE)
					{
						/* Add Zbias to W */
						for(i = 0; i < INSTCOUNT(psPositionWBiasSection); i++)
						{
							pInstBuffer[dwCurrentInstruction++] = psPositionWBiasSection[i];
						}
					}
					else
					{
						/* Add Zbias to Z */
						for(i = 0; i < INSTCOUNT(psPositionZBiasSection); i++)
						{
							pInstBuffer[dwCurrentInstruction++] = psPositionZBiasSection[i];
						}
					}
				}

				/* If were in process vertices mode we'll need the viewport transform section */
				if(psContext->dwFlags & D3DM_CONTEXT_SWFLAGS_PROCVERT_MODE)
				{
					/* Add Vport Xform section */
					for(i = 0; i < INSTCOUNT(psPositionWBiasSection); i++)
					{
						pInstBuffer[dwCurrentInstruction++] = psPositionViewPortTransformSection[i];
					}
				}

				/* Copy R0 to outputs */
				pInstBuffer[dwCurrentInstruction++] = psPositionOutputSection[0];

				if(dwRSFlags & TSTATE_RSFLAGS_CLIPPING)
				{	
					/* Set front and rear clip */
					for(i = 0; i < INSTCOUNT(psPositionClipSection); i++)
					{
						pInstBuffer[dwCurrentInstruction++] = psPositionClipSection[i];
					}
				}
			}
			/* Set executable range */
			SetSectionExeRange(VGPTNL_SECTIONORD_POSITION,
							   dwBaseInstruction, 
							   dwCurrentInstruction - 1,
							   psContext);

			/* Flag modified instructions */
			FlagArraySetFlagRange((PFLAGARRAY)&psContext->sHWStateCtl.sVGPInstsChanged, 
								  dwBaseInstruction, 
								  dwCurrentInstruction - 1);
		}



		dwSectionModFlags &= ~(1 << VGPTNL_SECTIONORD_POSITION);
	}


	/* FIXME: Output the specular directly if it is not calculated by the lighting code */

	/* Set up the transform of the position and normal into camera space */
	if(((dwRSFlags & TSTATE_RSFLAGS_LIGHTING) && (dwTNLFlags & PVRD3DTNL_FLAGS_ENABLED))	||
	    (dwTNLFlags2 & PVRD3DTNL_FLAGS2_TEXGEN_NEEDPOSITION)								||
	    (dwTNLFlags2 & PVRD3DTNL_FLAGS2_TEXGEN_NEEDNORMAL)									||
		(dwRSFlags & TSTATE_RSFLAGS_FOG))
	{	
		/* Enable the position/normal object->view space transform */
		dwSectionsToEnable |= 1 << VGPTNL_SECTIONORD_POSTOVIEW;

		if((dwTNLFlags2 & PVRD3DTNL_FLAGS2_TEXGEN_NEEDNORMAL)	||
		  ((dwRSFlags & TSTATE_RSFLAGS_LIGHTING) && (dwTNLFlags & PVRD3DTNL_FLAGS_ENABLED)))
		{
			/* Also perform normal-vector normalisation if required */
			dwSectionStart = 0;
			if	(dwRSFlags & TSTATE_RSFLAGS_NORMALIZENORMALS)
			{
				dwSectionEnd = SECTION_POSTOVIEW_NORMALISENORMAL_SIZE - 1;
			}
			else
			{
				dwSectionEnd = SECTION_POSTOVIEW_NORMAL_SIZE - 1;
			}
		}
		else
		{
			/* We need the view position only for texgen or fog purposes */
			dwSectionEnd = SECTION_POSTOVIEW_BASE_SIZE - 1;
		}

		SetSectionExeRange(VGPTNL_SECTIONORD_POSTOVIEW,
							 dwSectionStart,
							 dwSectionEnd,
							 psContext);
	}

	/*
		Enable local viewer setup as appropriate
	*/
	if(((dwRSFlags & TSTATE_RSFLAGS_LIGHTING) && (dwTNLFlags & PVRD3DTNL_FLAGS_ENABLED)) ||
	    (dwTNLFlags2 & PVRD3DTNL_FLAGS2_TEXGEN_NEEDLOCALVIEWER))
	{			
		if	(dwRSFlags & TSTATE_RSFLAGS_LOCALVIEWER)
		{
			dwSectionsToEnable |= 1 << VGPTNL_SECTIONORD_LVIEWERSETUPFROMVERTEX;
		}
		else
		{
			dwSectionsToEnable |= 1 << VGPTNL_SECTIONORD_LVIEWERSETUPFROMDEFAULT;
		}
	}

	/*
		Lighting enabled?	
	*/
	if((dwRSFlags & TSTATE_RSFLAGS_LIGHTING) &&
	   (dwTNLFlags & PVRD3DTNL_FLAGS_ENABLED))
	{
		DWORD dwColourSourceIndex, dwColourSourceBaseInstruction;
		DWORD pdwSources[3];
		DWORD i;

		/*
			Enable the lighting colour-source selection section
		*/
		dwSectionsToEnable |= 1 << VGPTNL_SECTIONORD_COLOURSOURCESETUP;

		/*
			Configure the section to select the appropriate colours

			NB:	The code is arranged as 27 intruction triples, providing all
				possible combinations of the colour-source selections for the
				ambient, diffuse and specular lighting colours (emissive is 
				handled differently). We use the required colour-sources to
				choose the appropriate three-instructions to execute.
		*/
		pdwSources[0] = (DWORD)psSWTNLState->sColourSourcesReq[TNLCOLSRCTYPE_AMBIENT];
		pdwSources[1] = (DWORD)psSWTNLState->sColourSourcesReq[TNLCOLSRCTYPE_DIFFUSE];
		pdwSources[2] = (DWORD)psSWTNLState->sColourSourcesReq[TNLCOLSRCTYPE_SPECULAR];



		dwColourSourceIndex = (pdwSources[0] * 9) + 
							  (pdwSources[1] * 3) + 
							  (pdwSources[2] * 1);

		/* Select instruction triplet */
		dwColourSourceIndex *= 3;

		/* Get first instruction address */
		dwColourSourceBaseInstruction = psContext->ppsFFTNLSections[VGPTNL_SECTIONORD_COLOURSOURCESETUP]->sConfig.sLoadRange.dwFirst;

		/* Write new instructions to state buffer */
		for(i=0; i < psContext->ppsFFTNLSections[VGPTNL_SECTIONORD_COLOURSOURCESETUP]->dwInstCount; i++)
		{
			pInstBuffer[dwColourSourceBaseInstruction + i] = psColourSourceSectionPrototype[dwColourSourceIndex++];
		}

		/* Flag modified instructions */
		FlagArraySetFlagRange((PFLAGARRAY)&psContext->sHWStateCtl.sVGPInstsChanged, dwColourSourceBaseInstruction, dwColourSourceBaseInstruction + 2);

		/*
			Any point lights enabled?
		*/
		if(psSWTNLState->dwLightCount > 0)
		{
			/* Enable the setup and lighting section */
			dwSectionsToEnable |= 1 << VGPTNL_SECTIONORD_LIGHTINGINIT;
			dwSectionsToEnable |= 1 << VGPTNL_SECTIONORD_GENERICLIGHT;

			/*
				Setup the execution-range to perform basic (diffuse+ambient)
				calculation, plus (optionally) the specular part if required.
			*/
			dwSectionStart = 0;
			if(dwRSFlags & TSTATE_RSFLAGS_SPECULAR)
			{
				dwSectionEnd = SECTION_GENERICLIGHT_SPECULAR_SIZE - 1;
			}
			else
			{
				dwSectionEnd = SECTION_GENERICLIGHT_BASE_SIZE - 1;
			}

			SetSectionExeRange(VGPTNL_SECTIONORD_GENERICLIGHT, 
								 dwSectionStart, 
								 dwSectionEnd,
								 psContext);

			/*
				Execute the section once for each enabled point light
			*/
			SetSectionRepeat(VGPTNL_SECTIONORD_GENERICLIGHT, 
							 psSWTNLState->dwLightCount,
							 psContext);
		}

		/*
			Finally: output the calculated colours (always output diffuse,
			specular is optional)
		*/
		dwSectionsToEnable |= 1 << VGPTNL_SECTIONORD_COLOUROUTPUT;

		dwSectionStart = 0;
		if(dwRSFlags & TSTATE_RSFLAGS_SPECULAR)
		{
			dwSectionEnd = SECTION_COLOUROUTPUT_FULL_SIZE - 1;
		}
		else
		{
			dwSectionEnd = SECTION_COLOUROUTPUT_DIFFUSEONLY_SIZE - 1;
		}

		SetSectionExeRange(VGPTNL_SECTIONORD_COLOUROUTPUT, 
							 dwSectionStart, 
							 dwSectionEnd,
							 psContext);
	}
	else
	{
		DWORD	dwColoursPresent;

		/*
			Configure and enable setting-up of vertex-colour defaults (only if
			both vertex colours are not present)
		*/
		dwColoursPresent = dwTNLFlags & (PVRD3DTNL_FLAGS_DIFFUSE_PRESENT |
										 PVRD3DTNL_FLAGS_SPECULAR_PRESENT);

		if(dwColoursPresent != (PVRD3DTNL_FLAGS_DIFFUSE_PRESENT |
								  PVRD3DTNL_FLAGS_SPECULAR_PRESENT))
		{
			/*
				Enable the default-colour setup section
			*/
			dwSectionsToEnable |= 1 << VGPTNL_SECTIONORD_COLOURSETDEFAULTS;

			/*
				Setup the section execution range to only set the default for the
				colour components that are not present
			*/
			if(dwColoursPresent & PVRD3DTNL_FLAGS_DIFFUSE_PRESENT)
			{
				dwSectionStart = 1;
			}
			else
			{
				dwSectionStart = 0;
			}

			if	(dwColoursPresent & PVRD3DTNL_FLAGS_SPECULAR_PRESENT)
			{
				dwSectionEnd = 0;
			}
			else
			{
				dwSectionEnd = 1;
			}

			SetSectionExeRange(VGPTNL_SECTIONORD_COLOURSETDEFAULTS,
								 dwSectionStart,
								 dwSectionEnd,
								 psContext);
		}

		/*
			Lighting disabled
		*/
		if(dwColoursPresent)
		{
			/*
				Enable the colour passthrough section
			*/

⌨️ 快捷键说明

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