DragonNest/Common/EternityEngine/D3DDevice9/EtStateManager.cpp
Cussrro 47f7895977 Revert "修复编码问题"
This reverts commit 9e69c01767.
2024-12-21 10:04:04 +08:00

456 lines
14 KiB
C++

#include "StdAfx.h"
#include "EtDevice.h"
#include "EtStateManager.h"
#ifdef _DEBUG
#define new new(_NORMAL_BLOCK,__FILE__,__LINE__)
#endif
CEtStateBlockManager::CEtStateBlockManager() : m_pD3DDevice( NULL )
{
m_bEnable = true;
Reset();
}
CEtStateBlockManager::~CEtStateBlockManager()
{
}
void CEtStateBlockManager::Initialize( CEtDevice *pDevice )
{
m_pD3DDevice = (IDirect3DDevice9*)pDevice->GetDevicePtr();
}
int CEtStateBlockManager::CreateStateBlock( SStateBlock *StateBlock )
{
int i, nSize;
nSize = (int)m_stateBlocks.size();
for( i = 0; i < nSize; i++) {
if( m_stateBlocks[ i ] == *StateBlock ) {
return i;
}
}
m_stateBlocks.push_back( *StateBlock );
return (int)m_stateBlocks.size()-1;
}
//#define _DEBUG_VALID_STATE
void CEtStateBlockManager::SetDefaultState()
{
#if defined( _DEBUG_VALID_STATE )
DWORD dwVal;
for( int i = 1; i < RS_MAX; i++) {
if( i <= 6 ) continue;
if( i >= 10 && i <= 13 ) continue;
if( i == 17 || i == 18 || i == 21 || i == 30 || i == 31 || i == 32 || i == 33 || ( i >= 39 && i <= 47) || (i>=49&&i<=51) || ( i >= 61 && i <= 127) ) continue;
if( i == 138 || i == 149 || i == 150 || i == 153 || i == 164 || i == 169 || i == 177 || i == 197 || i == 198 ) continue;
m_pD3DDevice->GetRenderState( (D3DRENDERSTATETYPE)i, &dwVal);
SetRenderStateDefered( (D3DRENDERSTATETYPE)i, dwVal);
}
for( int j = 1; j < STAGE_MAX; j++) {
for( int i = 0; i < SS_MAX; i++) {
m_pD3DDevice->GetSamplerState( j, (D3DSAMPLERSTATETYPE)i, &dwVal);
SetSamplerStateDefered( j, (D3DSAMPLERSTATETYPE)i, dwVal);
}
for( int i = 1; i < TS_MAX; i++) {
if( (i >= 12 && i <= 21) || i == 25 || i == 29 || i == 30 || i == 31 ) continue;
m_pD3DDevice->GetTextureStageState( j, (D3DTEXTURESTAGESTATETYPE)i, &dwVal);
SetTextureStageStateDefered( j, (D3DTEXTURESTAGESTATETYPE)i, dwVal);
}
}
#endif
SetRenderStateDefered( D3DRS_ZENABLE, D3DZB_TRUE );
SetRenderStateDefered( D3DRS_ZWRITEENABLE, TRUE );
SetRenderStateDefered( D3DRS_CULLMODE, D3DCULL_CCW );
SetRenderStateDefered( D3DRS_ALPHABLENDENABLE, FALSE );
SetRenderStateDefered( D3DRS_ALPHAREF, ALPHA_TEST_VALUE );
SetRenderStateDefered( D3DRS_ALPHATESTENABLE, TRUE );
SetRenderStateDefered( D3DRS_SCISSORTESTENABLE, FALSE);
SetRenderStateDefered( D3DRS_LIGHTING, FALSE );
SetRenderStateDefered( D3DRS_COLORWRITEENABLE, 0xf );
SetRenderStateDefered( D3DRS_ZFUNC, D3DCMP_LESSEQUAL );
SetRenderStateDefered( D3DRS_DEPTHBIAS, 0 );
SetRenderStateDefered( D3DRS_ALPHAFUNC, D3DCMP_GREATER );
SetRenderStateDefered( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
SetRenderStateDefered( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
SetRenderStateDefered( D3DRS_BLENDOP, D3DBLENDOP_ADD );
// State For Sprite
GetEtDevice()->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
GetEtDevice()->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
GetEtDevice()->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
GetEtDevice()->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
GetEtDevice()->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
GetEtDevice()->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE );
GetEtDevice()->SetSamplerState( 0, D3DSAMP_MAXANISOTROPY, 1 );
for( int i = 0; i < STAGE_MAX; i++) {
SetSamplerStateDefered( i, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
SetSamplerStateDefered( i, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
SetSamplerStateDefered( i, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR );
SetSamplerStateDefered( i, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP );
SetSamplerStateDefered( i, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP );
}
}
void CEtStateBlockManager::Reset()
{
for( int i = 0; i < RS_MAX; i++) {
m_RenderState[ 0 ][ i ] = RESET_MAGIC_NUMBER;
m_RenderState[ 1 ][ i ] = RESET_MAGIC_NUMBER;
m_RenderState[ 2 ][ i ] = RESET_MAGIC_NUMBER;
m_RenderState[ 3 ][ i ] = RESET_MAGIC_NUMBER;
}
for( int j = 0; j < STAGE_MAX; j++)
{
for( int i = 0; i < SS_MAX; i++) {
m_SamplerState[ 0 ][ j ][ i ] = RESET_MAGIC_NUMBER;
m_SamplerState[ 1 ][ j ][ i ] = RESET_MAGIC_NUMBER;
m_SamplerState[ 2 ][ j ][ i ] = RESET_MAGIC_NUMBER;
m_SamplerState[ 3 ][ j ][ i ] = RESET_MAGIC_NUMBER;
}
for( int i = 0; i < TS_MAX; i++) {
m_TextureStageState[ 0 ][ j ][ i ] = RESET_MAGIC_NUMBER;
m_TextureStageState[ 1 ][ j ][ i ] = RESET_MAGIC_NUMBER;
m_TextureStageState[ 2 ][ j ][ i ] = RESET_MAGIC_NUMBER;
m_TextureStageState[ 3 ][ j ][ i ] = RESET_MAGIC_NUMBER;
}
}
for( int i = 0; i < RS_MAX; i++) {
m_DirtyRenderFlag[ i ] = false;
}
for( int j = 0; j < STAGE_MAX; j++) {
for( int i = 0; i < SS_MAX; i++) {
m_DirtySamplerFlag[ j ][ i ] = false;
}
for( int i = 0; i < TS_MAX; i++) {
m_DirtyTextureStageFlag[ j ][ i ] = false;
}
}
m_nDirtyRenderCount = 0;
for( int i = 0; i < STAGE_MAX; i++) {
m_DirtySamplerCount[ i ] = 0;
m_DirtyTextureStageCount[ i ] = 0;
m_currTexture[ i ] = NULL;
}
m_currPixelShader = NULL;
m_currVertexShader = NULL;
#if defined( _CHECK_STATE_PERFORMANCE )
m_nStateSkip = 0;
m_nStateTotal = 0;
m_nShaderSkip = 0;
m_nShaderTotal = 0;
m_nTextureSkip = 0;
m_nTextureTotal = 0;
#endif
}
void CEtStateBlockManager::GetRenderStateDefered( D3DRENDERSTATETYPE State, DWORD *pdwValue )
{
if( m_bEnable ) {
ASSERT( m_RenderState[ 0 ][ State ] != RESET_MAGIC_NUMBER );
*pdwValue = m_RenderState[ 0 ][ State ];
}
else {
m_pD3DDevice->GetRenderState( State, pdwValue );
}
}
void CEtStateBlockManager::SetRenderStateDefered( D3DRENDERSTATETYPE State, DWORD dwValue )
{
if( m_bEnable ) {
ASSERT( m_nDirtyRenderCount < DIRTY_MAX );
if( m_nDirtyRenderCount >= DIRTY_MAX ) {
return;
}
if( m_DirtyRenderFlag[ State ] == false ) {
m_DirtyRenderFlag[ State ] = true;
m_DirtyRenderState[ m_nDirtyRenderCount++ ] = State;
}
m_RenderState[ 0 ][ State ] = dwValue;
}
else {
m_pD3DDevice->SetRenderState( State, dwValue );
}
}
void CEtStateBlockManager::GetSamplerStateDefered( DWORD Sampler, D3DSAMPLERSTATETYPE State, DWORD *pdwValue )
{
if( m_bEnable ) {
//ASSERT( Sampler <= 5 );
//ASSERT( m_SamplerState[ 0 ][ Sampler ][ State ] != RESET_MAGIC_NUMBER );
*pdwValue = m_SamplerState[ 0 ][ Sampler ][ State ];
}
else {
m_pD3DDevice->GetSamplerState( Sampler, State, pdwValue );
}
}
void CEtStateBlockManager::SetSamplerStateDefered( DWORD Sampler, D3DSAMPLERSTATETYPE State, DWORD Value )
{
if( m_bEnable )
{
if( Sampler >= STAGE_MAX || m_DirtySamplerCount[ Sampler ] >= DIRTY_MAX )
{
ASSERT( Sampler < STAGE_MAX );
ASSERT( m_DirtySamplerCount[ Sampler ] < DIRTY_MAX );
return;
}
if( m_DirtySamplerFlag[ Sampler ][ State ] == false ) {
m_DirtySamplerFlag[ Sampler ][ State ] = true;
m_DirtySamplerState[ Sampler ][ m_DirtySamplerCount[ Sampler ]++ ] = State;
}
m_SamplerState[ 0 ][ Sampler ][ State ] = Value;
}
else {
m_pD3DDevice->SetSamplerState( Sampler, State, Value );
}
}
void CEtStateBlockManager::GetTextureStageStateDefered( DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD *pdwValue)
{
if( m_bEnable ) {
//ASSERT( Stage < STAGE_MAX );
//ASSERT( m_TextureStageState[ 0 ][ Stage ][ Type ] != RESET_MAGIC_NUMBER );
*pdwValue = m_TextureStageState[ 0 ][ Stage ][ Type ];
}
else {
m_pD3DDevice->GetTextureStageState( Stage, Type, pdwValue );
}
}
void CEtStateBlockManager::SetTextureStageStateDefered( DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value)
{
if( m_bEnable )
{
if( Stage >= STAGE_MAX || m_DirtyTextureStageCount[ Stage ] >= DIRTY_MAX )
{
ASSERT( Stage < STAGE_MAX );
ASSERT( m_DirtyTextureStageCount[ Stage ] < DIRTY_MAX );
return;
}
if( m_DirtyTextureStageFlag[ Stage ][ Type ] == false ) {
m_DirtyTextureStageFlag[ Stage ][ Type ] = true;
m_DirtyTextureStageState[ Stage ][ m_DirtyTextureStageCount[ Stage ]++ ] = Type;
}
m_TextureStageState[ 0 ][ Stage ][ Type ] = Value;
}
else {
m_pD3DDevice->SetTextureStageState( Stage, Type, Value );
}
}
void CEtStateBlockManager::FlushDeferedStates()
{
#if defined( _CHECK_STATE_PERFORMANCE )
static bool bPressPrev = false;
bool bPress = GetAsyncKeyState(VK_HOME)<0;
if( !bPressPrev && bPress ) {
SetEnable( !IsEnable() );
OutputDebug("RenderState Optimize %s\n", IsEnable() ? "Enable" : "Disable");
}
bPressPrev = bPress;
#endif
if( !m_bEnable ) {
return;
}
#if defined( _DEBUG_VALID_STATE )
for( int i = 1; i < RS_MAX; i++) {
if( m_RenderState[ 1 ][ i ] != RESET_MAGIC_NUMBER )
{
DWORD dwVal=0;
m_pD3DDevice->GetRenderState( (D3DRENDERSTATETYPE)i, &dwVal);
ASSERT( m_RenderState[ 1 ][ i ] == dwVal );
}
}
for( int j = 0; j < STAGE_MAX; j++) {
for( int i = 1; i < SS_MAX; i++) {
if( RESET_MAGIC_NUMBER != m_SamplerState[ 1 ][ j ][ i ] ) {
DWORD dwVal=0;
m_pD3DDevice->GetSamplerState( j, (D3DSAMPLERSTATETYPE)i, &dwVal);
ASSERT( m_SamplerState[ 1 ][ j ][ i ] == dwVal );
}
}
for( int i = 1; i < TS_MAX; i++) {
if( m_TextureStageState[ 1 ][ j ][ i ] != RESET_MAGIC_NUMBER ) {
DWORD dwVal=0;
m_pD3DDevice->GetTextureStageState( j, (D3DTEXTURESTAGESTATETYPE)i, &dwVal);
ASSERT( m_TextureStageState[ 1 ][ j ][ i ] == dwVal );
}
}
}
#endif
#if defined( _CHECK_STATE_PERFORMANCE )
m_nStateTotal += m_nDirtyRenderCount;
#endif
for( int i = 0; i < m_nDirtyRenderCount; i++) {
D3DRENDERSTATETYPE State = (D3DRENDERSTATETYPE)m_DirtyRenderState[ i ];
m_DirtyRenderFlag[ State ] = false;
if( m_RenderState[ 0 ][ State ] != m_RenderState[ 1 ][ State ] ) {
m_pD3DDevice->SetRenderState( State, m_RenderState[ 0 ][ State ] );
m_RenderState[ 1 ][ State ] = m_RenderState[ 0 ][ State ];
}
#if defined( _CHECK_STATE_PERFORMANCE )
else {
m_nStateSkip++;
}
#endif
}
m_nDirtyRenderCount = 0;
for( int j = 0; j < STAGE_MAX; j++) {
#if defined( _CHECK_STATE_PERFORMANCE )
m_nStateTotal += m_DirtySamplerCount[ j ];
m_nStateTotal += m_DirtyTextureStageCount[ j ];
#endif
for( int i = 0; i < m_DirtySamplerCount[ j ]; i++) {
D3DSAMPLERSTATETYPE State = (D3DSAMPLERSTATETYPE)m_DirtySamplerState[ j ][ i ];
m_DirtySamplerFlag[ j ][ State ] = false;
if( m_SamplerState[ 0 ][ j ][ State ] != m_SamplerState[ 1 ][ j ][ State ] ) {
m_pD3DDevice->SetSamplerState( j, State, m_SamplerState[ 0 ][ j ][ State ] );
m_SamplerState[ 1 ][ j ][ State ] = m_SamplerState[ 0 ][ j ][ State ];
}
#if defined( _CHECK_STATE_PERFORMANCE )
else {
m_nStateSkip++;
}
#endif
}
m_DirtySamplerCount[ j ] = 0;
for( int i = 0; i < m_DirtyTextureStageCount[ j ]; i++) {
D3DTEXTURESTAGESTATETYPE State = (D3DTEXTURESTAGESTATETYPE)m_DirtyTextureStageState[ j ][ i ];
m_DirtyTextureStageFlag[ j ][ State ] = false;
if( m_TextureStageState[ 0 ][ j ][ State ] != m_TextureStageState[ 1 ][ j ][ State ] ) {
m_pD3DDevice->SetTextureStageState( j, State, m_TextureStageState[ 0 ][ j ][ State ] );
m_TextureStageState[ 1 ][ j ][ State ] = m_TextureStageState[ 0 ][ j ][ State ];
}
#if defined( _CHECK_STATE_PERFORMANCE )
else {
m_nStateSkip++;
}
#endif
}
m_DirtyTextureStageCount[ j ] = 0;
}
}
void CEtStateBlockManager::Capture()
{
for( int i = 0; i < RS_MAX; i++) {
m_RenderState[ 2 ][ i ] = m_RenderState[ 0 ][ i ];
}
for( int j = 0; j < STAGE_MAX; j++) {
for( int i = 0; i < SS_MAX; i++) {
m_SamplerState[ 2 ][ j ][ i ] = m_SamplerState[ 0 ][ j ][ i ];
}
for( int i = 0; i < TS_MAX; i++) {
m_TextureStageState[ 2 ][ j ][ i ] = m_TextureStageState[ 0 ][ j ][ i ];
}
}
}
void CEtStateBlockManager::Diff()
{
for( int i = 0; i < RS_MAX; i++) {
if( m_RenderState[ 3 ][ i ] != RESET_MAGIC_NUMBER && m_RenderState[ 3 ][ i ] != m_RenderState[ 0 ][ i ] )
{
int df = 3;
}
m_RenderState[ 3 ][ i ] = m_RenderState[ 0 ][ i ];
}
for( int j = 0; j < STAGE_MAX; j++) {
for( int i = 0; i < SS_MAX; i++) {
if( m_SamplerState[ 3 ][ j ][ i ] != RESET_MAGIC_NUMBER && m_SamplerState[ 3 ][ j ][ i ] != m_SamplerState[ 0 ][ j ][ i ] )
{
int df = 3;
}
m_SamplerState[ 3 ][ j ][ i ] = m_SamplerState[ 0 ][ j ][ i ];
}
for( int i = 0; i < TS_MAX; i++) {
if( m_TextureStageState[ 3 ][ j ][ i ] != RESET_MAGIC_NUMBER && m_TextureStageState[ 3 ][ j ][ i ] != m_TextureStageState[ 0 ][ j ][ i ] )
{
int df = 3;
}
m_TextureStageState[ 3 ][ j ][ i ] = m_TextureStageState[ 0 ][ j ][ i ];
}
}
}
void CEtStateBlockManager::Restore()
{
for( int i = 0; i < RS_MAX; i++) {
if( m_RenderState[ 2 ][ i ] != m_RenderState[ 0 ][ i ] ) {
ASSERT( m_RenderState[ 2 ][ i ] != RESET_MAGIC_NUMBER );
SetRenderStateDefered( (D3DRENDERSTATETYPE) i, m_RenderState[ 2 ][ i ]);
}
}
for( int j = 0; j < STAGE_MAX; j++) {
for( int i = 0; i < SS_MAX; i++) {
if( m_SamplerState[ 2 ][ j ][ i ] != m_SamplerState[ 0 ][ j ][ i ] ) {
ASSERT( m_SamplerState[ 2 ][ j ][ i ] != RESET_MAGIC_NUMBER );
SetSamplerStateDefered( j, (D3DSAMPLERSTATETYPE)i, m_SamplerState[ 2 ][ j ][ i ]);
}
}
for( int i = 0; i < TS_MAX; i++) {
if( m_TextureStageState[ 2 ][ j ][ i ] != m_TextureStageState[ 0 ][ j ][ i ] ) {
ASSERT( m_TextureStageState[ 2 ][ j ][ i ] != RESET_MAGIC_NUMBER );
SetTextureStageStateDefered( j, (D3DTEXTURESTAGESTATETYPE)i, m_TextureStageState[ 2 ][ j ][ i ]);
}
}
}
}
void CEtStateBlockManager::DebugDumpState()
{
#if defined(_DEBUG) || defined(_RDEBUG)
FILE *fp = fopen( "d:\\RenderState.txt", "wt");
for( int i = 0; i < RS_MAX; i++) {
fprintf(fp, "RS %d = %d\n", i, m_RenderState[ 0 ][ i ] );
}
for( int j = 0; j < STAGE_MAX; j++) {
for( int i = 0; i < SS_MAX; i++) {
fprintf(fp, "SS %d:%d = %d\n", j, i, m_SamplerState[ 0 ][ j ][ i ] );
}
for( int i = 0; i < TS_MAX; i++) {
fprintf(fp, "TS %d:%d = %d\n", j, i, m_TextureStageState[ 0 ][ j ][ i ] );
}
}
fclose(fp);
#endif
}
static CEtStateBlockManager s_EtStateManager;
CEtStateBlockManager* GetEtStateManager()
{
return &s_EtStateManager;
}