You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
407 lines
12 KiB
407 lines
12 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
// $NoKeywords: $ |
|
// |
|
//=============================================================================// |
|
|
|
#ifndef TRANSITION_TABLE_H |
|
#define TRANSITION_TABLE_H |
|
|
|
#ifdef _WIN32 |
|
#pragma once |
|
#endif |
|
|
|
#include "utlvector.h" |
|
#include "shadershadowdx8.h" |
|
#include "UtlSortVector.h" |
|
#include "checksum_crc.h" |
|
#include "shaderapi/ishaderapi.h" |
|
|
|
// Required for DEBUG_BOARD_STATE |
|
#include "shaderapidx8_global.h" |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Forward declarations |
|
//----------------------------------------------------------------------------- |
|
struct IDirect3DStateBlock9; |
|
//----------------------------------------------------------------------------- |
|
// Enumeration for ApplyStateFunc_ts |
|
//----------------------------------------------------------------------------- |
|
// Any function that does not require a texture stage |
|
// NOTE: If you change this, change the function table s_pRenderFunctionTable[] below!! |
|
enum RenderStateFunc_t |
|
{ |
|
RENDER_STATE_DepthTest = 0, |
|
RENDER_STATE_ZWriteEnable, |
|
RENDER_STATE_ColorWriteEnable, |
|
RENDER_STATE_AlphaTest, |
|
RENDER_STATE_FillMode, |
|
RENDER_STATE_Lighting, |
|
RENDER_STATE_SpecularEnable, |
|
RENDER_STATE_SRGBWriteEnable, |
|
RENDER_STATE_AlphaBlend, |
|
RENDER_STATE_SeparateAlphaBlend, |
|
RENDER_STATE_CullEnable, |
|
RENDER_STATE_VertexBlendEnable, |
|
RENDER_STATE_FogMode, |
|
RENDER_STATE_ActivateFixedFunction, |
|
RENDER_STATE_TextureEnable, |
|
RENDER_STATE_DiffuseMaterialSource, |
|
RENDER_STATE_DisableFogGammaCorrection, |
|
RENDER_STATE_EnableAlphaToCoverage, |
|
|
|
RENDER_STATE_COUNT, |
|
}; |
|
|
|
|
|
// Any function that requires a texture stage |
|
// NOTE: If you change this, change the function table s_pTextureFunctionTable[] below!! |
|
enum TextureStateFunc_t |
|
{ |
|
TEXTURE_STATE_TexCoordIndex = 0, |
|
TEXTURE_STATE_SRGBReadEnable, |
|
TEXTURE_STATE_Fetch4Enable, |
|
#ifdef DX_TO_GL_ABSTRACTION |
|
TEXTURE_STATE_ShadowFilterEnable, |
|
#endif |
|
// Fixed function states |
|
TEXTURE_STATE_ColorTextureStage, |
|
TEXTURE_STATE_AlphaTextureStage, |
|
TEXTURE_STATE_COUNT |
|
}; |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Types related to transition table entries |
|
//----------------------------------------------------------------------------- |
|
typedef void (*ApplyStateFunc_t)( const ShadowState_t& shadowState, int arg ); |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// The DX8 implementation of the transition table |
|
//----------------------------------------------------------------------------- |
|
class CTransitionTable |
|
{ |
|
public: |
|
struct CurrentTextureStageState_t |
|
{ |
|
D3DTEXTUREOP m_ColorOp; |
|
int m_ColorArg1; |
|
int m_ColorArg2; |
|
D3DTEXTUREOP m_AlphaOp; |
|
int m_AlphaArg1; |
|
int m_AlphaArg2; |
|
}; |
|
struct CurrentSamplerState_t |
|
{ |
|
bool m_SRGBReadEnable; |
|
bool m_Fetch4Enable; |
|
bool m_ShadowFilterEnable; |
|
}; |
|
struct CurrentState_t |
|
{ |
|
// Everything in this 'CurrentState' structure is a state whose value we don't care about |
|
// under certain circumstances, (which therefore can diverge from the shadow state), |
|
// or states which we override in the dynamic pass. |
|
|
|
// Alpha state |
|
bool m_AlphaBlendEnable; |
|
D3DBLEND m_SrcBlend; |
|
D3DBLEND m_DestBlend; |
|
D3DBLENDOP m_BlendOp; |
|
|
|
// GR - Separate alpha state |
|
bool m_SeparateAlphaBlendEnable; |
|
D3DBLEND m_SrcBlendAlpha; |
|
D3DBLEND m_DestBlendAlpha; |
|
D3DBLENDOP m_BlendOpAlpha; |
|
|
|
// Depth testing states |
|
D3DZBUFFERTYPE m_ZEnable; |
|
D3DCMPFUNC m_ZFunc; |
|
PolygonOffsetMode_t m_ZBias; |
|
|
|
// Alpha testing states |
|
bool m_AlphaTestEnable; |
|
D3DCMPFUNC m_AlphaFunc; |
|
int m_AlphaRef; |
|
|
|
bool m_ForceDepthFuncEquals; |
|
bool m_bOverrideDepthEnable; |
|
D3DZBUFFERTYPE m_OverrideZWriteEnable; |
|
|
|
bool m_bOverrideAlphaWriteEnable; |
|
bool m_bOverriddenAlphaWriteValue; |
|
bool m_bOverrideColorWriteEnable; |
|
bool m_bOverriddenColorWriteValue; |
|
DWORD m_ColorWriteEnable; |
|
|
|
bool m_bLinearColorSpaceFrameBufferEnable; |
|
|
|
bool m_StencilEnable; |
|
D3DCMPFUNC m_StencilFunc; |
|
int m_StencilRef; |
|
int m_StencilMask; |
|
DWORD m_StencilFail; |
|
DWORD m_StencilZFail; |
|
DWORD m_StencilPass; |
|
int m_StencilWriteMask; |
|
|
|
// Texture stage state |
|
CurrentTextureStageState_t m_TextureStage[MAX_TEXTURE_STAGES]; |
|
CurrentSamplerState_t m_SamplerState[MAX_SAMPLERS]; |
|
}; |
|
|
|
public: |
|
// constructor, destructor |
|
CTransitionTable( ); |
|
virtual ~CTransitionTable(); |
|
|
|
// Initialization, shutdown |
|
bool Init( ); |
|
void Shutdown( ); |
|
|
|
// Resets the snapshots... |
|
void Reset(); |
|
|
|
// Takes a snapshot |
|
StateSnapshot_t TakeSnapshot( ); |
|
|
|
// Take startup snapshot |
|
void TakeDefaultStateSnapshot( ); |
|
|
|
// Makes the board state match the snapshot |
|
void UseSnapshot( StateSnapshot_t snapshotId ); |
|
|
|
// Cause the board to match the default state snapshot |
|
void UseDefaultState(); |
|
|
|
// Snapshotted state overrides |
|
void ForceDepthFuncEquals( bool bEnable ); |
|
void OverrideDepthEnable( bool bEnable, bool bDepthEnable ); |
|
void OverrideAlphaWriteEnable( bool bOverrideEnable, bool bAlphaWriteEnable ); |
|
void OverrideColorWriteEnable( bool bOverrideEnable, bool bColorWriteEnable ); |
|
void EnableLinearColorSpaceFrameBuffer( bool bEnable ); |
|
|
|
// Returns a particular snapshot |
|
const ShadowState_t &GetSnapshot( StateSnapshot_t snapshotId ) const; |
|
const ShadowShaderState_t &GetSnapshotShader( StateSnapshot_t snapshotId ) const; |
|
|
|
// Gets the current shadow state |
|
const ShadowState_t *CurrentShadowState() const; |
|
const ShadowShaderState_t *CurrentShadowShaderState() const; |
|
|
|
// Return the current shapshot |
|
int CurrentSnapshot() const { return m_CurrentSnapshotId; } |
|
|
|
CurrentState_t& CurrentState() { return m_CurrentState; } |
|
|
|
#ifdef DEBUG_BOARD_STATE |
|
ShadowState_t& BoardState() { return m_BoardState; } |
|
ShadowShaderState_t& BoardShaderState() { return m_BoardShaderState; } |
|
#endif |
|
|
|
// The following are meant to be used by the transition table only |
|
public: |
|
// Applies alpha blending |
|
void ApplyAlphaBlend( const ShadowState_t& state ); |
|
// GR - separate alpha blend |
|
void ApplySeparateAlphaBlend( const ShadowState_t& state ); |
|
void ApplyAlphaTest( const ShadowState_t& state ); |
|
void ApplyDepthTest( const ShadowState_t& state ); |
|
|
|
// Applies alpha texture op |
|
void ApplyColorTextureStage( const ShadowState_t& state, int stage ); |
|
void ApplyAlphaTextureStage( const ShadowState_t& state, int stage ); |
|
|
|
void ApplySRGBWriteEnable( const ShadowState_t& state ); |
|
private: |
|
enum |
|
{ |
|
INVALID_TRANSITION_OP = 0xFFFFFF |
|
}; |
|
|
|
typedef short ShadowStateId_t; |
|
|
|
// For the transition table |
|
struct TransitionList_t |
|
{ |
|
unsigned int m_FirstOperation : 24; |
|
unsigned int m_NumOperations : 8; |
|
}; |
|
|
|
union TransitionOp_t |
|
{ |
|
unsigned char m_nBits; |
|
struct |
|
{ |
|
unsigned char m_nOpCode : 7; |
|
unsigned char m_bIsTextureCode : 1; |
|
} m_nInfo; |
|
}; |
|
|
|
struct SnapshotShaderState_t |
|
{ |
|
ShadowShaderState_t m_ShaderState; |
|
ShadowStateId_t m_ShadowStateId; |
|
unsigned short m_nReserved; // Pad to 2 ints |
|
unsigned int m_nReserved2; |
|
}; |
|
|
|
struct ShadowStateDictEntry_t |
|
{ |
|
CRC32_t m_nChecksum; |
|
ShadowStateId_t m_nShadowStateId; |
|
}; |
|
|
|
struct SnapshotDictEntry_t |
|
{ |
|
CRC32_t m_nChecksum; |
|
StateSnapshot_t m_nSnapshot; |
|
}; |
|
|
|
class ShadowStateDictLessFunc |
|
{ |
|
public: |
|
bool Less( const ShadowStateDictEntry_t &src1, const ShadowStateDictEntry_t &src2, void *pCtx ); |
|
}; |
|
|
|
class SnapshotDictLessFunc |
|
{ |
|
public: |
|
bool Less( const SnapshotDictEntry_t &src1, const SnapshotDictEntry_t &src2, void *pCtx ); |
|
}; |
|
|
|
class UniqueSnapshotLessFunc |
|
{ |
|
public: |
|
bool Less( const TransitionList_t &src1, const TransitionList_t &src2, void *pCtx ); |
|
}; |
|
|
|
CurrentTextureStageState_t &TextureStage( int stage ) { return m_CurrentState.m_TextureStage[stage]; } |
|
const CurrentTextureStageState_t &TextureStage( int stage ) const { return m_CurrentState.m_TextureStage[stage]; } |
|
|
|
CurrentSamplerState_t &SamplerState( int stage ) { return m_CurrentState.m_SamplerState[stage]; } |
|
const CurrentSamplerState_t &SamplerState( int stage ) const { return m_CurrentState.m_SamplerState[stage]; } |
|
|
|
// creates state snapshots |
|
ShadowStateId_t CreateShadowState( const ShadowState_t ¤tState ); |
|
StateSnapshot_t CreateStateSnapshot( ShadowStateId_t shadowStateId, const ShadowShaderState_t& currentShaderState ); |
|
|
|
// finds state snapshots |
|
ShadowStateId_t FindShadowState( const ShadowState_t& currentState ) const; |
|
StateSnapshot_t FindStateSnapshot( ShadowStateId_t id, const ShadowShaderState_t& currentState ) const; |
|
|
|
// Finds identical transition lists |
|
unsigned int FindIdenticalTransitionList( unsigned int firstElem, |
|
unsigned short numOps, unsigned int nFirstTest ) const; |
|
|
|
// Adds a transition |
|
void AddTransition( RenderStateFunc_t func ); |
|
void AddTextureTransition( TextureStateFunc_t func, int stage ); |
|
|
|
// Apply a transition |
|
void ApplyTransition( TransitionList_t& list, int snapshot ); |
|
|
|
// Creates an entry in the transition table |
|
void CreateTransitionTableEntry( int to, int from ); |
|
|
|
// Checks if a state is valid |
|
bool TestShadowState( const ShadowState_t& state, const ShadowShaderState_t &shaderState ); |
|
|
|
// Perform state block overrides |
|
void PerformShadowStateOverrides( ); |
|
|
|
// Applies the transition list |
|
void ApplyTransitionList( int snapshot, int nFirstOp, int nOpCount ); |
|
|
|
// Apply shader state (stuff that doesn't lie in the transition table) |
|
void ApplyShaderState( const ShadowState_t &shadowState, const ShadowShaderState_t &shaderState ); |
|
|
|
// Wrapper for the non-standard transitions for stateblock + non-stateblock cases |
|
int CreateNormalTransitions( const ShadowState_t& fromState, const ShadowState_t& toState, bool bForce ); |
|
|
|
// State setting methods |
|
void SetZEnable( D3DZBUFFERTYPE nEnable ); |
|
void SetZFunc( D3DCMPFUNC nCmpFunc ); |
|
|
|
private: |
|
// Sets up the default state |
|
StateSnapshot_t m_DefaultStateSnapshot; |
|
TransitionList_t m_DefaultTransition; |
|
ShadowState_t m_DefaultShadowState; |
|
|
|
// The current snapshot id |
|
ShadowStateId_t m_CurrentShadowId; |
|
StateSnapshot_t m_CurrentSnapshotId; |
|
|
|
// Maintains a list of all used snapshot transition states |
|
CUtlVector< ShadowState_t > m_ShadowStateList; |
|
|
|
// Lookup table for fast snapshot finding |
|
CUtlSortVector< ShadowStateDictEntry_t, ShadowStateDictLessFunc > m_ShadowStateDict; |
|
|
|
// The snapshot transition table |
|
CUtlVector< CUtlVector< TransitionList_t > > m_TransitionTable; |
|
|
|
// List of unique transitions |
|
CUtlSortVector< TransitionList_t, UniqueSnapshotLessFunc > m_UniqueTransitions; |
|
|
|
// Stores all state transition operations |
|
CUtlVector< TransitionOp_t > m_TransitionOps; |
|
|
|
// Stores all state for a particular snapshot |
|
CUtlVector< SnapshotShaderState_t > m_SnapshotList; |
|
|
|
// Lookup table for fast snapshot finding |
|
CUtlSortVector< SnapshotDictEntry_t, SnapshotDictLessFunc > m_SnapshotDict; |
|
|
|
// The current board state. |
|
CurrentState_t m_CurrentState; |
|
|
|
#ifdef DEBUG_BOARD_STATE |
|
// Maintains the total shadow state |
|
ShadowState_t m_BoardState; |
|
ShadowShaderState_t m_BoardShaderState; |
|
#endif |
|
}; |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Inline methods |
|
//----------------------------------------------------------------------------- |
|
inline const ShadowState_t &CTransitionTable::GetSnapshot( StateSnapshot_t snapshotId ) const |
|
{ |
|
Assert( (snapshotId >= 0) && (snapshotId < m_SnapshotList.Count()) ); |
|
return m_ShadowStateList[m_SnapshotList[snapshotId].m_ShadowStateId]; |
|
} |
|
|
|
inline const ShadowShaderState_t &CTransitionTable::GetSnapshotShader( StateSnapshot_t snapshotId ) const |
|
{ |
|
Assert( (snapshotId >= 0) && (snapshotId < m_SnapshotList.Count()) ); |
|
return m_SnapshotList[snapshotId].m_ShaderState; |
|
} |
|
|
|
inline const ShadowState_t *CTransitionTable::CurrentShadowState() const |
|
{ |
|
if ( m_CurrentShadowId == -1 ) |
|
return NULL; |
|
|
|
Assert( (m_CurrentShadowId >= 0) && (m_CurrentShadowId < m_ShadowStateList.Count()) ); |
|
return &m_ShadowStateList[m_CurrentShadowId]; |
|
} |
|
|
|
inline const ShadowShaderState_t *CTransitionTable::CurrentShadowShaderState() const |
|
{ |
|
if ( m_CurrentShadowId == -1 ) |
|
return NULL; |
|
|
|
Assert( (m_CurrentShadowId >= 0) && (m_CurrentShadowId < m_ShadowStateList.Count()) ); |
|
return &m_SnapshotList[m_CurrentShadowId].m_ShaderState; |
|
} |
|
|
|
|
|
#endif // TRANSITION_TABLE_H
|
|
|