back  Return to list

GL_NV_vertex_program2_option
homeprevnext Name
  
    NV_vertex_program2_option  
  
homeprevnext Name Strings
  
    GL_NV_vertex_program2_option  
  
homeprevnext Contact
  
    Pat Brown, NVIDIA Corporation (pbrown 'at' nvidia.com)  
  
homeprevnext Status
  
    Shipping.  
  
homeprevnext Version
  
    Last Modified:      05/16/2004  
    NVIDIA Revision:    2  
  
homeprevnext Number
  
    Unassigned  
  
homeprevnext Dependencies
  
    ARB_vertex_program is required.  
  
homeprevnext Overview
  
    This extension provides additional vertex program functionality  
    to extend the standard ARB_vertex_program language and execution  
    environment.  ARB programs wishing to use this added functionality  
    need only add:  
  
        OPTION NV_vertex_program2;  
  
    to the beginning of their vertex programs.  
  
    The functionality provided by this extension, which is roughly  
    equivalent to that provided by the NV_vertex_program2 extension,  
    includes:  
  
      * general purpose dynamic branching,  
  
      * subroutine calls,  
  
      * data-dependent conditional write masks,  
  
      * programmable user clip distances,  
  
      * address registers with four components (instead of just one),  
  
      * absolute value operator on scalar and swizzled operand loads,  
  
      * rudimentary address register math,  
  
      * SIN and COS trigonometry instructions, and  
  
      * fully orthogonal "set on" instructions, including a "set sign"  
        instruction.  
  
homeprevnext Issues
  
    Why is this a separate extension, rather than just an additional  
    feature of NV_vertex_program2?  
  
      RESOLVED:  The NV_vertex_program2 specification was completed  
      (with a published implementation) prior to the completion of  
      ARB_vertex_program.  Future NVIDIA vertex program extensions should  
      contain extensions to the ARB_vertex_program execution environment  
      as a standard feature.  
  
    NV_vertex_program1_1 contains one feature not found in  
    ARB_vertex_program: the "RCC" (reciprocal clamped) instruction.  
    Should a "NV_vertex_program1_1" program option be provided to expose  
    this small amount of missing functionality?  
  
      RESOLVED:  No.  By itself, that functionality is not all that  
      interesting.  
  
    Should this extension provide a mechanism to specify an "ARB"  
    version of NV_vertex_program state programs (!!VSP1.0)?  
  
      RESOLVED:  No.  
  
    Should a similar option be provided to expose ARB_vertex_program  
    features not found in NV_vertex_program (e.g., local parameters, state  
    bindings, certain "macro" instructions) under the NV_vertex_program  
    interface?  
  
      RESOLVED:  No.  Why not just write an ARB program in that case?  
  
    The ARB_vertex_program spec has a minor grammar bug that requires  
    that inline scalar constants used as scalar operands include a  
    component selector.  In other words, you have to say "11.0.x" to  
    use the constant "11.0".  What should we do here?  
  
      RESOLVED:  The NV_vertex_program2_option grammar will correct  
      this problem, which should be fixed in future revisions to the  
      ARB language.  
  
homeprevnext New Procedures and Functions
  
    None.  
  
homeprevnext New Tokens
  
    Accepted by the <pname> parameter of GetProgramivARB:  
  
        MAX_PROGRAM_EXEC_INSTRUCTIONS_NV                0x88F4  
        MAX_PROGRAM_CALL_DEPTH_NV                       0x88F5  
  
homeprevnext Additions to Chapter 2 of the OpenGL 1.4 Specification (OpenGL Operation)
  
    Modify Section 2.11, Clipping (p. 42)  
  
    (insert before the second paragraph, p. 43) In vertex program mode,  
    conventional user clipping is performed if the vertex program is  
    position-invariant (section 2.14.4.5.1).  When the vertex program  
    is not position-invariant, it can write a single floating-point clip  
    distance for each supported clip plane.  The half-space corresponding  
    to clip plane <n> is given by the set of points that satisfy the  
    inequality  
  
      c_n(P) >=0,  
  
    where c_n(P) is the value of clip distance <n> at point P.  For point  
    primitives, c_n(P) is simply the clip distance for the vertex in  
    question.  For line and triangle primitives, per-vertex clip distances  
    are interpolated using a weighted mean, with weights derived according  
    to the algorithms described in sections 3.4 and 3.5.  
  
    Modify Section 2.14.2, Vertex Program Grammar and Restrictions  
  
    (mostly add to existing grammar rules, modify a few existing grammar  
    rules -- changes marked with "***")  
  
    <optionName>            ::= "NV_vertex_program2"  
  
    <statement>             ::= <branchLabel> ":"  
  
    <instruction>           ::= <FlowInstruction>  
  
    <ALUInstruction>        ::= <ARAop_instruction>  
  
    <FlowInstruction>       ::= <BRAop_instruction>  
                              | <FLOWCCop_instruction>  
  
    <VECTORop>              ::= "SSG"  
  
    <SCALARop>              ::= "COS"  
                              | "RCC"  
                              | "SIN"  
  
    <BINop>                 ::= "SEQ"  
                              | "SFL"  
                              | "SGT"  
                              | "SLE"  
                              | "SNE"  
                              | "STR"  
  
    <ARLop>                 ::= "ARR"  
  
    <ARLop_src>             ::= <instOperandV>    
                                  (*** instead of <instOperandS>)  
  
    <ARAop_instruction>     ::= <ARAop> <instResultAddr> ","   
                                <instOperandAddrVNS>  
  
    <ARAop>                 ::= "ARA"  
  
    <BRAop_instruction>     ::= <BRAop> <branchLabel> <optBranchCond>  
  
    <BRAop>                 ::= "BRA"  
                              | "CAL"  
  
    <FLOWCCop_instruction>  ::= <FLOWCCop> <optBranchCond>  
  
    <FLOWCCop>              ::= "RET"  
  
    <optBranchCond>         ::= /* empty */  
                              | <ccMask>  
  
    <instOperandV>          ::= <instOperandAbsV>  
  
    <instOperandAbsV>       ::= <optSign> "|" <instOperandBaseV> "|"  
  
    <instOperandS>          ::= <instOperandAbsS>  
  
    <instOperandAbsS>       ::= <optSign> "|" <instOperandBaseS> "|"  
  
  
    <instOperandAddrVNS>    ::= <addrUseVNS>  
  
    <instResult>            ::= <instResultCC>  
  
    <instResultCC>          ::= <instResultBase> <ccMask>  
  
    <instResultAddr>        ::= <instResultAddrCC>  
  
    <instResultAddrCC>      ::= <instResultAddrBase> <ccMask>  
  
    <branchLabel>           ::= <identifier>  
  
    <paramUseV>             ::= <constantScalar>   
                                  (*** instead of <constantScalar>  
                                       <swizzleSuffix>)  
  
    <paramUseS>             ::= <constantScalar>   
                                  (*** instead of <constantScalar>  
                                       <scalarSuffix>)  
  
    <resultVtxBasic>        ::= "clip" "[" <clipPlaneNum> "]"  
  
    <addrUseVNS>            ::= <addrVarName>  
  
    <addrUseW>              ::= <addrVarName> <optAddrWriteMask>  
                                  (*** instead of <addrVarName>   
                                       <addrWriteMask>)  
  
    <ccMask>                ::= "(" <ccTest> ")"  
  
    <ccTest>                ::= <ccMaskRule> <swizzleSuffix>  
  
    <ccMaskRule>            ::= "EQ"  
                              | "GE"  
                              | "GT"  
                              | "LE"  
                              | "LT"  
                              | "NE"  
                              | "TR"  
                              | "FL"  
  
    <optAddrWriteMask>      ::= <optWriteMask>   
                                  (*** instead of "." "x")  
  
    <addrComponent>         ::= <xyzwComponent>   
                                  (*** instead of "x")  
  
    (modify description of reserved identifiers)  
      
    ... The following strings are reserved keywords and may not be used  
    as identifiers:  
  
        ABS, ADD, ADDRESS, ALIAS, ARA, ARL, ARR, ATTRIB, BRA, CAL, COS,  
        DP3, DP4, DPH, DST, END, EX2, EXP, FLR, FRC, LG2, LIT, LOG, MAD,  
        MAX, MIN, MOV, MUL, OPTION, OUTPUT, PARAM, POW, RCC, RCP, RET,  
        RSQ, SEQ, SFL, SGE, SGT, SIN, SLE, SLT, SNE, SUB, SSG, STR, SWZ,  
        TEMP, XPD, program, result, state, and vertex.  
  
    Add to Section 2.14.3.4, Vertex Program Results  
  
    (add to binding table)  
  
      Binding                        Components  Description  
      -----------------------------  ----------  ----------------------------  
      result.clip[n]                 (d,*,*,*)   clip plane distance  
  
    (add a paragraph before the last one) If a result variable binding  
    matches "result.clip[n]", updates to the "x" component of the result  
    variable set the clip distance for clip plane <n>.  
  
    (modify last paragraph) When in vertex program mode, all attributes  
    of a transformed vertex, except for clip distances, are undefined  
    at each vertex program invocation.  Any results, or even individual  
    components of results, that are not written to during vertex program  
    execution remain undefined.  All clip distances are initially zero,  
    and remain zero if not written by the vertex program.  
  
    Modify Section 2.14.3.5, Vertex Program Address Registers  
  
    (modify first paragraph) Vertex program address register variables are  
    a set of four-component signed integer vectors.  Address registers  
    are used as indices when performing relative addressing in program  
    parameter arrays (section 2.14.4.2).  
  
    (modify third paragraph) Vertex program address register variables are  
    undefined at each vertex program invocation.  Address registers can  
    be written by the ARA, ARL, and ARL instructions (section 2.14.5),  
    and will be read by the ARA instruction and when a program uses  
    relative addressing in program parameter arrays.  
  
    Add New Section 2.14.3.X, Condition Code Register (insert after  
    Section 2.14.3.5, Vertex Program Address Registers)  
  
    The vertex program condition code register is a single four-component  
    vector.  Each component of this register is one of four enumerated  
    values: GT (greater than), EQ (equal), LT (less than), or UN  
    (unordered).  The condition code register can be used to mask writes  
    to registers and to evaluate conditional branches.  
  
    Most vertex program instructions can optionally update the condition  
    code register.  When a vertex program instruction updates the  
    condition code register, a condition code component is set to LT if  
    the corresponding component of the result is less than zero, EQ if it  
    is equal to zero, GT if it is greater than zero, and UN if it is NaN  
    (not a number).  
  
    The condition code register is initialized to a vector of EQ values  
    each time a vertex program executes.  
  
    Modify Section 2.14.4, Vertex Program Execution Environment  
  
    (modify 3rd paragraph) Vertex programs execute a sequence of  
    instructions, with support for conditional and unconditional branches,  
    subroutine calls, and returns.  Vertex programs begin by executing  
    the instruction following the label "main".  If no label "main" is  
    defined, execution begins at the first instruction in the program.  
    Instructions are executed in the order specified in the program,  
    jumping when specified in branch instructions, until the end of the  
    program is reached.  
  
    (modify instruction table) There are forty-two vertex program  
    instructions.  Vertex program instructions may have an optional  
    suffix of "C" to allow an update of the condition code register  
    (section 2.14.3.X).  For example, there are two instructions to  
    perform vector addition, "ADD" and "ADDC".  The instructions and their  
    respective input and output parameters are summarized in Table X.5.  
  
      Instruction    Inputs  Output   Description  
      -----------    ------  ------   --------------------------------  
      ABS[C]         v       v        absolute value  
      ADD[C]         v,v     v        add  
      ARA[C]         a       a        address register add  
      ARL[C]         s       a        address register load  
      ARR[C]         v       a        address register load (round)  
      BRA            c       -        branch  
      CAL            c       -        subroutine call  
      COS[C]         s       ssss     cosine  
      DP3[C]         v,v     ssss     3-component dot product  
      DP4[C]         v,v     ssss     4-component dot product  
      DPH[C]         v,v     ssss     homogeneous dot product  
      DST[C]         v,v     v        distance vector  
      EX2[C]         s       ssss     exponential base 2  
      EXP[C]         s       v        exponential base 2 (approximate)  
      FLR[C]         v       v        floor  
      FRC[C]         v       v        fraction  
      LG2[C]         s       ssss     logarithm base 2  
      LIT[C]         v       v        compute light coefficients  
      LOG[C]         s       v        logarithm base 2 (approximate)  
      MAD[C]         v,v,v   v        multiply and add  
      MAX[C]         v,v     v        maximum  
      MIN[C]         v,v     v        minimum  
      MOV[C]         v       v        move  
      MUL[C]         v,v     v        multiply  
      POW[C]         s,s     ssss     exponentiate  
      RCC[C]         s       ssss     reciprocal (clamped)  
      RCP[C]         s       ssss     reciprocal  
      RET            c       -        subroutine return  
      RSQ[C]         s       ssss     reciprocal square root  
      SEQ[C]         v,v     v        set on equal  
      SFL[C]         v,v     v        set on false  
      SGE[C]         v,v     v        set on greater than or equal  
      SGT[C]         v,v     v        set on greater than  
      SIN[C]         s       ssss     sine  
      SLE[C]         v,v     v        set on less than or equal  
      SLT[C]         v,v     v        set on less than  
      SNE[C]         v,v     v        set on not equal  
      SSG[C]         v       v        set sign  
      STR[C]         v,v     v        set on true  
      SUB[C]         v,v     v        subtract  
      SWZ[C]         v       v        extended swizzle  
      XPD[C]         v,v     v        cross product  
  
      Table X.5:  Summary of vertex program instructions.  "[C]" indicates  
      that the opcode supports the condition code update modifier. "v"  
      indicates a floating-point vector input or output, "s" indicates  
      a floating-point scalar input, "ssss" indicates a scalar output  
      replicated across a 4-component result vector, "a" indicates a  
      vector address register, and "c" indicates a condition code test.  
  
    Modify Section 2.14.4.1, Vertex Program Operands  
  
    (add prior to the discussion of negation) A component-wise absolute  
    value operation can optionally performed on the operand if the operand  
    is surrounded with two "|" characters.  For example, "|src|" indicates  
    that a component-wise absolute value operation should be performed on  
    the variable named "src".  In terms of the grammar, this operation  
    is performed if the <instOperandV> or <instOperandS> grammar rules  
    match <instOperandAbsV> or <instOperandAbsS>, respectively.  
  
    (modify operand load pseudo-code) The following pseudo-code spells  
    out the operand generation process.  In the example, "float" is a  
    floating-point scalar type, while "floatVec" is a four-component  
    vector.  "source" refers to the register used for the operand,  
    matching the <srcReg> rule.  "abs" is TRUE if an absolute value  
    operation should be performed on the operand (<instOperandAbsV> or  
    <instOperandAbsS> rules) "negate" is TRUE if the <optionalSign> rule  
    in <scalarSrcReg> or <swizzleSrcReg> matches "-" and FALSE otherwise.  
    The ".c***", ".*c**", ".**c*", ".***c" modifiers refer to the x,  
    y, z, and w components obtained by the swizzle operation; the ".c"  
    modifier refers to the single component selected for a scalar load.  
  
      floatVec VectorLoad(floatVec source)  
      {  
          floatVec operand;  
  
          operand.x = source.c***;  
          operand.y = source.*c**;  
          operand.z = source.**c*;  
          operand.w = source.***c;  
          if (abs) {  
             operand.x = abs(operand.x);  
             operand.y = abs(operand.y);  
             operand.z = abs(operand.z);  
             operand.w = abs(operand.w);  
          }  
          if (negate) {  
             operand.x = -operand.x;  
             operand.y = -operand.y;  
             operand.z = -operand.z;  
             operand.w = -operand.w;  
          }  
  
          return operand;  
      }  
  
      float ScalarLoad(floatVec source)   
      {  
          float operand;  
  
          operand = source.c;  
          if (abs) {  
            operand = abs(operand);  
          if (negate) {  
            operand = -operand;  
          }  
  
          return operand;  
      }  
  
    Rewrite Section 2.14.4.3,  Vertex Program Destination Register Update  
  
    Most vertex program instructions write a 4-component result vector to  
    a single temporary or vertex result register.  Writes to individual  
    components of the destination register are controlled by individual  
    component write masks specified as part of the instruction.  
  
    The component write mask is specified by the <optionalMask> rule  
    found in the <maskedDstReg> rule.  If the optional mask is "",  
    all components are enabled.  Otherwise, the optional mask names  
    the individual components to enable.  The characters "x", "y",  
    "z", and "w" match the x, y, z, and w components respectively.  
    For example, an optional mask of ".xzw" indicates that the x, z,  
    and w components should be enabled for writing but the y component  
    should not.  The grammar requires that the destination register mask  
    components must be listed in "xyzw" order.  
  
    The condition code write mask is specified by the <ccMask> rule found  
    in the <instResultCC> and <instResultAddrCC> rules.  The condition  
    code register is loaded and swizzled according to the swizzle  
    codes specified by <swizzleSuffix>.  Each component of the swizzled  
    condition code is tested according to the rule given by <ccMaskRule>.  
    <ccMaskRule> may have the values "EQ", "NE", "LT", "GE", LE", or "GT",  
    which mean to enable writes if the corresponding condition code field  
    evaluates to equal, not equal, less than, greater than or equal, less  
    than or equal, or greater than, respectively.  Comparisons involving  
    condition codes of "UN" (unordered) evaluate to true for "NE" and  
    false otherwise.  For example, if the condition code is (GT,LT,EQ,GT)  
    and the condition code mask is "(NE.zyxw)", the swizzle operation  
    will load (EQ,LT,GT,GT) and the mask will thus will enable writes on  
    the y, z, and w components.  In addition, "TR" always enables writes  
    and "FL" always disables writes, regardless of the condition code.  
    If the condition code mask is empty, it is treated as "(TR)".  
  
    Each component of the destination register is updated with the result  
    of the vertex program instruction if and only if the component is  
    enabled for writes by both the component write mask and the condition  
    code write mask.  Otherwise, the component of the destination register  
    remains unchanged.  
  
    A vertex program instruction can also optionally update the condition  
    code register.  The condition code is updated if the condition  
    code register update suffix "C" is present in the instruction.  
    The instruction "ADDC" will update the condition code; the otherwise  
    equivalent instruction "ADD" will not.  If condition code updates  
    are enabled, each component of the destination register enabled  
    for writes is compared to zero.  The corresponding component of  
    the condition code is set to "LT", "EQ", or "GT", if the written  
    component is less than, equal to, or greater than zero, respectively.  
    Condition code components are set to "UN" if the written component is  
    NaN (not a number).  Values of -0.0 and +0.0 both evaluate to "EQ".  
    If a component of the destination register is not enabled for writes,  
    the corresponding condition code component is also unchanged.  
  
    In the following example code,  
  
        # R1=(-2, 0, 2, NaN)              R0                  CC  
        MOVC R0, R1;               # ( -2,  0,   2, NaN) (LT,EQ,GT,UN)  
        MOVC R0.xyz, R1.yzwx;      # (  0,  2, NaN, NaN) (EQ,GT,UN,UN)  
        MOVC R0 (NE), R1.zywx;     # (  0,  0, NaN,  -2) (EQ,EQ,UN,LT)  
  
    the first instruction writes (-2,0,2,NaN) to R0 and updates the  
    condition code to (LT,EQ,GT,UN).  The second instruction, only the  
    "x", "y", and "z" components of R0 and the condition code are updated,  
    so R0 ends up with (0,2,NaN,NaN) and the condition code ends up with  
    (EQ,GT,UN,UN).  In the third instruction, the condition code mask  
    disables writes to the x component (its condition code field is "EQ"),  
    so R0 ends up with (0,0,NaN,-2) and the condition code ends up with  
    (EQ,EQ,UN,LT).  
  
    The following pseudocode illustrates the process of writing a result  
    vector to the destination register.  In the pseudocode, "instrmask"  
    refers to the component write mask given by the <optWriteMask>  
    rule.  "ccMaskRule" refers to the condition code mask rule given  
    by <ccMask> and "updatecc" is TRUE if and only if condition code  
    updates are enabled.  "result", "destination", and "cc" refer to  
    the result vector, the register selected by <dstRegister> and the  
    condition code, respectively.  Condition codes do not exist in the  
    VP1 execution environment.  
  
      boolean TestCC(CondCode field) {  
          switch (ccMaskRule) {  
          case "EQ":  return (field == "EQ");  
          case "NE":  return (field != "EQ");  
          case "LT":  return (field == "LT");  
          case "GE":  return (field == "GT" || field == "EQ");  
          case "LE":  return (field == "LT" || field == "EQ");  
          case "GT":  return (field == "GT");  
          case "TR":  return TRUE;  
          case "FL":  return FALSE;  
          case "":    return TRUE;  
          }  
      }  
  
      enum GenerateCC(float value) {  
        if (value == NaN) {  
          return UN;  
        } else if (value < 0) {  
          return LT;  
        } else if (value == 0) {  
          return EQ;  
        } else {  
          return GT;  
        }  
      }  
  
      void UpdateDestination(floatVec destination, floatVec result)  
      {  
          floatVec merged;  
          ccVec    mergedCC;  
  
          // Merge the converted result into the destination register, under  
          // control of the compile- and run-time write masks.  
          merged = destination;  
          mergedCC = cc;  
          if (instrMask.x && TestCC(cc.c***)) {  
              merged.x = result.x;  
              if (updatecc) mergedCC.x = GenerateCC(result.x);  
          }  
          if (instrMask.y && TestCC(cc.*c**)) {  
              merged.y = result.y;  
              if (updatecc) mergedCC.y = GenerateCC(result.y);  
          }  
          if (instrMask.z && TestCC(cc.**c*)) {  
              merged.z = result.z;  
              if (updatecc) mergedCC.z = GenerateCC(result.z);  
          }  
          if (instrMask.w && TestCC(cc.***c)) {  
              merged.w = result.w;  
              if (updatecc) mergedCC.w = GenerateCC(result.w);  
          }  
  
          // Write out the new destination register and condition code.  
          destination = merged;  
          cc = mergedCC;  
      }  
  
    While this rule describes floating-point results, the same logic  
    applies to the integer results generated by the ARA, ARL, and ARR  
    instructions.  
  
    Add Section 2.14.4.X, Vertex Program Branching (before Section  
    2.14.4.4, Vertex Program Result Processing)  
  
    Vertex programs can contain one or more instruction labels, matching  
    the grammar rule <branchLabel>.  An instruction label can be referred  
    to explicitly in branch (BRA) or subroutine call (CAL) instructions.  
    Instruction labels can be defined or used at any point in the body  
    of a program, and can be used in instructions before being defined  
    in the program string.  
  
    Branching instructions can be conditional.  The branch condition  
    is specified by the <optBranchCond> grammar rule and may depend on  
    the contents of the condition code register.  Branch conditions are  
    evaluated by evaluating a condition code write mask in exactly the  
    same manner as done for register writes (section 2.14.2.2).  If any  
    of the four components of the condition code write mask are enabled,  
    the branch is taken and execution continues with the instruction  
    following the label specified in the instruction.  Otherwise, the  
    instruction is ignored and vertex program execution continues with  
    the next instruction.  In the following example code,  
  
        MOVC CC, c[0];         # c[0]=(-2, 0, 2, NaN), CC gets (LT,EQ,GT,UN)  
        BRA label1 (LT.xyzw);  
        MOV R0,R1;             # not executed  
      label1:  
        BRA label2 (LT.wyzw);  
        MOV R0,R2;             # executed  
      label2:  
  
    the first BRA instruction loads a condition code of (LT,EQ,GT,UN)  
    while the second BRA instruction loads a condition code of  
    (UN,EQ,GT,UN).  The first branch will be taken because the "x"  
    component evaluates to LT; the second branch will not be taken  
    because no component evaluates to LT.  
  
    Vertex programs can specify subroutine calls.  When a subroutine  
    call (CAL) instruction is executed, a reference to the instruction  
    immediately following the CAL instruction is pushed onto the  
    call stack.  When a subroutine return (RET) instruction is  
    executed, an instruction reference is popped off the call stack  
    and program execution continues with the popped instruction.  
    A vertex program will terminate if a CAL instruction is executed  
    with MAX_PROGRAM_CALL_DEPTH_NV entries already in the call stack or  
    if a RET instruction is executed with an empty call stack.  
  
    If a vertex program has an instruction label "main", program  
    execution begins with the instruction immediately following the  
    instruction label.  Otherwise, program execution begins with the  
    first instruction of the program.  Instructions will be executed  
    sequentially in the order specified in the program, although  
    branch instructions will affect the instruction execution order,  
    as described above.  A vertex program will terminate after executing  
    a RET instruction with an empty call stack.  A vertex program will  
    also terminate after executing the last instruction in the program,  
    unless that instruction was a taken branch.  
  
    A vertex program will fail to load if an instruction refers to a  
    label that is not defined in the program string.  
  
    A vertex program will terminate abnormally if a subroutine call  
    instruction produces a call stack overflow.  Additionally,  
    a vertex program will terminate abnormally after executing  
    MAX_PROGRAM_EXEC_INSTRUCTIONS instructions to prevent hangs caused  
    by infinite loops in the program.  
  
    When a vertex program terminates, normally or abnormally, it will  
    emit a vertex whose attributes are taken from the final values of  
    the vertex result registers (section 2.14.1.5).  
  
    Modify Section 2.14.4.4,  Vertex Program Result Processing  
  
    (modify 3rd paragraph) Transformed vertices are then assembled into  
    primitives and clipped as described in section 2.11.  Clip distance  
    results are used to control user clip planes.  
      
    Add to Section 2.14.4.5, Vertex Program Options:  
  
    Section 2.14.4.5.2, NV_vertex_program2 Option  
  
    If a vertex program specifies the "NV_vertex_program2" program option,  
    the grammar will be extended to support the features found in the  
    NV_vertex_program2 extension not present in the ARB_vertex_program  
    extension, including:  
  
      * the availability of the following instructions:    
  
          - ARA (address register add, useful for looping),   
          - ARR (address register load with round),   
          - BRA (branch),   
          - CAL (subroutine call),   
          - COS (cosine),   
          - RET (subroutine return),   
          - SEQ (set on equal),   
          - SFL (set on false),   
          - SGT (set on greater than),   
          - SIN (sine),   
          - SLE (set on less than or equal),   
          - SNE (set on not equal),   
          - SSG (set sign), and  
          - STR (set on true).  
  
      * up to MAX_CALL_DEPTH_NV levels of subroutine calls/returns,  
  
      * a four-component condition code register to hold the sign of  
        result vector components (useful for comparisons),  
  
      * a condition code update opcode suffix "C", where the results of  
        the instruction are used to update the condition code register,  
  
      * a condition code write mask operator, where the condition code  
        register is swizzled and tested, and the test results are used  
        to mask register writes,  
  
      * six clip distance result bindings that can be used to perform  
        more complicated user clipping operations than those provided  
        with the position invariant program option,  
  
      * four-component address registers (instead of one-component  
        registers in ARB_vertex_program), with the "ARL" instruction  
        extended to produce a vector result,  
  
      * an absolute value operator on scalar and swizzled operands.  
  
    The added functionality is identical to that provided by  
    NV_vertex_program2 extension specification.  
  
    Modify Section 2.14.5.3,  ARL:  Address Register Load  
  
    The ARL instruction loads a single vector operand and performs a  
    component-wise floor operation to generate a signed integer result  
    vector.  
  
      tmp = VectorLoad(op0);  
      iresult.x = floor(tmp.x);  
      iresult.y = floor(tmp.y);  
      iresult.z = floor(tmp.z);  
      iresult.w = floor(tmp.w);  
  
    The floor operation returns the largest integer less than or equal  
    to the operand.  For example floor(-1.7) = -2.0, floor(+1.0) = +1.0,  
    and floor(+3.7) = +3.0.  
  
    Note that in the unextended ARB_vertex_program specification, the ARL  
    instruction loads a scalar operand and generates a scalar result.    
  
    Add to Section 2.14.5,  Vertex Program Instruction Set  
  
    Section 2.14.5.28,  ARA:  Address Register Add  
  
    The ARA instruction adds two pairs of components of a vector address  
    register operand to produce an integer result vector.  The "x" and "z"  
    components of the result vector contain the sum of the "x" and "z"  
    components of the operand; the "y" and "w" components of the result  
    vector contain the sum of the "y" and "w" components of the operand.  
  
      itmp = AddrVectorLoad(op0);  
      iresult.x = itmp.x + itmp.z;  
      iresult.y = itmp.y + itmp.w;  
      iresult.z = itmp.x + itmp.z;  
      iresult.w = itmp.y + itmp.w;  
  
    Component swizzling is not supported when the operand is loaded.  
  
    Section 2.14.5.29,  ARR:  Address Register Load (with round)  
  
    The ARR instruction loads a single vector operand and performs a  
    component-wise round operation to generate a signed integer result  
    vector.  
  
      tmp = VectorLoad(op0);  
      iresult.x = floor(tmp.x);  
      iresult.y = floor(tmp.y);  
      iresult.z = floor(tmp.z);  
      iresult.w = floor(tmp.w);  
  
    The round operation returns the nearest integer to the operand.  
    For example round(-1.7) = -2.0, round(+1.0) = +1.0, and round(+3.7)  
    = +4.0.    
  
    Section 2.14.5.30,  BRA:  Branch  
  
    The BRA instruction conditionally transfers control to the instruction  
    following the label specified in the instruction.  The following  
    pseudocode describes the operation of the instruction:  
  
      if (TestCC(cc.c***) || TestCC(cc.*c**) ||   
          TestCC(cc.**c*) || TestCC(cc.***c)) {  
        // continue execution at instruction following <branchLabel>  
      } else {  
        // do nothing  
      }  
  
    In the pseudocode, <branchLabel> is the label specified in the  
    instruction according to the <branchLabel> grammar rule.  
  
    Section 2.14.5.31,  CAL:  Subroutine Call  
  
    The CAL instruction conditionally transfers control to the instruction  
    following the label specified in the instruction.  It also pushes a  
    reference to the instruction immediately following the CAL instruction  
    onto the call stack, where execution will continue after executing  
    the matching RET instruction.  The following pseudocode describes  
    the operation of the instruction:  
  
      if (TestCC(cc.c***) || TestCC(cc.*c**) ||   
          TestCC(cc.**c*) || TestCC(cc.***c)) {  
        if (callStackDepth >= MAX_PROGRAM_CALL_DEPTH_NV) {  
          // terminate vertex program  
        } else {  
          callStack[callStackDepth] = nextInstruction;  
          callStackDepth++;  
        }  
        // continue execution at instruction following <branchLabel>  
      } else {  
        // do nothing  
      }  
  
    In the pseudocode, <branchLabel> is the label specified in the  
    instruction matching the <branchLabel> grammar rule, <callStackDepth>  
    is the current depth of the call stack, <callStack> is an array  
    holding the call stack, and <nextInstruction> is a reference to the  
    instruction immediately following the present one in the program  
    string.  
  
    Section 2.14.5.32,  COS:  Cosine  
  
    The COS instruction approximates the cosine of the angle specified  
    by the scalar operand and replicates the approximation to all four  
    components of the result vector.  The angle is specified in radians  
    and does not have to be in the range [0,2*PI].  
  
      tmp = ScalarLoad(op0);  
      result.x = ApproxCosine(tmp);  
      result.y = ApproxCosine(tmp);  
      result.z = ApproxCosine(tmp);  
      result.w = ApproxCosine(tmp);  
  
    Section 2.14.5.33,  RCC:  Reciprocal (Clamped)  
  
    The RCC instruction approximates the reciprocal of the scalar operand,  
    clamps the result to one of two ranges, and replicates the clamped  
    result to all four components of the result vector.  
  
    If the approximated reciprocal is greater than 0.0, the result is  
    clamped to the range [2^-64, 2^+64].  If the approximate reciprocal  
    is not greater than zero, the result is clamped to the range [-2^+64,  
    -2^-64].  
  
      tmp = ScalarLoad(op0);  
      result.x = ClampApproxReciprocal(tmp);  
      result.y = ClampApproxReciprocal(tmp);  
      result.z = ClampApproxReciprocal(tmp);  
      result.w = ClampApproxReciprocal(tmp);  
  
    The following rule applies to reciprocation:  
  
      1. ApproxReciprocal(+1.0) = +1.0.  
  
    Section 2.14.5.34,  RET:  Subroutine Call Return  
  
    The RET instruction conditionally returns from a subroutine initiated  
    by a CAL instruction by popping an instruction reference off the  
    top of the call stack and transferring control to the referenced  
    instruction.  The following pseudocode describes the operation of  
    the instruction:  
  
      if (TestCC(cc.c***) || TestCC(cc.*c**) ||   
          TestCC(cc.**c*) || TestCC(cc.***c)) {  
        if (callStackDepth <= 0) {  
          // terminate vertex program  
        } else {  
          callStackDepth--;  
          instruction = callStack[callStackDepth];  
        }  
  
        // continue execution at <instruction>  
      } else {  
        // do nothing  
      }  
  
    In the pseudocode, <callStackDepth> is the depth of the call stack,  
    <callStack> is an array holding the call stack, and <instruction> is  
    a reference to an instruction previously pushed onto the call stack.  
  
    Section 2.14.5.35,  SEQ:  Set on Equal  
  
    The SEQ instruction performs a component-wise comparison of the  
    two operands.  Each component of the result vector is 1.0 if the  
    corresponding component of the first operand is equal to that of  
    the second, and 0.0 otherwise.  
  
      tmp0 = VectorLoad(op0);  
      tmp1 = VectorLoad(op1);  
      result.x = (tmp0.x == tmp1.x) ? 1.0 : 0.0;  
      result.y = (tmp0.y == tmp1.y) ? 1.0 : 0.0;  
      result.z = (tmp0.z == tmp1.z) ? 1.0 : 0.0;  
      result.w = (tmp0.w == tmp1.w) ? 1.0 : 0.0;  
  
    Section 2.14.5.36,  SFL:  Set on False  
  
    The SFL instruction is a degenerate case of the other "Set on"  
    instructions that sets all components of the result vector to 0.0.  
  
      result.x = 0.0;  
      result.y = 0.0;  
      result.z = 0.0;  
      result.w = 0.0;  
  
    Section 2.14.5.37,  SGT:  Set on Greater Than  
  
    The SGT instruction performs a component-wise comparison of the  
    two operands.  Each component of the result vector is 1.0 if the  
    corresponding component of the first operands is greater than that  
    of the second, and 0.0 otherwise.  
  
      tmp0 = VectorLoad(op0);  
      tmp1 = VectorLoad(op1);  
      result.x = (tmp0.x > tmp1.x) ? 1.0 : 0.0;  
      result.y = (tmp0.y > tmp1.y) ? 1.0 : 0.0;  
      result.z = (tmp0.z > tmp1.z) ? 1.0 : 0.0;  
      result.w = (tmp0.w > tmp1.w) ? 1.0 : 0.0;  
  
    Section 2.14.5.38,  SIN:  Sine  
  
    The SIN instruction approximates the sine of the angle specified by  
    the scalar operand and replicates it to all four components of the  
    result vector.  The angle is specified in radians and does not have  
    to be in the range [0,2*PI].  
  
      tmp = ScalarLoad(op0);  
      result.x = ApproxSine(tmp);  
      result.y = ApproxSine(tmp);  
      result.z = ApproxSine(tmp);  
      result.w = ApproxSine(tmp);  
  
    Section 2.14.5.39,  SLE:  Set on Less Than or Equal  
  
    The SLE instruction performs a component-wise comparison of the  
    two operands.  Each component of the result vector is 1.0 if the  
    corresponding component of the first operand is less than or equal  
    to that of the second, and 0.0 otherwise.  
  
      tmp0 = VectorLoad(op0);  
      tmp1 = VectorLoad(op1);  
      result.x = (tmp0.x <= tmp1.x) ? 1.0 : 0.0;  
      result.y = (tmp0.y <= tmp1.y) ? 1.0 : 0.0;  
      result.z = (tmp0.z <= tmp1.z) ? 1.0 : 0.0;  
      result.w = (tmp0.w <= tmp1.w) ? 1.0 : 0.0;  
  
    Section 2.14.5.40,  SNE:  Set on Not Equal  
  
    The SNE instruction performs a component-wise comparison of the  
    two operands.  Each component of the result vector is 1.0 if the  
    corresponding component of the first operand is not equal to that  
    of the second, and 0.0 otherwise.  
  
      tmp0 = VectorLoad(op0);  
      tmp1 = VectorLoad(op1);  
      result.x = (tmp0.x != tmp1.x) ? 1.0 : 0.0;  
      result.y = (tmp0.y != tmp1.y) ? 1.0 : 0.0;  
      result.z = (tmp0.z != tmp1.z) ? 1.0 : 0.0;  
      result.w = (tmp0.w != tmp1.w) ? 1.0 : 0.0;  
  
    Section 2.14.5.41,  SSG:  Set Sign  
  
    The SSG instruction generates a result vector containing the signs of  
    each component of the single vector operand.  Each component of the  
    result vector is 1.0 if the corresponding component of the operand  
    is greater than zero, 0.0 if the corresponding component of the  
    operand is equal to zero, and -1.0 if the corresponding component  
    of the operand is less than zero.  
  
      tmp = VectorLoad(op0);  
      result.x = SetSign(tmp.x);  
      result.y = SetSign(tmp.y);  
      result.z = SetSign(tmp.z);  
      result.w = SetSign(tmp.w);  
  
    Section 2.14.5.42,  STR:  Set on True  
  
    The STR instruction is a degenerate case of the other "Set on"  
    instructions that sets all components of the result vector to 1.0.  
  
      result.x = 1.0;  
      result.y = 1.0;  
      result.z = 1.0;  
      result.w = 1.0;  
  
homeprevnext Additions to Chapter 3 of the OpenGL 1.4 Specification (Rasterization)
  
    None.  
  
homeprevnext Additions to Chapter 4 of the OpenGL 1.4 Specification (Per-Fragment Operations and the Frame Buffer)
  
    None.  
  
homeprevnext Additions to Chapter 5 of the OpenGL 1.4 Specification (Special Functions)
  
    None.  
  
homeprevnext Additions to Chapter 6 of the OpenGL 1.4 Specification (State and State Requests)
  
    None.  
  
homeprevnext Additions to Appendix A of the OpenGL 1.4 Specification (Invariance)
  
    None.  
  
homeprevnext Additions to the AGL/GLX/WGL Specifications
  
    None.  
  
homeprevnext Dependencies on ARB_vertex_program
  
    This specification is based on a modified version of the grammar  
    published in the ARB_vertex_program specification.  This modified  
    grammar (see below) includes a few structural changes to better  
    accommodate new functionality from this and other extensions, but  
    should be functionally equivalent to the ARB_vertex_program grammar.  
  
    <program>               ::= <optionSequence> <statementSequence> "END"  
  
    <optionSequence>        ::= <optionSequence> <option>  
                              | /* empty */  
  
    <option>                ::= "OPTION" <optionName> ";"  
  
    <optionName>            ::= "ARB_position_invariant"  
  
    <statementSequence>     ::= <statement> <statementSequence>  
                              | /* empty */  
  
    <statement>             ::= <instruction> ";"  
                              | <namingStatement> ";"  
  
    <instruction>           ::= <ALUInstruction>  
  
    <ALUInstruction>        ::= <VECTORop_instruction>  
                              | <SCALARop_instruction>  
                              | <BINSCop_instruction>  
                              | <BINop_instruction>  
                              | <TRIop_instruction>  
                              | <SWZop_instruction>  
                              | <ARLop_instruction>  
  
    <VECTORop_instruction>  ::= <VECTORop> <instResult> "," <instOperandV>  
  
    <VECTORop>              ::= "ABS"  
                              | "FLR"  
                              | "FRC"  
                              | "LIT"  
                              | "MOV"  
  
    <SCALARop_instruction>  ::= <SCALARop> <instResult> "," <instOperandS>  
  
    <SCALARop>              ::= "EX2"  
                              | "EXP"  
                              | "LG2"  
                              | "LOG"  
                              | "RCP"  
                              | "RSQ"  
  
    <BINSCop_instruction>   ::= <BINSCop> <instResult> "," <instOperandS> ","   
                                <instOperandS>  
  
    <BINSCop>               ::= "POW"  
  
    <BINop_instruction>     ::= <BINop> <instResult> "," <instOperandV> ","   
                                <instOperandV>  
  
    <BINop>                 ::= "ADD"  
                              | "DP3"  
                              | "DP4"  
                              | "DPH"  
                              | "DST"  
                              | "MAX"  
                              | "MIN"  
                              | "MUL"  
                              | "SGE"  
                              | "SLT"  
                              | "SUB"  
                              | "XPD"  
  
    <TRIop_instruction>     ::= <TRIop> <instResult> "," <instOperandV> ","   
                                <instOperandV> "," <instOperandV>  
  
    <TRIop>                 ::= "MAD"  
  
    <SWZop_instruction>     ::= <SWZop> <instResult> "," <instOperandVNS> ","   
                                <extendedSwizzle>  
  
    <SWZop>                 ::= "SWZ"  
  
    <ARLop_instruction>     ::= <ARLop> <instResultAddr> "," <ARLop_src>  
  
    <ARLop>                 ::= "ARL"  
  
    <ARLop_src>             ::= <instOperandS>  
  
    <instOperandV>          ::= <instOperandBaseV>  
  
    <instOperandBaseV>      ::= <optSign> <attribUseV>  
                              | <optSign> <tempUseV>  
                              | <optSign> <paramUseV>  
  
    <instOperandS>          ::= <instOperandBaseS>  
  
    <instOperandBaseS>      ::= <optSign> <attribUseS>  
                              | <optSign> <tempUseS>  
                              | <optSign> <paramUseS>  
  
    <instOperandVNS>        ::= <attribUseVNS>  
                              | <tempUseVNS>  
                              | <paramUseVNS>  
  
    <instResult>            ::= <instResultBase>  
  
    <instResultBase>        ::= <tempUseW>  
                              | <resultUseW>  
  
    <instResultAddr>        ::= <instResultAddrBase>  
  
    <instResultAddrBase>    ::= <addrUseW>  
  
    <namingStatement>       ::= <ATTRIB_statement>  
                              | <PARAM_statement>  
                              | <TEMP_statement>  
                              | <OUTPUT_statement>  
                              | <ALIAS_statement>  
                              | <ADDRESS_statement>  
  
    <ATTRIB_statement>      ::= "ATTRIB" <establishName> "=" <attribUseD>  
  
    <PARAM_statement>       ::= <PARAM_singleStmt>  
                              | <PARAM_multipleStmt>  
  
    <PARAM_singleStmt>      ::= "PARAM" <establishName> <paramSingleInit>  
  
    <PARAM_multipleStmt>    ::= "PARAM" <establishName> "[" <optArraySize> "]"   
                                <paramMultipleInit>  
  
    <optArraySize>          ::= /* empty */  
                              | <integer> /* [1,MAX_PROGRAM_PARAMETERS_ARB]*/  
  
    <paramSingleInit>       ::= "=" <paramUseDB>  
  
    <paramMultipleInit>     ::= "=" "{" <paramMultInitList> "}"  
  
    <paramMultInitList>     ::= <paramUseDM>  
                              | <paramUseDM> "," <paramMultInitList>  
  
    <TEMP_statement>        ::= "TEMP" <varNameList>  
  
    <OUTPUT_statement>      ::= "OUTPUT" <establishName> "=" <resultUseD>  
  
    <ALIAS_statement>       ::= "ALIAS" <establishName> "=" <establishedName>  
  
    <establishedName>       ::= <tempVarName>  
                              | <addrVarName>  
                              | <attribVarName>  
                              | <paramArrayVarName>  
                              | <paramSingleVarName>  
                              | <resultVarName>  
  
    <ADDRESS_statement>     ::= "ADDRESS" <varNameList>  
  
    <varNameList>           ::= <establishName>  
                              | <establishName> "," <varNameList>  
  
    <establishName>         ::= <identifier>  
  
    <attribUseV>            ::= <attribBasic> <swizzleSuffix>  
                              | <attribVarName> <swizzleSuffix>  
                              | <attribColor> <swizzleSuffix>  
                              | <attribColor> "." <colorType> <swizzleSuffix>  
  
    <attribUseS>            ::= <attribBasic> <scalarSuffix>  
                              | <attribVarName> <scalarSuffix>  
                              | <attribColor> <scalarSuffix>  
                              | <attribColor> "." <colorType> <scalarSuffix>  
  
    <attribUseVNS>          ::= <attribBasic>  
                              | <attribVarName>  
                              | <attribColor>  
                              | <attribColor> "." <colorType>  
  
    <attribUseD>            ::= <attribBasic>  
                              | <attribColor>  
                              | <attribColor> "." <colorType>  
  
    <attribBasic>           ::= "vertex" "." <attribVtxBasic>  
  
    <attribVtxBasic>        ::= "position"  
                              | "weight" <vtxOptWeightNum>  
                              | "normal"  
                              | "fogcoord"  
                              | "texcoord" <optTexCoordNum>  
                              | "matrixindex" "[" <vtxWeightNum> "]"  
                              | "attrib" "[" <vtxAttribNum> "]"  
  
    <attribColor>           ::= "vertex" "." "color"  
  
    <paramUseV>             ::= <paramSingleVarName> <swizzleSuffix>  
                              | <paramArrayVarName> "[" <arrayMem> "]"   
                                <swizzleSuffix>  
                              | <stateSingleItem> <swizzleSuffix>  
                              | <programSingleItem> <swizzleSuffix>  
                              | <constantVector> <swizzleSuffix>  
                              | <constantScalar> <swizzleSuffix>  
  
    <paramUseS>             ::= <paramSingleVarName> <scalarSuffix>  
                              | <paramArrayVarName> "[" <arrayMem> "]"   
                                <scalarSuffix>  
                              | <stateSingleItem> <scalarSuffix>  
                              | <programSingleItem> <scalarSuffix>  
                              | <constantVector> <scalarSuffix>  
                              | <constantScalar> <scalarSuffix>  
  
    <paramUseVNS>           ::= <paramSingleVarName>  
                              | <paramArrayVarName> "[" <arrayMem> "]"  
                              | <stateSingleItem>  
                              | <programSingleItem>  
                              | <constantVector>  
                              | <constantScalar>  
  
    <paramUseDB>            ::= <stateSingleItem>  
                              | <programSingleItem>  
                              | <constantVector>  
                              | <signedConstantScalar>  
  
    <paramUseDM>            ::= <stateMultipleItem>  
                              | <programMultipleItem>  
                              | <constantVector>  
                              | <signedConstantScalar>  
  
    <stateMultipleItem>     ::= <stateSingleItem>  
                              | "state" "." <stateMatrixRows>  
  
    <stateSingleItem>       ::= "state" "." <stateMaterialItem>  
                              | "state" "." <stateLightItem>  
                              | "state" "." <stateLightModelItem>  
                              | "state" "." <stateLightProdItem>  
                              | "state" "." <stateFogItem>  
                              | "state" "." <stateMatrixRow>  
                              | "state" "." <stateTexGenItem>  
                              | "state" "." <stateClipPlaneItem>  
                              | "state" "." <statePointItem>  
  
    <stateMaterialItem>     ::= "material" "." <stateMatProperty>  
                              | "material" "." <faceType> "."   
                                <stateMatProperty>  
  
    <stateMatProperty>      ::= "ambient"  
                              | "diffuse"  
                              | "specular"  
                              | "emission"  
                              | "shininess"  
  
    <stateLightItem>        ::= "light" "[" <stateLightNumber> "]" "."   
                                <stateLightProperty>  
  
    <stateLightProperty>    ::= "ambient"  
                              | "diffuse"  
                              | "specular"  
                              | "position"  
                              | "attenuation"  
                              | "spot" "." <stateSpotProperty>  
                              | "half"  
  
    <stateSpotProperty>     ::= "direction"  
  
    <stateLightModelItem>   ::= "lightmodel" <stateLModProperty>  
  
    <stateLModProperty>     ::= "." "ambient"  
                              | "." "scenecolor"  
                              | "." <faceType> "." "scenecolor"  
  
    <stateLightProdItem>    ::= "lightprod" "[" <stateLightNumber> "]" "."   
                                <stateLProdProperty>  
                              | "lightprod" "[" <stateLightNumber> "]" "."   
                                <faceType> "." <stateLProdProperty>  
  
    <stateLProdProperty>    ::= "ambient"  
                              | "diffuse"  
                              | "specular"  
  
    <stateLightNumber>      ::= <integer> /* [0,MAX_LIGHTS-1] */  
  
    <stateFogItem>          ::= "fog" "." <stateFogProperty>  
  
    <stateFogProperty>      ::= "color"  
                              | "params"  
  
    <stateMatrixRows>       ::= <stateMatrixItem>  
                              | <stateMatrixItem> "." <stateMatModifier>  
                              | <stateMatrixItem> "." "row" "["   
                                <stateMatrixRowNum> ".." <stateMatrixRowNum>   
                                "]"  
                              | <stateMatrixItem> "." <stateMatModifier> "."   
                                "row" "[" <stateMatrixRowNum> ".."   
                                <stateMatrixRowNum> "]"  
  
    <stateMatrixRow>        ::= <stateMatrixItem> "." "row" "["   
                                <stateMatrixRowNum> "]"  
                              | <stateMatrixItem> "." <stateMatModifier> "."   
                                "row" "[" <stateMatrixRowNum> "]"  
  
    <stateMatrixItem>       ::= "matrix" "." <stateMatrixName>  
  
    <stateMatModifier>      ::= "inverse"  
                              | "transpose"  
                              | "invtrans"  
  
    <stateMatrixName>       ::= "modelview" <stateOptModMatNum>  
                              | "projection"  
                              | "mvp"  
                              | "texture" <optTexCoordNum>  
                              | "palette" "[" <statePaletteMatNum> "]"  
                              | "program" "[" <stateProgramMatNum> "]"  
  
    <stateMatrixRowNum>     ::= <integer> /* [0,3] */  
  
    <stateOptModMatNum>     ::= /* empty */  
                              | "[" <stateModMatNum> "]"  
  
    <stateModMatNum>        ::= <integer> /*[0,MAX_VERTEX_UNITS_ARB-1]*/  
  
    <statePaletteMatNum>    ::= <integer> /*[0,MAX_PALETTE_MATRICES_ARB-1]*/  
  
    <stateProgramMatNum>    ::= <integer> /*[0,MAX_PROGRAM_MATRICES_ARB-1]*/  
  
    <stateTexGenItem>       ::= "texgen" <optTexCoordNum> "."   
                                <stateTexGenType> "." <stateTexGenCoord>  
  
    <stateTexGenType>       ::= "eye"  
                              | "object"  
  
    <stateTexGenCoord>      ::= "s"  
                              | "t"  
                              | "r"  
                              | "q"  
  
    <stateClipPlaneItem>    ::= "clip" "[" <clipPlaneNum> "]" "." "plane"  
  
    <statePointItem>        ::= "point" "." <statePointProperty>  
  
    <statePointProperty>    ::= "size"  
                              | "attenuation"  
  
    <programSingleItem>     ::= <progEnvParam>  
                              | <progLocalParam>  
  
    <programMultipleItem>   ::= <progEnvParams>  
                              | <progLocalParams>  
  
    <progEnvParams>         ::= "program" "." "env" "[" <progEnvParamNums> "]"  
  
    <progEnvParamNums>      ::= <progEnvParamNum>  
                              | <progEnvParamNum> ".." <progEnvParamNum>  
  
    <progEnvParam>          ::= "program" "." "env" "[" <progEnvParamNum> "]"  
  
    <progLocalParams>       ::= "program" "." "local" "[" <progLocalParamNums>   
                                "]"  
  
    <progLocalParamNums>    ::= <progLocalParamNum>  
                              | <progLocalParamNum> ".." <progLocalParamNum>  
  
    <progLocalParam>        ::= "program" "." "local" "[" <progLocalParamNum>   
                                "]"  
  
    <progEnvParamNum>       ::= <integer>   
                                /*[0,MAX_PROGRAM_ENV_PARAMETERS_ARB-1]*/  
  
    <progLocalParamNum>     ::= <integer>   
                                /*[0,MAX_PROGRAM_LOCAL_PARAMETERS_ARB-1]*/  
  
    <constantVector>        ::= "{" <constantVectorList> "}"  
  
    <constantVectorList>    ::= <signedConstantScalar>  
                              | <signedConstantScalar> ","   
                                <signedConstantScalar>  
                              | <signedConstantScalar> ","   
                                <signedConstantScalar> ","   
                                <signedConstantScalar>  
                              | <signedConstantScalar> ","   
                                <signedConstantScalar> ","   
                                <signedConstantScalar> ","   
                                <signedConstantScalar>  
  
    <signedConstantScalar>  ::= <optSign> <constantScalar>  
  
    <constantScalar>        ::= <floatConstant>  
  
    <floatConstant>         ::= <float>  
  
    <tempUseV>              ::= <tempVarName> <swizzleSuffix>  
  
    <tempUseS>              ::= <tempVarName> <scalarSuffix>  
  
    <tempUseVNS>            ::= <tempVarName>  
  
    <tempUseW>              ::= <tempVarName> <optWriteMask>  
  
    <resultUseW>            ::= <resultBasic> <optWriteMask>  
                              | <resultVarName> <optWriteMask>  
                              | <resultVtxColor> <optWriteMask>  
                              | <resultVtxColor> "." <colorType>   
                                <optWriteMask>  
                              | <resultVtxColor> "." <faceType> <optWriteMask>  
                              | <resultVtxColor> "." <faceType> "."   
                                <colorType> "." <optWriteMask>  
  
    <resultUseD>            ::= <resultBasic>  
                              | <resultVtxColor>  
                              | <resultVtxColor> "." <colorType>  
                              | <resultVtxColor> "." <faceType>  
                              | <resultVtxColor> "." <faceType> "."   
                                <colorType>  
  
    <resultBasic>           ::= "result" "." <resultVtxBasic>  
  
    <resultVtxBasic>        ::= "position"  
                              | "fogcoord"  
                              | "pointsize"  
                              | "texcoord" <optTexCoordNum>  
  
    <resultVtxColor>        ::= "result" "." "color"  
  
    <arrayMem>              ::= <arrayMemAbs>  
                              | <arrayMemRel>  
  
    <arrayMemRel>           ::= <addrUseS> <arrayMemRelOffset>  
  
    <arrayMemAbs>           ::= <integer>  
  
    <arrayMemRelOffset>     ::= /* empty */  
                              | "+" <integer>  
                              | "-" <integer>  
  
    <addrUseS>              ::= <addrVarName> <scalarAddrSuffix>  
  
    <addrUseW>              ::= <addrVarName> <addrWriteMask>  
  
    <addrWriteMask>         ::= "." "x"  
  
    <optWriteMask>          ::= /* empty */  
                              | <xyzwMask>  
  
    <xyzwMask>              ::= "." "x"  
                              | "." "y"  
                              | "." "xy"  
                              | "." "z"  
                              | "." "xz"  
                              | "." "yz"  
                              | "." "xyz"  
                              | "." "w"  
                              | "." "xw"  
                              | "." "yw"  
                              | "." "xyw"  
                              | "." "zw"  
                              | "." "xzw"  
                              | "." "yzw"  
                              | "." "xyzw"  
  
    <swizzleSuffix>         ::= /* empty */  
                              | "." <component>  
                              | "." <xyzwComponent> <xyzwComponent>   
                                <xyzwComponent> <xyzwComponent>  
  
    <extendedSwizzle>       ::= <extSwizComp> "," <extSwizComp> ","   
                                <extSwizComp> "," <extSwizComp>  
  
    <extSwizComp>           ::= <optSign> <xyzwExtSwizSel>  
  
    <xyzwExtSwizSel>        ::= "0"  
                              | "1"  
                              | <xyzwComponent>  
  
    <scalarAddrSuffix>      ::= "." <addrComponent>  
  
    <addrComponent>         ::= "x"  
  
    <scalarSuffix>          ::= "." <component>  
  
    <component>             ::= <xyzwComponent>  
  
    <xyzwComponent>         ::= "x"  
                              | "y"  
                              | "z"  
                              | "w"  
  
    <optSign>               ::= /* empty */  
                              | "-"  
                              | "+"  
  
    <faceType>              ::= "front"  
                              | "back"  
  
    <colorType>             ::= "primary"  
                              | "secondary"  
  
    <vtxAttribNum>          ::= <integer> /*[0,MAX_VERTEX_ATTRIBS_ARB-1]*/  
  
    <vtxOptWeightNum>       ::= /* empty */  
                              | "[" <vtxWeightNum> "]"  
  
    <vtxWeightNum>          ::= <integer> /*[0,MAX_VERTEX_UNITS_ARB-1] must be   
                                divisible by four */  
  
    <optTexCoordNum>        ::= /* empty */  
                              | "[" <texCoordNum> "]"  
  
    <texCoordNum>           ::= <integer> /*[0,MAX_TEXTURE_COORDS_ARB-1]*/  
  
    <clipPlaneNum>          ::= <integer> /*[0,MAX_CLIP_PLANES-1]*/  
  
    The <integer>, <float>, and <identifier> grammar rules match  
    integer constants, floating point constants, and identifier names  
    as described in the ARB_vertex_program specification.  The <float>  
    grammar rule here is identical to the <floatConstant> grammar rule  
    in ARB_vertex_program.  
  
    The grammar rules <tempVarName>, <addrVarName>, <attribVarName>,  
    <paramArrayVarName>, <paramSingleVarName>, <resultVarName> refer  
    to the names of temporary, address register, attribute, program  
    parameter array, program parameter, and result variables declared  
    in the program text.  
  
homeprevnext GLX Protocol
  
    None.  
  
homeprevnext Errors
  
    None.  
  
homeprevnext New State
  
    None.  
  
  
homeprevnext New Implementation Dependent State
                                                                  Min  
    Get Value                            Type    Get Command      Value   Description         Sec       Attrib  
    -----------------------------------  ----    ---------------  ------  -----------------   --------  ------  
    MAX_PROGRAM_EXEC_INSTRUCTIONS_NV     Z+      GetProgramivARB  65536   maximum program     2.14.4.4  -  
                                                                          execution inst-  
                                                                          ruction count  
    MAX_PROGRAM_CALL_DEPTH_NV            Z+      GetProgramivARB  4       maximum program     2.14.4.4  -  
                                                                          call stack depth  
  
    (add to Table X.11.  New Implementation-Dependent Values Introduced  
    by ARB_vertex_program.  Values queried by GetProgramivARB require  
    a <pname> of VERTEX_PROGRAM_ARB.)  
  
homeprevnext Revision History
  
    Rev.  Date      Author   Changes  
    ----  --------  -------  --------------------------------------------  
    2     05/16/04  pbrown   Documented terminals in modified vertex program  
                             grammar.   
  
    1     --------  pbrown   Internal pre-release revisions.  
    1     --------  pbrown   Internal pre-release revisions.  
Valid XHTML 1.1! Valid CSS! Last update: November 14, 2006.
Cette page doit être lue avec un navigateur récent respectant le standard XHTML 1.1.