diff options
| author | lbavoil <[email protected]> | 2016-03-25 13:01:54 +0100 |
|---|---|---|
| committer | lbavoil <[email protected]> | 2016-03-25 13:01:54 +0100 |
| commit | 99174e4e5fb4b7079da80b35a6dfd68f3fd56a1c (patch) | |
| tree | fbcd4260d6c953d569a887505336a1c3f202e10f /build/tools/HLSLcc/May_2014/src/decodeDX9.c | |
| download | hbaoplus-99174e4e5fb4b7079da80b35a6dfd68f3fd56a1c.tar.xz hbaoplus-99174e4e5fb4b7079da80b35a6dfd68f3fd56a1c.zip | |
GFSDK_HBAO+_distro_r3.0_cl20573789
Diffstat (limited to 'build/tools/HLSLcc/May_2014/src/decodeDX9.c')
| -rw-r--r-- | build/tools/HLSLcc/May_2014/src/decodeDX9.c | 1146 |
1 files changed, 1146 insertions, 0 deletions
diff --git a/build/tools/HLSLcc/May_2014/src/decodeDX9.c b/build/tools/HLSLcc/May_2014/src/decodeDX9.c new file mode 100644 index 0000000..4106b60 --- /dev/null +++ b/build/tools/HLSLcc/May_2014/src/decodeDX9.c @@ -0,0 +1,1146 @@ + +#include "internal_includes/tokens.h" +#include "internal_includes/structs.h" +#include "internal_includes/decode.h" +#include "stdlib.h" +#include "stdio.h" +#include "internal_includes/reflect.h" +#include "internal_includes/debug.h" +#include "internal_includes/hlslcc_malloc.h" + +#define FOURCC(a, b, c, d) ((uint32_t)(uint8_t)(a) | ((uint32_t)(uint8_t)(b) << 8) | ((uint32_t)(uint8_t)(c) << 16) | ((uint32_t)(uint8_t)(d) << 24 )) +static enum {FOURCC_CTAB = FOURCC('C', 'T', 'A', 'B')}; //Constant table + +#ifdef _DEBUG +static uint64_t operandID = 0; +static uint64_t instructionID = 0; +#endif + +static uint32_t aui32ImmediateConst[256]; +static uint32_t ui32MaxTemp = 0; + +uint32_t DX9_DECODE_OPERAND_IS_SRC = 0x1; +uint32_t DX9_DECODE_OPERAND_IS_DEST = 0x2; +uint32_t DX9_DECODE_OPERAND_IS_DECL = 0x4; + +uint32_t DX9_DECODE_OPERAND_IS_CONST = 0x8; +uint32_t DX9_DECODE_OPERAND_IS_ICONST = 0x10; +uint32_t DX9_DECODE_OPERAND_IS_BCONST = 0x20; + +#define MAX_INPUTS 64 + +static DECLUSAGE_DX9 aeInputUsage[MAX_INPUTS]; +static uint32_t aui32InputUsageIndex[MAX_INPUTS]; + +static void DecodeOperandDX9(const Shader* psShader, + const uint32_t ui32Token, + const uint32_t ui32Token1, + uint32_t ui32Flags, + Operand *psOperand) +{ + const uint32_t ui32RegNum = DecodeOperandRegisterNumberDX9(ui32Token); + const uint32_t ui32RegType = DecodeOperandTypeDX9(ui32Token); + const uint32_t bRelativeAddr = DecodeOperandIsRelativeAddressModeDX9(ui32Token); + + const uint32_t ui32WriteMask = DecodeDestWriteMaskDX9(ui32Token); + const uint32_t ui32Swizzle = DecodeOperandSwizzleDX9(ui32Token); + + SHADER_VARIABLE_TYPE ConstType; + + psOperand->ui32RegisterNumber = ui32RegNum; + + psOperand->iNumComponents = 4; + +#ifdef _DEBUG + psOperand->id = operandID++; +#endif + + psOperand->iWriteMaskEnabled = 0; + psOperand->iGSInput = 0; + psOperand->iExtended = 0; + psOperand->psSubOperand[0] = 0; + psOperand->psSubOperand[1] = 0; + psOperand->psSubOperand[2] = 0; + + psOperand->iIndexDims = INDEX_0D; + + psOperand->iIntegerImmediate = 0; + + psOperand->pszSpecialName[0] ='\0'; + + + psOperand->eModifier = OPERAND_MODIFIER_NONE; + if(ui32Flags & DX9_DECODE_OPERAND_IS_SRC) + { + uint32_t ui32Modifier = DecodeSrcModifierDX9(ui32Token); + + switch(ui32Modifier) + { + case SRCMOD_DX9_NONE: + { + break; + } + case SRCMOD_DX9_NEG: + { + psOperand->eModifier = OPERAND_MODIFIER_NEG; + break; + } + case SRCMOD_DX9_ABS: + { + psOperand->eModifier = OPERAND_MODIFIER_ABS; + break; + } + case SRCMOD_DX9_ABSNEG: + { + psOperand->eModifier = OPERAND_MODIFIER_ABSNEG; + break; + } + default: + { + ASSERT(0); + break; + } + } + } + + if((ui32Flags & DX9_DECODE_OPERAND_IS_DECL)==0) + { + if(ui32Flags & DX9_DECODE_OPERAND_IS_DEST) + { + if(ui32WriteMask != DX9_WRITEMASK_ALL) + { + psOperand->iWriteMaskEnabled = 1; + psOperand->eSelMode = OPERAND_4_COMPONENT_MASK_MODE; + + if(ui32WriteMask & DX9_WRITEMASK_0) + { + psOperand->ui32CompMask |= OPERAND_4_COMPONENT_MASK_X; + } + if(ui32WriteMask & DX9_WRITEMASK_1) + { + psOperand->ui32CompMask |= OPERAND_4_COMPONENT_MASK_Y; + } + if(ui32WriteMask & DX9_WRITEMASK_2) + { + psOperand->ui32CompMask |= OPERAND_4_COMPONENT_MASK_Z; + } + if(ui32WriteMask & DX9_WRITEMASK_3) + { + psOperand->ui32CompMask |= OPERAND_4_COMPONENT_MASK_W; + } + } + } + else + if(ui32Swizzle != NO_SWIZZLE_DX9) + { + uint32_t component; + + psOperand->iWriteMaskEnabled = 1; + psOperand->eSelMode = OPERAND_4_COMPONENT_SWIZZLE_MODE; + + psOperand->ui32Swizzle = 1; + + /* Add the swizzle */ + if(ui32Swizzle == REPLICATE_SWIZZLE_DX9(0)) + { + psOperand->eSelMode = OPERAND_4_COMPONENT_SELECT_1_MODE; + psOperand->aui32Swizzle[0] = OPERAND_4_COMPONENT_X; + } + else + if(ui32Swizzle == REPLICATE_SWIZZLE_DX9(1)) + { + psOperand->eSelMode = OPERAND_4_COMPONENT_SELECT_1_MODE; + psOperand->aui32Swizzle[0] = OPERAND_4_COMPONENT_Y; + } + else + if(ui32Swizzle == REPLICATE_SWIZZLE_DX9(2)) + { + psOperand->eSelMode = OPERAND_4_COMPONENT_SELECT_1_MODE; + psOperand->aui32Swizzle[0] = OPERAND_4_COMPONENT_Z; + } + else + if(ui32Swizzle == REPLICATE_SWIZZLE_DX9(3)) + { + psOperand->eSelMode = OPERAND_4_COMPONENT_SELECT_1_MODE; + psOperand->aui32Swizzle[0] = OPERAND_4_COMPONENT_W; + } + else + { + for (component = 0; component < 4; component++) + { + uint32_t ui32CompSwiz = + ui32Swizzle & (3 << (DX9_SWIZZLE_SHIFT+(component*2))); + ui32CompSwiz >>= (DX9_SWIZZLE_SHIFT+(component*2)); + + if (ui32CompSwiz == 0) + { + psOperand->aui32Swizzle[component] = OPERAND_4_COMPONENT_X; + } + else if (ui32CompSwiz == 1) + { + psOperand->aui32Swizzle[component] = OPERAND_4_COMPONENT_Y; + } + else if (ui32CompSwiz == 2) + { + psOperand->aui32Swizzle[component] = OPERAND_4_COMPONENT_Z; + } + else + { + psOperand->aui32Swizzle[component] = OPERAND_4_COMPONENT_W; + } + } + } + } + + if(bRelativeAddr) + { + psOperand->psSubOperand[0] = hlslcc_malloc(sizeof(Operand)); + DecodeOperandDX9(psShader, ui32Token1, 0, ui32Flags, psOperand->psSubOperand[0]); + + psOperand->iIndexDims = INDEX_1D; + + psOperand->eIndexRep[0] = OPERAND_INDEX_RELATIVE; + + psOperand->aui32ArraySizes[0] = 0; + } + } + + if(ui32RegType == OPERAND_TYPE_DX9_CONSTBOOL) + { + ui32Flags |= DX9_DECODE_OPERAND_IS_BCONST; + ConstType = SVT_BOOL; + } + else if(ui32RegType == OPERAND_TYPE_DX9_CONSTINT) + { + ui32Flags |= DX9_DECODE_OPERAND_IS_ICONST; + ConstType = SVT_INT; + } + else if(ui32RegType == OPERAND_TYPE_DX9_CONST) + { + ui32Flags |= DX9_DECODE_OPERAND_IS_CONST; + ConstType = SVT_FLOAT; + } + + switch(ui32RegType) + { + case OPERAND_TYPE_DX9_TEMP: + { + psOperand->eType = OPERAND_TYPE_TEMP; + + if(ui32MaxTemp < ui32RegNum+1) + { + ui32MaxTemp = ui32RegNum+1; + } + break; + } + case OPERAND_TYPE_DX9_INPUT: + { + psOperand->eType = OPERAND_TYPE_INPUT; + + ASSERT(ui32RegNum < MAX_INPUTS); + + if(psShader->eShaderType == PIXEL_SHADER) + { + if(aeInputUsage[ui32RegNum] == DECLUSAGE_TEXCOORD) + { + psOperand->eType = OPERAND_TYPE_SPECIAL_TEXCOORD; + psOperand->ui32RegisterNumber = aui32InputUsageIndex[ui32RegNum]; + } + else + //0 = base colour, 1 = offset colour. + if(ui32RegNum == 0) + { + psOperand->eType = OPERAND_TYPE_SPECIAL_OUTBASECOLOUR; + } + else + { + ASSERT(ui32RegNum == 1); + psOperand->eType = OPERAND_TYPE_SPECIAL_OUTOFFSETCOLOUR; + } + } + break; + } + //Same value as OPERAND_TYPE_DX9_TEXCRDOUT + //OPERAND_TYPE_DX9_TEXCRDOUT is the pre-SM3 equivalent + case OPERAND_TYPE_DX9_OUTPUT: + { + psOperand->eType = OPERAND_TYPE_OUTPUT; + + if(psShader->eShaderType == VERTEX_SHADER) + { + psOperand->eType = OPERAND_TYPE_SPECIAL_TEXCOORD; + } + break; + } + case OPERAND_TYPE_DX9_RASTOUT: + { + //RegNum: + //0=POSIION + //1=FOG + //2=POINTSIZE + psOperand->eType = OPERAND_TYPE_OUTPUT; + switch(ui32RegNum) + { + case 0: + { + psOperand->eType = OPERAND_TYPE_SPECIAL_POSITION; + break; + } + case 1: + { + psOperand->eType = OPERAND_TYPE_SPECIAL_FOG; + break; + } + case 2: + { + psOperand->eType = OPERAND_TYPE_SPECIAL_POINTSIZE; + psOperand->iNumComponents = 1; + break; + } + } + break; + } + case OPERAND_TYPE_DX9_ATTROUT: + { + ASSERT(psShader->eShaderType == VERTEX_SHADER); + + psOperand->eType = OPERAND_TYPE_OUTPUT; + + //0 = base colour, 1 = offset colour. + if(ui32RegNum == 0) + { + psOperand->eType = OPERAND_TYPE_SPECIAL_OUTBASECOLOUR; + } + else + { + ASSERT(ui32RegNum == 1); + psOperand->eType = OPERAND_TYPE_SPECIAL_OUTOFFSETCOLOUR; + } + + break; + } + case OPERAND_TYPE_DX9_COLOROUT: + { + ASSERT(psShader->eShaderType == PIXEL_SHADER); + psOperand->eType = OPERAND_TYPE_OUTPUT; + break; + } + case OPERAND_TYPE_DX9_CONSTBOOL: + case OPERAND_TYPE_DX9_CONSTINT: + case OPERAND_TYPE_DX9_CONST: + { + //c# = constant float + //i# = constant int + //b# = constant bool + + //c0 might be an immediate while i0 is in the constant buffer + if(aui32ImmediateConst[ui32RegNum] & ui32Flags) + { + if(ConstType != SVT_FLOAT) + { + psOperand->eType = OPERAND_TYPE_SPECIAL_IMMCONSTINT; + } + else + { + psOperand->eType = OPERAND_TYPE_SPECIAL_IMMCONST; + } + } + else + { + psOperand->eType = OPERAND_TYPE_CONSTANT_BUFFER; + psOperand->aui32ArraySizes[1] = psOperand->ui32RegisterNumber; + } + break; + } + case OPERAND_TYPE_DX9_ADDR: + { + //Vertex shader: address register (only have one of these) + //Pixel shader: texture coordinate register (a few of these) + if(psShader->eShaderType == PIXEL_SHADER) + { + psOperand->eType = OPERAND_TYPE_SPECIAL_TEXCOORD; + } + else + { + psOperand->eType = OPERAND_TYPE_SPECIAL_ADDRESS; + } + break; + } + case OPERAND_TYPE_DX9_SAMPLER: + { + psOperand->eType = OPERAND_TYPE_RESOURCE; + break; + } + case OPERAND_TYPE_DX9_LOOP: + { + psOperand->eType = OPERAND_TYPE_SPECIAL_LOOPCOUNTER; + break; + } + default: + { + ASSERT(0); + break; + } + } +} + +static void DeclareNumTemps(Shader* psShader, + const uint32_t ui32NumTemps, + Declaration* psDecl) +{ + psDecl->eOpcode = OPCODE_DCL_TEMPS; + psDecl->value.ui32NumTemps = ui32NumTemps; +} + +static void SetupRegisterUsage(const Shader* psShader, + const uint32_t ui32Token0, + const uint32_t ui32Token1) +{ + DECLUSAGE_DX9 eUsage = DecodeUsageDX9(ui32Token0); + uint32_t ui32UsageIndex = DecodeUsageIndexDX9(ui32Token0); + uint32_t ui32RegNum = DecodeOperandRegisterNumberDX9(ui32Token1); + uint32_t ui32RegType = DecodeOperandTypeDX9(ui32Token1); + + if(ui32RegType == OPERAND_TYPE_DX9_INPUT) + { + ASSERT(ui32RegNum < MAX_INPUTS); + aeInputUsage[ui32RegNum] = eUsage; + aui32InputUsageIndex[ui32RegNum] = ui32UsageIndex; + } +} + +//Declaring one constant from a constant buffer will cause all constants in the buffer decalared. +//In dx9 there is only one constant buffer per shader. +static void DeclareConstantBuffer(const Shader* psShader, + Declaration* psDecl) +{ + DECLUSAGE_DX9 eUsage = (DECLUSAGE_DX9)0; + uint32_t ui32UsageIndex = 0; + //Pick any constant register in the table. Might not start at c0 (e.g. when register(cX) is used). + uint32_t ui32RegNum = psShader->sInfo.psConstantBuffers->asVars[0].ui32StartOffset / 16; + OPERAND_TYPE_DX9 ui32RegType = OPERAND_TYPE_DX9_CONST; + + if(psShader->sInfo.psConstantBuffers->asVars[0].sType.Type == SVT_INT) + { + ui32RegType = OPERAND_TYPE_DX9_CONSTINT; + } + else if(psShader->sInfo.psConstantBuffers->asVars[0].sType.Type == SVT_BOOL) + { + ui32RegType = OPERAND_TYPE_DX9_CONSTBOOL; + } + + if(psShader->eShaderType == VERTEX_SHADER) + { + psDecl->eOpcode = OPCODE_DCL_INPUT; + } + else + { + psDecl->eOpcode = OPCODE_DCL_INPUT_PS; + } + psDecl->ui32NumOperands = 1; + + DecodeOperandDX9(psShader, CreateOperandTokenDX9(ui32RegNum, ui32RegType), 0, DX9_DECODE_OPERAND_IS_DECL, &psDecl->asOperands[0]); + + ASSERT(psDecl->asOperands[0].eType == OPERAND_TYPE_CONSTANT_BUFFER); + + psDecl->eOpcode = OPCODE_DCL_CONSTANT_BUFFER; + + ASSERT(psShader->sInfo.ui32NumConstantBuffers); + + psDecl->asOperands[0].aui32ArraySizes[0] = 0;//Const buffer index + psDecl->asOperands[0].aui32ArraySizes[1] = psShader->sInfo.psConstantBuffers[0].ui32TotalSizeInBytes / 16;//Number of vec4 constants. +} + +static void DecodeDeclarationDX9(const Shader* psShader, + const uint32_t ui32Token0, + const uint32_t ui32Token1, + Declaration* psDecl) +{ + DECLUSAGE_DX9 eUsage = DecodeUsageDX9(ui32Token0); + uint32_t ui32UsageIndex = DecodeUsageIndexDX9(ui32Token0); + uint32_t ui32RegNum = DecodeOperandRegisterNumberDX9(ui32Token1); + uint32_t ui32RegType = DecodeOperandTypeDX9(ui32Token1); + + if(psShader->eShaderType == VERTEX_SHADER) + { + psDecl->eOpcode = OPCODE_DCL_INPUT; + } + else + { + psDecl->eOpcode = OPCODE_DCL_INPUT_PS; + } + psDecl->ui32NumOperands = 1; + DecodeOperandDX9(psShader, ui32Token1, 0, DX9_DECODE_OPERAND_IS_DECL, &psDecl->asOperands[0]); + + if(ui32RegType == OPERAND_TYPE_DX9_SAMPLER) + { + const RESOURCE_DIMENSION eResDim = DecodeTextureTypeMaskDX9(ui32Token0); + psDecl->value.eResourceDimension = eResDim; + psDecl->ui32IsShadowTex = 0; + psDecl->eOpcode = OPCODE_DCL_RESOURCE; + } + + if(psDecl->asOperands[0].eType == OPERAND_TYPE_OUTPUT) + { + psDecl->eOpcode = OPCODE_DCL_OUTPUT; + + if(psDecl->asOperands[0].ui32RegisterNumber==0 && psShader->eShaderType == VERTEX_SHADER) + { + psDecl->eOpcode = OPCODE_DCL_OUTPUT_SIV; + //gl_Position + psDecl->asOperands[0].eSpecialName = NAME_POSITION; + } + } + else + if(psDecl->asOperands[0].eType == OPERAND_TYPE_CONSTANT_BUFFER) + { + psDecl->eOpcode = OPCODE_DCL_CONSTANT_BUFFER; + + ASSERT(psShader->sInfo.ui32NumConstantBuffers); + + psDecl->asOperands[0].aui32ArraySizes[0] = 0;//Const buffer index + psDecl->asOperands[0].aui32ArraySizes[1] = psShader->sInfo.psConstantBuffers[0].ui32TotalSizeInBytes / 16;//Number of vec4 constants. + } +} + +static void DefineDX9(Shader* psShader, + const uint32_t ui32RegNum, + const uint32_t ui32Flags, + const uint32_t c0, + const uint32_t c1, + const uint32_t c2, + const uint32_t c3, + Declaration* psDecl) +{ + psDecl->eOpcode = OPCODE_SPECIAL_DCL_IMMCONST; + psDecl->ui32NumOperands = 2; + + memset(&psDecl->asOperands[0], 0, sizeof(Operand)); + psDecl->asOperands[0].eType = OPERAND_TYPE_SPECIAL_IMMCONST; + + psDecl->asOperands[0].ui32RegisterNumber = ui32RegNum; + + if(ui32Flags & (DX9_DECODE_OPERAND_IS_ICONST|DX9_DECODE_OPERAND_IS_BCONST)) + { + psDecl->asOperands[0].eType = OPERAND_TYPE_SPECIAL_IMMCONSTINT; + } + + aui32ImmediateConst[ui32RegNum] |= ui32Flags; + + memset(&psDecl->asOperands[1], 0, sizeof(Operand)); + psDecl->asOperands[1].eType = OPERAND_TYPE_IMMEDIATE32; + psDecl->asOperands[1].iNumComponents = 4; + psDecl->asOperands[1].iIntegerImmediate = (ui32Flags & (DX9_DECODE_OPERAND_IS_ICONST|DX9_DECODE_OPERAND_IS_BCONST)) ? 1 : 0; + psDecl->asOperands[1].afImmediates[0] = *((float*)&c0); + psDecl->asOperands[1].afImmediates[1] = *((float*)&c1); + psDecl->asOperands[1].afImmediates[2] = *((float*)&c2); + psDecl->asOperands[1].afImmediates[3] = *((float*)&c3); +} + +static void CreateD3D10Instruction( + Shader* psShader, + Instruction* psInst, + const OPCODE_TYPE eType, + const uint32_t bHasDest, + const uint32_t ui32SrcCount, + const uint32_t* pui32Tokens) +{ + uint32_t ui32Src; + uint32_t ui32Offset = 1; + + memset(psInst, 0, sizeof(Instruction)); + +#ifdef _DEBUG + psInst->id = instructionID++; +#endif + + psInst->eOpcode = eType; + psInst->ui32NumOperands = ui32SrcCount; + + if(bHasDest) + { + ++psInst->ui32NumOperands; + + DecodeOperandDX9(psShader, + pui32Tokens[ui32Offset], + pui32Tokens[ui32Offset+1], + DX9_DECODE_OPERAND_IS_DEST, + &psInst->asOperands[0]); + + if(DecodeDestModifierDX9(pui32Tokens[ui32Offset]) & DESTMOD_DX9_SATURATE) + { + psInst->bSaturate = 1; + } + + ui32Offset++; + psInst->ui32FirstSrc = 1; + } + + for(ui32Src=0; ui32Src < ui32SrcCount; ++ui32Src) + { + DecodeOperandDX9(psShader, + pui32Tokens[ui32Offset], + pui32Tokens[ui32Offset+1], + DX9_DECODE_OPERAND_IS_SRC, + &psInst->asOperands[bHasDest+ui32Src]); + + ui32Offset++; + } +} + +Shader* DecodeDX9BC(const uint32_t* pui32Tokens) +{ + const uint32_t* pui32CurrentToken = pui32Tokens; + uint32_t ui32NumInstructions = 0; + uint32_t ui32NumDeclarations = 0; + Instruction* psInst; + Declaration* psDecl; + uint32_t decl, inst; + uint32_t bDeclareConstantTable = 0; + Shader* psShader = hlslcc_calloc(1, sizeof(Shader)); + + memset(aui32ImmediateConst, 0, 256); + + psShader->ui32MajorVersion = DecodeProgramMajorVersionDX9(*pui32CurrentToken); + psShader->ui32MinorVersion = DecodeProgramMinorVersionDX9(*pui32CurrentToken); + psShader->eShaderType = DecodeShaderTypeDX9(*pui32CurrentToken); + + pui32CurrentToken++; + + //Work out how many instructions and declarations we need to allocate memory for. + while (1) + { + OPCODE_TYPE_DX9 eOpcode = DecodeOpcodeTypeDX9(pui32CurrentToken[0]); + uint32_t ui32InstLen = DecodeInstructionLengthDX9(pui32CurrentToken[0]); + + if(eOpcode == OPCODE_DX9_END) + { + //SM4+ always end with RET. + //Insert a RET instruction on END to + //replicate this behaviour. + ++ui32NumInstructions; + break; + } + else if(eOpcode == OPCODE_DX9_COMMENT) + { + ui32InstLen = DecodeCommentLengthDX9(pui32CurrentToken[0]); + if(pui32CurrentToken[1] == FOURCC_CTAB) + { + LoadD3D9ConstantTable((char*)(&pui32CurrentToken[2]), &psShader->sInfo); + + ASSERT(psShader->sInfo.ui32NumConstantBuffers); + + if(psShader->sInfo.psConstantBuffers[0].ui32NumVars) + { + ++ui32NumDeclarations; + bDeclareConstantTable = 1; + } + } + } + else if((eOpcode == OPCODE_DX9_DEF)||(eOpcode == OPCODE_DX9_DEFI)||(eOpcode == OPCODE_DX9_DEFB)) + { + ++ui32NumDeclarations; + } + else if(eOpcode == OPCODE_DX9_DCL) + { + const OPERAND_TYPE_DX9 eType = DecodeOperandTypeDX9(pui32CurrentToken[2]); + uint32_t ignoreDCL = 0; + + //Inputs and outputs are declared in AddVersionDependentCode + if(psShader->eShaderType == PIXEL_SHADER && (OPERAND_TYPE_DX9_CONST != eType && OPERAND_TYPE_DX9_SAMPLER != eType)) + { + ignoreDCL = 1; + } + if(!ignoreDCL) + { + ++ui32NumDeclarations; + } + } + else + { + switch(eOpcode) + { + case OPCODE_DX9_NRM: + { + //Emulate with dp4 and rsq + ui32NumInstructions += 2; + break; + } + default: + { + ++ui32NumInstructions; + break; + } + } + } + + pui32CurrentToken += ui32InstLen + 1; + } + + psInst = hlslcc_malloc(sizeof(Instruction) * ui32NumInstructions); + psShader->psInst = psInst; + psShader->ui32InstCount = ui32NumInstructions; + + if(psShader->eShaderType == VERTEX_SHADER) + { + //Declare gl_Position. vs_3_0 does declare it, SM1/2 do not + ui32NumDeclarations++; + } + + //For declaring temps. + ui32NumDeclarations++; + + psDecl = hlslcc_malloc(sizeof(Declaration) * ui32NumDeclarations); + psShader->psDecl = psDecl; + psShader->ui32DeclCount = ui32NumDeclarations; + + pui32CurrentToken = pui32Tokens + 1; + + inst=0; + decl=0; + while (1) + { + OPCODE_TYPE_DX9 eOpcode = DecodeOpcodeTypeDX9(pui32CurrentToken[0]); + uint32_t ui32InstLen = DecodeInstructionLengthDX9(pui32CurrentToken[0]); + + if(eOpcode == OPCODE_DX9_END) + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_RET, 0, 0, pui32CurrentToken); + inst++; + break; + } + else if(eOpcode == OPCODE_DX9_COMMENT) + { + ui32InstLen = DecodeCommentLengthDX9(pui32CurrentToken[0]); + } + else if(eOpcode == OPCODE_DX9_DCL) + { + const OPERAND_TYPE_DX9 eType = DecodeOperandTypeDX9(pui32CurrentToken[2]); + uint32_t ignoreDCL = 0; + //Inputs and outputs are declared in AddVersionDependentCode + if(psShader->eShaderType == PIXEL_SHADER && (OPERAND_TYPE_DX9_CONST != eType && OPERAND_TYPE_DX9_SAMPLER != eType)) + { + ignoreDCL = 1; + } + + SetupRegisterUsage(psShader, pui32CurrentToken[1], pui32CurrentToken[2]); + + if(!ignoreDCL) + { + DecodeDeclarationDX9(psShader, pui32CurrentToken[1], pui32CurrentToken[2], &psDecl[decl]); + decl++; + } + } + else if((eOpcode == OPCODE_DX9_DEF)||(eOpcode == OPCODE_DX9_DEFI)||(eOpcode == OPCODE_DX9_DEFB)) + { + const uint32_t ui32Const0 = *(pui32CurrentToken+2); + const uint32_t ui32Const1 = *(pui32CurrentToken+3); + const uint32_t ui32Const2 = *(pui32CurrentToken+4); + const uint32_t ui32Const3 = *(pui32CurrentToken+5); + uint32_t ui32Flags = 0; + + if(eOpcode == OPCODE_DX9_DEF) + { + ui32Flags |= DX9_DECODE_OPERAND_IS_CONST; + } + else if(eOpcode == OPCODE_DX9_DEFI) + { + ui32Flags |= DX9_DECODE_OPERAND_IS_ICONST; + } + else + { + ui32Flags |= DX9_DECODE_OPERAND_IS_BCONST; + } + + + DefineDX9(psShader, + DecodeOperandRegisterNumberDX9(pui32CurrentToken[1]), + ui32Flags, + ui32Const0, + ui32Const1, + ui32Const2, + ui32Const3, + &psDecl[decl]); + decl++; + } + else + { + switch(eOpcode) + { + case OPCODE_DX9_MOV: + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_MOV, 1, 1, pui32CurrentToken); + break; + } + case OPCODE_DX9_LIT: + { + /*Dest.x = 1 + Dest.y = (Src0.x > 0) ? Src0.x : 0 + Dest.z = (Src0.x > 0 && Src0.y > 0) ? pow(Src0.y, Src0.w) : 0 + Dest.w = 1 + */ + ASSERT(0); + break; + } + case OPCODE_DX9_ADD: + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_ADD, 1, 2, pui32CurrentToken); + break; + } + case OPCODE_DX9_SUB: + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_ADD, 1, 2, pui32CurrentToken); + ASSERT(psInst[inst].asOperands[2].eModifier == OPERAND_MODIFIER_NONE); + psInst[inst].asOperands[2].eModifier = OPERAND_MODIFIER_NEG; + break; + } + case OPCODE_DX9_MAD: + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_MAD, 1, 3, pui32CurrentToken); + break; + } + case OPCODE_DX9_MUL: + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_MUL, 1, 2, pui32CurrentToken); + break; + } + case OPCODE_DX9_RCP: + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_RCP, 1, 1, pui32CurrentToken); + break; + } + case OPCODE_DX9_RSQ: + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_RSQ, 1, 1, pui32CurrentToken); + break; + } + case OPCODE_DX9_DP3: + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_DP3, 1, 2, pui32CurrentToken); + break; + } + case OPCODE_DX9_DP4: + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_DP4, 1, 2, pui32CurrentToken); + break; + } + case OPCODE_DX9_MIN: + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_MIN, 1, 2, pui32CurrentToken); + break; + } + case OPCODE_DX9_MAX: + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_MAX, 1, 2, pui32CurrentToken); + break; + } + case OPCODE_DX9_SLT: + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_LT, 1, 2, pui32CurrentToken); + break; + } + case OPCODE_DX9_SGE: + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_GE, 1, 2, pui32CurrentToken); + break; + } + case OPCODE_DX9_EXP: + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_EXP, 1, 1, pui32CurrentToken); + break; + } + case OPCODE_DX9_LOG: + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_LOG, 1, 1, pui32CurrentToken); + break; + } + case OPCODE_DX9_NRM: + { + //Convert NRM RESULT, SRCA into: + //dp4 RESULT, SRCA, SRCA + //rsq RESULT, RESULT + + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_DP4, 1, 1, pui32CurrentToken); + memcpy(&psInst[inst].asOperands[2],&psInst[inst].asOperands[1], sizeof(Operand)); + ++inst; + + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_RSQ, 0, 0, pui32CurrentToken); + memcpy(&psInst[inst].asOperands[0],&psInst[inst-1].asOperands[0], sizeof(Operand)); + break; + } + case OPCODE_DX9_SINCOS: + { + //Before SM3, SINCOS has 2 extra constant sources -D3DSINCOSCONST1 and D3DSINCOSCONST2. + //Ignore them. + + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_SINCOS, 1, 1, pui32CurrentToken); + //Pre-SM4: + //If the write mask is .x: dest.x = cos( V ) + //If the write mask is .y: dest.y = sin( V ) + //If the write mask is .xy: + //dest.x = cos( V ) + //dest.y = sin( V ) + + //SM4+ + //destSin destCos Angle + + psInst[inst].ui32NumOperands = 3; + + //Set the angle + memcpy(&psInst[inst].asOperands[2],&psInst[inst].asOperands[1], sizeof(Operand)); + + //Set the cosine dest + memcpy(&psInst[inst].asOperands[1],&psInst[inst].asOperands[0], sizeof(Operand)); + + //Set write masks + psInst[inst].asOperands[0].ui32CompMask &= ~OPERAND_4_COMPONENT_MASK_Y; + if(psInst[inst].asOperands[0].ui32CompMask & OPERAND_4_COMPONENT_MASK_X) + { + //Need cosine + } + else + { + psInst[inst].asOperands[0].eType = OPERAND_TYPE_NULL; + } + psInst[inst].asOperands[1].ui32CompMask &= ~OPERAND_4_COMPONENT_MASK_X; + if(psInst[inst].asOperands[1].ui32CompMask & OPERAND_4_COMPONENT_MASK_Y) + { + //Need sine + } + else + { + psInst[inst].asOperands[1].eType = OPERAND_TYPE_NULL; + } + + break; + } + case OPCODE_DX9_FRC: + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_FRC, 1, 1, pui32CurrentToken); + break; + } + + case OPCODE_DX9_MOVA: + { + //MOVA preforms RoundToNearest on the src data. + //The only rounding functions available in all GLSL version are ceil and floor. + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_ROUND_NI, 1, 1, pui32CurrentToken); + break; + } + + case OPCODE_DX9_TEX: + { + //texld r0, t0, s0 + // srcAddress[.swizzle], srcResource[.swizzle], srcSampler + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_SAMPLE, 1, 2, pui32CurrentToken); + psInst[inst].asOperands[2].ui32RegisterNumber = 0; + + + break; + } + case OPCODE_DX9_TEXLDL: + { + //texld r0, t0, s0 + // srcAddress[.swizzle], srcResource[.swizzle], srcSampler + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_SAMPLE_L, 1, 2, pui32CurrentToken); + psInst[inst].asOperands[2].ui32RegisterNumber = 0; + + //Lod comes from fourth coordinate of address. + memcpy(&psInst[inst].asOperands[4], &psInst[inst].asOperands[1], sizeof(Operand)); + + psInst[inst].ui32NumOperands = 5; + + break; + } + + case OPCODE_DX9_IF: + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_IF, 0, 1, pui32CurrentToken); + psInst[inst].eDX9TestType = D3DSPC_BOOLEAN; + break; + } + + case OPCODE_DX9_IFC: + { + const COMPARISON_DX9 eCmpOp = DecodeComparisonDX9(pui32CurrentToken[0]); + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_IF, 0, 2, pui32CurrentToken); + psInst[inst].eDX9TestType = eCmpOp; + break; + } + case OPCODE_DX9_ELSE: + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_ELSE, 0, 0, pui32CurrentToken); + break; + } + case OPCODE_DX9_CMP: + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_MOVC, 1, 3, pui32CurrentToken); + break; + } + case OPCODE_DX9_REP: + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_REP, 0, 1, pui32CurrentToken); + break; + } + case OPCODE_DX9_ENDREP: + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_ENDREP, 0, 0, pui32CurrentToken); + break; + } + case OPCODE_DX9_BREAKC: + { + const COMPARISON_DX9 eCmpOp = DecodeComparisonDX9(pui32CurrentToken[0]); + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_BREAKC, 0, 2, pui32CurrentToken); + psInst[inst].eDX9TestType = eCmpOp; + break; + } + + case OPCODE_DX9_DSX: + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_DERIV_RTX, 1, 1, pui32CurrentToken); + break; + } + case OPCODE_DX9_DSY: + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_DERIV_RTY, 1, 1, pui32CurrentToken); + break; + } + case OPCODE_DX9_TEXKILL: + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_DISCARD, 1, 0, pui32CurrentToken); + break; + } + case OPCODE_DX9_TEXLDD: + { + // texldd, dst, src0, src1, src2, src3 + // srcAddress[.swizzle], srcResource[.swizzle], srcSampler, XGradient, YGradient + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_SAMPLE_D, 1, 4, pui32CurrentToken); + psInst[inst].asOperands[2].ui32RegisterNumber = 0; + break; + } + case OPCODE_DX9_LRP: + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_LRP, 1, 3, pui32CurrentToken); + break; + } + case OPCODE_DX9_DP2ADD: + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_DP2ADD, 1, 3, pui32CurrentToken); + break; + } + case OPCODE_DX9_POW: + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_POW, 1, 2, pui32CurrentToken); + break; + } + + case OPCODE_DX9_DST: + case OPCODE_DX9_M4x4: + case OPCODE_DX9_M4x3: + case OPCODE_DX9_M3x4: + case OPCODE_DX9_M3x3: + case OPCODE_DX9_M3x2: + case OPCODE_DX9_CALL: + case OPCODE_DX9_CALLNZ: + case OPCODE_DX9_LABEL: + + case OPCODE_DX9_CRS: + case OPCODE_DX9_SGN: + case OPCODE_DX9_ABS: + + case OPCODE_DX9_TEXCOORD: + case OPCODE_DX9_TEXBEM: + case OPCODE_DX9_TEXBEML: + case OPCODE_DX9_TEXREG2AR: + case OPCODE_DX9_TEXREG2GB: + case OPCODE_DX9_TEXM3x2PAD: + case OPCODE_DX9_TEXM3x2TEX: + case OPCODE_DX9_TEXM3x3PAD: + case OPCODE_DX9_TEXM3x3TEX: + case OPCODE_DX9_TEXM3x3SPEC: + case OPCODE_DX9_TEXM3x3VSPEC: + case OPCODE_DX9_EXPP: + case OPCODE_DX9_LOGP: + case OPCODE_DX9_CND: + case OPCODE_DX9_TEXREG2RGB: + case OPCODE_DX9_TEXDP3TEX: + case OPCODE_DX9_TEXM3x2DEPTH: + case OPCODE_DX9_TEXDP3: + case OPCODE_DX9_TEXM3x3: + case OPCODE_DX9_TEXDEPTH: + case OPCODE_DX9_BEM: + case OPCODE_DX9_SETP: + case OPCODE_DX9_BREAKP: + { + ASSERT(0); + break; + } + case OPCODE_DX9_NOP: + case OPCODE_DX9_PHASE: + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_NOP, 0, 0, pui32CurrentToken); + break; + } + case OPCODE_DX9_LOOP: + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_LOOP, 0, 2, pui32CurrentToken); + break; + } + case OPCODE_DX9_RET: + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_RET, 0, 0, pui32CurrentToken); + break; + } + case OPCODE_DX9_ENDLOOP: + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_ENDLOOP, 0, 0, pui32CurrentToken); + break; + } + case OPCODE_DX9_ENDIF: + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_ENDIF, 0, 0, pui32CurrentToken); + break; + } + case OPCODE_DX9_BREAK: + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_BREAK, 0, 0, pui32CurrentToken); + break; + } + default: + { + ASSERT(0); + break; + } + } + + UpdateOperandReferences(psShader, &psInst[inst]); + + inst++; + } + + pui32CurrentToken += ui32InstLen + 1; + } + + DeclareNumTemps(psShader, ui32MaxTemp, &psDecl[decl]); + ++decl; + + if(psShader->eShaderType == VERTEX_SHADER) + { + //Declare gl_Position. vs_3_0 does declare it, SM1/2 do not + if(bDeclareConstantTable) + { + DecodeDeclarationDX9(psShader, 0, CreateOperandTokenDX9(0, OPERAND_TYPE_DX9_RASTOUT), &psDecl[decl+1]); + } + else + { + DecodeDeclarationDX9(psShader, 0, CreateOperandTokenDX9(0, OPERAND_TYPE_DX9_RASTOUT), &psDecl[decl]); + } + } + + if(bDeclareConstantTable) + { + DeclareConstantBuffer(psShader, &psDecl[decl]); + } + + return psShader; +} |