From 0ea5fc66924303d1bf73ba283a383e2aadee02f2 Mon Sep 17 00:00:00 2001 From: neodarz Date: Sat, 11 Aug 2018 20:21:34 +0200 Subject: Initial commit --- docs/doxygen/nel/a03717.html | 1777 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1777 insertions(+) create mode 100644 docs/doxygen/nel/a03717.html (limited to 'docs/doxygen/nel/a03717.html') diff --git a/docs/doxygen/nel/a03717.html b/docs/doxygen/nel/a03717.html new file mode 100644 index 00000000..07933653 --- /dev/null +++ b/docs/doxygen/nel/a03717.html @@ -0,0 +1,1777 @@ + + +NeL: CVPParser class Reference + + + +
+

CVPParser Class Reference

#include <vertex_program_parse.h> +

+


Detailed Description

+A vertex program parser.
Author:
Nicolas Vizerie

+Nevrax France

+
Date:
2002
+ +

+ +

+Definition at line 191 of file vertex_program_parse.h. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Public Types

typedef std::vector< CVPInstructionTProgram

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]
+


Member Typedef Documentation

+

+ + + + +
+ + +
typedef std::vector<CVPInstruction> CVPParser::TProgram +
+
+ + + + + +
+   + + +

+ +

+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().

+


Member Function Documentation

+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
void CVPParser::dump const TProgram prg,
std::string &  dest
[static]
+
+ + + + + +
+   + + +

+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. +

+

01111 {       
+01112         dest = "!!VP1.0 \n";
+01113         for(uint k = 0; k < prg.size(); ++k)
+01114         {
+01115                 std::string instr;
+01116                 dumpInstr(prg[k], instr);
+01117                 dest += instr;
+01118         }
+01119         dest +="END";
+01120 }
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
bool CVPParser::isInputUsed const TProgram prg,
CVPOperand::EInputRegister  input
[static]
+
+ + + + + +
+   + + +

+ +

+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 }
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
bool CVPParser::parse const char *  src,
TProgram result,
std::string &  errorOutput
+
+ + + + + +
+   + + +

+Parse a vertex program, and convert to proprietary format. It is intended to be use by a driver implementation.

Warning:
: Only syntax is checked. It doesn't check that a register has been initialised before use.
+
Parameters:
+ + + + +
src The input text of a vertex program, in OpenGL format.
result The result program.
errorOuput If parsing failed, contains the reason
+
+
Returns:
true if the parsing succeeded
+ +

+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 }
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
bool CVPParser::parseAddressRegister CVPOperand operand,
std::string &  errorOutput
[private]
+
+ + + + + +
+   + + +

+ +

+Definition at line 533 of file vertex_program_parse.cpp. +

+References _CurrChar, and CVPOperand::Type. +

+Referenced by parseOperand(). +

+

00534 {
+00535         ++_CurrChar;
+00536         operand.Type = CVPOperand::AddressRegister;
+00537         if (_CurrChar[0] != '0' || _CurrChar[1] != '.' || _CurrChar[2] != 'x')
+00538         {
+00539                 errorOutput = "Can't parse address register.";
+00540                 return false;
+00541         }
+00542         _CurrChar += 3;
+00543         return true;    
+00544 }
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
bool CVPParser::parseConstantRegister CVPOperand operand,
std::string &  errorOutput
[private]
+
+ + + + + +
+   + + +

+ +

+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 }
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
bool CVPParser::parseInputRegister CVPOperand operand,
std::string &  errorOutput
[private]
+
+ + + + + +
+   + + +

+ +

+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 }
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
bool CVPParser::parseInstruction CVPInstruction instr,
std::string &  errorOutput,
bool &  endEncountered
[private]
+
+ + + + + +
+   + + +

+ +

+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 }
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
bool CVPParser::parseOp2 CVPInstruction instr,
std::string &  errorOutput
[private]
+
+ + + + + +
+   + + +

+ +

+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 }
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
bool CVPParser::parseOp3 CVPInstruction instr,
std::string &  errorOutput
[private]
+
+ + + + + +
+   + + +

+ +

+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 }
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
bool CVPParser::parseOp4 CVPInstruction instr,
std::string &  errorOutput
[private]
+
+ + + + + +
+   + + +

+ +

+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 }
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
bool CVPParser::parseOperand CVPOperand operand,
bool  outputOperand,
std::string &  errorOutput
[private]
+
+ + + + + +
+   + + +

+ +

+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 }
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
bool CVPParser::parseOutputRegister CVPOperand operand,
std::string &  errorOutput
[private]
+
+ + + + + +
+   + + +

+ +

+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 }
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
bool CVPParser::parseSwizzle CVPSwizzle swizzle,
std::string &  errorOutput
[private]
+
+ + + + + +
+   + + +

+ +

+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 }
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
bool CVPParser::parseVariableRegister CVPOperand operand,
std::string &  errorOutput
[private]
+
+ + + + + +
+   + + +

+ +

+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 }
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
bool CVPParser::parseWriteMask uint mask,
std::string &  errorOutput
[private]
+
+ + + + + +
+   + + +

+ +

+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 }
+
+

+ + + + +
+ + + + + + + + + +
void CVPParser::skipSpacesAndComments  )  [private]
+
+ + + + + +
+   + + +

+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 }
+
+


Field Documentation

+

+ + + + +
+ + +
const char* CVPParser::_CurrChar [private] +
+
+ + + + + +
+   + + +

+ +

+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().

+

+ + + + +
+ + +
uint CVPParser::_LineIndex [private] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 218 of file vertex_program_parse.h. +

+Referenced by parse(), and skipSpacesAndComments().

+

+ + + + +
+ + +
const char* CVPParser::_LineStart [private] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 217 of file vertex_program_parse.h. +

+Referenced by parse(), and skipSpacesAndComments().

+

+ + + + +
+ + +
uint CVPParser::_RegisterMask[96] [private] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 219 of file vertex_program_parse.h. +

+Referenced by parse(), parseInstruction(), and parseOperand().

+


The documentation for this class was generated from the following files: +
Generated on Tue Mar 16 06:43:56 2004 for NeL by + +doxygen +1.3.6
+ + -- cgit v1.2.1