📄 ps_1_4.cpp
字号:
}
};
PS_1_4::MacroRegModify PS_1_4::texm3x3pad_MacroMods = {
texm3x3pad, ARRAYSIZE(texm3x3pad),
texm3xxpad_RegMods, ARRAYSIZE(texm3xxpad_RegMods)
};
// macro token expansion for ps_1_1 instruction: texm3x3pad
PS_1_4::TokenInst PS_1_4::texm3x3tex[] = {
// texcoord t(x)
{ sid_TEXOP_PS1_1_3, sid_TEXCOORD
_token_ sid_TEX_PS1_1_3, sid_1T1
// dp3 r4.b, r(x), r(y)
_token_ sid_BINARYOP, sid_DP3
_token_ sid_REG_PS1_4, sid_R4
_token_ sid_DSTMASK, sid_B
_token_ sid_SEPERATOR, sid_COMMA
_token_ sid_REG_PS1_4, sid_R1
_token_ sid_SEPERATOR, sid_COMMA
_token_ sid_REG_PS1_4, sid_R0
// texld r1, r4
_token_ sid_TEXOP_PS1_4, sid_TEXLD
_token_ sid_REG_PS1_4, sid_R1
_token_ sid_SEPERATOR, sid_COMMA
_token_ sid_REG_PS1_4, sid_R4
}
};
PS_1_4::MacroRegModify PS_1_4::texm3x3tex_MacroMods = {
texm3x3tex, ARRAYSIZE(texm3x3tex),
texm3xxtex_RegMods, ARRAYSIZE(texm3xxtex_RegMods)
};
// macro token expansion for ps_1_1 instruction: texm3x3spec
PS_1_4::TokenInst PS_1_4::texm3x3spec[] = {
// texcoord t(x)
{ sid_TEXOP_PS1_1_3, sid_TEXCOORD
_token_ sid_TEX_PS1_1_3, sid_1T3
// dp3 r4.b, r3, r(x)
_token_ sid_BINARYOP, sid_DP3
_token_ sid_REG_PS1_4, sid_R4
_token_ sid_DSTMASK, sid_B
_token_ sid_SEPERATOR, sid_COMMA
_token_ sid_REG_PS1_4, sid_R3
_token_ sid_SEPERATOR, sid_COMMA
_token_ sid_REG_PS1_4, sid_R0
// dp3_x2 r3, r4, c(x)
_token_ sid_BINARYOP, sid_DP3
_token_ sid_DSTMOD, sid_X2
_token_ sid_REG_PS1_4, sid_R3
_token_ sid_SEPERATOR, sid_COMMA
_token_ sid_REG_PS1_4, sid_R4
_token_ sid_SEPERATOR, sid_COMMA
_token_ sid_CONSTANT, sid_C0
// mul r3, r3, c(x)
_token_ sid_UNARYOP, sid_MUL
_token_ sid_REG_PS1_4, sid_R3
_token_ sid_SEPERATOR, sid_COMMA
_token_ sid_REG_PS1_4, sid_R3
_token_ sid_SEPERATOR, sid_COMMA
_token_ sid_CONSTANT, sid_C0
// dp3 r2, r4, r4
_token_ sid_BINARYOP, sid_DP3
_token_ sid_REG_PS1_4, sid_R2
_token_ sid_SEPERATOR, sid_COMMA
_token_ sid_REG_PS1_4, sid_R4
_token_ sid_SEPERATOR, sid_COMMA
_token_ sid_REG_PS1_4, sid_R4
// mad r4.rgb, 1-c(x), r2, r3
_token_ sid_TERNARYOP, sid_MAD
_token_ sid_REG_PS1_4, sid_R4
_token_ sid_DSTMASK, sid_RGB
_token_ sid_SEPERATOR, sid_COMMA
_token_ sid_PRESRCMOD, sid_INVERT
_token_ sid_CONSTANT, sid_C0
_token_ sid_SEPERATOR, sid_COMMA
_token_ sid_REG_PS1_4, sid_R2
_token_ sid_SEPERATOR, sid_COMMA
_token_ sid_REG_PS1_4, sid_R3
// + mov r4.a, r2.r
_token_ sid_UNARYOP, sid_MOV
_token_ sid_REG_PS1_4, sid_R4
_token_ sid_DSTMASK, sid_A
_token_ sid_SEPERATOR, sid_COMMA
_token_ sid_REG_PS1_4, sid_R2
_token_ sid_SRCREP, sid_RRRR
// texld r3, r4.xyz_dz
_token_ sid_TEXOP_PS1_4, sid_TEXLD
_token_ sid_REG_PS1_4, sid_R3
_token_ sid_SEPERATOR, sid_COMMA
_token_ sid_REG_PS1_4, sid_R4
_token_ sid_TEXSWIZZLE, sid_STRDR
}
};
PS_1_4::RegModOffset PS_1_4::texm3x3spec_RegMods[] = {
{8, R_BASE, 1},
{15, R_BASE, 2},
{21, C_BASE, 2},
{33, C_BASE, 2},
};
PS_1_4::MacroRegModify PS_1_4::texm3x3spec_MacroMods = {
texm3x3spec, ARRAYSIZE(texm3x3spec),
texm3x3spec_RegMods, ARRAYSIZE(texm3x3spec_RegMods)
};
/* ********************* END OF CLASS STATIC DATA ********************************* */
PS_1_4::PS_1_4()
{
// allocate enough room for a large pixel shader
mPhase1TEX_mi.reserve(50);
mPhase2TEX_mi.reserve(30);
mPhase1ALU_mi.reserve(100);
mPhase2ALU_mi.reserve(100);
mSymbolTypeLib = PS_1_4_SymbolTypeLib;
mSymbolTypeLibCnt = ARRAYSIZE(PS_1_4_SymbolTypeLib);
mRootRulePath = PS_1_x_RulePath;
mRulePathLibCnt = ARRAYSIZE(PS_1_x_RulePath);
// tell compiler what the symbol id is for a numeric value
mValueID = sid_VALUE;
// The type library must have text definitions initialized
// before compiler is invoked
// only need to initialize the rule database once
if(LibInitialized == false) {
InitSymbolTypeLib();
LibInitialized = true;
}
// set initial context to recognize PS base instructions
mActiveContexts = ckp_PS_BASE;
}
bool PS_1_4::bindMachineInstInPassToFragmentShader(const MachineInstContainer & PassMachineInstructions)
{
size_t instIDX = 0;
size_t instCount = PassMachineInstructions.size();
bool error = false;
while ((instIDX < instCount) && !error) {
switch(PassMachineInstructions[instIDX]) {
case mi_COLOROP1:
if((instIDX+7) < instCount)
glColorFragmentOp1ATI_ptr(PassMachineInstructions[instIDX+1], // op
PassMachineInstructions[instIDX+2], // dst
PassMachineInstructions[instIDX+3], // dstMask
PassMachineInstructions[instIDX+4], // dstMod
PassMachineInstructions[instIDX+5], // arg1
PassMachineInstructions[instIDX+6], // arg1Rep
PassMachineInstructions[instIDX+7]);// arg1Mod
instIDX += 8;
break;
case mi_COLOROP2:
if((instIDX+10) < instCount)
glColorFragmentOp2ATI_ptr(PassMachineInstructions[instIDX+1], // op
PassMachineInstructions[instIDX+2], // dst
PassMachineInstructions[instIDX+3], // dstMask
PassMachineInstructions[instIDX+4], // dstMod
PassMachineInstructions[instIDX+5], // arg1
PassMachineInstructions[instIDX+6], // arg1Rep
PassMachineInstructions[instIDX+7], // arg1Mod
PassMachineInstructions[instIDX+8], // arg2
PassMachineInstructions[instIDX+9], // arg2Rep
PassMachineInstructions[instIDX+10]);// arg2Mod
instIDX += 11;
break;
case mi_COLOROP3:
if((instIDX+13) < instCount)
glColorFragmentOp3ATI_ptr(PassMachineInstructions[instIDX+1], // op
PassMachineInstructions[instIDX+2], // dst
PassMachineInstructions[instIDX+3], // dstMask
PassMachineInstructions[instIDX+4], // dstMod
PassMachineInstructions[instIDX+5], // arg1
PassMachineInstructions[instIDX+6], // arg1Rep
PassMachineInstructions[instIDX+7], // arg1Mod
PassMachineInstructions[instIDX+8], // arg2
PassMachineInstructions[instIDX+9], // arg2Rep
PassMachineInstructions[instIDX+10], // arg2Mod
PassMachineInstructions[instIDX+11], // arg2
PassMachineInstructions[instIDX+12], // arg2Rep
PassMachineInstructions[instIDX+13]);// arg2Mod
instIDX += 14;
break;
case mi_ALPHAOP1:
if((instIDX+6) < instCount)
glAlphaFragmentOp1ATI_ptr(PassMachineInstructions[instIDX+1], // op
PassMachineInstructions[instIDX+2], // dst
PassMachineInstructions[instIDX+3], // dstMod
PassMachineInstructions[instIDX+4], // arg1
PassMachineInstructions[instIDX+5], // arg1Rep
PassMachineInstructions[instIDX+6]); // arg1Mod
instIDX += 7;
break;
case mi_ALPHAOP2:
if((instIDX+9) < instCount)
glAlphaFragmentOp2ATI_ptr(PassMachineInstructions[instIDX+1], // op
PassMachineInstructions[instIDX+2], // dst
PassMachineInstructions[instIDX+3], // dstMod
PassMachineInstructions[instIDX+4], // arg1
PassMachineInstructions[instIDX+5], // arg1Rep
PassMachineInstructions[instIDX+6], // arg1Mod
PassMachineInstructions[instIDX+7], // arg2
PassMachineInstructions[instIDX+8], // arg2Rep
PassMachineInstructions[instIDX+9]); // arg2Mod
instIDX += 10;
break;
case mi_ALPHAOP3:
if((instIDX+12) < instCount)
glAlphaFragmentOp3ATI_ptr(PassMachineInstructions[instIDX+1], // op
PassMachineInstructions[instIDX+2], // dst
PassMachineInstructions[instIDX+3], // dstMod
PassMachineInstructions[instIDX+4], // arg1
PassMachineInstructions[instIDX+5], // arg1Rep
PassMachineInstructions[instIDX+6], // arg1Mod
PassMachineInstructions[instIDX+7], // arg2
PassMachineInstructions[instIDX+8], // arg2Rep
PassMachineInstructions[instIDX+9], // arg2Mod
PassMachineInstructions[instIDX+10], // arg2
PassMachineInstructions[instIDX+11], // arg2Rep
PassMachineInstructions[instIDX+12]); // arg2Mod
instIDX += 13;
break;
case mi_SETCONSTANTS:
if((instIDX+2) < instCount)
glSetFragmentShaderConstantATI_ptr(PassMachineInstructions[instIDX+1], // dst
&mConstants[PassMachineInstructions[instIDX+2]]);
instIDX += 3;
break;
case mi_PASSTEXCOORD:
if((instIDX+3) < instCount)
glPassTexCoordATI_ptr(PassMachineInstructions[instIDX+1], // dst
PassMachineInstructions[instIDX+2], // coord
PassMachineInstructions[instIDX+3]); // swizzle
instIDX += 4;
break;
case mi_SAMPLEMAP:
if((instIDX+3) < instCount)
glSampleMapATI_ptr(PassMachineInstructions[instIDX+1], // dst
PassMachineInstructions[instIDX+2], // interp
PassMachineInstructions[instIDX+3]); // swizzle
instIDX += 4;
break;
default:
instIDX = instCount;
// should generate an error since an unknown instruction was found
// instead for now the bind process is terminated and the fragment program may still function
// but its output may not be what was programmed
} // end of switch
error = (glGetError() != GL_NO_ERROR);
}// end of while
return !error;
}
size_t PS_1_4::getMachineInst( size_t Idx)
{
if (Idx < mPhase1TEX_mi.size()) {
return mPhase1TEX_mi[Idx];
}
else {
Idx -= mPhase1TEX_mi.size();
if (Idx < mPhase1ALU_mi.size()) {
return mPhase1ALU_mi[Idx];
}
else {
Idx -= mPhase1ALU_mi.size();
if (Idx < mPhase2TEX_mi.size()) {
return mPhase2TEX_mi[Idx];
}
else {
Idx -= mPhase2TEX_mi.size();
if (Idx < mPhase2ALU_mi.size()) {
return mPhase2ALU_mi[Idx];
}
}
}
}
return 0;
}
void PS_1_4::addMachineInst(const PhaseType phase, const uint inst)
{
switch(phase) {
case ptPHASE1TEX:
mPhase1TEX_mi.push_back(inst);
break;
case ptPHASE1ALU:
mPhase1ALU_mi.push_back(inst);
break;
case ptPHASE2TEX:
mPhase2TEX_mi.push_back(inst);
break;
case ptPHASE2ALU:
mPhase2ALU_mi.push_back(inst);
break;
} // end switch(phase)
}
size_t PS_1_4::getMachineInstCount()
{
return (mPhase1TEX_mi.size() + mPhase1ALU_mi.size() + mPhase2TEX_mi.size() + mPhase2ALU_mi.size());
}
bool PS_1_4::bindAllMachineInstToFragmentShader()
{
bool passed;
// there are 4 machine instruction ques to pass to the ATI fragment shader
passed = bindMachineInstInPassToFragmentShader(mPhase1TEX_mi);
passed &= bindMachineInstInPassToFragmentShader(mPhase1ALU_mi);
passed &= bindMachineInstInPassToFragmentShader(mPhase2TEX_mi);
passed &= bindMachineInstInPassToFragmentShader(mPhase2ALU_mi);
return passed;
}
bool PS_1_4::expandMacro(const MacroRegModify & MacroMod)
{
RegModOffset * regmod;
// set source and destination registers in macro expansion
for (uint i = 0; i < MacroMod.RegModSize; i++) {
regmod = &MacroMod.RegMods[i];
MacroMod.Macro[regmod->MacroOffset].mID = regmod->RegisterBase + mOpParrams[regmod->OpParramsIndex].Arg;
}
// turn macro support on so that ps.1.4 ALU instructions get put in phase 1 alu instruction sequence container
mMacroOn = true;
// pass macro tokens on to be turned into machine instructions
// expand macro to ps.1.4 by doing recursive call to doPass2
bool passed = Pass2scan(MacroMod.Macro, MacroMod.MacroSize);
mMacroOn = false;
return passed;
}
bool PS_1_4::BuildMachineInst()
{
// check the states to see if a machine instruction can be assembled
// assume all arguments have been set up
bool passed = false;
passed = true; // assume everything will go okay untill proven otherwise
// start with machine NOP instuction
// this is used after the switch to see if an instruction was set up
// determine which MachineInstID is required based on the op instruction
mOpType = mi_NOP;
switch(mOpInst) {
// ALU operations
case sid_ADD:
case sid_SUB:
case sid_MUL:
case sid_MAD:
case sid_LRP:
case sid_MOV:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -