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
|
//========= Copyright Valve Corporation, All rights reserved. ============//
// TOGL CODE LICENSE
//
// Copyright 2011-2014 Valve Corporation
// All Rights Reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//------------------------------------------------------------------------------
// DX9AsmToGL2.h
//------------------------------------------------------------------------------
#ifndef DX9_ASM_TO_GL_2_H
#define DX9_ASM_TO_GL_2_H
#include "tier1/utlstring.h"
#define DISASM_OK 0
#define DISASM_ERROR 1
#define MAX_SHADER_CONSTANTS 512
#define MAX_DECLARED_OUTPUTS 32
#define MAX_DECLARED_INPUTS 32
#define HEXCODE_HEADER "// Hex: "
// Option bits
#define D3DToGL_OptionUseEnvParams 0x0001
#define D3DToGL_OptionDoFixupZ 0x0002 // Add instructions to put Z in the right interval for GL
#define D3DToGL_OptionDoFixupY 0x0004 // Add instructions to flip the Y over for GL
#define D3DToGL_OptionDoUserClipPlanes 0x0008 // ARB mode: Include OPTION vertex_program_2 and append DP4's to write into oCLP[0] and oCLP[1]
// GLSL mode: generate code to write gl_ClipVertex
#define D3DToGL_AddHexComments 0x0020 // Include hex comments in the code for debugging
#define D3DToGL_PutHexCommentsAfterLines 0x0040 // If D3DToGL_AddHexComments is set, this puts the codes to the right, rather than on separate lines
#define D3DToGL_GeneratingDebugText 0x0080 // This tells it that we're just getting info for debugging so go easy on asserts and errors
#define D3DToGL_OptionSRGBWriteSuffix 0x0400 // Tack sRGB conversion suffix on to pixel shaders
#define D3DToGL_OptionGenerateBoneUniformBuffer 0x0800 // if enabled, the vertex shader "bone" registers (all regs DXABSTRACT_VS_FIRST_BONE_SLOT and higher) will be separated out into another uniform buffer (vcbone)
#define D3DToGL_OptionUseBindlessTexturing 0x1000
#define D3DToGL_OptionSpew 0x80000000
// Code for which component of the "dummy" address register is needed by an instruction
#define ARL_DEST_NONE -1
#define ARL_DEST_X 0
#define ARL_DEST_Y 1
#define ARL_DEST_Z 2
#define ARL_DEST_W 3
class D3DToGL
{
private:
// Pointers for dwToken stream management
uint32* m_pdwBaseToken;
uint32* m_pdwNextToken;
// Vertex shader or pixel shader, and version (necessary because some opcodes alias)
bool m_bVertexShader;
uint32 m_dwMinorVersion;
uint32 m_dwMajorVersion;
// Option flags
bool m_bUseEnvParams; // set D3DToGL_OptionUseEnvParams in 'options' to use
bool m_bDoFixupZ; // set D3DToGL_OptionDoFixupZ
bool m_bDoFixupY; // set D3DToGL_OptionDoFixupZ
bool m_bDoUserClipPlanes; // set D3DToGL_OptionDoUserClipPlanes
bool m_bSpew; // set D3DToGL_OptionSpew
bool m_bGenerateSRGBWriteSuffix; // set D3DToGL_OptionSRGBWriteSuffix
bool m_bGenerateBoneUniformBuffer;
bool m_bUseBindlessTexturing;
// Counter for dealing with nested loops
int m_nLoopDepth;
// Add "// Hex: 0xFFEEF00"-type statements after each instruction is parsed.
bool m_bAddHexCodeComments; // set D3DToGL_AddHexComments
// Only applicable if m_bAddHexCodeComments is true.
// If this is true, then it puts the hex code comments to the right of the instructions in a comment
// rather than preceding the instructions.
// Defaults to FALSE.
bool m_bPutHexCodesAfterLines; // set D3DToGL_PutHexCommentsAtEnd
// This tells it that we're just getting info for debugging so go easy on asserts and errors.
// Defaults to FALSE.
bool m_bGeneratingDebugText;
// Various scratch temps needed to handle mis-matches in instruction sets between D3D and OpenGL
bool m_bNeedsD2AddTemp;
bool m_bNeedsNRMTemp;
bool m_bDeclareAddressReg;
bool m_bNeedsLerpTemp;
bool m_bNeedsSinCosDeclarations;
// Keep track of which vs outputs are used so we can declare them
bool m_bDeclareVSOPos;
bool m_bDeclareVSOFog;
uint32 m_dwTexCoordOutMask;
int32 m_nVSPositionOutput;
// Mask of varyings which need centroid decoration
uint32 m_nCentroidMask;
// Keep track of which temps are used so they can be declared
uint32 m_dwTempUsageMask;
uint32 m_dwTempBoolUsageMask;
bool m_bOutputColorRegister[4];
bool m_bOutputDepthRegister;
// Declaration of integer and bool constants
uint32 m_dwConstIntUsageMask;
uint32 m_dwConstBoolUsageMask;
uint32 m_dwDefConstIntUsageMask;
uint32 m_dwDefConstIntIterCount[32];
// Did we use atomic_temp_var?
bool m_bUsedAtomicTempVar;
// Track constants so we know how to declare them
bool m_bConstantRegisterDefined[MAX_SHADER_CONSTANTS];
// Track sampler types when declared so we can properly decorate TEX instructions
uint32 m_dwSamplerTypes[32];
// Track sampler usage
uint32 m_dwSamplerUsageMask;
// Track shadow sampler usage
int m_nShadowDepthSamplerMask;
bool m_bDeclareShadowOption;
// Track attribute references
// init to 0xFFFFFFFF (unhit)
// index by (dwRegToken & D3DSP_REGNUM_MASK) in VS DCL insns
// fill with (usage<<4) | (usage index).
uint32 m_dwAttribMap[16];
// Register high water mark
uint32 m_nHighestRegister;
int32 m_nHighestBoneRegister;
// GLSL does indentation for readability
int m_NumIndentTabs;
// Output buffers.
CUtlBuffer *m_pBufHeaderCode;
CUtlBuffer *m_pBufAttribCode;
CUtlBuffer *m_pBufParamCode;
CUtlBuffer *m_pBufALUCode;
char *m_pFinalAssignmentsCode;
int m_nFinalAssignmentsBufSize;
// Recorded positions for debugging.
uint32* m_pRecordedInputTokenStart;
int m_nRecordedParamCodeStrlen;
int m_nRecordedALUCodeStrlen;
int m_nRecordedAttribCodeStrlen;
// In GLSL mode, these store the semantic attached to each oN register.
// They are the values that you pass to GetUsageIndexAndString.
uint32 m_DeclaredOutputs[MAX_DECLARED_OUTPUTS];
uint32 m_DeclaredInputs[MAX_DECLARED_INPUTS];
// Have they used the tangent input semantic (i.e. is g_pTangentAttributeName declared)?
bool m_bTangentInputUsed;
bool m_bUsesDSTInstruction;
private:
// Utilities to aid in decoding token stream
uint32 GetNextToken( void );
void SkipTokens( uint32 numToSkip );
uint32 Opcode( uint32 dwToken );
uint32 OpcodeSpecificData( uint32 dwToken );
uint32 TextureType ( uint32 dwToken );
uint32 GetRegType( uint32 dwRegToken );
// Write to the different buffers.
void StrcatToHeaderCode( const char *pBuf );
void StrcatToALUCode( const char *pBuf );
void StrcatToParamCode( const char *pBuf );
void StrcatToAttribCode( const char *pBuf );
void PrintToBufWithIndents( CUtlBuffer &buf, const char *pFormat, ... );
// This helps write the token hex codes into the output stream for debugging.
void AddTokenHexCodeToBuffer( char *pBuffer, int nSize, int nLastStrlen );
void RecordInputAndOutputPositions();
void AddTokenHexCode();
// Utilities for decoding tokens in to strings according to ASM syntax
void PrintOpcode( uint32 inst, char* buff, int nBufLen );
// fSemanticFlags is SEMANTIC_INPUT or SEMANTIC_OUTPUT.
void PrintUsageAndIndexToString( uint32 dwToken, char* strUsageUsageIndexName, int nBufLen, int fSemanticFlags );
CUtlString GetUsageAndIndexString( uint32 dwToken, int fSemanticFlags );
CUtlString GetParameterString( uint32 dwToken, uint32 dwSourceOrDest, bool bForceScalarSource, int *pARLDestReg );
const char* GetGLSLOperatorString( uint32 inst );
void PrintParameterToString ( uint32 dwToken, uint32 dwSourceOrDest, char *pRegisterName, int nBufLen, bool bForceScalarSource, int *pARLDestReg );
void InsertMoveFromAddressRegister( CUtlBuffer *pCode, int nARLComp0, int nARLComp1, int nARLComp2 = ARL_DEST_NONE );
void InsertMoveInstruction( CUtlBuffer *pCode, int nARLComponent );
void FlagIndirectRegister( uint32 dwToken, int *pARLDestReg );
// Utilities for decoding tokens in to strings according to GLSL syntax
bool OpenIntrinsic( uint32 inst, char* buff, int nBufLen, uint32 destDimension, uint32 nArgumentDimension );
void PrintIndentation( char *pBuf, int nBufLen );
uint32 MaintainAttributeMap( uint32 dwToken, uint32 dwRegToken );
CUtlString FixGLSLSwizzle( const char *pDestRegisterName, const char *pSrcRegisterName );
void WriteGLSLCmp( const char *pDestReg, const char *pSrc0Reg, const char *pSrc1Reg, const char *pSrc2Reg );
void WriteGLSLSamplerDefinitions();
void WriteGLSLOutputVariableAssignments();
void WriteGLSLInputVariableAssignments();
void NoteTangentInputUsed();
void Handle_DCL();
void Handle_DEF();
void Handle_DEFIB( uint32 nInstruction );
void Handle_MAD( uint32 nInstruction );
void Handle_DP2ADD();
void Handle_SINCOS();
void Handle_LRP( uint32 nInstruction );
void Handle_TEX( uint32 dwToken, bool bIsTexLDL );
void Handle_TexLDD( uint32 nInstruction );
void Handle_TexCoord();
void Handle_UnaryOp( uint32 nInstruction );
void Handle_BREAKC( uint32 dwToken );
void HandleBinaryOp_GLSL( uint32 nInstruction );
void HandleBinaryOp_ASM( uint32 nInstruction );
void Handle_CMP();
void Handle_NRM();
void Handle_DeclarativeNonDclOp( uint32 nInstruction );
public:
D3DToGL();
int TranslateShader( uint32* code, CUtlBuffer *pBufDisassembledCode, bool *bVertexShader, uint32 options, int32 nShadowDepthSamplerMask, uint32 nCentroidMask, char *debugLabel );
};
#endif // DX9_ASM_TO_GL_2_H
|