📄 rstate.c
字号:
/******************************************************************************
<module>
* Name : RState.h
* Title : D3DM state modification
* Author(s) : Imagination Technologies
* Created : 2 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 : Render state change processing and software state set up
*
* Platform : Windows CE
*
</module>
********************************************************************************/
#include "context.h"
/*----------------------------------------------------------------------------
<function>
FUNCTION : SetupObjectType
PURPOSE : Sets the object-type in the HW ISP/TSP control word
PARAMETERS : psContext - Current 3D rendering context
RETURNS : none.
</function>
------------------------------------------------------------------------------*/
void SetupObjectType(LPD3DM_CONTEXT psContext)
{
PHWTACTL3DSTATE psTACtl3dState;
DWORD dwISPTSPCtl;
DWORD dwTSPObjCtl;
psTACtl3dState = &psContext->sHWState.sTACtl3DState;
/*
Get the current HW ISP/TSP and TSP per-object words, clearing
any alpha-test and object-type related controls
*/
dwISPTSPCtl = psTACtl3dState->dwISPTSPCtl & MBX1_ISPTSPCTL_OBJTYPECLRMASK;
dwTSPObjCtl = psTACtl3dState->dwTSPObjCtl & (MBX1_TSPOBJ_ALPHACMPCLRMASK &
MBX1_TSPOBJ_ALPHAREFCLRMASK);
/*
Alpha Test in use?
*/
if (
(psContext->dwFlags & D3DM_CONTEXT_SWFLAGS_ALPHATESTENABLED) /*&&
(psContext->dwFlags & D3DM_CONTEXT_SWFLAGS_USESTEXTUREALPHA)*/
)
{
/*
Must be handled as a punch-through object
*/
dwISPTSPCtl |= MBX1_ISPTSPCTL_OBJTYPE_PSPT;
/*
HW Tag-writes must be enabled for alpha-test to work
*/
dwISPTSPCtl &= ~MBX1_ISPTSPCTL_TAGWDISABLE;
/*
Use the current alpha-test compare-mode and reference-value
*/
dwTSPObjCtl |= psContext->sTState.dwAlphaTest;
}
else
{
/*
Alpha-test disabled, so set the HW alpha-compare mode to ALWAYS
*/
dwTSPObjCtl |= MBX1_TSPOBJ_ACMPMODEALWAYS;
/*
Alpha-blending in use?
*/
if (psContext->dwFlags & D3DM_CONTEXT_SWFLAGS_ALPHABLENDENABLED)
{
/*
Must be handled as a transparent object
*/
dwISPTSPCtl |= MBX1_ISPTSPCTL_OBJTYPE_PSTRANS;
}
else
{
/*
Handle as an opaque object
*/
dwISPTSPCtl |= MBX1_ISPTSPCTL_OBJTYPE_OPAQUE;
}
}
/*
Save the new HW control words
*/
psTACtl3dState->dwISPTSPCtl = dwISPTSPCtl;
psTACtl3dState->dwTSPObjCtl = dwTSPObjCtl;
/*
Indicate that state has changed
*/
psContext->sHWStateCtl.dwTACtl3DStateChanged |= MBX1_TASTATEPRES_ISPCTL |
MBX1_TASTATEPRES_TSPCTL;
}
/*----------------------------------------------------------------------------
<function>
FUNCTION : ProcessAlphaBlendState
PURPOSE : Setup HW alpha blend state given current D3D state
PARAMETERS : psContext - Current D3D context.
RETURNS : void
</function>
------------------------------------------------------------------------------*/
void ProcessAlphaBlendState(LPD3DM_CONTEXT psContext)
{
DWORD dwNewHWBlendMode;
DWORD dwISPTSPCtl;
/*
Reset HW alpha-blend controls and enable tag-writes (as that is the
most common case)
*/
dwISPTSPCtl = psContext->sHWState.sTACtl3DState.dwISPTSPCtl;
dwISPTSPCtl &= MBX1_ISPTSPCTL_SRCBLENDCLRMASK &
MBX1_ISPTSPCTL_DESTBLENDCLRMASK &
(~MBX1_ISPTSPCTL_TAGWDISABLE);
/*
Examine the new blend-mode to see if we really need to do alpha-blending
*/
dwNewHWBlendMode = psContext->sTState.dwBlendMode;
if (
(psContext->sTState.dwRSFlags & TSTATE_RSFLAGS_ALPHABLEND) &&
(dwNewHWBlendMode ^ (MBX1_ISPTSPCTL_SRCBLENDONE |
MBX1_ISPTSPCTL_DESTBLENDZERO))
)
{
/*
Alpha-blending enabled with a non-opaque blend. Put the new blend
mode into HW TSP/TSP control word
NB: Even if this is a null blend and we disable tag-writes to
increase performance, the required blend mode must be set
in-case we have to enable tag-writes later.
*/
dwISPTSPCtl |= dwNewHWBlendMode;
/*
Is this a null blend?
*/
if (dwNewHWBlendMode ^ (MBX1_ISPTSPCTL_SRCBLENDZERO |
MBX1_ISPTSPCTL_DESTBLENDONE))
{
/*
Non NULL blend, flag that the HW is doing alpha-blending.
*/
psContext->dwFlags |= D3DM_CONTEXT_SWFLAGS_ALPHABLENDENABLED;
}
else
{
/*
NULL blend. Rather than doing an alpha-blend that has no effect,
we simply disable ISP tag-writes (essentially disabling colour-
writes), which is faster.
NB: Tag-writes are required for HW alpha-test to work. This is
handled in SortOutObjectType
*/
dwISPTSPCtl |= MBX1_ISPTSPCTL_TAGWDISABLE;
/*
Flag that the HW is not doing alpha-blending.
*/
psContext->dwFlags &= ~D3DM_CONTEXT_SWFLAGS_ALPHABLENDENABLED;
}
}
else
{
/*
Alpha-blending disabled, or the chosen blend mode is opaque.
Force the HW blend-mode to src-one dest-zero.
*/
dwISPTSPCtl |= MBX1_ISPTSPCTL_SRCBLENDONE | MBX1_ISPTSPCTL_DESTBLENDZERO;
/*
Flag that the HW is not doing alpha-blending.
*/
psContext->dwFlags &= ~D3DM_CONTEXT_SWFLAGS_ALPHABLENDENABLED;
}
/*
Update the required HW-state and flag that the ISP/TSP control word
has been modified
*/
psContext->sHWState.sTACtl3DState.dwISPTSPCtl = dwISPTSPCtl;
psContext->sHWStateCtl.dwTACtl3DStateChanged |= MBX1_TASTATEPRES_ISPCTL;
/*
If doing app-hinted alphablend-only alphatesting disable only opaque
alphatest.
*/
if (psContext->sRegData.dwFlags & D3DMREG_DISABLE_ALTEST_OPAQUE)
{
if (
(psContext->dwFlags & D3DM_CONTEXT_SWFLAGS_ALPHABLENDENABLED) &&
(psContext->sTState.dwRSFlags & TSTATE_RSFLAGS_ALPHATEST) &&
((psContext->sTState.dwAlphaTest & (~MBX1_TSPOBJ_ALPHACMPCLRMASK)) != MBX1_TSPOBJ_ACMPMODEALWAYS)
)
{
psContext->dwFlags |= D3DM_CONTEXT_SWFLAGS_ALPHATESTENABLED;
}
else
{
psContext->dwFlags &= ~D3DM_CONTEXT_SWFLAGS_ALPHATESTENABLED;
}
}
/*
Update the HW object type required
*/
SetupObjectType(psContext);
}
/*----------------------------------------------------------------------------
<function>
FUNCTION : ProcessFogState
PURPOSE : Setup HW fog-state given current D3D state
PARAMETERS : psContext - Current D3D context.
RETURNS : void
</function>
------------------------------------------------------------------------------*/
void ProcessFogState(LPD3DM_CONTEXT psContext)
{
DWORD dwISPTSPCtl;
/*
Update the HW fog state
NB: MBX1 does not support pixel fog, so we either do vertex-fog or
disable it.
*/
dwISPTSPCtl = psContext->sHWState.sTACtl3DState.dwISPTSPCtl;
#ifdef FIX_HW_PRN_145
dwISPTSPCtl &= MBX1_ISPTSPCTL_BLENDOPMODECLRMASK;
#endif
if((psContext->sTState.dwRSFlags & TSTATE_RSFLAGS_FOG) &&
(psContext->sTState.dwD3DTableFogMode == D3DMFOG_NONE))
{
/*
Non-pixel-fog enabled. Turn on HW vertex fog blending, and indicate
that the vertices contain an offset colour
*/
dwISPTSPCtl |= MBX1_ISPTSPCTL_OFFSET |
#ifdef FIX_HW_PRN_145
MBX1_ISPTSPCTL_BLENDOPMODEVERTEXFOG;
#else
MBX1_ISPTSPCTL_FOGENABLE;
#endif
}
else
{
/* Disable vertex fog */
#ifdef FIX_HW_PRN_145
dwISPTSPCtl |= MBX1_ISPTSPCTL_BLENDOPMODEFOGNONE;
#else
dwISPTSPCtl &= ~MBX1_ISPTSPCTL_FOGENABLE;
#endif
/*
If specular-colour add is disabled, then vertices do not need
to have an offset colour component.
NB: MBX1 cannot use the vertex offset colour for texture-blending
*/
if (!(psContext->sTState.dwRSFlags & TSTATE_RSFLAGS_SPECULAR))
{
dwISPTSPCtl &= ~MBX1_ISPTSPCTL_OFFSET;
}
}
psContext->sHWState.sTACtl3DState.dwISPTSPCtl = dwISPTSPCtl;
/*
Indicate that the ISP/TSP control word has been modified
*/
psContext->sHWStateCtl.dwTACtl3DStateChanged |= MBX1_TASTATEPRES_ISPCTL;
}
/*----------------------------------------------------------------------------
<function>
FUNCTION : ProcessDepthState
PURPOSE : Setup HW depth state given current D3D state
PARAMETERS : psContext - Current D3D context.
RETURNS : void
</function>
------------------------------------------------------------------------------*/
void ProcessDepthState(LPD3DM_CONTEXT psContext)
{
DWORD dwISPTSPCtl;
/*
Reset the depth-compare and write-enable HW controls
*/
dwISPTSPCtl = psContext->sHWState.sTACtl3DState.dwISPTSPCtl;
dwISPTSPCtl &= MBX1_ISPTSPCTL_DCMPMODECLRMASK &
(~MBX1_ISPTSPCTL_DWDISABLE);
/*
Setup HW-state based upon the required depth-buffering mode
*/
switch (psContext->sTState.dwRSFlags & (TSTATE_RSFLAGS_WENABLE |
TSTATE_RSFLAGS_ZENABLE))
{
case TSTATE_RSFLAGS_ZENABLE:
{
#if defined (SUPPORT_VGP) || defined (SUPPORT_VGP_LITE)
if(psContext->dwTAPrimCtl & MBX1_TAPRIM_WBUFFERING_ENABLE)
{
/* We need to update position section */
psContext->sTState.sSWTNLState.dwSectionModFlags |= (1 << VGPTNL_SECTIONORD_POSITION);
}
#endif
/*
Disable W-buffering.
*/
psContext->dwTAPrimCtl &= ~MBX1_TAPRIM_WBUFFERING_ENABLE;
/*
Set current depth-compare mode and depth-write enable state
*/
dwISPTSPCtl |= psContext->sTState.dwDepthCtl;
break;
}
case TSTATE_RSFLAGS_WENABLE:
{
#if defined (SUPPORT_VGP) || defined (SUPPORT_VGP_LITE)
if(!(psContext->dwTAPrimCtl & MBX1_TAPRIM_WBUFFERING_ENABLE))
{
/* We need to update position section */
psContext->sTState.sSWTNLState.dwSectionModFlags |= (1 << VGPTNL_SECTIONORD_POSITION);
}
#endif
/*
Enable W-Buffering.
*/
psContext->dwTAPrimCtl |= MBX1_TAPRIM_WBUFFERING_ENABLE;
/*
Set current depth-compare mode and depth-write enable state
*/
dwISPTSPCtl |= psContext->sTState.dwDepthCtl;
/*
For W-buffering, the TA puts RHW into Z. However, the 3D-core ISP
doesn't know anything about this, so to get depth-comparisons to
work correctly, we must flip the 'less-than'/'greater-than' sense
of the compare-mode (if z1 > z2 then 1/z1 < 1/z2)
Fortunately, the HW depth-compare mode is encoded with three bits:
One specifying 'pass on less-than', one 'pass on greater-than',
and the last 'pass on equality'. Using various combinations of
these bits (and hence tests), all possible compare modes are
achieved.
Therefore, for W-buffering, we have to swap the 'less-than' and
'greater-than' bits in the HW depth-compare mode. Easy.
*/
if (
(dwISPTSPCtl & MBX1_ISPTSPCTL_DCMPMODENE) &&
((dwISPTSPCtl & MBX1_ISPTSPCTL_DCMPMODENE) ^ MBX1_ISPTSPCTL_DCMPMODENE)
)
{
dwISPTSPCtl ^= MBX1_ISPTSPCTL_DCMPMODENE;
}
break;
}
default:
{
/*
No Z-Buffer mode. Disable Z writes and set mode to always.
*/
dwISPTSPCtl |= MBX1_ISPTSPCTL_DWDISABLE |
MBX1_ISPTSPCTL_DCMPMODEALWAYS;
break;
}
}
psContext->sHWState.sTACtl3DState.dwISPTSPCtl = dwISPTSPCtl;
/*
Flag that the ISP/TSP control-word has been modified
*/
psContext->sHWStateCtl.dwTACtl3DStateChanged |= MBX1_TASTATEPRES_ISPCTL;
/*
Update the viewport transform
*/
SetupViewportTransform(psContext);
}
/*----------------------------------------------------------------------------
<function>
FUNCTION : ProcessAlphaTestState
PURPOSE : Setup internel alpha test state given current D3D state
PARAMETERS : psContext - Current D3D context.
RETURNS : void
</function>
------------------------------------------------------------------------------*/
void ProcessAlphaTestState(LPD3DM_CONTEXT psContext)
{
/*
Reset the flag indicating alpha-testing is required
*/
psContext->dwFlags &= ~D3DM_CONTEXT_SWFLAGS_ALPHATESTENABLED;
/*
Is Alpha-testing enabled in renderstate?
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -