1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
|
//========= 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
|