#include <vertex_program_parse.h>
Nevrax France
Definition at line 191 of file vertex_program_parse.h.
Public Types | |
typedef std::vector< CVPInstruction > | TProgram |
Public Member Functions | |
bool | parse (const char *src, TProgram &result, std::string &errorOutput) |
Static Public Member Functions | |
void | dump (const TProgram &prg, std::string &dest) |
bool | isInputUsed (const TProgram &prg, CVPOperand::EInputRegister input) |
Private Member Functions | |
bool | parseAddressRegister (CVPOperand &operand, std::string &errorOutput) |
bool | parseConstantRegister (CVPOperand &operand, std::string &errorOutput) |
bool | parseInputRegister (CVPOperand &operand, std::string &errorOutput) |
bool | parseInstruction (CVPInstruction &instr, std::string &errorOutput, bool &endEncountered) |
bool | parseOp2 (CVPInstruction &instr, std::string &errorOutput) |
bool | parseOp3 (CVPInstruction &instr, std::string &errorOutput) |
bool | parseOp4 (CVPInstruction &instr, std::string &errorOutput) |
bool | parseOperand (CVPOperand &operand, bool outputOperand, std::string &errorOutput) |
bool | parseOutputRegister (CVPOperand &operand, std::string &errorOutput) |
bool | parseSwizzle (CVPSwizzle &swizzle, std::string &errorOutput) |
bool | parseVariableRegister (CVPOperand &operand, std::string &errorOutput) |
bool | parseWriteMask (uint &mask, std::string &errorOutput) |
void | skipSpacesAndComments () |
Private Attributes | |
const char * | _CurrChar |
uint | _LineIndex |
const char * | _LineStart |
uint | _RegisterMask [96] |
|
Definition at line 194 of file vertex_program_parse.h. Referenced by NL3D::CDriverGL::activeEXTVertexShader(), NL3D::CDriverGL::activeNVVertexProgram(), dump(), NL3D::CMeshVPPerPixelLight::initInstance(), isInputUsed(), parse(), and NL3D::CDriverGL::setupEXTVertexShader(). |
|
Debugging purpose : This output a parsed vertex program in a string, with the standard format. This can serve as a base for other format code generation Definition at line 1110 of file vertex_program_parse.cpp. References dumpInstr(), TProgram, and uint.
|
|
Definition at line 893 of file vertex_program_parse.cpp. References src, TProgram, and uint. Referenced by NL3D::CDriverGL::setupEXTVertexShader().
00894 { 00895 for(uint k = 0; k < prg.size(); ++k) 00896 { 00897 uint numSrc = prg[k].getNumUsedSrc(); 00898 for(uint l = 0; l < numSrc; ++l) 00899 { 00900 const CVPOperand &src = prg[k].getSrc(l); 00901 if (src.Type == CVPOperand::InputRegister && src.Value.InputRegisterValue == input) return true; 00902 } 00903 } 00904 return false; 00905 } |
|
Parse a vertex program, and convert to proprietary format. It is intended to be use by a driver implementation.
Definition at line 921 of file vertex_program_parse.cpp. References _CurrChar, _LineIndex, _LineStart, _RegisterMask, getStringUntilCR(), parseInstruction(), src, NLMISC::toString(), and TProgram. Referenced by NL3D::CDriverGL::activeEXTVertexShader(), NL3D::CDriverGL::activeNVVertexProgram(), and NL3D::CMeshVPPerPixelLight::initInstance().
00922 { 00923 if (!src) return false; 00924 // 00925 std::fill(_RegisterMask, _RegisterMask + 96, 0); 00926 00927 // 00928 _CurrChar = src; 00929 _LineStart = src; 00930 _LineIndex = 1; 00931 // 00932 //skipSpacesAndComments(); // in fact space are not allowed at the start of the vertex program 00933 00934 // parse version 00935 if ( _CurrChar[0] != '!' 00936 || _CurrChar[1] != '!' 00937 || _CurrChar[2] != 'V' 00938 || _CurrChar[3] != 'P' 00939 || _CurrChar[4] != '1' 00940 || _CurrChar[5] != '.' 00941 || (_CurrChar[6] != '0' && _CurrChar[6] != '1')) 00942 { 00943 errorOutput = "Can't parse version."; 00944 return false; 00945 } 00946 _CurrChar += 7; 00947 00948 errorOutput.clear(); 00949 // parse instructions 00950 bool endEncoutered = false; 00951 00952 std::string errorMess; 00953 for(;;) 00954 { 00955 CVPInstruction instr; 00956 if (!parseInstruction(instr, errorMess, endEncoutered)) 00957 { 00958 errorOutput = std::string("CVPParser::parse : Error encountered at line ") + NLMISC::toString(_LineIndex) + std::string(" : ") + errorMess + std::string(" Text : ") + getStringUntilCR(_LineStart); 00959 return false; 00960 } 00961 if (endEncoutered) break; 00962 result.push_back(instr); 00963 } 00964 return true; 00965 } |
|
Definition at line 533 of file vertex_program_parse.cpp. References _CurrChar, and CVPOperand::Type. Referenced by parseOperand().
|
|
Definition at line 442 of file vertex_program_parse.cpp. References _CurrChar, index, CVPOperand::Indexed, parseUInt(), skipSpacesAndComments(), CVPOperand::Type, uint, and CVPOperand::Value. Referenced by parseOperand().
00443 { 00444 ++_CurrChar; 00445 operand.Type = CVPOperand::Constant; 00446 if (*_CurrChar != '[') 00447 { 00448 errorOutput = "'[' expected when parsing a constant register."; 00449 return false; 00450 } 00451 ++_CurrChar; 00452 skipSpacesAndComments(); 00453 uint &index = operand.Value.ConstantValue; 00454 if (isdigit(*_CurrChar)) 00455 { 00456 // immediat case : c[0] to c[95] 00457 _CurrChar = parseUInt(_CurrChar, index); 00458 if (index > 95) 00459 { 00460 errorOutput = "Constant register index must range from 0 to 95."; 00461 return false; 00462 } 00463 operand.Indexed = false; 00464 } 00465 else if (*_CurrChar == 'A') 00466 { 00467 // indexed case : c[A0.x + 0] to c[A0.x + 95] 00468 operand.Indexed = true; 00469 index = 0; 00470 if (_CurrChar[1] == '0' 00471 && _CurrChar[2] == '.' 00472 && _CurrChar[3] == 'x') 00473 { 00474 _CurrChar += 4; 00475 skipSpacesAndComments(); 00476 if (*_CurrChar == '+') 00477 { 00478 ++ _CurrChar; 00479 skipSpacesAndComments(); 00480 if (isdigit(*_CurrChar)) 00481 { 00482 _CurrChar = parseUInt(_CurrChar, index); 00483 if (index > 95) 00484 { 00485 errorOutput = "Constant register index must range from 0 to 95."; 00486 return false; 00487 } 00488 } 00489 else 00490 { 00491 errorOutput = "Can't parse offset for constant register."; 00492 return false; 00493 } 00494 } 00495 } 00496 else 00497 { 00498 errorOutput = "Can't parse constant register index."; 00499 return false; 00500 } 00501 } 00502 skipSpacesAndComments(); 00503 if (*_CurrChar != ']') 00504 { 00505 errorOutput = "']' expected when parsing an input register."; 00506 return false; 00507 } 00508 ++_CurrChar; 00509 return true; 00510 } |
|
Definition at line 224 of file vertex_program_parse.cpp. References _CurrChar, index, skipSpacesAndComments(), CVPOperand::Type, uint, uint32, and CVPOperand::Value. Referenced by parseOperand().
00225 { 00226 ++_CurrChar; 00227 operand.Type = CVPOperand::InputRegister; 00228 if (*_CurrChar != '[') 00229 { 00230 errorOutput = "'[' expected when parsing an input register."; 00231 return false; 00232 } 00233 ++_CurrChar; 00234 skipSpacesAndComments(); 00235 if (isdigit(*_CurrChar)) 00236 { 00237 // The input register is expressed as an index 00238 uint index = *_CurrChar - '0'; 00239 ++_CurrChar; 00240 if (isdigit(*_CurrChar)) 00241 { 00242 index = 10 * index + (*_CurrChar - '0'); 00243 ++_CurrChar; 00244 } 00245 if (index > 15) 00246 { 00247 errorOutput = "Invalid index for input register, must be in [0, 15]."; 00248 return false; 00249 } 00250 operand.Value.InputRegisterValue = (CVPOperand::EInputRegister) index; 00251 } 00252 else 00253 { 00254 // The input register is expressed as a string 00255 uint32 strValue = 0; 00256 // read the 4 letters 00257 for(uint k = 0; k < 4; ++k) 00258 { 00259 if (!isalnum(*_CurrChar)) 00260 { 00261 errorOutput = "Can't parse index for input register."; 00262 return false; 00263 } 00264 strValue |= ((uint32) *_CurrChar) << (8 * (3 - k)); 00265 ++_CurrChar; 00266 } 00267 switch (strValue) 00268 { 00269 case 'OPOS': operand.Value.InputRegisterValue = CVPOperand::IPosition; break; 00270 case 'WGHT': operand.Value.InputRegisterValue = CVPOperand::IWeight; break; 00271 case 'NRML': operand.Value.InputRegisterValue = CVPOperand::INormal; break; 00272 case 'COL0': operand.Value.InputRegisterValue = CVPOperand::IPrimaryColor; break; 00273 case 'COL1': operand.Value.InputRegisterValue = CVPOperand::ISecondaryColor; break; 00274 case 'FOGC': operand.Value.InputRegisterValue = CVPOperand::IFogCoord; break; 00275 // texture argument 00276 case 'TEX0': 00277 case 'TEX1': 00278 case 'TEX2': 00279 case 'TEX3': 00280 case 'TEX4': 00281 case 'TEX5': 00282 case 'TEX6': 00283 case 'TEX7': 00284 operand.Value.InputRegisterValue = (CVPOperand::EInputRegister) (CVPOperand::ITex0 + strValue & 0xff - '0'); 00285 break; 00286 default: 00287 errorOutput = "Can't parse index for input register."; 00288 return false; 00289 } 00290 } 00291 skipSpacesAndComments(); 00292 if (*_CurrChar != ']') 00293 { 00294 errorOutput = "']' expected when parsing an input register."; 00295 return false; 00296 } 00297 ++ _CurrChar; 00298 return true; 00299 } |
|
Definition at line 714 of file vertex_program_parse.cpp. References _CurrChar, _RegisterMask, CVPInstruction::Dest, END, CVPSwizzle::isScalar(), CVPInstruction::LOG, LOG, CVPInstruction::Opcode, parseOp2(), parseOp3(), parseOp4(), skipSpacesAndComments(), CVPInstruction::Src1, CVPOperand::Swizzle, CVPOperand::Type, uint, uint32, CVPOperand::Value, and CVPOperand::WriteMask. Referenced by parse().
00715 { 00716 skipSpacesAndComments(); 00717 endEncountered = false; 00718 uint32 instrStr = 0; 00719 uint k; 00720 for(k = 0; k < 4; ++k) 00721 { 00722 if (!isalnum(*_CurrChar)) 00723 { 00724 if (k < 3) // at least 3 letter in an instruction 00725 { 00726 errorOutput = "Syntax error : can't read opcode."; 00727 return false; 00728 } 00729 else break; 00730 } 00731 instrStr |= ((uint) *_CurrChar) << (8 * (3 - k)); 00732 ++ _CurrChar; 00733 } 00734 if (k != 4) 00735 { 00736 instrStr |= (uint32) ' '; 00737 } 00738 switch (instrStr) 00739 { 00740 case 'ARL ': 00741 instr.Opcode = CVPInstruction::ARL; 00742 if (!parseOp2(instr, errorOutput)) return false; 00743 if (!instr.Src1.Swizzle.isScalar()) 00744 { 00745 errorOutput = "ARL need a scalar src value."; 00746 return false; 00747 } 00748 break; 00749 case 'RSQ ': 00750 instr.Opcode = CVPInstruction::RSQ; 00751 if (!parseOp2(instr, errorOutput)) return false; 00752 if (!instr.Src1.Swizzle.isScalar()) 00753 { 00754 errorOutput = "RSQ need a scalar src value."; 00755 return false; 00756 } 00757 break; 00758 case 'EXP ': 00759 case 'EXPP': 00760 instr.Opcode = CVPInstruction::EXPP; 00761 if (!parseOp2(instr, errorOutput)) return false; 00762 if (!instr.Src1.Swizzle.isScalar()) 00763 { 00764 errorOutput = "EXP need a scalar src value."; 00765 return false; 00766 } 00767 /* 00768 if (instr.Src1.Swizzle.Comp[0] != CVPSwizzle.W) 00769 { 00770 errorOutput = "EXPP input scalar must be w"; 00771 return false; 00772 }*/ 00773 break; 00774 case 'LOG ': 00775 instr.Opcode = CVPInstruction::LOG; 00776 if (!parseOp2(instr, errorOutput)) return false; 00777 if (!instr.Src1.Swizzle.isScalar()) 00778 { 00779 errorOutput = "LOG need a scalar src value."; 00780 return false; 00781 } 00782 /* 00783 if (instr.Src1.Swizzle.Comp[0] != CVPSwizzle.W) 00784 { 00785 errorOutput = "LOG input scalar must be w"; 00786 return false; 00787 } 00788 */ 00789 break; 00790 case 'RCP ': 00791 instr.Opcode = CVPInstruction::RCP; 00792 if (!parseOp2(instr, errorOutput)) return false; 00793 if (!instr.Src1.Swizzle.isScalar()) 00794 { 00795 errorOutput = "RCP need a scalar src value."; 00796 return false; 00797 } 00798 break; 00800 case 'MOV ': 00801 instr.Opcode = CVPInstruction::MOV; 00802 if (!parseOp2(instr, errorOutput)) return false; 00803 00804 break; 00805 case 'LIT ': 00806 instr.Opcode = CVPInstruction::LIT; 00807 if (!parseOp2(instr, errorOutput)) return false; 00808 break; 00810 case 'MAD ': 00811 instr.Opcode = CVPInstruction::MAD; 00812 if (!parseOp4(instr, errorOutput)) return false; 00813 break; 00815 case 'ADD ': 00816 instr.Opcode = CVPInstruction::ADD; 00817 if (!parseOp3(instr, errorOutput)) return false; 00818 break; 00820 case 'MUL ': 00821 instr.Opcode = CVPInstruction::MUL; 00822 if (!parseOp3(instr, errorOutput)) return false; 00823 break; 00824 case 'DP3 ': 00825 instr.Opcode = CVPInstruction::DP3; 00826 if (!parseOp3(instr, errorOutput)) return false; 00827 break; 00828 case 'DP4 ': 00829 instr.Opcode = CVPInstruction::DP4; 00830 if (!parseOp3(instr, errorOutput)) return false; 00831 break; 00832 case 'DST ': 00833 instr.Opcode = CVPInstruction::DST; 00834 if (!parseOp3(instr, errorOutput)) return false; 00835 break; 00836 case 'MIN ': 00837 instr.Opcode = CVPInstruction::MIN; 00838 if (!parseOp3(instr, errorOutput)) return false; 00839 break; 00840 case 'MAX ': 00841 instr.Opcode = CVPInstruction::MAX; 00842 if (!parseOp3(instr, errorOutput)) return false; 00843 break; 00844 case 'SLT ': 00845 instr.Opcode = CVPInstruction::SLT; 00846 if (!parseOp3(instr, errorOutput)) return false; 00847 break; 00848 case 'SGE ': 00849 instr.Opcode = CVPInstruction::SGE; 00850 if (!parseOp3(instr, errorOutput)) return false; 00851 break; 00853 case 'END ': 00854 endEncountered = true; 00855 return true; 00856 break; 00857 default: 00858 errorOutput = "Syntax error : unknow opcode."; 00859 return false; 00860 break; 00861 } 00862 00863 00864 if (instr.Dest.Type == CVPOperand::Variable) 00865 { 00866 _RegisterMask[instr.Dest.Value.VariableValue] |= instr.Dest.WriteMask; 00867 } 00868 00869 // it is not allowed to write to an adress register except for ARL 00870 if (instrStr != 'ARL ') 00871 { 00872 if (instr.Dest.Type == CVPOperand::AddressRegister) 00873 { 00874 errorOutput = "Can't write to address register."; 00875 return false; 00876 } 00877 } 00878 00879 // parse semi-colon 00880 skipSpacesAndComments(); 00881 // 00882 if (*_CurrChar != ';') 00883 { 00884 errorOutput = "';' expected."; 00885 return false; 00886 } 00887 ++_CurrChar; 00888 return true; 00889 } |
|
Definition at line 547 of file vertex_program_parse.cpp. References _CurrChar, CVPInstruction::Dest, parseOperand(), skipSpacesAndComments(), CVPInstruction::Src1, and CVPOperand::Type. Referenced by parseInstruction(), and parseOp3().
00548 { 00549 skipSpacesAndComments(); 00550 // parse ouput 00551 if (!parseOperand(instr.Dest, true, errorOutput)) return false; 00552 // Can't write in input or consant register 00553 if (instr.Dest.Type == CVPOperand::Constant || instr.Dest.Type == CVPOperand::InputRegister) 00554 { 00555 errorOutput = "Can't write to a constant or input register"; 00556 return false; 00557 } 00558 // 00559 skipSpacesAndComments(); 00560 if (*_CurrChar != ',') 00561 { 00562 errorOutput = "',' expected."; 00563 return false; 00564 } 00565 ++_CurrChar; 00566 skipSpacesAndComments(); 00567 // parse src1 00568 if (!parseOperand(instr.Src1, false, errorOutput)) return false; 00569 if (instr.Src1.Type == CVPOperand::AddressRegister 00570 || instr.Src1.Type == CVPOperand::OutputRegister) 00571 { 00572 errorOutput = "Src1 must be constant, variable, or input register."; 00573 return false; 00574 } 00575 return true; 00576 } |
|
Definition at line 579 of file vertex_program_parse.cpp. References _CurrChar, CVPOperand::Indexed, parseOp2(), parseOperand(), skipSpacesAndComments(), CVPInstruction::Src1, CVPInstruction::Src2, CVPOperand::Type, and CVPOperand::Value. Referenced by parseInstruction(), and parseOp4().
00580 { 00581 if (!parseOp2(instr, errorOutput)) return false; 00582 skipSpacesAndComments(); 00583 if (*_CurrChar != ',') 00584 { 00585 errorOutput = "',' expected."; 00586 return false; 00587 } 00588 ++_CurrChar; 00589 skipSpacesAndComments(); 00590 // parse src2 00591 if (!parseOperand(instr.Src2, false, errorOutput)) return false; 00592 if (instr.Src2.Type == CVPOperand::AddressRegister 00593 || instr.Src2.Type == CVPOperand::OutputRegister) 00594 { 00595 errorOutput = "Src2 must be constant, variable, or input register."; 00596 return false; 00597 } 00598 // make sure we do not have 2 =/= contant register as src (or in put register) 00599 00600 // 2 constant registers ? 00601 if (instr.Src1.Type == CVPOperand::Constant 00602 && instr.Src2.Type == CVPOperand::Constant) 00603 { 00604 // the index must be the same 00605 if (! 00606 ( 00607 instr.Src1.Indexed == instr.Src2.Indexed 00608 && instr.Src1.Value.ConstantValue == instr.Src2.Value.ConstantValue 00609 ) 00610 ) 00611 { 00612 errorOutput = "Can't read 2 different constant registers in a single instruction."; 00613 return false; 00614 } 00615 } 00616 00617 // 2 input registers ? 00618 if (instr.Src1.Type == CVPOperand::InputRegister 00619 && instr.Src2.Type == CVPOperand::InputRegister) 00620 { 00621 // the index must be the same 00622 if (instr.Src1.Value.InputRegisterValue != instr.Src2.Value.InputRegisterValue) 00623 { 00624 errorOutput = "Can't read 2 different input registers in a single instruction."; 00625 return false; 00626 } 00627 } 00628 return true; 00629 } |
|
Definition at line 632 of file vertex_program_parse.cpp. References _CurrChar, CVPOperand::Indexed, parseOp3(), parseOperand(), skipSpacesAndComments(), CVPInstruction::Src1, CVPInstruction::Src2, CVPInstruction::Src3, CVPOperand::Type, and CVPOperand::Value. Referenced by parseInstruction().
00633 { 00634 if (!parseOp3(instr, errorOutput)) return false; 00635 // parse src 3 00636 skipSpacesAndComments(); 00637 if (*_CurrChar != ',') 00638 { 00639 errorOutput = "',' expected."; 00640 return false; 00641 } 00642 ++_CurrChar; 00643 skipSpacesAndComments(); 00644 // parse src4 00645 if (!parseOperand(instr.Src3, false, errorOutput)) return false; 00646 if (instr.Src3.Type == CVPOperand::AddressRegister 00647 || instr.Src3.Type == CVPOperand::OutputRegister) 00648 { 00649 errorOutput = "Src3 must be constant, variable, or input register."; 00650 return false; 00651 } 00652 00654 // check for different contant / input registers // 00656 00657 // Duplicated constant register 00658 if (instr.Src3.Type == CVPOperand::Constant) 00659 { 00660 if (instr.Src1.Type == CVPOperand::Constant) 00661 { 00662 if (! 00663 ( 00664 instr.Src1.Indexed == instr.Src3.Indexed 00665 && instr.Src1.Value.ConstantValue == instr.Src3.Value.ConstantValue 00666 ) 00667 ) 00668 { 00669 errorOutput = "Can't read 2 different constant registers in a single instruction."; 00670 return false; 00671 } 00672 } 00673 if (instr.Src2.Type == CVPOperand::Constant) 00674 { 00675 if (! 00676 ( 00677 instr.Src2.Indexed == instr.Src3.Indexed 00678 && instr.Src2.Value.ConstantValue == instr.Src3.Value.ConstantValue 00679 ) 00680 ) 00681 { 00682 errorOutput = "Can't read 2 different constant registers in a single instruction."; 00683 return false; 00684 } 00685 } 00686 } 00687 00688 // Duplicated input register 00689 if (instr.Src3.Type == CVPOperand::InputRegister) 00690 { 00691 if (instr.Src1.Type == CVPOperand::InputRegister) 00692 { 00693 if (instr.Src1.Value.InputRegisterValue != instr.Src3.Value.InputRegisterValue) 00694 { 00695 errorOutput = "Can't read 2 different input registers in a single instruction."; 00696 return false; 00697 } 00698 } 00699 if (instr.Src2.Type == CVPOperand::InputRegister) 00700 { 00701 if (instr.Src2.Value.InputRegisterValue != instr.Src3.Value.InputRegisterValue) 00702 { 00703 errorOutput = "Can't read 2 different input registers in a single instruction."; 00704 return false; 00705 } 00706 } 00707 } 00708 00709 00710 return true; 00711 } |
|
Definition at line 142 of file vertex_program_parse.cpp. References _CurrChar, _RegisterMask, CVPSwizzle::Comp, CVPOperand::Negate, parseAddressRegister(), parseConstantRegister(), parseInputRegister(), parseOutputRegister(), parseSwizzle(), parseVariableRegister(), parseWriteMask(), skipSpacesAndComments(), CVPOperand::Swizzle, CVPOperand::Type, uint, CVPOperand::Value, and CVPOperand::WriteMask. Referenced by parseOp2(), parseOp3(), and parseOp4().
00143 { 00144 skipSpacesAndComments(); 00145 bool result; 00146 if (outputOperand) 00147 { 00148 operand.Negate = false; 00149 switch(*_CurrChar) 00150 { 00151 case 'o': result = parseOutputRegister(operand, errorOutput); break; 00152 case 'R': 00153 result = parseVariableRegister(operand, errorOutput); 00154 break; 00155 case 'A': result = parseAddressRegister(operand, errorOutput); break; 00156 case '-': 00157 errorOutput = "Negation not allowed on ouput register."; 00158 return false; 00159 default: 00160 errorOutput = "Output, Address, or Temporary register expected as an output operand."; 00161 return false; 00162 } 00163 if (!result) return false; 00164 00165 // parse the write mask 00166 return parseWriteMask(operand.WriteMask, errorOutput); 00167 } 00168 else 00169 { 00170 operand.Negate = false; 00171 switch(*_CurrChar) 00172 { 00173 case 'v': result = parseInputRegister(operand, errorOutput); break; 00174 case 'R': result = parseVariableRegister(operand, errorOutput); break; 00175 case 'c': result = parseConstantRegister(operand, errorOutput); break; 00176 case 'a': result = parseAddressRegister(operand, errorOutput); break; 00177 case '-': 00178 { 00179 operand.Negate = true; 00180 // negation 00181 ++ _CurrChar; 00182 skipSpacesAndComments(); 00183 switch(*_CurrChar) 00184 { 00185 case 'v': result = parseInputRegister(operand, errorOutput); break; 00186 case 'R': result = parseVariableRegister(operand, errorOutput); break; 00187 case 'c': result = parseConstantRegister(operand, errorOutput); break; 00188 default: 00189 errorOutput = "Negation must be followed by an input register, a variable register, or a constant."; 00190 return false; 00191 break; 00192 } 00193 } 00194 break; 00195 default: 00196 errorOutput = "Syntax error."; 00197 return false; 00198 break; 00199 } 00200 if (!result) return false; 00201 if (operand.Type != CVPOperand::AddressRegister) 00202 { 00203 if (!parseSwizzle(operand.Swizzle, errorOutput)) return false; 00204 if (operand.Type == CVPOperand::Variable) 00205 { 00206 for(uint k = 0; k < 4; ++k) 00207 { 00208 if (!(_RegisterMask[operand.Value.VariableValue] & (1 << operand.Swizzle.Comp[k]))) 00209 { 00210 errorOutput = "Can't read a register component before writing to it."; 00211 return false; 00212 } 00213 } 00214 } 00215 } 00216 return true; 00217 } 00218 00219 00220 } |
|
Definition at line 370 of file vertex_program_parse.cpp. References _CurrChar, skipSpacesAndComments(), CVPOperand::Type, uint, uint32, and CVPOperand::Value. Referenced by parseOperand().
00371 { 00372 ++_CurrChar; 00373 operand.Type = CVPOperand::OutputRegister; 00374 if (*_CurrChar != '[') 00375 { 00376 errorOutput = "'[' expected when parsing an ouput register."; 00377 return false; 00378 } 00379 ++_CurrChar; 00380 skipSpacesAndComments(); 00381 // The input register is expressed as a string 00382 uint32 strValue = 0; 00383 // read the 4 letters 00384 for(uint k = 0; k < 4; ++k) 00385 { 00386 if (!isalnum(*_CurrChar)) 00387 { 00388 errorOutput = "Can't parse index for output register."; 00389 return false; 00390 } 00391 strValue |= ((uint32) *_CurrChar) << (8 * (3 - k)); 00392 ++_CurrChar; 00393 } 00394 // convert to enum 00395 switch(strValue) 00396 { 00397 case 'HPOS': operand.Value.OutputRegisterValue = CVPOperand::OHPosition; break; 00398 case 'COL0': operand.Value.OutputRegisterValue = CVPOperand::OPrimaryColor; break; 00399 case 'COL1': operand.Value.OutputRegisterValue = CVPOperand::OSecondaryColor; break; 00400 case 'BFC0': operand.Value.OutputRegisterValue = CVPOperand::OBackFacePrimaryColor; break; 00401 case 'BFC1': operand.Value.OutputRegisterValue = CVPOperand::OBackFaceSecondaryColor; break; 00402 case 'FOGC': operand.Value.OutputRegisterValue = CVPOperand::OFogCoord; break; 00403 case 'PSIZ': operand.Value.OutputRegisterValue = CVPOperand::OPointSize; break; 00404 case 'TEX0': operand.Value.OutputRegisterValue = CVPOperand::OTex0; break; 00405 case 'TEX1': operand.Value.OutputRegisterValue = CVPOperand::OTex1; break; 00406 case 'TEX2': operand.Value.OutputRegisterValue = CVPOperand::OTex2; break; 00407 case 'TEX3': operand.Value.OutputRegisterValue = CVPOperand::OTex3; break; 00408 case 'TEX4': operand.Value.OutputRegisterValue = CVPOperand::OTex4; break; 00409 case 'TEX5': operand.Value.OutputRegisterValue = CVPOperand::OTex5; break; 00410 case 'TEX6': operand.Value.OutputRegisterValue = CVPOperand::OTex6; break; 00411 case 'TEX7': operand.Value.OutputRegisterValue = CVPOperand::OTex7; break; 00412 default: 00413 errorOutput = "Can't read index for output register."; 00414 return false; 00415 break; 00416 } 00417 skipSpacesAndComments(); 00418 if (*_CurrChar != ']') 00419 { 00420 errorOutput = "']' expected when parsing an output register."; 00421 return false; 00422 } 00423 ++_CurrChar; 00424 return true; 00425 } |
|
Definition at line 315 of file vertex_program_parse.cpp. References _CurrChar, CVPSwizzle::Comp, letterToSwizzleComp(), and uint. Referenced by parseOperand().
00316 { 00317 if (*_CurrChar != '.') 00318 { 00319 // no swizzle 00320 swizzle.Comp[0] = CVPSwizzle::X; 00321 swizzle.Comp[1] = CVPSwizzle::Y; 00322 swizzle.Comp[2] = CVPSwizzle::Z; 00323 swizzle.Comp[3] = CVPSwizzle::W; 00324 return true; 00325 } 00326 ++_CurrChar; 00327 // 4 letters case 00328 for(uint k = 0; k < 4; ++k) 00329 { 00330 if (!isalpha(*_CurrChar)) 00331 { 00332 if (k == 1) // 1 letter case 00333 { 00334 switch(*_CurrChar) 00335 { 00336 case ',': 00337 case ';': 00338 case ' ': 00339 case '\t': 00340 case '\r': 00341 case '\n': 00342 case '#': 00343 swizzle.Comp[1] = swizzle.Comp[2] = swizzle.Comp[3] = swizzle.Comp[0]; 00344 return true; 00345 break; 00346 default: 00347 errorOutput = "Can't parse swizzle."; 00348 00349 } 00350 } 00351 else 00352 { 00353 errorOutput = "Invalid swizzle value."; 00354 return false; 00355 } 00356 } 00357 00358 if (!letterToSwizzleComp(*_CurrChar, swizzle.Comp[k])) 00359 { 00360 errorOutput = "Invalid swizzle value."; 00361 return false; 00362 } 00363 ++ _CurrChar; 00364 } 00365 00366 return true; 00367 } |
|
Definition at line 513 of file vertex_program_parse.cpp. References _CurrChar, index, parseUInt(), CVPOperand::Type, uint, and CVPOperand::Value. Referenced by parseOperand().
00514 { 00515 ++_CurrChar; 00516 operand.Type = CVPOperand::Variable; 00517 if (!isdigit(*_CurrChar)) 00518 { 00519 errorOutput = "Can't parse variable register."; 00520 return false; 00521 } 00522 uint &index = operand.Value.VariableValue; 00523 _CurrChar = parseUInt(_CurrChar, index); 00524 if (index > 11) 00525 { 00526 errorOutput = "Variable register index must range from 0 to 11."; 00527 return false; 00528 } 00529 return true; 00530 } |
|
Definition at line 31 of file vertex_program_parse.cpp. References _CurrChar, and uint. Referenced by parseOperand().
00032 { 00033 // parse output mask 00034 if (*_CurrChar != '.') 00035 { 00036 // no output masks 00037 mask = 0xf; //output 4 coordinates 00038 return true; 00039 } 00040 else 00041 { 00042 ++ _CurrChar; 00043 mask = 0; 00044 for(uint k = 0; k < 4; ++k) 00045 { 00046 uint maskIndex; 00047 switch(*_CurrChar) 00048 { 00049 case 'x': maskIndex = 0; break; 00050 case 'y': maskIndex = 1; break; 00051 case 'z': maskIndex = 2; break; 00052 case 'w': maskIndex = 3; break; 00053 default: 00054 if (k >= 1) return true; 00055 else 00056 { 00057 errorOutput = "Can't parse output mask."; 00058 return false; 00059 } 00060 break; 00061 } 00062 ++_CurrChar; 00063 if (mask & (1 << maskIndex)) 00064 { 00065 errorOutput = "Duplicated output mask component."; 00066 return false; 00067 } 00068 mask |= 1 << maskIndex; 00069 } 00070 return true; 00071 } 00072 } |
|
Skip tabulation and space in a source code Definition at line 77 of file vertex_program_parse.cpp. References _CurrChar, _LineIndex, and _LineStart. Referenced by parseConstantRegister(), parseInputRegister(), parseInstruction(), parseOp2(), parseOp3(), parseOp4(), parseOperand(), and parseOutputRegister().
00078 { 00079 bool stop = false; 00080 do 00081 { 00082 switch(*_CurrChar) 00083 { 00084 case '\t': 00085 case '\r': 00086 case ' ' : 00087 ++_CurrChar; 00088 break; 00089 // 00090 case '\n': 00091 ++_CurrChar; 00092 ++_LineIndex; 00093 _LineStart = _CurrChar; 00094 break; 00095 case '#': // comment go till end of line 00096 while (*_CurrChar != '\n' && *_CurrChar != '\0') ++_CurrChar; 00097 skipSpacesAndComments(); 00098 break; 00099 default: 00100 stop = true; 00101 break; 00102 } 00103 } 00104 while (!stop); 00105 } |
|
Definition at line 216 of file vertex_program_parse.h. Referenced by parse(), parseAddressRegister(), parseConstantRegister(), parseInputRegister(), parseInstruction(), parseOp2(), parseOp3(), parseOp4(), parseOperand(), parseOutputRegister(), parseSwizzle(), parseVariableRegister(), parseWriteMask(), and skipSpacesAndComments(). |
|
Definition at line 218 of file vertex_program_parse.h. Referenced by parse(), and skipSpacesAndComments(). |
|
Definition at line 217 of file vertex_program_parse.h. Referenced by parse(), and skipSpacesAndComments(). |
|
Definition at line 219 of file vertex_program_parse.h. Referenced by parse(), parseInstruction(), and parseOperand(). |