You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1114 lines
38 KiB
C
1114 lines
38 KiB
C
// Modifications copyright Amazon.com, Inc. or its affiliates
|
|
// Modifications copyright Crytek GmbH
|
|
|
|
#include "internal_includes/debug.h"
|
|
#include "internal_includes/decode.h"
|
|
#include "internal_includes/hlslcc_malloc.h"
|
|
#include "internal_includes/reflect.h"
|
|
#include "internal_includes/structs.h"
|
|
#include "internal_includes/tokens.h"
|
|
#include "stdio.h"
|
|
#include "stdlib.h"
|
|
|
|
enum
|
|
{
|
|
FOURCC_CTAB = FOURCC('C', 'T', 'A', 'B')
|
|
}; // Constant table
|
|
|
|
#ifdef _DEBUG
|
|
static uint64_t dx9operandID = 0;
|
|
static uint64_t dx9instructionID = 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 = dx9operandID++;
|
|
#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)
|
|
{
|
|
(void)psShader;
|
|
|
|
psDecl->eOpcode = OPCODE_DCL_TEMPS;
|
|
psDecl->value.ui32NumTemps = ui32NumTemps;
|
|
}
|
|
|
|
static void SetupRegisterUsage(const Shader* psShader, const uint32_t ui32Token0, const uint32_t ui32Token1)
|
|
{
|
|
(void)psShader;
|
|
|
|
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)
|
|
{
|
|
// 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)
|
|
{
|
|
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->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)
|
|
{
|
|
(void)psShader;
|
|
|
|
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 = dx9instructionID++;
|
|
#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;
|
|
}
|
|
}
|
|
|
|
UpdateInstructionReferences(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;
|
|
}
|