back  Return to list

GL_NV_fragment_program2
homeprevnext Name
  
    NV_fragment_program2  
  
homeprevnext Name Strings
  
    GL_NV_fragment_program2  
  
homeprevnext Contact
  
    Pat Brown, NVIDIA Corporation (pbrown 'at' nvidia.com)  
    Eric Werness, NVIDIA Corporation (ewerness 'at' nvidia.com)  
  
homeprevnext Status
  
    Shipping.  
  
homeprevnext Version
  
    Last Modified:      $Date: 2004/05/17 $  
    NVIDIA Revision:    6  
  
homeprevnext Number
  
    Unassigned  
  
  
homeprevnext Dependencies
  
    ARB_fragment_program is required.  
    NV_fragment_program_option is required.  
  
homeprevnext Overview
  
    This extension, like the NV_fragment_program_option extension, provides  
    additional fragment program functionality to extend the standard  
    ARB_fragment_program language and execution environment.  ARB programs  
    wishing to use this added functionality need only add:  
  
        OPTION NV_fragment_program2;  
  
    to the beginning of their fragment programs.  
  
    New functionality provided by this extension, above and beyond that  
    already provided by the NV_fragment_program_option extension, includes:  
  
  
      * structured branching support, including data-dependent IF tests, loops  
        supporting a fixed number of iterations, and a data-dependent loop  
        exit instruction (BRK),  
  
      * subroutine calls,  
  
      * instructions to perform vector normalization, divide vector components  
        by a scalar, and perform two-component dot products (with or without a  
        scalar add),  
  
      * an instruction to perform a texture lookup with an explicit LOD,  
  
      * a loop index register for indirect access into the texture coordinate  
        attribute array, and  
  
      * a facing attribute that indicates whether the fragment is generated  
        from a front- or back-facing primitive.  
  
  
homeprevnext Issues
  
    * Should this extension expose projective forms of the LOD-modifying  
      texture instructions?  
  
        RESOLVED: No. The user can manually add a DIV instruction to achieve  
        the same effect.  
  
    * Should this extension expose precision explicitly?  
  
        RESOLVED: Only for storage using the SHORT TEMP and LONG TEMP syntax  
        (similar to NV_fragment_program_option).  
  
    * How are resources (such as registers and condition codes) scoped?  
  
        RESOLVED: All resources are globally scoped. This means that if, for  
        instance, a subroutine modifies a condition code, that modification  
        effects both the caller and the callee.  
  
    * How is the scope determined for instructions required to be within a  
      specific loop construct?  
  
        RESOLVED: The scope is determined statically at compile time. This means  
        that calling BRK and using A0 from a subroutine called within a loop is  
        a compile error.  
  
  
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  
        MAX_PROGRAM_IF_DEPTH_NV                         0x88F6  
        MAX_PROGRAM_LOOP_DEPTH_NV                       0x88F7  
        MAX_PROGRAM_LOOP_COUNT_NV                       0x88F8  
  
  
homeprevnext Additions to Chapter 2 of the OpenGL 1.2.1 Specification (OpenGL Operation)
  
    None.  
  
homeprevnext Additions to Chapter 3 of the OpenGL 1.2.1 Specification (Rasterization)
  
    Modify Section 3.11 of ARB_fragment_program (Fragment Program):  
  
    Delete the sentence referring to the lack of branching or looping.  
  
    Modify Section 3.11.2 of ARB_fragment_program (Fragment Program Grammar  
    and Restrictions):  
  
    (mostly add to existing grammar rules, as extended by  
    NV_fragment_program_option)  
      
    <optionName>            ::= "NV_fragment_program2"  
  
    <statement>             ::= <branchLabel> ":"  
  
    <instruction>           ::= <FlowInstruction>  
  
    <ALUInstruction>        ::= <VECSCAop_instruction>  
  
    <FlowInstruction>       ::= <BRAop_instruction>  
                              | <FLOWCCop_instruction>  
                              | <IFop_instruction>  
                              | <LOOPop_instruction>  
                              | <ENDFLOWop_instruction>  
  
    <VECTORop>              ::= "NRM"  
  
    <VECSCAop_instruction>  ::= <VECSCAop> <instResult> "," <instOperandV> ","   
                                <instOperandS>  
  
    <VECSCAop>              ::= "DIV"  
  
    <BINop>                 ::= "DP2"  
  
    <TRIop>                 ::= "DP2A"  
  
    <TEXop>                 ::= "TXL"  
  
    <BRAop_instruction>     ::= <BRAop> <branchLabel> <optBranchCond>  
  
    <BRAop>                 ::= "CAL"  
  
    <FLOWCCop_instruction>  ::= <FLOWCCop> <optBranchCond>  
  
    <FLOWCCop>              ::= "RET"  
                              | "BRK"  
  
    <IFop_instruction>      ::= <IFop> <ccTest>  
  
    <IFop>                  ::= "IF"  
  
    <LOOPop_instruction>    ::= <LOOPop> <instOperandV>  
  
    <LOOPop>                ::= "LOOP"  
                              | "REP"  
  
    <ENDFLOWop_instruction> ::= <ENDFLOWop>  
  
    <ENDFLOWop>             ::= "ELSE"  
                              | "ENDIF"  
                              | "ENDLOOP"  
                              | "ENDREP"  
  
    <optBranchCond>         ::= /* empty */  
                              | <ccMask>  
  
    <branchLabel>           ::= <identifier>  
  
    <attribFragBasic>       ::= "texcoord" "[" <arrayMemRel> "]"  
                              | "facing"  
  
    <arrayMemRel>           ::= <addrUseS> <arrayMemRelOffset>  
  
    <arrayMemRelOffset>     ::= /* empty */  
                              | "+" <addrRegPosOffset>  
  
    <addrRegPosOffset>      ::= <integer> from 0 to 9  
  
    <addrUseS>              ::= <addrVarName> <scalarAddrSuffix>  
  
    <scalarAddrSuffix>      ::= "." <addrComponent>  
  
    <addrComponent>         ::= "x"  
  
    Note:  This extension provides a pre-defined address register (A0) that  
    matches the <addrVarName> grammar rule and can be used as a loop counter  
    (Section 3.11.3.Y).  It is not possible to declare additional address  
    register variables.  
      
  
    Modify Section 3.11.3.1, Fragment Attributes  
  
    (add new bindings to binding table)  
  
      Fragment Attribute Binding  Components  Underlying State  
      --------------------------  ----------  ----------------------------  
      ...  
      fragment.texcoord[A0.x+n]   (s,t,r,q)   indexed texture coordinate  
      fragment.facing             (f,0,0,1)   fragment facing  
  
    If a fragment attribute binding matches "fragment.texcoord[A0.x+n]", a  
    texture coordinate number <c> is computed by adding the current value of  
    the "A0.x" address register (the loop index -- Section 3.11.3.Y) and <n>.  
    The "x", "y", "z", and "w" components of the fragment attribute variable  
    are filled with the "s", "t", "r", and "q" components, respectively, of  
    the fragment texture coordinates for texture coordinate set <c>.  If <c>  
    is negative or greater than or equal to MAX_TEXTURE_COORDS_ARB, the  
    fragment attribute variable is undefined.  
  
    If a fragment attribute binding matches "fragment.facing", the "x"  
    component of the fragment attribute variable is filled with +1.0 or -1.0,  
    depending on the orientation of the primitive producing the fragment.  If  
    the fragment is generated by a back-facing polygon (including point- and  
    line-mode polygons), the facing is -1.0; otherwise, the facing is +1.0.  
    The "y", "z", and "w" coordinates are filled with 0, 0, and 1,  
    respectively.  
  
  
    Add New Section 3.11.3.Y, Fragment Program Address Register (insert after  
    Section 3.11.3.X, Condition Code Register)  
  
    Fragment program address register variables are a set of four-component  
    signed integer vectors where only the "x" component of the address  
    registers is currently accessible.  Address registers are used as indices  
    when performing relative addressing in the "fragment.texcoord" attribute  
    array (section 3.11.3.1).  
  
    Fragment program address registers can not be declared in a fragment  
    program.  There is only a single built-in address register, "A0.x" (loop  
    index), which is available inside LOOP/ENDLOOP blocks.  A fragment program  
    that accesses A0.x outside a LOOP/ENDLOOP block will fail to load.  
  
    A0.x is initialized in by the LOOP instruction and updated by the ENDLOOP  
    instruction.  When LOOP blocks are nested, each block has its own value  
    for A0.x, but only the A0.x value for the innermost block can be used. The  
    value of A0.x is clamped to be greater than or equal to 0.  
  
      
    Modify Section 3.11.4, Fragment Program Execution Environment  
  
    (modify instruction table) There are sixty-seven fragment program  
    instructions....  
  
               Modifiers  
      Instr.   R H X C S  Inputs  Output   Description  
      -------  - - - - -  ------  ------   --------------------------------  
      ABS      X X X X X  v       v        absolute value  
      ADD      X X X X X  v,v     v        add  
      BRK      - - - - -  c       -        break out of loop instruction  
      CAL      - - - - -  c       -        subroutine call  
      CMP      - - - X X  v,v,v   v        compare  
      COS      X X - X X  s       ssss     cosine with reduction to [-PI,PI]  
      DDX      X X - X X  v       v        partial derivative relative to X  
      DDY      X X - X X  v       v        partial derivative relative to Y  
      DIV      X X - X X  v,s     v        divide vector components by scalar  
      DP2      X X X X X  v,v     ssss     2-component dot product  
      DP2A     X X X X X  v,v,v   ssss     2-comp. dot product w/scalar add  
      DP3      X X X X X  v,v     ssss     3-component dot product  
      DP4      X X X X X  v,v     ssss     4-component dot product  
      DPH      X X X X X  v,v     ssss     homogeneous dot product  
      DST      X X - X X  v,v     v        distance vector  
      ELSE     - - - - -  -       -        start if test else block  
      ENDIF    - - - - -  -       -        end if test block  
      ENDLOOP  - - - - -  -       -        end of loop block  
      ENDREP   - - - - -  -       -        end of repeat block  
      EX2      X X - X X  s       ssss     exponential base 2  
      FLR      X X X X X  v       v        floor  
      FRC      X X X X X  v       v        fraction  
      IF       - - - - -  c       -        start of if test block  
      KIL      - - - - -  v or c  v        kill fragment  
      LG2      X X - X X  s       ssss     logarithm base 2  
      LIT      X X - X X  v       v        compute light coefficients  
      LOOP     - - - - -  v       -        start of loop block          
      LRP      X X X X X  v,v,v   v        linear interpolation  
      MAD      X X X X X  v,v,v   v        multiply and add  
      MAX      X X X X X  v,v     v        maximum  
      MIN      X X X X X  v,v     v        minimum  
      MOV      X X X X X  v       v        move  
      MUL      X X X X X  v,v     v        multiply  
      NRM      X X - X X  v       v        normalize 3-component vector  
      PK2H     - - - - -  v       ssss     pack two 16-bit floats  
      PK2US    - - - - -  v       ssss     pack two unsigned 16-bit scalars  
      PK4B     - - - - -  v       ssss     pack four signed 8-bit scalars  
      PK4UB    - - - - -  v       ssss     pack four unsigned 8-bit scalars  
      POW      X X - X X  s,s     ssss     exponentiate  
      RCP      X X - X X  s       ssss     reciprocal  
      REP      - - - - -  v       -        start of repeat block  
      RET      - - - - -  c       -        subroutine return  
      RFL      X X - X X  v       v        reflection vector  
      RSQ      X X - X X  s       ssss     reciprocal square root  
      SCS      X X - X X  s       ss--     sine/cosine without reduction  
      SEQ      X X X X X  v,v     v        set on equal  
      SFL      X X X X X  v,v     v        set on false  
      SGE      X X X X X  v,v     v        set on greater than or equal  
      SGT      X X X X X  v,v     v        set on greater than  
      SIN      X X - X X  s       ssss     sine with reduction to [-PI,PI]  
      SLE      X X X X X  v,v     v        set on less than or equal  
      SLT      X X X X X  v,v     v        set on less than  
      SNE      X X X X X  v,v     v        set on not equal  
      STR      X X X X X  v,v     v        set on true  
      SUB      X X X X X  v,v     v        subtract  
      SWZ      X X - X X  v       v        extended swizzle  
      TEX      - - - X X  v       v        texture sample  
      TXB      - - - X X  v       v        texture sample with bias  
      TXD      - - - X X  v,v,v   v        texture sample w/partials        
      TXL      - - - X X  v       v        texture same w/explicit LOD  
      TXP      - - - X X  v       v        texture sample with projection  
      UP2H     - - - X X  s       v        unpack two 16-bit floats  
      UP2US    - - - X X  s       v        unpack two unsigned 16-bit scalars  
      UP4B     - - - X X  s       v        unpack four signed 8-bit scalars  
      UP4UB    - - - X X  s       v        unpack four unsigned 8-bit scalars  
      X2D      X X - X X  v,v,v   v        2D coordinate transformation  
      XPD      X X - X X  v,v     v        cross product  
  
      Table X.5:  Summary of fragment program instructions.  The columns "R",  
      "H", "X", "C", and "S" indicate whether the "R", "H", or "X" precision  
      modifiers, the C condition code update modifier, and the "_SAT"/"_SSAT"  
      saturation modifiers, respectively, are supported for the opcode.  In  
      the input/output columns, "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, "ss--"  
      indicates two scalar outputs in the first two components, and "c"  
      indicates a condition code test.  Instructions describe as "texture  
      sample" also specify a texture image unit identifier and a texture  
      target.  
  
  
    Modify Section 3.11.4.3, Fragment Program Destination Register Update  
  
    (modify saturation discussion) If the instruction opcode has the "_SAT"  
    suffix, requesting saturated result vectors, each component of the result  
    vector is clamped to the range [0,1] before updating the destination  
    register.  If the instruction opcode has the "_SSAT" suffix, requesting  
    signed saturation, each component of the result vector is clamped to the  
    range [-1,1] before updating the destination register.  
  
  
    Add Section 3.11.4.X, Fragment Program Branching (before Section 3.11.4.4,  
    Fragment Program Result Processing)  
  
    Fragment programs support a limited model of branching.  Fragment programs  
    can specify one of several types of instruction blocks: IF/ELSE/ENDIF  
    blocks, LOOP/ENDLOOP blocks, and REP/ENDREP blocks.  Examples include the  
    following:  
  
      LOOP {5, 0, 1};     # 5 iterations with loop index at 0,1,2,3,4  
      ADD R0, R0, R1;  
      ENDLOOP;  
  
      REP repCount;  
      ADD R0, R0, R1;  
      ENDREP;  
  
      MOVC CC, R0;  
      IF GT.x;  
        MOV R0, R1;  # executes if R0.x > 0  
      ELSE;  
        MOV R0, R2;  # executes if R0.x <= 0  
      ENDIF;  
  
    Instruction blocks may be nested -- for example, a LOOP block may be  
    contained inside an IF/ELSE/ENDIF block.  In all cases, each instruction  
    block must be terminated with the appropriate instruction (ENDIF for IF,  
    ENDLOOP for LOOP, ENDREP for REP).  Nested instruction blocks must be  
    wholly contained within a block -- if a LOOP instruction is found between  
    an IF and ELSE instruction, the ENDLOOP must also be present between the  
    IF and ELSE.  A fragment program will fail to load if any instruction  
    block is terminated by an incorrect instruction or is not terminated  
    before the block containing it.  
  
    IF/ELSE/ENDIF blocks evaluate a condition to determine which instructions  
    to execute.  If the condition is true, all instructions between the IF and  
    ELSE are executed.  If the condition is false, all instructions between  
    the ELSE and ENDIF are executed.  The ELSE instruction is optional.  If  
    the ELSE is omitted, all instructions between the IF and ENDIF are  
    executed if the condition is true, or skipped if the condition is false.  
    A limited amount of nesting is supported -- a fragment program will fail  
    to load if an IF instruction is nested inside MAX_PROGRAM_IF_DEPTH_NV or  
    more IF/ELSE/ENDIF blocks.  
  
    The condition of an IF test is specified by the <ccTest> 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 fragment 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)  
        CAL label1 (LT.xyzw);  # call taken  
        CAL label2 (LT.wyzw);  # call not taken  
  
    the first CAL instruction loads a condition code of (LT,EQ,GT,UN) while  
    the second CAL instruction loads a condition code of (UN,EQ,GT,UN).  The  
    first call will be made because the "x" component evaluates to LT; the  
    second call will not be made because no component evaluates to LT.  
  
    LOOP/ENDLOOP and REP/ENDREP blocks involve a loop counter that indicates  
    the number of times the instructions between the LOOP/REP and  
    ENDLOOP/ENDREP are executed.  Looping blocks have a number of significant  
    limitations.  First, the loop counter can not be computed at run time; it  
    must be specified as a program parameter.  Second, the number of loop  
    iterations is limited to the value MAX_PROGRAM_LOOP_COUNT_NV, which must  
    be at least 255.  Third, only a limited amount of nesting is supported --  
    a fragment program will fail to load if a LOOP or REP instruction is  
    nested inside MAX_PROGRAM_LOOP_DEPTH_NV or more LOOP/ENDLOOP or REP/ENDREP  
    blocks.  
  
    The BRK instruction is available to terminate a loop block early.  A BRK  
    instruction can be conditional; the condition is evaluated in the same  
    manner as the condition of an IF instruction, and the loop is terminated  
    if the condition is true.  A fragment program will fail to load if it  
    contains a BRK instruction that is not nested inside a LOOP/ENDLOOP or  
    REP/ENDREP block.  
  
    Fragment programs can contain one or more instruction labels, matching the  
    grammar rule <branchLabel>.  An instruction label can be referred to  
    explicitly in subroutine call (CAL) instructions.  Instruction labels can  
    be used at any point in the body of a program, and can be used in  
    instructions before being defined in the program string.  Instruction  
    labels can be defined anywhere in the program, except inside an  
    IF/ELSE/ENDIF, LOOP/ENDLOOP, or REP/ENDREP instruction block.  A fragment  
    program will fail to load if it contains an instruction label inside an  
    instruction block.  
  
    Fragment programs can also 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 fragment 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.  Subroutine calls may be conditional; the condition is specified by  
    the <optBranchCond> grammar rule and evaluated in the same way as the  
    condition of the IF instruction.  If no condition is specified, it is as  
    though "(TR)" were specified -- the branch is unconditional.  
  
    If a fragment 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 fragment program will  
    terminate after executing a RET instruction with an empty call stack.  A  
    fragment program will also terminate after executing the last instruction  
    in the program, unless that instruction was a taken branch.  
  
    A fragment program will fail to load if an instruction refers to a label  
    that is not defined in the program string.  
  
    A fragment program will terminate abnormally if a subroutine call  
    instruction produces a call stack overflow.  Additionally, a fragment  
    program will terminate abnormally after executing  
    MAX_PROGRAM_EXEC_INSTRUCTIONS instructions to prevent hangs caused by  
    infinite loops in the program.  
  
    When a fragment program terminates, normally or abnormally, it will emit a  
    fragment whose attributes are taken from the final values of the fragment  
    program result variables (section 3.11.3.4).  
  
  
    Add to Section 3.11.4.5 of ARB_fragment_program (Fragment Program  
    Options):  
  
    Section 3.11.4.5.3, NV_fragment_program2 Option  
  
    If a fragment program specifies the "NV_fragment_program2" option, the  
    ARB_fragment_program grammar and execution environment are extended to  
    take advantage of all the features of the "NV_fragment_program" option,  
    plus the following features:  
  
      * structured branching support, including data-dependent IF tests, loops  
        supporting a fixed number of iterations, and a data-dependent loop  
        exit instruction (BRK),  
  
      * subroutine calls,  
  
      * several new instructions:  
  
        * NRM -- vector normalization  
        * DIV -- divide vector components by a scalar  
        * DP2 -- two-component dot product  
        * DP2A -- two-component dot product with scalar add  
        * TXL -- texture lookup with explicit LOD specified  
        * IF/ELSE/ENDIF -- conditional execution blocks  
        * REP/ENDREP -- loop block  
        * LOOP/ENDLOOP -- loop block using index register  
        * BRK -- break out of loop block  
        * CAL -- subroutine call  
        * RET -- subroutine return  
  
      * a loop index register inside LOOP/ENDLOOP blocks that can be used for  
        indirect access into the texture coordinate attribute array, and  
  
      * a facing attribute that indicates whether the fragment is generated  
        from a front- or back-facing primitive.  
  
  
    Modify Section 3.11.5,  Fragment Program ALU Instruction Set  
  
    Section 3.11.5.48, DIV:  Divide (Vector Components by Scalar)  
  
    The DIV instruction divides each component of the first vector operand by  
    the second scalar operand to produce a 4-component result vector.  
  
      tmp0 = VectorLoad(op0);  
      tmp1 = ScalarLoad(op1);  
      result.x = tmp0.x / tmp1;  
      result.y = tmp0.y / tmp1;  
      result.z = tmp0.z / tmp1;  
      result.w = tmp0.w / tmp1;  
  
    This instruction may not produce results identical to a RCP/MUL  
    instruction sequence.  
  
  
    Section 3.11.5.49, DP2:  2-Component Dot Product  
  
    The DP2 instruction computes a two-component dot product of the two  
    operands (using the first two components) and replicates the dot product  
    to all four components of the result vector.  
  
      tmp0 = VectorLoad(op0);  
      tmp1 = VectorLoad(op1);  
      dot = (tmp0.x * tmp1.x) + (tmp0.y * tmp1.y);  
      result.x = dot;  
      result.y = dot;  
      result.z = dot;  
      result.w = dot;  
  
    Section 3.11.5.50, DP2A:  2-Component Dot Product w/Scalar Add  
  
    The DP2 instruction computes a two-component dot product of the two  
    operands (using the first two components), adds the x component of the  
    third operand, and replicates the result to all four components of the  
    result vector.  
  
      tmp0 = VectorLoad(op0);  
      tmp1 = VectorLoad(op1);  
      tmp2 = VectorLoad(op2);  
      dot = (tmp0.x * tmp1.x) + (tmp0.y * tmp1.y) + tmp2.x;  
      result.x = dot;  
      result.y = dot;  
      result.z = dot;  
      result.w = dot;  
  
  
    Section 3.11.5.51, NRM:  3-Component Vector Normalize  
  
    The NRM instruction normalizes the vector given by the x, y, and z  
    components of the vector operand to produce the x, y, and z components of  
    the result vector.  The w component of the result is undefined.  
  
      tmp = VectorLoad(op0);  
      scale = ApproxRSQ(tmp.x * tmp.x + tmp.y * tmp.y + tmp.z * tmp.z);  
      result.x = tmp.x * scale;  
      result.y = tmp.y * scale;  
      result.z = tmp.z * scale;  
      result.w = undefined;  
  
    Note that the normalization uses an approximate scale and may be carried  
    at lower precision than a corresponding sequence of DP3, RSQ, and MUL  
    instructions.  
  
  
    Add Section 3.11.6.6, TXL: Texture Lookup with Explicit LOD  
  
    The TXD instruction takes the x, y, and z components of the vector operand  
    and maps them to s, t, and r, respectively.  These coordinates are used to  
    sample from the specified texture target on the specified texture image  
    unit in a manner consistent with its parameters.  
  
    The level of detail is computed as specified in section 3.8.8, except that  
    log_2(rho(x,y)) is given by 2^w, where w is the w component of the vector  
    operand.  
      
    The resulting sample is mapped to RGBA as described in table 3.21   
    and written to the result vector.  
  
      tmp = VectorLoad(op0);  
      result = TextureSample(tmp.x, tmp.y, tmp.z, 0.0, op1, op2);  
  
  
    Add Section 3.11.X, Fragment Program Flow Control Instruction Set  
    (immediately after Section 3.11.6, Fragment Program Texture Instruction  
    Set)  
  
    3.11.X.1, BRK:  Break  
  
    The BRK instruction conditionally transfers control to the instruction  
    immediately following the next ENDLOOP or ENDREP instruction.  A BRK  
    instruction has no effect if the condition code test evaluates to FALSE.  
  
    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 the next ENDLOOP or  
          ENDREP;  
      }  
  
  
    3.11.X.2, CAL:  Subroutine Call  
  
    The CAL instruction conditionally transfers control to the instruction  
    following the label specified in the instruction.  A CAL instruction has  
    no effect if the condition code test evaluates to FALSE.  
  
    When executed, the CAL instruction pushes a reference to the instruction  
    immediately following the CAL instruction onto the call stack.  When a  
    matching RET instruction is executed, execution will continue at that  
    instruction after executing the matching RET instruction.    
      
    Implementations may have a limited call stack.  If the number of CAL  
    instructions that have been performed without returning is  
    MAX_PROGRAM_CALL_DEPTH_NV, a CAL instruction will cause the call stack to  
    overflow and the fragment program to terminate.  
  
    The following pseudocode describes the operation of the instruction:  
  
      if (TestCC(cc.c***) || TestCC(cc.*c**) ||   
          TestCC(cc.**c*) || TestCC(cc.***c)) {  
  
        // Check for call stack overflow.  
        if (callStackDepth >= MAX_PROGRAM_CALL_DEPTH_NV) {  
          terminate fragment program;  
        }  
  
        push instruction following the CAL instruction on the call stack;  
        continue execution at instruction following <branchLabel>;  
      }  
  
  
    3.11.X.3, ELSE:  Beginning of ELSE Block  
  
    The ELSE instruction signifies the end of the "execute if true" portion of  
    an IF/ELSE/ENDIF block.    
  
    If the condition evaluated at the IF statement was TRUE, when a program  
    reaches the ELSE statement, it has completed the entire "execute if true"  
    portion of the IF/ELSE/ENDIF block.  Execution will continue at the  
    corresponding ENDIF instruction.  
  
    If the condition evaluated at the IF statement was FALSE, program  
    execution would skip over the entire "execute if true" portion of the  
    IF/ELSE/ENDIF block, including the ELSE instruction.  
  
  
    3.11.X.4, ENDIF:  End of IF/ELSE Block  
  
    The ENDIF instruction signifies the end of an IF/ELSE/ENDIF block.  It has  
    no other effect on program execution.  
  
  
    3.11.X.5, ENDLOOP:  End of LOOP Block  
  
    The ENDLOOP instruction specifies the end of a LOOP block.  When an  
    ENDLOOP instruction executes, the loop count is decremented and the loop  
    index increment value is added to the loop index (A0.x).  If the  
    decremented loop count is greater than zero, execution continues at the  
    top of the LOOP block.  
  
      LoopCount--;  
      LoopIndex += LoopIncr;  
      if (LoopCount > 0) {  
        continue execution at instruction following corresponding LOOP  
          instruction;  
      }  
  
    3.11.X.6, ENDREP:  End of REP Block  
  
    The ENDREP instruction specifies the end of a REP block.  When an ENDREP  
    instruction executes, the loop count is decremented.  If the decremented  
    loop count is greater than zero, execution continues at the top of the REP  
    block.  
  
      LoopCount--;  
      if (LoopCount > 0) {  
        continue execution at instruction following corresponding LOOP  
          instruction;  
      }  
  
  
    3.11.X.7, IF:  Beginning of IF Block  
  
    The IF instruction conditionally transfers control to the instruction  
    immediately following the corresponding ELSE instruction (if present) or  
    ENDIF instruction (if no ELSE is present).  
  
    Implementations may have a limited ability to nest IF blocks at run time.  
    If the number of IF/ENDIF blocks that are currently active is  
    MAX_PROGRAM_IF_DEPTH_NV, an IF instruction will cause the fragment program  
    to terminate.  If an IF instruction is executed inside a subroutine, any  
    active IF/ENDIF blocks in the calling code count against this limit.  
  
      if (IF block nested too deeply) {  
        terminate fragment program;  
      }  
  
      // Evaluate the condition.  If the condition is true, continue at the  
      // next instruction.  Otherwise, continue at the   
      if (TestCC(cc.c***) || TestCC(cc.*c**) ||   
          TestCC(cc.**c*) || TestCC(cc.***c)) {  
        continue execution at the next instruction;  
      } else if (IF block contains an ELSE statement) {  
        continue execution at instruction following corresponding ELSE;  
      } else {  
        continue execution at instruction following corresponding ENDIF;  
      }  
  
  
    3.11.X.8, LOOP:  Beginning of LOOP Block  
  
    The LOOP instruction begins a LOOP block.  The x, y, and z components of  
    the single vector operand specify the initial values for the loop count,  
    loop index, and loop index increment, respectively.  
  
    The loop count indicates the number of times the instructions between the  
    LOOP and corresponding ENDLOOP instruction will be executed.  If the  
    initial value of the loop count is not positive, the entire block is  
    skipped and execution continues at the corresponding ENDLOOP instruction.  
  
    The loop index (A0.x) can be used for indirect addressing in the set of  
    texture coordinate fragment attributes.  A fragment program can only use  
    the loop index of the current LOOP block; loop indices for containing LOOP  
    blocks are not available.  
  
    Implementations may have a limited ability to nest LOOP and REP blocks at  
    run time.  If the number of LOOP/ENDLOOP and REP/ENDREP blocks that have  
    not completed is MAX_PROGRAM_LOOP_DEPTH_NV, a LOOP instruction will cause  
    the fragment program to terminate.  If a LOOP instruction is executed  
    inside a subroutine, any active LOOP/ENDLOOP or REP/ENDREP blocks in the  
    calling code count against this limit.  
  
      if (LOOP block nested too deeply) {  
        terminate fragment program;  
      }  
  
      // Set up loop information for the new nesting level.  
      tmp = VectorLoad(op0);  
      LoopCount = floor(op0.x);  
      LoopIndex = floor(op0.y);  
      LoopIncr  = floor(op0.z);  
      if (LoopCount <= 0) {  
        continue execution at the corresponding ENDLOOP;  
      }  
  
    LOOP blocks do not support fully general branching -- a fragment program  
    will fail to load if the vector operand is not a program parameter.  
  
  
    3.11.X.9, REP:  Beginning of REP Block  
  
    The REP instruction begins a REP block.  The x component of the single  
    vector operand specifies the initial value for the loop count.  REP blocks  
    are completely identical to LOOP blocks except that they don't use the  
    loop index at all.  
  
    The loop count indicates the number of times the instructions between the  
    REP and corresponding ENDREP instruction will be executed.  If the initial  
    value of the loop count is not positive, the entire block is skipped and  
    execution continues at the instruction following the corresponding ENDREP  
    instruction.  
  
    Implementations may have a limited ability to nest LOOP and REP blocks at  
    run time.  If the number of LOOP/ENDLOOP and REP/ENDREP blocks that have  
    not completed is MAX_PROGRAM_LOOP_DEPTH_NV, a REP instruction will cause  
    the fragment program to terminate.  If a REP instruction is executed  
    inside a subroutine, any active LOOP/ENDLOOP or REP/ENDREP blocks in the  
    calling code count against this limit.  
  
      if (REP block nested too deeply) {  
        terminate fragment program;  
      }  
  
      // Set up loop information for the new nesting level.  
      tmp = VectorLoad(op0);  
      LoopCount = floor(op0.x);  
      if (LoopCount <= 0) {  
        continue execution at the corresponding ENDREP;  
      }  
  
    REP blocks do not support fully general branching -- a fragment program  
    will fail to load if the vector operand is not a program parameter.  
  
  
    3.11.X.10, RET:  Subroutine Return  
  
    The RET instruction conditionally returns from a subroutine initiated by a  
    CAL instruction.  A RET instruction has no effect if the condition code  
    test evaluates to FALSE.  
  
    When executed, the RET instruction pops a reference to the instruction  
    immediately following the corresponding CAL instruction onto the call  
    stack and continues execution at that instruction.  
  
    If a RET instruction is issued when the call stack is empty, the fragment  
    program is terminated.  
  
      if (TestCC(cc.c***) || TestCC(cc.*c**) ||   
          TestCC(cc.**c*) || TestCC(cc.***c)) {  
  
        if (callStackDepth <= 0) {  
          terminate fragment program;  
        }  
          
        pop instruction following the CAL instruction off the call stack;  
        continue execution at that instruction;  
      }  
  
  
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_fragment_program
  
    ARB_fragment_program is required.  
  
    This specification and NV_fragment_program_option are based on a modified  
    version of the grammar published in the ARB_fragment_program  
    specification.  This modified grammar includes a few structural changes to  
    better accommodate new functionality from this and other extensions, but  
    should be functionally equivalent to the ARB_fragment_program grammar.  
    See NV_fragment_program_option for details on the base grammar.  
  
homeprevnext Dependencies on NV_fragment_program2_option
  
    NV_fragment_program_option is required.  
  
    If the NV_fragment_program2 program option is specified, all the  
    functionality described in both this extension and the  
    NV_fragment_program_option specification is available.  
  
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     3.11.4.X  -  
                                                                          execution inst-  
                                                                          ruction count  
    MAX_PROGRAM_CALL_DEPTH_NV            Z+      GetProgramivARB  4       maximum program     3.11.4.X  -  
                                                                          call stack depth  
    MAX_PROGRAM_IF_DEPTH_NV              Z+      GetProgramivARB  48      maximum program     3.11.4.X  -  
                                                                          if nesting  
    MAX_PROGRAM_LOOP_DEPTH_NV            Z+      GetProgramivARB  4       maximum program     3.11.4.X  -  
                                                                          loop nesting  
    MAX_PROGRAM_LOOP_COUNT_NV            Z+      GetProgramivARB  255     maximum program     3.11.4.X  -  
                                                                          initial loop count  
  
    (add to Table X.10.  New Implementation-Dependent Values Introduced by  
     ARB_fragment_program.  Values queried by GetProgramivARB require a <pname>  
     of FRAGMENT_PROGRAM_ARB.)  
  
homeprevnext Revision History
  
    Rev.  Date      Author   Changes  
    ----  --------  -------  --------------------------------------------  
    6     05/16/04  pbrown   Documented that "A0" is a pre-defined address  
                             register variable for the purposes of the   
                             grammar, and that no other address register  
                             variables can be declared.   
  
    5     --------  pbrown   Internal pre-release revisions.  
    5     --------  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.