|
|
//------------------------------------------------------------------------------
// 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
|