summaryrefslogtreecommitdiff
path: root/materialsystem/shaderapidx9/TransitionTable.h
blob: 730943b392f8efdc47778e6ad0a26ef497a7d6f5 (plain) (blame)
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 &currentState );
	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