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

📄 tsstate.c

📁 Lido PXA270平台开发板的最新BSP,包括源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
		DWORD					dwArg2;
		DWORD					dwColourOpLCtl3;
		DWORD					dwAlphaOpLCtl3;
		DWORD					dwMipFilterCtl;
		DWORD					dwLCtl1;
		DWORD					dwLCtl2;
		DWORD					dwLCtl3;

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

		psLState = &psContext->sTState.sLState[i];
		psTexture = psLState->psSurfData;
		psHWLState = &psTACtl3DState->sTSPLState[i];

		/*
			Get the partially-setup HW texture-layer control words for this 
			D3D stage

			NB:	Word3 holds texture-blending controls only and is completely
				setup here based on the chosen D3D colour/alpha ops'n'args.
		*/
		dwLCtl1 = psLState->sTSPLState.dwLCtl1;
		dwLCtl2 = psLState->sTSPLState.dwLCtl2;
		dwLCtl3 = 0;

		/*
			Update the HW mipmap-filtering mode

			Enable if textured, the bound texture is a mipmap, and mipmapping
			is not globally disabled.
		*/
		dwMipFilterCtl = MBX1_TSPPL2_MIPCTLNOTMIPMAP;

		if(psTexture)
		{
			if((psTexture->sDescription.sTexture.psMapDetails->dwSuppliedLevels > 1) &&
			   (!(psContext->sRegData.dwFlags2 & D3DMREG2_DISABLE_MIPMAP)))
			{
				dwMipFilterCtl = psLState->dwMipFilterCtl;
			}
		}

		dwLCtl2 &= MBX1_TSPPL2_MIPCTLCLRMASK;
		dwLCtl2 |= dwMipFilterCtl;

		/* Setup the appropriate mipmap-level clamp if mipmapping is in-use	*/
		dwLCtl1 &= MBX1_TSPPL1_MIPMAPCLAMPCLRMASK;
		if(dwMipFilterCtl != MBX1_TSPPL2_MIPCTLNOTMIPMAP)
		{
			DWORD	dwMipLevels;

			/* Get Number of Supplied Mip Map levels */
			dwMipLevels  = psTexture->sDescription.sTexture.psMapDetails->dwSuppliedLevels;
			dwMipLevels -= psLState->dwMaxMipLevel;

			if(dwMipLevels > 1)
			{
				DWORD	dwLevelClamp;

				dwLevelClamp = dwMipLevels - 1;
				if(dwLevelClamp > ((~MBX1_TSPPL1_MIPMAPCLAMPCLRMASK) >> MBX1_TSPPL1_MIPMAPCLAMPSHIFT))
				{
					dwLevelClamp = (~MBX1_TSPPL1_MIPMAPCLAMPCLRMASK) >> MBX1_TSPPL1_MIPMAPCLAMPSHIFT;
				}

				dwLCtl1 |= dwLevelClamp << MBX1_TSPPL1_MIPMAPCLAMPSHIFT;
			}
		}

		/*
			Enable HW texture super-sampling to improved filtering when
			anisotropic is requires.

			NB:	Anisotropic filtering depends on the filtermode and maximum
				anisotropy level. Only required if both are valid.
		*/
		if	((psLState->dwLFlags & (LTSTATE_FLAGS_ANISOFILTERINGREQ | 
									LTSTATE_FLAGS_MAXANISOLEVELNOTONE))
								== (LTSTATE_FLAGS_ANISOFILTERINGREQ | 
									LTSTATE_FLAGS_MAXANISOLEVELNOTONE)
#if defined (FIX_HW_PRN_530)
		/* if supersample is enabled on one layer, enable on all */
			 || (bTextureSuperSampleUsed == IMG_TRUE))
		{
			bTextureSuperSampleUsed = IMG_TRUE;
#else
		 )
		{
#endif
#if defined (FIX_HW_PRN_734)
			if(psContext->sHWState.sTACtl3DState.dwISPTSPCtl & MBX1_ISPTSPCTL_OFFSET)
			{
				/* If offset is present don't enable supersampling */
				dwLCtl1 &= ~MBX1_TSPPL1_TSUPERSAMPLE;
			}
			else
			{
				dwLCtl1 |= MBX1_TSPPL1_TSUPERSAMPLE;
			}
#else
			dwLCtl1 |= MBX1_TSPPL1_TSUPERSAMPLE;
#endif
		}
		else
		{
			dwLCtl1 &= ~MBX1_TSPPL1_TSUPERSAMPLE;
		}

		/*
			Lookup the HW state for the chosen D3D colour-op and args

			NB:	We clear some bits of the texture argument flags, in case
				SPECULAR has been chosen. If the stage has been validated
				it should have failed - if not, clearing the bits will
				safely set the choice to DIFFUSE.
		*/
		dwArg1 = psLState->dwCArg1 & (D3DMTA_TFACTOR | 
									  D3DMTA_COMPLEMENT | 
									  D3DMTA_ALPHAREPLICATE);

		dwArg2 = psLState->dwCArg2 & (D3DMTA_TFACTOR | 
									  D3DMTA_COMPLEMENT | 
									  D3DMTA_ALPHAREPLICATE);

		dwColourOpLCtl3 = GetColourOpLCtl3(psLState->dwCOp,
										   dwArg1,
										   dwArg2,
										   psLState->dwArgTransFlags);

		if	(dwColourOpLCtl3 != 0xffffffff)
		{
			dwLCtl3 |= dwColourOpLCtl3;
		}

		/*
			DotProd3 blending requires a change to the layer one control
			word and the alpha channel blend to be in a known state.
		*/
		if	(psLState->dwCOp == D3DMTOP_DOTPRODUCT3)
		{
			dwLCtl1 |= MBX1_TSPPL1_CSUM;
			
			/*
				When DotProd3 blending, the CSUM(CS1 * CS2) result is copied
				from the colour blend to replace the (AS1 * AS2) blend in the
				alpha channel. The (AS3 * AS4) blend must then be zero.
			*/
			dwLCtl3 |= MBX1_TSPPL3_AS1SELONE |
					   MBX1_TSPPL3_AS2SELDIFFUSEALPHA |
					   MBX1_TSPPL3_AS3SELONE |
					   MBX1_TSPPL3_INVAS3 |
					   MBX1_TSPPL3_ABEOP1X;
		}
		else
		{
			/*
				Lookup the HW state for the chosen D3D alpha-op and args

				NB:	We clear some bits of the texture argument flags, in
					case SPECULAR has been chosen. If the stage has been
					validated it should have failed - if not, clearing the
					bits will safely set the choice to DIFFUSE.
			*/
			dwArg1 = psLState->dwAArg1 & (D3DMTA_TFACTOR | 
										  D3DMTA_COMPLEMENT | 
										  D3DMTA_ALPHAREPLICATE);

			dwArg2 = psLState->dwAArg2 & (D3DMTA_TFACTOR | 
										  D3DMTA_COMPLEMENT | 
										  D3DMTA_ALPHAREPLICATE);

			dwAlphaOpLCtl3 = GetAlphaOpLCtl3(psLState->dwAOp, 
											 dwArg1,
											 dwArg2,
											 psLState->dwArgTransFlags);

			if	(dwAlphaOpLCtl3 != 0xffffffff)
			{
				dwLCtl3 |= dwAlphaOpLCtl3;
			}
		}

		/*
			See if TextureAlpha is being used.
			Used to work out if we really need Alpha Test enabled.
		*/
		if	(psTexture)
		{
			if	(!(psLState->dwArgTransFlags & PVR_ARGTRANSFLAG_OPAQUETEXTURE))
			{
				if	(
						((dwLCtl3 & (~MBX1_TSPPL3_AS1SELCLRMASK)) == MBX1_TSPPL3_AS1SELTEXTUREALPHA) |
						((dwLCtl3 & (~MBX1_TSPPL3_AS2SELCLRMASK)) == MBX1_TSPPL3_AS2SELTEXTUREALPHA) |
						((dwLCtl3 & (~MBX1_TSPPL3_AS3SELCLRMASK)) == MBX1_TSPPL3_AS3SELTEXTUREALPHA) |
						((dwLCtl3 & (~MBX1_TSPPL3_AS4SELCLRMASK)) == MBX1_TSPPL3_AS4SELTEXTUREALPHA) |
						((dwLCtl3 & (~MBX1_TSPPL3_CS2SELCLRMASK)) == MBX1_TSPPL3_CS2SELTEXTUREALPHA) |
						((dwLCtl3 & (~MBX1_TSPPL3_CS4SELCLRMASK)) == MBX1_TSPPL3_CS4SELTEXTUREALPHA)
					)
				{
					psContext->dwFlags |= D3DM_CONTEXT_SWFLAGS_USESTEXTUREALPHA;
				}
			}
		}
		else
		{
			psContext->dwFlags |= D3DM_CONTEXT_SWFLAGS_USESTEXTUREALPHA;

			/*
				Layer is Untextured. Check if it is trying to use a texture
			*/
			if	(
					((dwLCtl3 & (~MBX1_TSPPL3_CS1SELCLRMASK)) == MBX1_TSPPL3_CS1SELTEXTURE) |
					((dwLCtl3 & (~MBX1_TSPPL3_CS2SELCLRMASK)) == MBX1_TSPPL3_CS2SELTEXTURE) |
					((dwLCtl3 & (~MBX1_TSPPL3_CS3SELCLRMASK)) == MBX1_TSPPL3_CS3SELTEXTURE) |
					((dwLCtl3 & (~MBX1_TSPPL3_CS4SELCLRMASK)) == MBX1_TSPPL3_CS4SELTEXTURE)
				)
			{		
				/*
					Referencing a texture. If not the first stage, simply 
					disable it. Otherwise, default to use the diffuse colour
					and alpha - refrast behaviour 
				*/
#if 0 //FIXME:  I'm sure we don't need to leave an enabled tstage here but 
		// uncomment if causes problems in state post processing
				if	(i)
				{
					psContext->dwFlags &= ~(D3DM_CONTEXT_SWFLAGS_LAYER0ENABLED << i);
					break;
				}
				else
				{
					dwLCtl3 = MBX1_TSPPL3_CS2SELDIFFUSE | 
							  MBX1_TSPPL3_CS1SELONE | 
							  MBX1_TSPPL3_CS3SELONE | 
							  MBX1_TSPPL3_INVCS3 |
							  MBX1_TSPPL3_AS2SELDIFFUSEALPHA | 
							  MBX1_TSPPL3_AS1SELONE | 
							  MBX1_TSPPL3_AS3SELONE | 
							  MBX1_TSPPL3_INVAS3;
				}
#else
				psContext->dwFlags &= ~(D3DM_CONTEXT_SWFLAGS_LAYER0ENABLED << i);
				break;
#endif
			}
		}

		/*
			Determine the number of passes required for this HW-layer
		*/
		if	(dwMipFilterCtl == MBX1_TSPPL2_MIPCTLMIPFILTER)
		{
			dwPassesReq += 2;
		}
		else
		{
			dwPassesReq += 1;
		}

		/*
			Redo D-Adjust (Mip LOD Bias).
			Always do it, since the mipmap mipfilter (between-level) mode may
			have changed, so we might need to bias the D-Adjust differently.
		*/
		SetupDAdjust(psContext, psLState->DAdjust, &dwLCtl2, (dwMipFilterCtl == MBX1_TSPPL2_MIPCTLMIPFILTER));

		/*
			Save the completed HW texture-layer state for the texture-stage,
			and flag that is has been altered.
		*/
		psHWLState->dwLCtl1 = dwLCtl1;
		psHWLState->dwLCtl2 = dwLCtl2;
		psHWLState->dwLCtl3 = dwLCtl3;

		psHWStateCtl->dwTACtl3DStateChanged |= MBX1_TASTATEPRES_LAYER0CTL << i;
	}

	/*
		Record the number of enabled D3D stages
	*/
	psContext->sTState.dwNumEnabledLayers = i;

	/*
		Update the TSP pass and texture-layer counts in the ISP/TSP control-word
	*/
	psTACtl3DState->dwISPTSPCtl &= MBX1_ISPTSPCTL_NUMPASSESCLRMASK &
								   MBX1_ISPTSPCTL_UVCOUNTCLRMASK;
	psTACtl3DState->dwISPTSPCtl |= (dwPassesReq << MBX1_ISPTSPCTL_NUMPASSESSHIFT) & 
								   (~MBX1_ISPTSPCTL_NUMPASSESCLRMASK);
	if	(dwPassesReq)
	{
		psTACtl3DState->dwISPTSPCtl |= ((i-1) << MBX1_ISPTSPCTL_UVCOUNTSHIFT) &
									   (~MBX1_ISPTSPCTL_UVCOUNTCLRMASK);
	}

	/*
		Flag this the ISP/TSP control word may have changed
	*/
	psHWStateCtl->dwTACtl3DStateChanged |= MBX1_TASTATEPRES_ISPCTL;

	/*
		Update the HW object type required (dependant upon 
		MBX1_SWFLAGS_USESTEXTUREALPHA flag)
	*/
	SetupObjectType(psContext);

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

/*----------------------------------------------------------------------------
<function>
 FUNCTION	: D3DM_TSS_NOP
    
 PURPOSE	: Does nothing !

 PARAMETERS	: psContext - Current D3D context
			  psLState	- Layer state
			  dwValue	- Value to set
			  
 RETURNS	: 
</function>
------------------------------------------------------------------------------*/
void D3DM_TSS_NOP(LPD3DM_CONTEXT psContext, LPD3DM_TEXTURESTAGESTATE psState)
{
	D3DM_DPF((DPF_ENTRY, "->D3DM_TSS_NOP"));
	D3DM_DPF((DPF_STATE, "D3DM_TSS_NOP: (State %d):  Stage %d: Value = 0x%08X", psState->State, psState->Stage, psState->Value));
	D3DM_DPF((DPF_EXIT, "<-D3DM_TSS_NOP"));
}


/*----------------------------------------------------------------------------
<function>
 FUNCTION	: D3DM_TSS_TextureMap
    
 PURPOSE	: 

 PARAMETERS	: psContext - Current D3D context
			  psLState	- Layer state to be applied to...
			  dwValue	- Value to set
			  
 RETURNS	: 
</function>
------------------------------------------------------------------------------*/
void D3DM_TSS_TextureMap(LPD3DM_CONTEXT psContext,LPD3DM_TEXTURESTAGESTATE psState)
{
	PMBX1_TSPLAYER_STATE	psTSPLState;
	LPD3DM_SURFACE			psPrevTexture;
	LPD3DM_SURFACE 			psTexture;
	PMAP_DETAILS			psMapDetails;
	PLAYER_TSTATE 			psLState;
	DWORD 					dwValue;
	DWORD 					dwStage;

	D3DM_DPF((DPF_ENTRY, "->D3DM_TSS_TextureMap"));
	D3DM_DPF((DPF_STATE, "D3DM_TSS_TextureMap: Stage %d: Handle = 0x%08X", psState->Stage, psState->Value));

	dwStage = (DWORD)psState->Stage;
	psLState = &psContext->sTState.sLState[dwStage];
	psTSPLState = &psLState->sTSPLState;

	dwValue = psState->Value;

	/*
		Enable texture parameters, note this will be turned off
		in primitive setup FN's if there are no textured layers.
	*/
	psContext->sHWStateCtl.dwTACtl3DStateChanged |= MBX1_TASTATEPRES_ISPCTL;

	/*
		Un-bind the current texture (if any) from this stage
	*/
	psPrevTexture = psLState->psSurfData;
	if	(psPrevTexture)
	{
		psMapDetails = psPrevTexture->sDescription.sTexture.psMapDetails;
		if	(psMapDetails)
		{
			psMapDetails->dwFlags &= ~(MAPDETAILSFLAGS_USEDINSTAGE0 << dwStage);
		}
		psLState->psSurfData = 0;
	}


	/* Get the new texture to be bound to this stage */
	psTexture = (LPD3DM_SURFACE) dwValue;

	/*
		Ignore if untextured
	*/
	if	(!psTexture)
	{
		return;
	}

	/*
		Associate the new texture with this stage
	*/
	psLState->psSurfData = psTexture;

	psMapDetails = psTexture->sDescription.sTexture.psMapDetails;
	psMapDetails->dwFlags |= MAPDETAILSFLAGS_USEDINSTAGE0 << dwStage;

	/*
		Fill-out texture parameters (setup once when the texture is created)
		that are independent of any other texture-blending state
	*/
	psTSPLState->dwLCtl1 &= MBX1_TSPPL1_TPIXFORMCLRMASK & 
							MBX1_TSPPL1_TUSIZECLRMASK & 
							MBX1_TSPPL1_TVSIZECLRMASK;
	psTSPLState->dwLCtl1 |= psMapDetails->sTSPCtl.dwLCtl1;

	psTSPLState->dwLCtl2 &= MBX1_TSPPL2_TEXADDRCLRMASK &
							MBX1_TSPPL2_TEXSTRIDECLRMASK;
	psTSPLState->dwLCtl2 |= psMapDetails->sTSPCtl.dwLCtl2;

	/*
		If this texture is opaque, update the colour/alphs arg translation
		flags (so that TEXTUREALPHA is mapped to ONE).
	*/
	if	(psMapDetails->dwFlags & MAPDETAILSFLAGS_OPAQUE)
	{
		psLState->dwArgTransFlags |= PVR_ARGTRANSFLAG_OPAQUETEXTURE;
	}
	else
	{
		psLState->dwArgTransFlags &= ~PVR_ARGTRANSFLAG_OPAQUETEXTURE;
	}

#ifdef FIXME // Luma texture
	/*
		An 8-bit luma texture? Update the colour/alphs arg translation
		flags so that TEXTUREALPHA is mapped to ONE
	*/
	if	(
			(psTexture->sPixelFormat.dwFlags & DDPF_LUMINANCE) &&
			(psTexture->sPixelFormat.dwLuminanceBitCount == 8)
		)
	{
		psLState->dwArgTransFlags |= PVR_ARGTRANSFLAG_OPAQUETEXTURE;
	}
#endif
	/*
		An 8-bit alpha texture? Update the colour/alphs arg translation
		flags so that TEXTURE is mapped to ZERO
	*/
	if(psTexture->eFormat == D3DMFMT_A8)
	{
		psLState->dwArgTransFlags |= PVR_ARGTRANSFLAG_NOTEXCOLOUR;
	}
	else
	{
		psLState->dwArgTransFlags &= ~PVR_ARGTRANSFLAG_NOTEXCOLOUR;
	}

	/*
		For mipmaps we need to check if a max level has been set

⌨️ 快捷键说明

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