mirror of
https://github.com/nillerusr/source-engine.git
synced 2024-12-22 14:16:50 +00:00
408 lines
12 KiB
C
408 lines
12 KiB
C
|
//========= 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
|