📄 transitiontable.cpp
字号:
//=========== (C) Copyright 1999 Valve, L.L.C. All rights reserved. ===========
//
// The copyright to the contents herein is the property of Valve, L.L.C.
// The contents may be used and/or copied only with the written permission of
// Valve, L.L.C., or in accordance with the terms and conditions stipulated in
// the agreement/contract under which the contents have been supplied.
//
// $Header: $
// $NoKeywords: $
//
// The dx8 implementation of the transition table
//=============================================================================
#include <windows.h>
#include "transitiontable.h"
#include "recording.h"
#include "shaderapidx8.h"
#include "materialsystem/materialsystem_config.h"
#include "IShaderUtil.h"
#include "CMaterialSystemStats.h"
#include "materialsystem/IMaterialSystemHardwareConfig.h"
#include "vertexshaderdx8.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
//-----------------------------------------------------------------------------
// Singleton
//-----------------------------------------------------------------------------
CTransitionTable *g_pTransitionTable = NULL;
#ifdef DEBUG_BOARD_STATE
inline ShadowState_t& BoardState()
{
return g_pTransitionTable->BoardState();
}
#endif
//-----------------------------------------------------------------------------
// Constructor, destructor
//-----------------------------------------------------------------------------
CTransitionTable::CTransitionTable() : m_DefaultStateSnapshot(-1),
m_CurrentShadowId(-1), m_CurrentSnapshotId(-1), m_TransitionOps( 0, 1024 ), m_ShadowStateList( 0, 32 ),
m_TransitionTable( 0, 32 ), m_SnapshotList( 0, 32 )
{
Assert( !g_pTransitionTable );
g_pTransitionTable = this;
m_bUsingStateBlocks = false;
#ifdef DEBUG_BOARD_STATE
memset( &m_BoardState, 0, sizeof( m_BoardState ) );
memset( &m_BoardShaderState, 0, sizeof( m_BoardShaderState ) );
#endif
}
CTransitionTable::~CTransitionTable()
{
Assert( g_pTransitionTable == this );
g_pTransitionTable = NULL;
}
//-----------------------------------------------------------------------------
// Initialization, shutdown
//-----------------------------------------------------------------------------
bool CTransitionTable::Init( bool bUseStateBlocks )
{
m_bUsingStateBlocks = false; // bUseStateBlocks;
return true;
}
void CTransitionTable::Shutdown( )
{
Reset();
}
//-----------------------------------------------------------------------------
// Creates a shadow, adding an entry into the shadow list and transition table
//-----------------------------------------------------------------------------
StateSnapshot_t CTransitionTable::CreateStateSnapshot( )
{
return m_SnapshotList.AddToTail();
}
//-----------------------------------------------------------------------------
// Creates a shadow, adding an entry into the shadow list and transition table
//-----------------------------------------------------------------------------
CTransitionTable::ShadowStateId_t CTransitionTable::CreateShadowState( )
{
int newShaderState = m_ShadowStateList.AddToTail();
// all existing states must transition to the new state
int i;
for ( i = 0; i < newShaderState; ++i )
{
// Add a new transition to all existing states
int newElem = m_TransitionTable[i].AddToTail();
m_TransitionTable[i][newElem].m_FirstOperation = INVALID_TRANSITION_OP;
m_TransitionTable[i][newElem].m_NumOperations = 0;
m_TransitionTable[i][newElem].m_nOpCountInStateBlock = 0;
m_TransitionTable[i][newElem].m_pStateBlock = NULL;
}
// Add a new vector for this transition
int newTransitionElem = m_TransitionTable.AddToTail();
m_TransitionTable[newTransitionElem].EnsureCapacity( 32 );
Assert( newShaderState == newTransitionElem );
for ( i = 0; i <= newShaderState; ++i )
{
// Add a new transition from all existing states
int newElem = m_TransitionTable[newShaderState].AddToTail();
m_TransitionTable[newShaderState][newElem].m_FirstOperation = INVALID_TRANSITION_OP;
m_TransitionTable[newShaderState][newElem].m_NumOperations = 0;
m_TransitionTable[newShaderState][newElem].m_nOpCountInStateBlock = 0;
m_TransitionTable[newShaderState][newElem].m_pStateBlock = NULL;
}
return newShaderState;
}
//-----------------------------------------------------------------------------
// Finds a snapshot, if it exists. Or creates a new one if it doesn't.
//-----------------------------------------------------------------------------
CTransitionTable::ShadowStateId_t CTransitionTable::FindShadowState( const ShadowState_t& currentState ) const
{
for (int i = m_ShadowStateList.Count(); --i >= 0; )
{
if (!memcmp(&m_ShadowStateList[i], ¤tState, sizeof(ShadowState_t) ))
return i;
}
// Need to create a new one
return (ShadowStateId_t)-1;
}
//-----------------------------------------------------------------------------
// Finds a snapshot, if it exists. Or creates a new one if it doesn't.
//-----------------------------------------------------------------------------
StateSnapshot_t CTransitionTable::FindStateSnapshot( ShadowStateId_t id, const ShadowShaderState_t& currentState ) const
{
for (int i = m_SnapshotList.Count(); --i >= 0; )
{
if ( (id == m_SnapshotList[i].m_ShadowStateId) &&
!memcmp(&m_SnapshotList[i].m_ShaderState, ¤tState, sizeof(ShadowShaderState_t)) )
{
return i;
}
}
// Need to create a new one
return (StateSnapshot_t)-1;
}
//-----------------------------------------------------------------------------
// Used to clear out state blocks from the transition table
//-----------------------------------------------------------------------------
void CTransitionTable::ClearStateBlocks()
{
// Release state blocks
for ( int i = m_TransitionTable.Count(); --i >= 0; )
{
for ( int j = m_TransitionTable[i].Count(); --j >= 0; )
{
if ( m_TransitionTable[i][j].m_pStateBlock )
{
m_TransitionTable[i][j].m_pStateBlock->Release();
m_TransitionTable[i][j].m_pStateBlock = NULL;
}
}
}
}
//-----------------------------------------------------------------------------
// Used to clear the transition table when we know it's become invalid.
//-----------------------------------------------------------------------------
void CTransitionTable::Reset()
{
ClearStateBlocks();
m_ShadowStateList.RemoveAll();
m_SnapshotList.RemoveAll();
m_TransitionTable.RemoveAll();
m_TransitionOps.RemoveAll();
m_CurrentShadowId = -1;
m_CurrentSnapshotId = -1;
m_DefaultStateSnapshot = -1;
}
//-----------------------------------------------------------------------------
// Sets the texture stage state
//-----------------------------------------------------------------------------
#pragma warning( disable : 4189 )
static inline void SetTextureStageState( int stage, D3DTEXTURESTAGESTATETYPE state, DWORD val )
{
Assert( !ShaderAPI()->IsDeactivated() );
RECORD_TEXTURE_STAGE_STATE( stage, state, val );
HRESULT hr = D3DDevice()->SetTextureStageState( stage, state, val );
Assert( !FAILED(hr) );
}
static inline void SetRenderState( D3DRENDERSTATETYPE state, DWORD val )
{
Assert( !ShaderAPI()->IsDeactivated() );
RECORD_RENDER_STATE( state, val );
HRESULT hr = D3DDevice()->SetRenderState( state, val );
Assert( !FAILED(hr) );
}
#pragma warning( default : 4189 )
//-----------------------------------------------------------------------------
// Methods that actually apply the state
//-----------------------------------------------------------------------------
#ifdef DEBUG_BOARD_STATE
static bool g_SpewTransitions = false;
#define APPLY_RENDER_STATE_FUNC( _d3dState, _state ) \
void Apply ## _state( const ShadowState_t& shaderState, int arg ) \
{ \
SetRenderState( _d3dState, shaderState.m_ ## _state ); \
BoardState().m_ ## _state = shaderState.m_ ## _state; \
if (g_SpewTransitions) \
{ \
char buf[128]; \
sprintf( buf, "Apply %s : %d\n", #_d3dState, shaderState.m_ ## _state ); \
OutputDebugString(buf); \
} \
}
#define APPLY_TEXTURE_STAGE_STATE_FUNC( _d3dState, _state ) \
void Apply ## _state( const ShadowState_t& shaderState, int stage ) \
{ \
SetTextureStageState( stage, _d3dState, shaderState.m_TextureStage[stage].m_ ## _state ); \
BoardState().m_TextureStage[stage].m_ ## _state = shaderState.m_TextureStage[stage].m_ ## _state; \
if (g_SpewTransitions) \
{ \
char buf[128]; \
sprintf( buf, "Apply Tex %s (%d): %d\n", #_d3dState, stage, shaderState.m_TextureStage[stage].m_ ## _state ); \
OutputDebugString(buf); \
} \
} \
#else
#define APPLY_RENDER_STATE_FUNC( _d3dState, _state ) \
void Apply ## _state( const ShadowState_t& shaderState, int arg ) \
{ \
SetRenderState( _d3dState, shaderState.m_ ## _state ); \
}
#define APPLY_TEXTURE_STAGE_STATE_FUNC( _d3dState, _state ) \
void Apply ## _state( const ShadowState_t& shaderState, int stage ) \
{ \
SetTextureStageState( stage, _d3dState, shaderState.m_TextureStage[stage].m_ ## _state ); \
}
#endif
APPLY_RENDER_STATE_FUNC( D3DRS_ZFUNC, ZFunc )
APPLY_RENDER_STATE_FUNC( D3DRS_ZENABLE, ZEnable )
APPLY_RENDER_STATE_FUNC( D3DRS_ZWRITEENABLE, ZWriteEnable )
APPLY_RENDER_STATE_FUNC( D3DRS_COLORWRITEENABLE, ColorWriteEnable )
APPLY_RENDER_STATE_FUNC( D3DRS_ALPHATESTENABLE, AlphaTestEnable )
APPLY_RENDER_STATE_FUNC( D3DRS_ALPHAFUNC, AlphaFunc )
APPLY_RENDER_STATE_FUNC( D3DRS_ALPHAREF, AlphaRef )
APPLY_RENDER_STATE_FUNC( D3DRS_FILLMODE, FillMode )
APPLY_RENDER_STATE_FUNC( D3DRS_LIGHTING, Lighting )
APPLY_RENDER_STATE_FUNC( D3DRS_SPECULARENABLE, SpecularEnable )
APPLY_RENDER_STATE_FUNC( D3DRS_SRGBWRITEENABLE, SRGBWriteEnable )
APPLY_TEXTURE_STAGE_STATE_FUNC( D3DTSS_TEXCOORDINDEX, TexCoordIndex )
void ApplyAlphaBlend( const ShadowState_t& state, int stage )
{
g_pTransitionTable->ApplyAlphaBlend( state.m_AlphaBlendEnable, state.m_SrcBlend, state.m_DestBlend );
}
void CTransitionTable::ApplyAlphaBlend( bool bEnable, D3DBLEND srcBlend, D3DBLEND destBlend )
{
if (!bEnable)
{
if (m_CurrentState.m_AlphaBlendEnable)
{
SetRenderState( D3DRS_ALPHABLENDENABLE, bEnable );
m_CurrentState.m_AlphaBlendEnable = bEnable;
}
}
else
{
if (!m_CurrentState.m_AlphaBlendEnable)
{
SetRenderState( D3DRS_ALPHABLENDENABLE, bEnable );
m_CurrentState.m_AlphaBlendEnable = bEnable;
}
// Set the blend state here...
if (m_CurrentState.m_SrcBlend != srcBlend)
{
SetRenderState( D3DRS_SRCBLEND, srcBlend );
m_CurrentState.m_SrcBlend = srcBlend;
}
if (m_CurrentState.m_DestBlend != destBlend)
{
SetRenderState( D3DRS_DESTBLEND, destBlend );
m_CurrentState.m_DestBlend = destBlend;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -