Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

261 lines
10 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. // TOGL CODE LICENSE
  3. //
  4. // Copyright 2011-2014 Valve Corporation
  5. // All Rights Reserved.
  6. //
  7. // Permission is hereby granted, free of charge, to any person obtaining a copy
  8. // of this software and associated documentation files (the "Software"), to deal
  9. // in the Software without restriction, including without limitation the rights
  10. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11. // copies of the Software, and to permit persons to whom the Software is
  12. // furnished to do so, subject to the following conditions:
  13. //
  14. // The above copyright notice and this permission notice shall be included in
  15. // all copies or substantial portions of the Software.
  16. //
  17. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  20. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  23. // THE SOFTWARE.
  24. //------------------------------------------------------------------------------
  25. // DX9AsmToGL2.h
  26. //------------------------------------------------------------------------------
  27. #ifndef DX9_ASM_TO_GL_2_H
  28. #define DX9_ASM_TO_GL_2_H
  29. #include "tier1/utlstring.h"
  30. #define DISASM_OK 0
  31. #define DISASM_ERROR 1
  32. #define MAX_SHADER_CONSTANTS 512
  33. #define MAX_DECLARED_OUTPUTS 32
  34. #define MAX_DECLARED_INPUTS 32
  35. #define HEXCODE_HEADER "// Hex: "
  36. // Option bits
  37. #define D3DToGL_OptionUseEnvParams 0x0001
  38. #define D3DToGL_OptionDoFixupZ 0x0002 // Add instructions to put Z in the right interval for GL
  39. #define D3DToGL_OptionDoFixupY 0x0004 // Add instructions to flip the Y over for GL
  40. #define D3DToGL_OptionDoUserClipPlanes 0x0008 // ARB mode: Include OPTION vertex_program_2 and append DP4's to write into oCLP[0] and oCLP[1]
  41. // GLSL mode: generate code to write gl_ClipVertex
  42. #define D3DToGL_AddHexComments 0x0020 // Include hex comments in the code for debugging
  43. #define D3DToGL_PutHexCommentsAfterLines 0x0040 // If D3DToGL_AddHexComments is set, this puts the codes to the right, rather than on separate lines
  44. #define D3DToGL_GeneratingDebugText 0x0080 // This tells it that we're just getting info for debugging so go easy on asserts and errors
  45. #define D3DToGL_OptionSRGBWriteSuffix 0x0400 // Tack sRGB conversion suffix on to pixel shaders
  46. #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)
  47. #define D3DToGL_OptionUseBindlessTexturing 0x1000
  48. #define D3DToGL_OptionSpew 0x80000000
  49. // Code for which component of the "dummy" address register is needed by an instruction
  50. #define ARL_DEST_NONE -1
  51. #define ARL_DEST_X 0
  52. #define ARL_DEST_Y 1
  53. #define ARL_DEST_Z 2
  54. #define ARL_DEST_W 3
  55. class D3DToGL
  56. {
  57. private:
  58. // Pointers for dwToken stream management
  59. uint32* m_pdwBaseToken;
  60. uint32* m_pdwNextToken;
  61. // Vertex shader or pixel shader, and version (necessary because some opcodes alias)
  62. bool m_bVertexShader;
  63. uint32 m_dwMinorVersion;
  64. uint32 m_dwMajorVersion;
  65. // Option flags
  66. bool m_bUseEnvParams; // set D3DToGL_OptionUseEnvParams in 'options' to use
  67. bool m_bDoFixupZ; // set D3DToGL_OptionDoFixupZ
  68. bool m_bDoFixupY; // set D3DToGL_OptionDoFixupZ
  69. bool m_bDoUserClipPlanes; // set D3DToGL_OptionDoUserClipPlanes
  70. bool m_bSpew; // set D3DToGL_OptionSpew
  71. bool m_bGenerateSRGBWriteSuffix; // set D3DToGL_OptionSRGBWriteSuffix
  72. bool m_bGenerateBoneUniformBuffer;
  73. bool m_bUseBindlessTexturing;
  74. // Counter for dealing with nested loops
  75. int m_nLoopDepth;
  76. // Add "// Hex: 0xFFEEF00"-type statements after each instruction is parsed.
  77. bool m_bAddHexCodeComments; // set D3DToGL_AddHexComments
  78. // Only applicable if m_bAddHexCodeComments is true.
  79. // If this is true, then it puts the hex code comments to the right of the instructions in a comment
  80. // rather than preceding the instructions.
  81. // Defaults to FALSE.
  82. bool m_bPutHexCodesAfterLines; // set D3DToGL_PutHexCommentsAtEnd
  83. // This tells it that we're just getting info for debugging so go easy on asserts and errors.
  84. // Defaults to FALSE.
  85. bool m_bGeneratingDebugText;
  86. // Various scratch temps needed to handle mis-matches in instruction sets between D3D and OpenGL
  87. bool m_bNeedsD2AddTemp;
  88. bool m_bNeedsNRMTemp;
  89. bool m_bDeclareAddressReg;
  90. bool m_bNeedsLerpTemp;
  91. bool m_bNeedsSinCosDeclarations;
  92. // Keep track of which vs outputs are used so we can declare them
  93. bool m_bDeclareVSOPos;
  94. bool m_bDeclareVSOFog;
  95. uint32 m_dwTexCoordOutMask;
  96. int32 m_nVSPositionOutput;
  97. // Mask of varyings which need centroid decoration
  98. uint32 m_nCentroidMask;
  99. // Keep track of which temps are used so they can be declared
  100. uint32 m_dwTempUsageMask;
  101. uint32 m_dwTempBoolUsageMask;
  102. bool m_bOutputColorRegister[4];
  103. bool m_bOutputDepthRegister;
  104. // Declaration of integer and bool constants
  105. uint32 m_dwConstIntUsageMask;
  106. uint32 m_dwConstBoolUsageMask;
  107. uint32 m_dwDefConstIntUsageMask;
  108. uint32 m_dwDefConstIntIterCount[32];
  109. // Did we use atomic_temp_var?
  110. bool m_bUsedAtomicTempVar;
  111. // Track constants so we know how to declare them
  112. bool m_bConstantRegisterDefined[MAX_SHADER_CONSTANTS];
  113. // Track sampler types when declared so we can properly decorate TEX instructions
  114. uint32 m_dwSamplerTypes[32];
  115. // Track sampler usage
  116. uint32 m_dwSamplerUsageMask;
  117. // Track shadow sampler usage
  118. int m_nShadowDepthSamplerMask;
  119. bool m_bDeclareShadowOption;
  120. // Track attribute references
  121. // init to 0xFFFFFFFF (unhit)
  122. // index by (dwRegToken & D3DSP_REGNUM_MASK) in VS DCL insns
  123. // fill with (usage<<4) | (usage index).
  124. uint32 m_dwAttribMap[16];
  125. // Register high water mark
  126. uint32 m_nHighestRegister;
  127. int32 m_nHighestBoneRegister;
  128. // GLSL does indentation for readability
  129. int m_NumIndentTabs;
  130. // Output buffers.
  131. CUtlBuffer *m_pBufHeaderCode;
  132. CUtlBuffer *m_pBufAttribCode;
  133. CUtlBuffer *m_pBufParamCode;
  134. CUtlBuffer *m_pBufALUCode;
  135. char *m_pFinalAssignmentsCode;
  136. int m_nFinalAssignmentsBufSize;
  137. // Recorded positions for debugging.
  138. uint32* m_pRecordedInputTokenStart;
  139. int m_nRecordedParamCodeStrlen;
  140. int m_nRecordedALUCodeStrlen;
  141. int m_nRecordedAttribCodeStrlen;
  142. // In GLSL mode, these store the semantic attached to each oN register.
  143. // They are the values that you pass to GetUsageIndexAndString.
  144. uint32 m_DeclaredOutputs[MAX_DECLARED_OUTPUTS];
  145. uint32 m_DeclaredInputs[MAX_DECLARED_INPUTS];
  146. // Have they used the tangent input semantic (i.e. is g_pTangentAttributeName declared)?
  147. bool m_bTangentInputUsed;
  148. bool m_bUsesDSTInstruction;
  149. private:
  150. // Utilities to aid in decoding token stream
  151. uint32 GetNextToken( void );
  152. void SkipTokens( uint32 numToSkip );
  153. uint32 Opcode( uint32 dwToken );
  154. uint32 OpcodeSpecificData( uint32 dwToken );
  155. uint32 TextureType ( uint32 dwToken );
  156. uint32 GetRegType( uint32 dwRegToken );
  157. // Write to the different buffers.
  158. void StrcatToHeaderCode( const char *pBuf );
  159. void StrcatToALUCode( const char *pBuf );
  160. void StrcatToParamCode( const char *pBuf );
  161. void StrcatToAttribCode( const char *pBuf );
  162. void PrintToBufWithIndents( CUtlBuffer &buf, const char *pFormat, ... );
  163. // This helps write the token hex codes into the output stream for debugging.
  164. void AddTokenHexCodeToBuffer( char *pBuffer, int nSize, int nLastStrlen );
  165. void RecordInputAndOutputPositions();
  166. void AddTokenHexCode();
  167. // Utilities for decoding tokens in to strings according to ASM syntax
  168. void PrintOpcode( uint32 inst, char* buff, int nBufLen );
  169. // fSemanticFlags is SEMANTIC_INPUT or SEMANTIC_OUTPUT.
  170. void PrintUsageAndIndexToString( uint32 dwToken, char* strUsageUsageIndexName, int nBufLen, int fSemanticFlags );
  171. CUtlString GetUsageAndIndexString( uint32 dwToken, int fSemanticFlags );
  172. CUtlString GetParameterString( uint32 dwToken, uint32 dwSourceOrDest, bool bForceScalarSource, int *pARLDestReg );
  173. const char* GetGLSLOperatorString( uint32 inst );
  174. void PrintParameterToString ( uint32 dwToken, uint32 dwSourceOrDest, char *pRegisterName, int nBufLen, bool bForceScalarSource, int *pARLDestReg );
  175. void InsertMoveFromAddressRegister( CUtlBuffer *pCode, int nARLComp0, int nARLComp1, int nARLComp2 = ARL_DEST_NONE );
  176. void InsertMoveInstruction( CUtlBuffer *pCode, int nARLComponent );
  177. void FlagIndirectRegister( uint32 dwToken, int *pARLDestReg );
  178. // Utilities for decoding tokens in to strings according to GLSL syntax
  179. bool OpenIntrinsic( uint32 inst, char* buff, int nBufLen, uint32 destDimension, uint32 nArgumentDimension );
  180. void PrintIndentation( char *pBuf, int nBufLen );
  181. uint32 MaintainAttributeMap( uint32 dwToken, uint32 dwRegToken );
  182. CUtlString FixGLSLSwizzle( const char *pDestRegisterName, const char *pSrcRegisterName );
  183. void WriteGLSLCmp( const char *pDestReg, const char *pSrc0Reg, const char *pSrc1Reg, const char *pSrc2Reg );
  184. void WriteGLSLSamplerDefinitions();
  185. void WriteGLSLOutputVariableAssignments();
  186. void WriteGLSLInputVariableAssignments();
  187. void NoteTangentInputUsed();
  188. void Handle_DCL();
  189. void Handle_DEF();
  190. void Handle_DEFIB( uint32 nInstruction );
  191. void Handle_MAD( uint32 nInstruction );
  192. void Handle_DP2ADD();
  193. void Handle_SINCOS();
  194. void Handle_LRP( uint32 nInstruction );
  195. void Handle_TEX( uint32 dwToken, bool bIsTexLDL );
  196. void Handle_TexLDD( uint32 nInstruction );
  197. void Handle_TexCoord();
  198. void Handle_UnaryOp( uint32 nInstruction );
  199. void Handle_BREAKC( uint32 dwToken );
  200. void HandleBinaryOp_GLSL( uint32 nInstruction );
  201. void HandleBinaryOp_ASM( uint32 nInstruction );
  202. void Handle_CMP();
  203. void Handle_NRM();
  204. void Handle_DeclarativeNonDclOp( uint32 nInstruction );
  205. public:
  206. D3DToGL();
  207. int TranslateShader( uint32* code, CUtlBuffer *pBufDisassembledCode, bool *bVertexShader, uint32 options, int32 nShadowDepthSamplerMask, uint32 nCentroidMask, char *debugLabel );
  208. };
  209. #endif // DX9_ASM_TO_GL_2_H