#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(). |
1.3.6