15bd8deadSopenharmony_ciName
25bd8deadSopenharmony_ci
35bd8deadSopenharmony_ci    NV_vertex_program2
45bd8deadSopenharmony_ci
55bd8deadSopenharmony_ciName Strings
65bd8deadSopenharmony_ci
75bd8deadSopenharmony_ci    GL_NV_vertex_program2
85bd8deadSopenharmony_ci
95bd8deadSopenharmony_ciContact
105bd8deadSopenharmony_ci
115bd8deadSopenharmony_ci    Pat Brown, NVIDIA Corporation (pbrown 'at' nvidia.com)
125bd8deadSopenharmony_ci    Mark Kilgard, NVIDIA Corporation (mjk 'at' nvidia.com)
135bd8deadSopenharmony_ci
145bd8deadSopenharmony_ciNotice
155bd8deadSopenharmony_ci
165bd8deadSopenharmony_ci    Copyright NVIDIA Corporation, 2000-2002.
175bd8deadSopenharmony_ci
185bd8deadSopenharmony_ciIP Status
195bd8deadSopenharmony_ci
205bd8deadSopenharmony_ci    NVIDIA Proprietary.
215bd8deadSopenharmony_ci
225bd8deadSopenharmony_ciStatus
235bd8deadSopenharmony_ci
245bd8deadSopenharmony_ci    Implemented in CineFX (NV30) Emulation driver, August 2002.
255bd8deadSopenharmony_ci    Shipping in Release 40 NVIDIA driver for CineFX hardware, January 2003.
265bd8deadSopenharmony_ci
275bd8deadSopenharmony_ciVersion
285bd8deadSopenharmony_ci
295bd8deadSopenharmony_ci    Last Modified Date:  03/18/2008
305bd8deadSopenharmony_ci    NVIDIA Revision:     33
315bd8deadSopenharmony_ci
325bd8deadSopenharmony_ciNumber
335bd8deadSopenharmony_ci
345bd8deadSopenharmony_ci    287
355bd8deadSopenharmony_ci
365bd8deadSopenharmony_ciDependencies
375bd8deadSopenharmony_ci
385bd8deadSopenharmony_ci    Written based on the wording of the OpenGL 1.3 Specification and requires
395bd8deadSopenharmony_ci    OpenGL 1.3.
405bd8deadSopenharmony_ci
415bd8deadSopenharmony_ci    Written based on the wording of the NV_vertex_program extension
425bd8deadSopenharmony_ci    specification, version 1.0.
435bd8deadSopenharmony_ci
445bd8deadSopenharmony_ci    NV_vertex_program is required.
455bd8deadSopenharmony_ci
465bd8deadSopenharmony_ciOverview
475bd8deadSopenharmony_ci
485bd8deadSopenharmony_ci    This extension further enhances the concept of vertex programmability
495bd8deadSopenharmony_ci    introduced by the NV_vertex_program extension, and extended by
505bd8deadSopenharmony_ci    NV_vertex_program1_1.  These extensions create a separate vertex program
515bd8deadSopenharmony_ci    mode where the configurable vertex transformation operations in unextended
525bd8deadSopenharmony_ci    OpenGL are replaced by a user-defined program.
535bd8deadSopenharmony_ci
545bd8deadSopenharmony_ci    This extension introduces the VP2 execution environment, which extends the
555bd8deadSopenharmony_ci    VP1 execution environment introduced in NV_vertex_program.  The VP2
565bd8deadSopenharmony_ci    environment provides several language features not present in previous
575bd8deadSopenharmony_ci    vertex programming execution environments:
585bd8deadSopenharmony_ci
595bd8deadSopenharmony_ci      * Branch instructions allow a program to jump to another instruction
605bd8deadSopenharmony_ci        specified in the program.
615bd8deadSopenharmony_ci
625bd8deadSopenharmony_ci      * Branching support allows for up to four levels of subroutine
635bd8deadSopenharmony_ci        calls/returns.
645bd8deadSopenharmony_ci
655bd8deadSopenharmony_ci      * A four-component condition code register allows an application to
665bd8deadSopenharmony_ci        compute a component-wise write mask at run time and apply that mask to
675bd8deadSopenharmony_ci        register writes.  
685bd8deadSopenharmony_ci
695bd8deadSopenharmony_ci      * Conditional branches are supported, where the condition code register
705bd8deadSopenharmony_ci        is used to determine if a branch should be taken.
715bd8deadSopenharmony_ci
725bd8deadSopenharmony_ci      * Programmable user clipping is supported support (via the CLP0-CLP5
735bd8deadSopenharmony_ci        clip distance registers).  Primitives are clipped to the area where
745bd8deadSopenharmony_ci        the interpolated clip distances are greater than or equal to zero.
755bd8deadSopenharmony_ci
765bd8deadSopenharmony_ci      * Instructions can perform a component-wise absolute value operation on
775bd8deadSopenharmony_ci        any operand load.
785bd8deadSopenharmony_ci
795bd8deadSopenharmony_ci    The VP2 execution environment provides a number of new instructions, and
805bd8deadSopenharmony_ci    extends the semantics of several instructions already defined in
815bd8deadSopenharmony_ci    NV_vertex_program.
825bd8deadSopenharmony_ci
835bd8deadSopenharmony_ci      * ARR:  Operates like ARL, except that float-to-int conversion is done
845bd8deadSopenharmony_ci        by rounding.  Equivalent results could be achieved (less efficiently)
855bd8deadSopenharmony_ci        in NV_vertex program using an ADD/ARL sequence and a program parameter
865bd8deadSopenharmony_ci        holding the value 0.5.
875bd8deadSopenharmony_ci
885bd8deadSopenharmony_ci      * BRA, CAL, RET:  Branch, subroutine call, and subroutine return
895bd8deadSopenharmony_ci        instructions.
905bd8deadSopenharmony_ci
915bd8deadSopenharmony_ci      * COS, SIN:  Adds support for high-precision sine and cosine
925bd8deadSopenharmony_ci        computations.
935bd8deadSopenharmony_ci
945bd8deadSopenharmony_ci      * FLR, FRC:  Adds support for computing the floor and fractional portion
955bd8deadSopenharmony_ci        of floating-point vector components.  Equivalent results could be
965bd8deadSopenharmony_ci        achieved (less efficiently) in NV_vertex_program using the EXP
975bd8deadSopenharmony_ci        instruction to compute the fractional portion of one component at a
985bd8deadSopenharmony_ci        time.
995bd8deadSopenharmony_ci
1005bd8deadSopenharmony_ci      * EX2, LG2:  Adds support for high-precision exponentiation and
1015bd8deadSopenharmony_ci        logarithm computations.
1025bd8deadSopenharmony_ci
1035bd8deadSopenharmony_ci      * ARA:  Adds pairs of components of an address register; useful for
1045bd8deadSopenharmony_ci        looping and other operations.
1055bd8deadSopenharmony_ci
1065bd8deadSopenharmony_ci      * SEQ, SFL, SGT, SLE, SNE, STR:  Add six new "set on" instructions,
1075bd8deadSopenharmony_ci        similar to the SLT and SGE instructions defined in NV_vertex_program.
1085bd8deadSopenharmony_ci        Equivalent results could be achieved (less efficiently) in
1095bd8deadSopenharmony_ci        NV_vertex_program with multiple SLT, SGE, and arithmetic instructions.
1105bd8deadSopenharmony_ci
1115bd8deadSopenharmony_ci      * SSG:  Adds a new "set sign" operation, which produces a vector holding
1125bd8deadSopenharmony_ci        negative one for negative components, zero for components with a value
1135bd8deadSopenharmony_ci        of zero, and positive one for positive components.  Equivalent results
1145bd8deadSopenharmony_ci        could be achieved (less efficiently) in NV_vertex_program with
1155bd8deadSopenharmony_ci        multiple SLT, SGE, and arithmetic instructions.
1165bd8deadSopenharmony_ci
1175bd8deadSopenharmony_ci      * The ARL instruction is extended to operate on four components instead
1185bd8deadSopenharmony_ci        of a single component.
1195bd8deadSopenharmony_ci
1205bd8deadSopenharmony_ci      * All instructions that produce integer or floating-point result vectors
1215bd8deadSopenharmony_ci        have variants that update the condition code register based on the
1225bd8deadSopenharmony_ci        result vector.
1235bd8deadSopenharmony_ci
1245bd8deadSopenharmony_ci    This extension also raises some of the resource limitations in the
1255bd8deadSopenharmony_ci    NV_vertex_program extension.
1265bd8deadSopenharmony_ci
1275bd8deadSopenharmony_ci      * 256 program parameter registers (versus 96 in NV_vertex_program).
1285bd8deadSopenharmony_ci
1295bd8deadSopenharmony_ci      * 16 temporary registers (versus 12 in NV_vertex_program).
1305bd8deadSopenharmony_ci
1315bd8deadSopenharmony_ci      * Two four-component integer address registers (versus one
1325bd8deadSopenharmony_ci        single-component register in NV_vertex_program).
1335bd8deadSopenharmony_ci
1345bd8deadSopenharmony_ci      * 256 total vertex program instructions (versus 128 in
1355bd8deadSopenharmony_ci        NV_vertex_program).
1365bd8deadSopenharmony_ci      
1375bd8deadSopenharmony_ci      * Including loops, programs can execute up to 64K instructions.
1385bd8deadSopenharmony_ci
1395bd8deadSopenharmony_ci
1405bd8deadSopenharmony_ciIssues
1415bd8deadSopenharmony_ci
1425bd8deadSopenharmony_ci    This extension builds upon the NV_vertex_program extension.  Should this
1435bd8deadSopenharmony_ci    specification contain selected edits to the NV_vertex_program
1445bd8deadSopenharmony_ci    specification or should the specs be unified?
1455bd8deadSopenharmony_ci
1465bd8deadSopenharmony_ci      RESOLVED:  Since NV_vertex_program and NV_vertex_program2 programs share
1475bd8deadSopenharmony_ci      many features, the main section of this specification is unified and
1485bd8deadSopenharmony_ci      describes both types of programs.  Other sections containing
1495bd8deadSopenharmony_ci      NV_vertex_program features that are unchanged by this extension will not
1505bd8deadSopenharmony_ci      be edited.
1515bd8deadSopenharmony_ci
1525bd8deadSopenharmony_ci    How can a program use condition codes to avoid extra computations?
1535bd8deadSopenharmony_ci
1545bd8deadSopenharmony_ci      Consider the example of evaluating the OpenGL lighting model for a
1555bd8deadSopenharmony_ci      given light.  If the diffuse dot product is negative (roughly 1/2 the
1565bd8deadSopenharmony_ci      time for random geometry), the only contribution to the light is
1575bd8deadSopenharmony_ci      ambient.  In this case, condition codes and branching can skip over a
1585bd8deadSopenharmony_ci      number of unneeded instructions.
1595bd8deadSopenharmony_ci      
1605bd8deadSopenharmony_ci          # R0 holds accumulated light color
1615bd8deadSopenharmony_ci          # R2 holds normal
1625bd8deadSopenharmony_ci          # R3 holds computed light vector
1635bd8deadSopenharmony_ci          # R4 holds computed half vector
1645bd8deadSopenharmony_ci          # c[0] holds ambient light/material product
1655bd8deadSopenharmony_ci          # c[1] holds diffuse light/material product
1665bd8deadSopenharmony_ci          # c[2].xyz holds specular light/material product
1675bd8deadSopenharmony_ci          # c[2].w   holds specular exponent
1685bd8deadSopenharmony_ci          DP3C R1.x, R2, R3;            # diffuse dot product
1695bd8deadSopenharmony_ci          ADD  R0, R0, c[0];            # accumulate ambient
1705bd8deadSopenharmony_ci          BRA  pointsAway (LT.x)        # skip rest if diffuse dot < 0
1715bd8deadSopenharmony_ci          MOV  R1.w, c[2].w;
1725bd8deadSopenharmony_ci          DP3  R1.y, R2, R4;            # specular dot product
1735bd8deadSopenharmony_ci          LIT  R1, R1;                  # compute expontiated specular
1745bd8deadSopenharmony_ci          MAD  R4, c[1], R0.y;          # accumulate diffuse
1755bd8deadSopenharmony_ci          MAD  R4, c[2], R0.z;          # accumulate specular
1765bd8deadSopenharmony_ci        pointsAway:
1775bd8deadSopenharmony_ci          ...                           # continue execution
1785bd8deadSopenharmony_ci
1795bd8deadSopenharmony_ci    How can a program use subroutines?
1805bd8deadSopenharmony_ci
1815bd8deadSopenharmony_ci      With subroutines, a program can encapsulate a small piece of
1825bd8deadSopenharmony_ci      functionality into a subroutine and call it multiple times, as in CPU
1835bd8deadSopenharmony_ci      code.  Applications will need to identify the registers used to pass
1845bd8deadSopenharmony_ci      data to and from the subroutine.  
1855bd8deadSopenharmony_ci
1865bd8deadSopenharmony_ci      Subroutines could be used for applications like evaluating lighting
1875bd8deadSopenharmony_ci      equations for a single light.  With conditional branching and
1885bd8deadSopenharmony_ci      subroutines, a variable number of lights (which could even vary
1895bd8deadSopenharmony_ci      per-vertex) can be easily supported.
1905bd8deadSopenharmony_ci    
1915bd8deadSopenharmony_ci        accumulate:
1925bd8deadSopenharmony_ci          # R0 holds the accumulated result
1935bd8deadSopenharmony_ci          # R1 holds the value to add
1945bd8deadSopenharmony_ci          ADD R0, R1;
1955bd8deadSopenharmony_ci          RET;
1965bd8deadSopenharmony_ci
1975bd8deadSopenharmony_ci          # Compute floor(A)*B by repeated addition using a subroutine.  Yes,
1985bd8deadSopenharmony_ci          # this is a stupid example. 
1995bd8deadSopenharmony_ci          #
2005bd8deadSopenharmony_ci          # c[0] holds (A,B,0,1).
2015bd8deadSopenharmony_ci          # R0 holds the accumulated result
2025bd8deadSopenharmony_ci          # R1 holds B, the value to accumulate.
2035bd8deadSopenharmony_ci          # R2 holds the number of iterations remaining.
2045bd8deadSopenharmony_ci          MOV R0, c[0].z;               # start with zero
2055bd8deadSopenharmony_ci          MOV R1, c[0].y;
2065bd8deadSopenharmony_ci          FLRC R2.x, c[0].x;
2075bd8deadSopenharmony_ci          BRA done (LE.x);
2085bd8deadSopenharmony_ci        top:
2095bd8deadSopenharmony_ci          CAL accumulate;
2105bd8deadSopenharmony_ci          ADDC R2.x, R2.x, -c[0].w;     # decrement count
2115bd8deadSopenharmony_ci          BRA top (GT.x);
2125bd8deadSopenharmony_ci        done:
2135bd8deadSopenharmony_ci          ...
2145bd8deadSopenharmony_ci
2155bd8deadSopenharmony_ci    How can conventional OpenGL clip planes be supported in vertex programs?
2165bd8deadSopenharmony_ci
2175bd8deadSopenharmony_ci      The clip distance in the OpenGL specification can be evaluated with a
2185bd8deadSopenharmony_ci      simple DP4 instruction that writes to one of the six clip distance
2195bd8deadSopenharmony_ci      registers.  Primitives will automatically be clipped to the half-space
2205bd8deadSopenharmony_ci      where o[CLPx] >= 0, which matches the definition in the spec.
2215bd8deadSopenharmony_ci
2225bd8deadSopenharmony_ci          # R0 holds eye coordinates
2235bd8deadSopenharmony_ci          # c[0] holds eye-space clip plane coefficients
2245bd8deadSopenharmony_ci          DP4 o[CLP0].x, R0, c[0];
2255bd8deadSopenharmony_ci
2265bd8deadSopenharmony_ci      Note that the clip plane or clip distance volume corresponding to the
2275bd8deadSopenharmony_ci      o[CLPn] register used must be enabled, or no clipping will be performed.
2285bd8deadSopenharmony_ci
2295bd8deadSopenharmony_ci      The clip distance registers allow for clip distance volumes to be
2305bd8deadSopenharmony_ci      computed more-or-less arbitrarily.  To approximate clipping to a sphere
2315bd8deadSopenharmony_ci      of radius <n>, the following code can be used.
2325bd8deadSopenharmony_ci
2335bd8deadSopenharmony_ci          # R0 holds eye coordinates
2345bd8deadSopenharmony_ci          # c[0].xyz holds sphere center
2355bd8deadSopenharmony_ci          # c[0].w holds the square of the sphere radius
2365bd8deadSopenharmony_ci          SUB R1.xyz, R0, c[0];            # distance vector
2375bd8deadSopenharmony_ci          DP3 R1.w, R1, R1;                # compute distance squared
2385bd8deadSopenharmony_ci          SUB o[CLP0].x, c[0].w, R1.w;     # compute r^2 - d^2
2395bd8deadSopenharmony_ci
2405bd8deadSopenharmony_ci      Since the clip distance is interpolated linearly over a primitive, the
2415bd8deadSopenharmony_ci      clip distance evaluated at a point will represent a piecewise-linear
2425bd8deadSopenharmony_ci      approximation of the true distance.  The approximation will become
2435bd8deadSopenharmony_ci      increasingly more accurate as the primitive is tesselated more finely.
2445bd8deadSopenharmony_ci
2455bd8deadSopenharmony_ci    How can looping be achieved in vertex programs?
2465bd8deadSopenharmony_ci
2475bd8deadSopenharmony_ci      Simple loops can be achieved using a general purpose floating-point
2485bd8deadSopenharmony_ci      register component as a counter.  The following code calls a function
2495bd8deadSopenharmony_ci      named "function" <n> times, where <n> is specified in a program
2505bd8deadSopenharmony_ci      parameter register component.
2515bd8deadSopenharmony_ci
2525bd8deadSopenharmony_ci          # c[0].x holds the number of iterations to execute.
2535bd8deadSopenharmony_ci          # c[1].x holds the constant 1.0.
2545bd8deadSopenharmony_ci          MOVC R15.x, c[0].x;
2555bd8deadSopenharmony_ci        startLoop:
2565bd8deadSopenharmony_ci          CAL  function (GT.x);             # if (counter > 0) function();
2575bd8deadSopenharmony_ci          SUBC R15.x, R15.x, c[1].x;        # counter = counter - 1;
2585bd8deadSopenharmony_ci          BRA  startLoop (GT.x);            # if (counter > 0) goto start;
2595bd8deadSopenharmony_ci        endLoop:
2605bd8deadSopenharmony_ci          ...
2615bd8deadSopenharmony_ci
2625bd8deadSopenharmony_ci      More complex loops (where a separate index may be needed for indexed
2635bd8deadSopenharmony_ci      addressing into the program parameter array) can be achieved using the
2645bd8deadSopenharmony_ci      ARA instruction, which will add the x/z and y/w components of an address
2655bd8deadSopenharmony_ci      register.
2665bd8deadSopenharmony_ci
2675bd8deadSopenharmony_ci          # c[0].x holds the number of iterations to execute
2685bd8deadSopenharmony_ci          # c[0].y holds the initial index value
2695bd8deadSopenharmony_ci          # c[0].z holds the constant -1.0 (used for the iteration count)
2705bd8deadSopenharmony_ci          # c[0].w holds the index step value
2715bd8deadSopenharmony_ci          ARLC A1, c[0];
2725bd8deadSopenharmony_ci        startLoop:
2735bd8deadSopenharmony_ci          CAL  function (GT.x);             # if (counter > 0) function();
2745bd8deadSopenharmony_ci                                            # Note: A1.y can be used for
2755bd8deadSopenharmony_ci                                            # indexing in function().
2765bd8deadSopenharmony_ci          ARAC A1.xy, A1;                   # counter = counter - 1;
2775bd8deadSopenharmony_ci                                            # index += loopStep;
2785bd8deadSopenharmony_ci          BRA  startLoop (GT.x);            # if (counter > 0) goto start;
2795bd8deadSopenharmony_ci        endLoop:
2805bd8deadSopenharmony_ci          ...
2815bd8deadSopenharmony_ci          
2825bd8deadSopenharmony_ci    Should this specification add support for vertex state programs beyond the
2835bd8deadSopenharmony_ci    VP1 execution environment?
2845bd8deadSopenharmony_ci
2855bd8deadSopenharmony_ci      No.  Vertex state programs are a little-used feature of
2865bd8deadSopenharmony_ci      NV_vertex_program and don't perform particularly well.  They are still
2875bd8deadSopenharmony_ci      supported for compatibility with the original NV_vertex_program spec,
2885bd8deadSopenharmony_ci      but they will not be extended to support new features.
2895bd8deadSopenharmony_ci
2905bd8deadSopenharmony_ci    How are NaN's be handled in the "set on" instructions (SEQ, SGE, SGT, SLE,
2915bd8deadSopenharmony_ci    SLT, SNE)?  What about MIN, MAX?  SSG?  When doing condition code tests?
2925bd8deadSopenharmony_ci
2935bd8deadSopenharmony_ci      Any of these instructions involving a NaN operand will produce a NaN
2945bd8deadSopenharmony_ci      result.  This behavior differs from the NV_fragment_program extension.
2955bd8deadSopenharmony_ci      There, SEQ, SGE, SGT, SLE, and SLT will produce 0.0 if either operand is
2965bd8deadSopenharmony_ci      a NaN, and SNE will produce 1.0 if either operand is a NaN.
2975bd8deadSopenharmony_ci
2985bd8deadSopenharmony_ci      For condition code updates, NaN values will result in "UN" condition
2995bd8deadSopenharmony_ci      codes.  All conditionals using a "UN" condition code, except "TR" and
3005bd8deadSopenharmony_ci      "NE" will evaluate to false.  This behavior is identical to the
3015bd8deadSopenharmony_ci      functionality in NV_fragment_program.
3025bd8deadSopenharmony_ci
3035bd8deadSopenharmony_ci    How can the various features of this extension be used to provide skinning
3045bd8deadSopenharmony_ci    functionality similar to that in ARB_vertex_blend and ARB_matrix_palette?
3055bd8deadSopenharmony_ci    And how can that functionality be extended?
3065bd8deadSopenharmony_ci
3075bd8deadSopenharmony_ci      Assume an implementation that allows application of up to 8 matrices at
3085bd8deadSopenharmony_ci      once.  Further assume that v[12].xyzw and v[13].xyzw hold the set of 8
3095bd8deadSopenharmony_ci      weights, and v[14].xyzw and v[15].xyzw hold the set of 8 matrix indices.
3105bd8deadSopenharmony_ci      Furthermore, assume that the palette of matrices are stored/tracked at
3115bd8deadSopenharmony_ci      c[0], c[4], c[8], and so on.  As an additional optimization, an
3125bd8deadSopenharmony_ci      application can specify that fewer than 8 matrices should be applied by
3135bd8deadSopenharmony_ci      storing a negative palette index immediately after the last index is
3145bd8deadSopenharmony_ci      applied.
3155bd8deadSopenharmony_ci
3165bd8deadSopenharmony_ci      Skinning support in this example can be provided by the following code:
3175bd8deadSopenharmony_ci
3185bd8deadSopenharmony_ci          ARLC A0, v[14];                 # load 4 palette indices at once
3195bd8deadSopenharmony_ci          DP4 R1.x, c[A0.x+0], v[0];      # 1st matrix transform
3205bd8deadSopenharmony_ci          DP4 R1.y, c[A0.x+1], v[0];
3215bd8deadSopenharmony_ci          DP4 R1.z, c[A0.x+2], v[0];
3225bd8deadSopenharmony_ci          DP4 R1.w, c[A0.x+3], v[0];
3235bd8deadSopenharmony_ci          MUL R0, R1, v[12].x;            # accumulate weighted sum in R0
3245bd8deadSopenharmony_ci          BRA end (LT.y);                 # stop on a negative matrix index
3255bd8deadSopenharmony_ci          DP4 R1.x, c[A0.y+0], v[0];      # 2nd matrix transform
3265bd8deadSopenharmony_ci          DP4 R1.y, c[A0.y+1], v[0];
3275bd8deadSopenharmony_ci          DP4 R1.z, c[A0.y+2], v[0];
3285bd8deadSopenharmony_ci          DP4 R1.w, c[A0.y+3], v[0];
3295bd8deadSopenharmony_ci          MAD R0, R1, v[12].y, R0;        # accumulate weighted sum in R0
3305bd8deadSopenharmony_ci          BRA end (LT.z);                 # stop on a negative matrix index
3315bd8deadSopenharmony_ci
3325bd8deadSopenharmony_ci          ...                             # 3rd and 4th matrix transform
3335bd8deadSopenharmony_ci
3345bd8deadSopenharmony_ci          ARLC A0, v[15];                 # load next four palette indices
3355bd8deadSopenharmony_ci          BRA end (LT.x);
3365bd8deadSopenharmony_ci          DP4 R1.x, c[A0.x+0], v[0];      # 5th matrix transform
3375bd8deadSopenharmony_ci          DP4 R1.y, c[A0.x+1], v[0];
3385bd8deadSopenharmony_ci          DP4 R1.z, c[A0.x+2], v[0];
3395bd8deadSopenharmony_ci          DP4 R1.w, c[A0.x+3], v[0];
3405bd8deadSopenharmony_ci          MAD R0, R1, v[13].x, R0;        # accumulate weighted sum in R0
3415bd8deadSopenharmony_ci          BRA end (LT.y);                 # stop on a negative matrix index
3425bd8deadSopenharmony_ci
3435bd8deadSopenharmony_ci          ...                             # 6th, 7th, and 8th matrix transform
3445bd8deadSopenharmony_ci        
3455bd8deadSopenharmony_ci        end:
3465bd8deadSopenharmony_ci          ...                             # any additional instructions
3475bd8deadSopenharmony_ci
3485bd8deadSopenharmony_ci      The amount of code used by this example could further be reduced using a
3495bd8deadSopenharmony_ci      subroutine performing four transformations at a time:
3505bd8deadSopenharmony_ci
3515bd8deadSopenharmony_ci          ARLC A0, v[14];  # load first four indices
3525bd8deadSopenharmony_ci          CAL  skin4;      # do first four transformations
3535bd8deadSopenharmony_ci          BRA  end (LT);   # end if any of the first 4 indices was < 0
3545bd8deadSopenharmony_ci          ARLC A0, v[15];  # load second four indices
3555bd8deadSopenharmony_ci          CAL  skin4;      # do second four transformations
3565bd8deadSopenharmony_ci        end:
3575bd8deadSopenharmony_ci          ...              # any additional instructions
3585bd8deadSopenharmony_ci
3595bd8deadSopenharmony_ci    Why does the RCC instruction exist?
3605bd8deadSopenharmony_ci
3615bd8deadSopenharmony_ci      RESOLVED:  To perform numeric operations that will avoid overflow and
3625bd8deadSopenharmony_ci      underflow issues.
3635bd8deadSopenharmony_ci
3645bd8deadSopenharmony_ci    Should the specification provide more examples?
3655bd8deadSopenharmony_ci
3665bd8deadSopenharmony_ci      RESOLVED:  It would be nice.
3675bd8deadSopenharmony_ci
3685bd8deadSopenharmony_ci
3695bd8deadSopenharmony_ciNew Procedures and Functions
3705bd8deadSopenharmony_ci
3715bd8deadSopenharmony_ci    None.
3725bd8deadSopenharmony_ci
3735bd8deadSopenharmony_ci
3745bd8deadSopenharmony_ciNew Tokens
3755bd8deadSopenharmony_ci
3765bd8deadSopenharmony_ci    None.
3775bd8deadSopenharmony_ci
3785bd8deadSopenharmony_ci
3795bd8deadSopenharmony_ciAdditions to Chapter 2 of the OpenGL 1.3 Specification (OpenGL Operation)
3805bd8deadSopenharmony_ci
3815bd8deadSopenharmony_ci    Modify Section 2.11, Clipping (p. 39)
3825bd8deadSopenharmony_ci
3835bd8deadSopenharmony_ci    (modify last paragraph, p. 39) When the GL is not in vertex program mode
3845bd8deadSopenharmony_ci
3855bd8deadSopenharmony_ci    (section 2.14), this view volume may be further restricted by as many as n
3865bd8deadSopenharmony_ci    client-defined clip planes to generate the clip volume. ...
3875bd8deadSopenharmony_ci
3885bd8deadSopenharmony_ci    (add before next-to-last paragraph, p. 40) When the GL is in vertex
3895bd8deadSopenharmony_ci    program mode, the view volume may be restricted to the individual clip
3905bd8deadSopenharmony_ci    distance volumes derived from the per-vertex clip distances (o[CLP0] -
3915bd8deadSopenharmony_ci    o[CLP5]).  Clip distance volumes are applied if and only if per-vertex
3925bd8deadSopenharmony_ci    clip distances are not supported in the vertex program execution
3935bd8deadSopenharmony_ci    environment.  A point P belonging to the primitive under consideration is
3945bd8deadSopenharmony_ci    in the clip distance volume numbered n if and only if
3955bd8deadSopenharmony_ci
3965bd8deadSopenharmony_ci      c_n(P) >= 0,
3975bd8deadSopenharmony_ci
3985bd8deadSopenharmony_ci    where c_n(P) is the interpolated value of the clip distance CLPn at the
3995bd8deadSopenharmony_ci    point P.  For point primitives, c_n(P) is simply the clip distance for the
4005bd8deadSopenharmony_ci    vertex in question.  For line and triangle primitives, per-vertex clip
4015bd8deadSopenharmony_ci    distances are interpolated using a weighted mean, with weights derived
4025bd8deadSopenharmony_ci    according to the algorithms described in sections 3.4 and 3.5.
4035bd8deadSopenharmony_ci
4045bd8deadSopenharmony_ci    (modify next-to-last paragraph, p.40) Client-defined clip planes or clip
4055bd8deadSopenharmony_ci    distance volumes are enabled with the generic Enable command and disabled
4065bd8deadSopenharmony_ci    with the Disable command. The value of the argument to either command is
4075bd8deadSopenharmony_ci    CLIP PLANEi where i is an integer between 0 and n; specifying a value of i
4085bd8deadSopenharmony_ci    enables or disables the plane equation with index i. The constants obey
4095bd8deadSopenharmony_ci    CLIP PLANEi = CLIP PLANE0 + i.
4105bd8deadSopenharmony_ci
4115bd8deadSopenharmony_ci
4125bd8deadSopenharmony_ci    Add Section 2.14,  Vertex Programs (p. 57).  This section supersedes the
4135bd8deadSopenharmony_ci    similar section added in the NV_vertex_program extension and extended in
4145bd8deadSopenharmony_ci    the NV_vertex_program1_1 extension.
4155bd8deadSopenharmony_ci
4165bd8deadSopenharmony_ci    The conventional GL vertex transformation model described in sections 2.10
4175bd8deadSopenharmony_ci    through 2.13 is a configurable, but essentially hard-wired, sequence of
4185bd8deadSopenharmony_ci    per-vertex computations based on a canonical set of per-vertex parameters
4195bd8deadSopenharmony_ci    and vertex transformation related state such as transformation matrices,
4205bd8deadSopenharmony_ci    lighting parameters, and texture coordinate generation parameters.
4215bd8deadSopenharmony_ci
4225bd8deadSopenharmony_ci    The general success and utility of the conventional GL vertex
4235bd8deadSopenharmony_ci    transformation model reflects its basic correspondence to the typical
4245bd8deadSopenharmony_ci    vertex transformation requirements of 3D applications.
4255bd8deadSopenharmony_ci
4265bd8deadSopenharmony_ci    However when the conventional GL vertex transformation model is not
4275bd8deadSopenharmony_ci    sufficient, the vertex program mode provides a substantially more flexible
4285bd8deadSopenharmony_ci    model for vertex transformation.  The vertex program mode permits
4295bd8deadSopenharmony_ci    applications to define their own vertex programs.
4305bd8deadSopenharmony_ci
4315bd8deadSopenharmony_ci
4325bd8deadSopenharmony_ci    Section 2.14.1, Vertex Program Execution Environment
4335bd8deadSopenharmony_ci
4345bd8deadSopenharmony_ci    The vertex program execution environment is an operational model that
4355bd8deadSopenharmony_ci    defines how a program is executed.  The execution environment includes a
4365bd8deadSopenharmony_ci    set of instructions, a set of registers, and semantic rules defining how
4375bd8deadSopenharmony_ci    operations are performed.  There are three vertex program execution
4385bd8deadSopenharmony_ci    environments, VP1, VP1.1, and VP2.  The environment names are taken from
4395bd8deadSopenharmony_ci    the mandatory program prefix strings found at the beginning of all vertex
4405bd8deadSopenharmony_ci    programs.  The VP1.1 execution environment is a minor addition to the VP1
4415bd8deadSopenharmony_ci    execution environment, so references to the VP1 execution environment
4425bd8deadSopenharmony_ci    below apply to both VP1 and VP1.1 execution environments except where
4435bd8deadSopenharmony_ci    otherwise noted.
4445bd8deadSopenharmony_ci
4455bd8deadSopenharmony_ci    The vertex program instruction set consists primarily of floating-point
4465bd8deadSopenharmony_ci    4-component vector operations operating on per-vertex attributes and
4475bd8deadSopenharmony_ci    program parameters.  Vertex programs execute on a per-vertex basis and
4485bd8deadSopenharmony_ci    operate on each vertex completely independently from the processing of
4495bd8deadSopenharmony_ci    other vertices.  Vertex programs execute without data hazards so results
4505bd8deadSopenharmony_ci    computed in one operation can be used immediately afterwards.  Vertex
4515bd8deadSopenharmony_ci    programs produce a set of vertex result vectors that becomes the set of
4525bd8deadSopenharmony_ci    transformed vertex parameters used by primitive assembly.
4535bd8deadSopenharmony_ci
4545bd8deadSopenharmony_ci    In the VP1 environment, vertex programs execute a finite fixed sequence of
4555bd8deadSopenharmony_ci    instructions with no branching or looping.  In the VP2 environment, vertex
4565bd8deadSopenharmony_ci    programs support conditional and unconditional branches and four levels of
4575bd8deadSopenharmony_ci    subroutine calls.
4585bd8deadSopenharmony_ci
4595bd8deadSopenharmony_ci    The vertex program register set consists of six types of registers
4605bd8deadSopenharmony_ci    described in the following sections.
4615bd8deadSopenharmony_ci
4625bd8deadSopenharmony_ci
4635bd8deadSopenharmony_ci    Section 2.14.1.1, Vertex Attribute Registers
4645bd8deadSopenharmony_ci
4655bd8deadSopenharmony_ci    The Vertex Attribute Registers are sixteen 4-component vector
4665bd8deadSopenharmony_ci    floating-point registers containing the current vertex's per-vertex
4675bd8deadSopenharmony_ci    attributes.  These registers are numbered 0 through 15.  These registers
4685bd8deadSopenharmony_ci    are private to each vertex program invocation and are initialized at each
4695bd8deadSopenharmony_ci    vertex program invocation by the current vertex attribute state specified
4705bd8deadSopenharmony_ci    with VertexAttribNV commands.  These registers are read-only during vertex
4715bd8deadSopenharmony_ci    program execution.  The VertexAttribNV commands used to update the vertex
4725bd8deadSopenharmony_ci    attribute registers can be issued both outside and inside of Begin/End
4735bd8deadSopenharmony_ci    pairs.  Vertex program execution is provoked by updating vertex attribute
4745bd8deadSopenharmony_ci    zero.  Updating vertex attribute zero outside of a Begin/End pair is
4755bd8deadSopenharmony_ci    ignored without generating any error (identical to the Vertex command
4765bd8deadSopenharmony_ci    operation).
4775bd8deadSopenharmony_ci
4785bd8deadSopenharmony_ci    The commands
4795bd8deadSopenharmony_ci
4805bd8deadSopenharmony_ci      void VertexAttrib{1234}{sfd}NV(uint index, T coords);
4815bd8deadSopenharmony_ci      void VertexAttrib{1234}{sfd}vNV(uint index, T coords);
4825bd8deadSopenharmony_ci      void VertexAttrib4ubNV(uint index, T coords);
4835bd8deadSopenharmony_ci      void VertexAttrib4ubvNV(uint index, T coords);
4845bd8deadSopenharmony_ci
4855bd8deadSopenharmony_ci    specify the particular current vertex attribute indicated by index.
4865bd8deadSopenharmony_ci    The coordinates for each vertex attribute are named x, y, z, and w.
4875bd8deadSopenharmony_ci    The VertexAttrib1NV family of commands sets the x coordinate to the
4885bd8deadSopenharmony_ci    provided single argument while setting y and z to 0 and w to 1.
4895bd8deadSopenharmony_ci    Similarly, VertexAttrib2NV sets x and y to the specified values,
4905bd8deadSopenharmony_ci    z to 0 and w to 1; VertexAttrib3NV sets x, y, and z, with w set
4915bd8deadSopenharmony_ci    to 1, and VertexAttrib4NV sets all four coordinates.  The error
4925bd8deadSopenharmony_ci    INVALID_VALUE is generated if index is greater than 15.
4935bd8deadSopenharmony_ci
4945bd8deadSopenharmony_ci    No conversions are applied to the vertex attributes specified as
4955bd8deadSopenharmony_ci    type short, float, or double.  However, vertex attributes specified
4965bd8deadSopenharmony_ci    as type ubyte are converted as described by Table 2.6.
4975bd8deadSopenharmony_ci
4985bd8deadSopenharmony_ci    The commands
4995bd8deadSopenharmony_ci
5005bd8deadSopenharmony_ci      void VertexAttribs{1234}{sfd}vNV(uint index, sizei n, T coords[]);
5015bd8deadSopenharmony_ci      void VertexAttribs4ubvNV(uint index, sizei n, GLubyte coords[]);
5025bd8deadSopenharmony_ci
5035bd8deadSopenharmony_ci    specify a contiguous set of n vertex attributes.  The effect of
5045bd8deadSopenharmony_ci
5055bd8deadSopenharmony_ci      VertexAttribs{1234}{sfd}vNV(index, n, coords)
5065bd8deadSopenharmony_ci
5075bd8deadSopenharmony_ci    is the same (assuming no errors) as the command sequence
5085bd8deadSopenharmony_ci
5095bd8deadSopenharmony_ci      #define NUM k  /* where k is 1, 2, 3, or 4 components */
5105bd8deadSopenharmony_ci      int i;
5115bd8deadSopenharmony_ci      for (i=n-1; i>=0; i--) {
5125bd8deadSopenharmony_ci        VertexAttrib{NUM}{sfd}vNV(i+index, &coords[i*NUM]);
5135bd8deadSopenharmony_ci      }
5145bd8deadSopenharmony_ci
5155bd8deadSopenharmony_ci    VertexAttribs4ubvNV behaves similarly.
5165bd8deadSopenharmony_ci
5175bd8deadSopenharmony_ci    The VertexAttribNV calls equivalent to VertexAttribsNV are issued in
5185bd8deadSopenharmony_ci    reverse order so that vertex program execution is provoked when index
5195bd8deadSopenharmony_ci    is zero only after all the other vertex attributes have first been
5205bd8deadSopenharmony_ci    specified.
5215bd8deadSopenharmony_ci
5225bd8deadSopenharmony_ci    The set and operation of vertex attribute registers are identical for both
5235bd8deadSopenharmony_ci    VP1 and VP2 execution environment.
5245bd8deadSopenharmony_ci
5255bd8deadSopenharmony_ci
5265bd8deadSopenharmony_ci    Section 2.14.1.2, Program Parameter Registers
5275bd8deadSopenharmony_ci
5285bd8deadSopenharmony_ci    The Program Parameter Registers are a set of 4-component floating-point
5295bd8deadSopenharmony_ci    vector registers containing the vertex program parameters.  In the VP1
5305bd8deadSopenharmony_ci    execution environment, there are 96 registers, numbered 0 through 95.  In
5315bd8deadSopenharmony_ci    the VP2 execution environment, there are 256 registers, numbered 0 through
5325bd8deadSopenharmony_ci    255.  This relatively large set of registers is intended to hold
5335bd8deadSopenharmony_ci    parameters such as matrices, lighting parameters, and constants required
5345bd8deadSopenharmony_ci    by vertex programs.  Vertex program parameter registers can be updated in
5355bd8deadSopenharmony_ci    one of two ways:  by the ProgramParameterNV commands outside of a
5365bd8deadSopenharmony_ci    Begin/End pair or by a vertex state program executed outside of a
5375bd8deadSopenharmony_ci    Begin/End pair (vertex state programs are discussed in section 2.14.3).
5385bd8deadSopenharmony_ci
5395bd8deadSopenharmony_ci    The commands
5405bd8deadSopenharmony_ci     
5415bd8deadSopenharmony_ci      void ProgramParameter4fNV(enum target, uint index,
5425bd8deadSopenharmony_ci                                float x, float y, float z, float w)
5435bd8deadSopenharmony_ci      void ProgramParameter4dNV(enum target, uint index,
5445bd8deadSopenharmony_ci                                double x, double y, double z, double w)
5455bd8deadSopenharmony_ci
5465bd8deadSopenharmony_ci    specify the particular program parameter indicated by index.
5475bd8deadSopenharmony_ci    The coordinates values x, y, z, and w are assigned to the respective
5485bd8deadSopenharmony_ci    components of the particular program parameter.  target must be
5495bd8deadSopenharmony_ci    VERTEX_PROGRAM_NV.
5505bd8deadSopenharmony_ci
5515bd8deadSopenharmony_ci    The commands
5525bd8deadSopenharmony_ci
5535bd8deadSopenharmony_ci      void ProgramParameter4dvNV(enum target, uint index, double *params);
5545bd8deadSopenharmony_ci      void ProgramParameter4fvNV(enum target, uint index, float *params);
5555bd8deadSopenharmony_ci
5565bd8deadSopenharmony_ci    operate identically to ProgramParameter4fNV and ProgramParameter4dNV
5575bd8deadSopenharmony_ci    respectively except that the program parameters are passed as an
5585bd8deadSopenharmony_ci    array of four components.
5595bd8deadSopenharmony_ci
5605bd8deadSopenharmony_ci    The error INVALID_VALUE is generated if the specified index is greater
5615bd8deadSopenharmony_ci    than or equal to the number of program parameters in the execution
5625bd8deadSopenharmony_ci    environment (96 for VP1, 256 for VP2).
5635bd8deadSopenharmony_ci
5645bd8deadSopenharmony_ci    The commands
5655bd8deadSopenharmony_ci
5665bd8deadSopenharmony_ci      void ProgramParameters4dvNV(enum target, uint index,
5675bd8deadSopenharmony_ci                                  uint num, double *params);
5685bd8deadSopenharmony_ci      void ProgramParameters4fvNV(enum target, uint index,
5695bd8deadSopenharmony_ci                                  uint num, float *params);
5705bd8deadSopenharmony_ci
5715bd8deadSopenharmony_ci    specify a contiguous set of num program parameters.  The effect is
5725bd8deadSopenharmony_ci    the same (assuming no errors) as
5735bd8deadSopenharmony_ci
5745bd8deadSopenharmony_ci      for (i=index; i<index+num; i++) {
5755bd8deadSopenharmony_ci        ProgramParameter4{fd}vNV(target, i, &params[i*4]);
5765bd8deadSopenharmony_ci      }
5775bd8deadSopenharmony_ci
5785bd8deadSopenharmony_ci    The error INVALID_VALUE is generated if sum of <index> and <num> is
5795bd8deadSopenharmony_ci    greater than the number of program parameters in the execution environment
5805bd8deadSopenharmony_ci    (96 for VP1, 256 for VP2).
5815bd8deadSopenharmony_ci
5825bd8deadSopenharmony_ci    The program parameter registers are shared to all vertex program
5835bd8deadSopenharmony_ci    invocations within a rendering context.  ProgramParameterNV command
5845bd8deadSopenharmony_ci    updates and vertex state program executions are serialized with respect to
5855bd8deadSopenharmony_ci    vertex program invocations and other vertex state program executions.
5865bd8deadSopenharmony_ci
5875bd8deadSopenharmony_ci    Writes to the program parameter registers during vertex state program
5885bd8deadSopenharmony_ci    execution can be maskable on a per-component basis.
5895bd8deadSopenharmony_ci
5905bd8deadSopenharmony_ci    The initial value of all 96 (VP1) or 256 (VP2) program parameter registers
5915bd8deadSopenharmony_ci    is (0,0,0,0).
5925bd8deadSopenharmony_ci
5935bd8deadSopenharmony_ci
5945bd8deadSopenharmony_ci    Section 2.14.1.3, Address Registers
5955bd8deadSopenharmony_ci
5965bd8deadSopenharmony_ci    The Address Registers are 4-component vector registers with signed 10-bit
5975bd8deadSopenharmony_ci    integer components.  In the VP1 execution environment, there is only a
5985bd8deadSopenharmony_ci    single address register (A0) and only the x component of the register is
5995bd8deadSopenharmony_ci    accessible.  In the VP2 execution environment, there are two address
6005bd8deadSopenharmony_ci    registers (A0 and A1), of which all four components are accessible.  The
6015bd8deadSopenharmony_ci    address registers are private to each vertex program invocation and are
6025bd8deadSopenharmony_ci    initialized to (0,0,0,0) at every vertex program invocation.  These
6035bd8deadSopenharmony_ci    registers can be written during vertex program execution (but not read)
6045bd8deadSopenharmony_ci    and their values can be used for as a relative offset for reading vertex
6055bd8deadSopenharmony_ci    program parameter registers.  Only the vertex program parameter registers
6065bd8deadSopenharmony_ci    can be read using relative addressing (writes using relative addressing
6075bd8deadSopenharmony_ci    are not supported).
6085bd8deadSopenharmony_ci
6095bd8deadSopenharmony_ci    See the discussion of relative addressing of program parameters in section
6105bd8deadSopenharmony_ci    2.14.2.1 and the discussion of the ARL instruction in section 2.14.3.4.
6115bd8deadSopenharmony_ci
6125bd8deadSopenharmony_ci
6135bd8deadSopenharmony_ci    Section 2.14.1.4, Temporary Registers
6145bd8deadSopenharmony_ci
6155bd8deadSopenharmony_ci    The Temporary Registers are 4-component floating-point vector registers
6165bd8deadSopenharmony_ci    used to hold temporary results during vertex program execution.  In the
6175bd8deadSopenharmony_ci    VP1 execution environment, there are 12 temporary registers, numbered 0
6185bd8deadSopenharmony_ci    through 11.  In the VP2 execution environment, there are 16 temporary
6195bd8deadSopenharmony_ci    registers, numbered 0 through 15.  These registers are private to each
6205bd8deadSopenharmony_ci    vertex program invocation and initialized to (0,0,0,0) at every vertex
6215bd8deadSopenharmony_ci    program invocation.  These registers can be read and written during vertex
6225bd8deadSopenharmony_ci    program execution.  Writes to these registers can be maskable on a
6235bd8deadSopenharmony_ci    per-component basis.
6245bd8deadSopenharmony_ci
6255bd8deadSopenharmony_ci    In the VP2 execution environment, there is one additional temporary
6265bd8deadSopenharmony_ci    pseudo-register, "CC".  CC is treated as unnumbered, write-only temporary
6275bd8deadSopenharmony_ci    register, whose sole purpose is to allow instructions to modify the
6285bd8deadSopenharmony_ci    condition code register (section 2.14.1.6) without overwriting the
6295bd8deadSopenharmony_ci    contents of any temporary register.
6305bd8deadSopenharmony_ci
6315bd8deadSopenharmony_ci
6325bd8deadSopenharmony_ci    Section 2.14.1.5, Vertex Result Registers
6335bd8deadSopenharmony_ci
6345bd8deadSopenharmony_ci    The Vertex Result Registers are 4-component floating-point vector
6355bd8deadSopenharmony_ci    registers used to write the results of a vertex program.  There are 15
6365bd8deadSopenharmony_ci    result registers in the VP1 execution environment, and 21 in the VP2
6375bd8deadSopenharmony_ci    execution environment.  Each register value is initialized to (0,0,0,1) at
6385bd8deadSopenharmony_ci    the invocation of each vertex program.  Writes to the vertex result
6395bd8deadSopenharmony_ci    registers can be maskable on a per-component basis.  These registers are
6405bd8deadSopenharmony_ci    named in Table X.1 and further discussed below.
6415bd8deadSopenharmony_ci
6425bd8deadSopenharmony_ci
6435bd8deadSopenharmony_ci    Vertex Result                                      Component
6445bd8deadSopenharmony_ci    Register Name   Description                        Interpretation
6455bd8deadSopenharmony_ci    --------------  ---------------------------------  --------------
6465bd8deadSopenharmony_ci     HPOS            Homogeneous clip space position    (x,y,z,w)
6475bd8deadSopenharmony_ci     COL0            Primary color (front-facing)       (r,g,b,a)
6485bd8deadSopenharmony_ci     COL1            Secondary color (front-facing)     (r,g,b,a)
6495bd8deadSopenharmony_ci     BFC0            Back-facing primary color          (r,g,b,a)
6505bd8deadSopenharmony_ci     BFC1            Back-facing secondary color        (r,g,b,a)
6515bd8deadSopenharmony_ci     FOGC            Fog coordinate                     (f,*,*,*)
6525bd8deadSopenharmony_ci     PSIZ            Point size                         (p,*,*,*)
6535bd8deadSopenharmony_ci     TEX0            Texture coordinate set 0           (s,t,r,q)
6545bd8deadSopenharmony_ci     TEX1            Texture coordinate set 1           (s,t,r,q)
6555bd8deadSopenharmony_ci     TEX2            Texture coordinate set 2           (s,t,r,q)
6565bd8deadSopenharmony_ci     TEX3            Texture coordinate set 3           (s,t,r,q)
6575bd8deadSopenharmony_ci     TEX4            Texture coordinate set 4           (s,t,r,q)
6585bd8deadSopenharmony_ci     TEX5            Texture coordinate set 5           (s,t,r,q)
6595bd8deadSopenharmony_ci     TEX6            Texture coordinate set 6           (s,t,r,q)
6605bd8deadSopenharmony_ci     TEX7            Texture coordinate set 7           (s,t,r,q)
6615bd8deadSopenharmony_ci     CLP0(*)         Clip distance 0                    (d,*,*,*)
6625bd8deadSopenharmony_ci     CLP1(*)         Clip distance 1                    (d,*,*,*)
6635bd8deadSopenharmony_ci     CLP2(*)         Clip distance 2                    (d,*,*,*)
6645bd8deadSopenharmony_ci     CLP3(*)         Clip distance 3                    (d,*,*,*)
6655bd8deadSopenharmony_ci     CLP4(*)         Clip distance 4                    (d,*,*,*)
6665bd8deadSopenharmony_ci     CLP5(*)         Clip distance 5                    (d,*,*,*)
6675bd8deadSopenharmony_ci
6685bd8deadSopenharmony_ci    Table X.1:  Vertex Result Registers.  (*) Registers CLP0 through CLP5, are
6695bd8deadSopenharmony_ci    available only in the VP2 execution environment.
6705bd8deadSopenharmony_ci
6715bd8deadSopenharmony_ci    HPOS is the transformed vertex's homogeneous clip space position.  The
6725bd8deadSopenharmony_ci    vertex's homogeneous clip space position is converted to normalized device
6735bd8deadSopenharmony_ci    coordinates and transformed to window coordinates as described at the end
6745bd8deadSopenharmony_ci    of section 2.10 and in section 2.11.  Further processing (subsequent to
6755bd8deadSopenharmony_ci    vertex program termination) is responsible for clipping primitives
6765bd8deadSopenharmony_ci    assembled from vertex program-generated vertices as described in section
6775bd8deadSopenharmony_ci    2.10 but all client-defined clip planes are treated as if they are
6785bd8deadSopenharmony_ci    disabled when vertex program mode is enabled.
6795bd8deadSopenharmony_ci
6805bd8deadSopenharmony_ci    Four distinct color results can be generated for each vertex.  COL0 is the
6815bd8deadSopenharmony_ci    transformed vertex's front-facing primary color.  COL1 is the transformed
6825bd8deadSopenharmony_ci    vertex's front-facing secondary color.  BFC0 is the transformed vertex's
6835bd8deadSopenharmony_ci    back-facing primary color.  BFC1 is the transformed vertex's back-facing
6845bd8deadSopenharmony_ci    secondary color.
6855bd8deadSopenharmony_ci
6865bd8deadSopenharmony_ci    Primitive coloring may operate in two-sided color mode.  This behavior is
6875bd8deadSopenharmony_ci    enabled and disabled by calling Enable or Disable with the symbolic value
6885bd8deadSopenharmony_ci    VERTEX_PROGRAM_TWO_SIDE_NV.  The selection between the back-facing colors
6895bd8deadSopenharmony_ci    and the front-facing colors depends on the primitive of which the vertex
6905bd8deadSopenharmony_ci    is a part.  If the primitive is a point or a line segment, the
6915bd8deadSopenharmony_ci    front-facing colors are always selected.  If the primitive is a polygon
6925bd8deadSopenharmony_ci    and two-sided color mode is disabled, the front-facing colors are
6935bd8deadSopenharmony_ci    selected.  If it is a polygon and two-sided color mode is enabled, then
6945bd8deadSopenharmony_ci    the selection is based on the sign of the (clipped or unclipped) polygon's
6955bd8deadSopenharmony_ci    signed area computed in window coordinates.  This facingness determination
6965bd8deadSopenharmony_ci    is identical to the two-sided lighting facingness determination described
6975bd8deadSopenharmony_ci    in section 2.13.1.
6985bd8deadSopenharmony_ci
6995bd8deadSopenharmony_ci    The selected primary and secondary colors for each primitive are clamped
7005bd8deadSopenharmony_ci    to the range [0,1] and then interpolated across the assembled primitive
7015bd8deadSopenharmony_ci    during rasterization with at least 8-bit accuracy for each color
7025bd8deadSopenharmony_ci    component.
7035bd8deadSopenharmony_ci
7045bd8deadSopenharmony_ci    FOGC is the transformed vertex's fog coordinate.  The register's first
7055bd8deadSopenharmony_ci    floating-point component is interpolated across the assembled primitive
7065bd8deadSopenharmony_ci    during rasterization and used as the fog distance to compute per-fragment
7075bd8deadSopenharmony_ci    the fog factor when fog is enabled.  However, if both fog and vertex
7085bd8deadSopenharmony_ci    program mode are enabled, but the FOGC vertex result register is not
7095bd8deadSopenharmony_ci    written, the fog factor is overridden to 1.0.  The register's other three
7105bd8deadSopenharmony_ci    components are ignored.
7115bd8deadSopenharmony_ci
7125bd8deadSopenharmony_ci    Point size determination may operate in program-specified point size mode.
7135bd8deadSopenharmony_ci    This behavior is enabled and disabled by calling Enable or Disable with
7145bd8deadSopenharmony_ci    the symbolic value VERTEX_PROGRAM_POINT_SIZE_NV.  If the vertex is for a
7155bd8deadSopenharmony_ci    point primitive and the mode is enabled and the PSIZ vertex result is
7165bd8deadSopenharmony_ci    written, the point primitive's size is determined by the clamped x
7175bd8deadSopenharmony_ci    component of the PSIZ register.  Otherwise (because vertex program mode is
7185bd8deadSopenharmony_ci    disabled, program-specified point size mode is disabled, or because the
7195bd8deadSopenharmony_ci    vertex program did not write PSIZ), the point primitive's size is
7205bd8deadSopenharmony_ci    determined by the point size state (the state specified using the
7215bd8deadSopenharmony_ci    PointSize command).
7225bd8deadSopenharmony_ci
7235bd8deadSopenharmony_ci    The PSIZ register's x component is clamped to the range zero through
7245bd8deadSopenharmony_ci    either the hi value of ALIASED_POINT_SIZE_RANGE if point smoothing is
7255bd8deadSopenharmony_ci    disabled or the hi value of the SMOOTH_POINT_SIZE_RANGE if point smoothing
7265bd8deadSopenharmony_ci    is enabled.  The register's other three components are ignored.
7275bd8deadSopenharmony_ci
7285bd8deadSopenharmony_ci    If the vertex is not for a point primitive, the value of the PSIZ vertex
7295bd8deadSopenharmony_ci    result register is ignored.
7305bd8deadSopenharmony_ci
7315bd8deadSopenharmony_ci    TEX0 through TEX7 are the transformed vertex's texture coordinate sets for
7325bd8deadSopenharmony_ci    texture units 0 through 7.  These floating-point coordinates are
7335bd8deadSopenharmony_ci    interpolated across the assembled primitive during rasterization and used
7345bd8deadSopenharmony_ci    for accessing textures.  If the number of texture units supported is less
7355bd8deadSopenharmony_ci    than eight, the values of vertex result registers that do not correspond
7365bd8deadSopenharmony_ci    to existent texture units are ignored.
7375bd8deadSopenharmony_ci
7385bd8deadSopenharmony_ci    CLP0 through CLP5, available only in the VP2 execution environment, are
7395bd8deadSopenharmony_ci    the transformed vertex's clip distances.  These floating-point coordinates
7405bd8deadSopenharmony_ci    are used by post-vertex program clipping process (see section 2.11).
7415bd8deadSopenharmony_ci
7425bd8deadSopenharmony_ci
7435bd8deadSopenharmony_ci    Section 2.14.1.6,  The Condition Code Register
7445bd8deadSopenharmony_ci
7455bd8deadSopenharmony_ci    The VP2 execution environment provides a single four-component vector
7465bd8deadSopenharmony_ci    called the condition code register.  Each component of this register is
7475bd8deadSopenharmony_ci    one of four enumerated values:  GT (greater than), EQ (equal), LT (less
7485bd8deadSopenharmony_ci    than), or UN (unordered).  The condition code register can be used to mask
7495bd8deadSopenharmony_ci    writes to registers and to evaluate conditional branches.
7505bd8deadSopenharmony_ci
7515bd8deadSopenharmony_ci    Most vertex program instructions can optionally update the condition code
7525bd8deadSopenharmony_ci    register.  When a vertex program instruction updates the condition code
7535bd8deadSopenharmony_ci    register, a condition code component is set to LT if the corresponding
7545bd8deadSopenharmony_ci    component of the result is less than zero, EQ if it is equal to zero, GT
7555bd8deadSopenharmony_ci    if it is greater than zero, and UN if it is NaN (not a number).
7565bd8deadSopenharmony_ci
7575bd8deadSopenharmony_ci    The condition code register is initialized to a vector of EQ values each
7585bd8deadSopenharmony_ci    time a vertex program executes.
7595bd8deadSopenharmony_ci
7605bd8deadSopenharmony_ci    There is no condition code register available in the VP1 execution
7615bd8deadSopenharmony_ci    environment.
7625bd8deadSopenharmony_ci
7635bd8deadSopenharmony_ci
7645bd8deadSopenharmony_ci    Section 2.14.1.7,  Semantic Meaning for Vertex Attributes and Program
7655bd8deadSopenharmony_ci                       Parameters 
7665bd8deadSopenharmony_ci
7675bd8deadSopenharmony_ci    One important distinction between the conventional GL vertex
7685bd8deadSopenharmony_ci    transformation mode and the vertex program mode is that per-vertex
7695bd8deadSopenharmony_ci    parameters and other state parameters in vertex program mode do not have
7705bd8deadSopenharmony_ci    dedicated semantic interpretations the way that they do with the
7715bd8deadSopenharmony_ci    conventional GL vertex transformation mode.
7725bd8deadSopenharmony_ci
7735bd8deadSopenharmony_ci    For example, in the conventional GL vertex transformation mode, the Normal
7745bd8deadSopenharmony_ci    command specifies a per-vertex normal.  The semantic that the Normal
7755bd8deadSopenharmony_ci    command supplies a normal for lighting is established because that is how
7765bd8deadSopenharmony_ci    the per-vertex attribute supplied by the Normal command is used by the
7775bd8deadSopenharmony_ci    conventional GL vertex transformation mode.  Similarly, other state
7785bd8deadSopenharmony_ci    parameters such as a light source position have semantic interpretations
7795bd8deadSopenharmony_ci    based on how the conventional GL vertex transformation model uses each
7805bd8deadSopenharmony_ci    particular parameter.
7815bd8deadSopenharmony_ci
7825bd8deadSopenharmony_ci    In contrast, vertex attributes and program parameters for vertex programs
7835bd8deadSopenharmony_ci    have no pre-defined semantic meanings.  The meaning of a vertex attribute
7845bd8deadSopenharmony_ci    or program parameter in vertex program mode is defined by how the vertex
7855bd8deadSopenharmony_ci    attribute or program parameter is used by the current vertex program to
7865bd8deadSopenharmony_ci    compute and write values to the Vertex Result Registers.  This is the
7875bd8deadSopenharmony_ci    reason that per-vertex attributes and program parameters for vertex
7885bd8deadSopenharmony_ci    programs are numbered instead of named.
7895bd8deadSopenharmony_ci
7905bd8deadSopenharmony_ci    For convenience however, the existing per-vertex parameters for the
7915bd8deadSopenharmony_ci    conventional GL vertex transformation mode (vertices, normals,
7925bd8deadSopenharmony_ci    colors, fog coordinates, vertex weights, and texture coordinates) are
7935bd8deadSopenharmony_ci    aliased to numbered vertex attributes.  This aliasing is specified in
7945bd8deadSopenharmony_ci    Table X.2.  The table includes how the various conventional components
7955bd8deadSopenharmony_ci    map to the 4-component vertex attribute components.
7965bd8deadSopenharmony_ci
7975bd8deadSopenharmony_ciVertex
7985bd8deadSopenharmony_ciAttribute  Conventional                                           Conventional
7995bd8deadSopenharmony_ciRegister   Per-vertex        Conventional                         Component
8005bd8deadSopenharmony_ciNumber     Parameter         Per-vertex Parameter Command         Mapping
8015bd8deadSopenharmony_ci---------  ---------------   -----------------------------------  ------------
8025bd8deadSopenharmony_ci 0         vertex position   Vertex                               x,y,z,w
8035bd8deadSopenharmony_ci 1         vertex weights    VertexWeightEXT                      w,0,0,1
8045bd8deadSopenharmony_ci 2         normal            Normal                               x,y,z,1
8055bd8deadSopenharmony_ci 3         primary color     Color                                r,g,b,a
8065bd8deadSopenharmony_ci 4         secondary color   SecondaryColorEXT                    r,g,b,1
8075bd8deadSopenharmony_ci 5         fog coordinate    FogCoordEXT                          fc,0,0,1
8085bd8deadSopenharmony_ci 6         -                 -                                    -
8095bd8deadSopenharmony_ci 7         -                 -                                    -
8105bd8deadSopenharmony_ci 8         texture coord 0   MultiTexCoord(GL_TEXTURE0_ARB, ...)  s,t,r,q
8115bd8deadSopenharmony_ci 9         texture coord 1   MultiTexCoord(GL_TEXTURE1_ARB, ...)  s,t,r,q
8125bd8deadSopenharmony_ci 10        texture coord 2   MultiTexCoord(GL_TEXTURE2_ARB, ...)  s,t,r,q
8135bd8deadSopenharmony_ci 11        texture coord 3   MultiTexCoord(GL_TEXTURE3_ARB, ...)  s,t,r,q
8145bd8deadSopenharmony_ci 12        texture coord 4   MultiTexCoord(GL_TEXTURE4_ARB, ...)  s,t,r,q
8155bd8deadSopenharmony_ci 13        texture coord 5   MultiTexCoord(GL_TEXTURE5_ARB, ...)  s,t,r,q
8165bd8deadSopenharmony_ci 14        texture coord 6   MultiTexCoord(GL_TEXTURE6_ARB, ...)  s,t,r,q
8175bd8deadSopenharmony_ci 15        texture coord 7   MultiTexCoord(GL_TEXTURE7_ARB, ...)  s,t,r,q
8185bd8deadSopenharmony_ci
8195bd8deadSopenharmony_ciTable X.2:  Aliasing of vertex attributes with conventional per-vertex
8205bd8deadSopenharmony_ciparameters.
8215bd8deadSopenharmony_ci
8225bd8deadSopenharmony_ci    Only vertex attribute zero is treated specially because it is
8235bd8deadSopenharmony_ci    the attribute that provokes the execution of the vertex program;
8245bd8deadSopenharmony_ci    this is the attribute that aliases to the Vertex command's vertex
8255bd8deadSopenharmony_ci    coordinates.
8265bd8deadSopenharmony_ci
8275bd8deadSopenharmony_ci    The result of a vertex program is the set of post-transformation
8285bd8deadSopenharmony_ci    vertex parameters written to the Vertex Result Registers.
8295bd8deadSopenharmony_ci    All vertex programs must write a homogeneous clip space position, but
8305bd8deadSopenharmony_ci    the other Vertex Result Registers can be optionally written.
8315bd8deadSopenharmony_ci
8325bd8deadSopenharmony_ci    Clipping and culling are not the responsibility of vertex programs because
8335bd8deadSopenharmony_ci    these operations assume the assembly of multiple vertices into a
8345bd8deadSopenharmony_ci    primitive.  View frustum clipping is performed subsequent to vertex
8355bd8deadSopenharmony_ci    program execution.  Clip planes are not supported in the VP1 execution
8365bd8deadSopenharmony_ci    environment.  Clip planes are supported indirectly via the clip distance
8375bd8deadSopenharmony_ci    (o[CLPx]) registers in the VP2 execution environment.
8385bd8deadSopenharmony_ci
8395bd8deadSopenharmony_ci
8405bd8deadSopenharmony_ci    Section 2.14.1.8,  Vertex Program Specification
8415bd8deadSopenharmony_ci
8425bd8deadSopenharmony_ci    Vertex programs are specified as an array of ubytes.  The array is a
8435bd8deadSopenharmony_ci    string of ASCII characters encoding the program.
8445bd8deadSopenharmony_ci
8455bd8deadSopenharmony_ci    The command
8465bd8deadSopenharmony_ci
8475bd8deadSopenharmony_ci      LoadProgramNV(enum target, uint id, sizei len,
8485bd8deadSopenharmony_ci                    const ubyte *program);
8495bd8deadSopenharmony_ci
8505bd8deadSopenharmony_ci    loads a vertex program when the target parameter is VERTEX_PROGRAM_NV.
8515bd8deadSopenharmony_ci    Multiple programs can be loaded with different names.  id names the
8525bd8deadSopenharmony_ci    program to load.  The name space for programs is the positive integers
8535bd8deadSopenharmony_ci    (zero is reserved).  The error INVALID_VALUE occurs if a program is loaded
8545bd8deadSopenharmony_ci    with an id of zero.  The error INVALID_OPERATION is generated if a program
8555bd8deadSopenharmony_ci    is loaded for an id that is currently loaded with a program of a different
8565bd8deadSopenharmony_ci    program target.  Managing the program name space and binding to vertex
8575bd8deadSopenharmony_ci    programs is discussed later in section 2.14.1.8.
8585bd8deadSopenharmony_ci
8595bd8deadSopenharmony_ci    program is a pointer to an array of ubytes that represents the program
8605bd8deadSopenharmony_ci    being loaded.  The length of the array is indicated by len.
8615bd8deadSopenharmony_ci
8625bd8deadSopenharmony_ci    A second program target type known as vertex state programs is discussed
8635bd8deadSopenharmony_ci    in 2.14.4.
8645bd8deadSopenharmony_ci
8655bd8deadSopenharmony_ci    At program load time, the program is parsed into a set of tokens possibly
8665bd8deadSopenharmony_ci    separated by white space.  Spaces, tabs, newlines, carriage returns, and
8675bd8deadSopenharmony_ci    comments are considered whitespace.  Comments begin with the character "#"
8685bd8deadSopenharmony_ci    and are terminated by a newline, a carriage return, or the end of the
8695bd8deadSopenharmony_ci    program array.
8705bd8deadSopenharmony_ci
8715bd8deadSopenharmony_ci    The Backus-Naur Form (BNF) grammar below specifies the syntactically valid
8725bd8deadSopenharmony_ci    sequences for several types of vertex programs.  The set of valid tokens
8735bd8deadSopenharmony_ci    can be inferred from the grammar.  The token "" represents an empty string
8745bd8deadSopenharmony_ci    and is used to indicate optional rules.  A program is invalid if it
8755bd8deadSopenharmony_ci    contains any undefined tokens or characters.
8765bd8deadSopenharmony_ci
8775bd8deadSopenharmony_ci    The grammar provides for three different vertex program types,
8785bd8deadSopenharmony_ci    corresponding to the three vertex program execution environments.  VP1,
8795bd8deadSopenharmony_ci    VP1.1, and VP2 programs match the grammar rules <vp1-program>,
8805bd8deadSopenharmony_ci    <vp11-program>, and <vp2-program>, respectively.  Some grammar rules
8815bd8deadSopenharmony_ci    correspond to features or instruction forms available only in certain
8825bd8deadSopenharmony_ci    execution environments.  Rules beginning with the prefix "vp1-" are
8835bd8deadSopenharmony_ci    available only to VP1 and VP1.1 programs.  Rules beginning with the
8845bd8deadSopenharmony_ci    prefixes "vp11-" and "vp2-" are available only to VP1.1 and VP2 programs,
8855bd8deadSopenharmony_ci    respectively.
8865bd8deadSopenharmony_ci
8875bd8deadSopenharmony_ci
8885bd8deadSopenharmony_ci    <program>              ::= <vp1-program>
8895bd8deadSopenharmony_ci                             | <vp11-program>
8905bd8deadSopenharmony_ci                             | <vp2-program>
8915bd8deadSopenharmony_ci
8925bd8deadSopenharmony_ci    <vp1-program>          ::= "!!VP1.0" <programBody> "END"
8935bd8deadSopenharmony_ci
8945bd8deadSopenharmony_ci    <vp11-program>         ::= "!!VP1.1" <programBody> "END"
8955bd8deadSopenharmony_ci
8965bd8deadSopenharmony_ci    <vp2-program>          ::= "!!VP2.0" <programBody> "END"
8975bd8deadSopenharmony_ci
8985bd8deadSopenharmony_ci    <programBody>          ::= <optionSequence> <programText>
8995bd8deadSopenharmony_ci
9005bd8deadSopenharmony_ci    <optionSequence>       ::= <option> <optionSequence>
9015bd8deadSopenharmony_ci                             | ""
9025bd8deadSopenharmony_ci
9035bd8deadSopenharmony_ci    <option>               ::= "OPTION" <vp11-option> ";"
9045bd8deadSopenharmony_ci                             | "OPTION" <vp2-option> ";"
9055bd8deadSopenharmony_ci
9065bd8deadSopenharmony_ci    <vp11-option>          ::= "NV_position_invariant"
9075bd8deadSopenharmony_ci
9085bd8deadSopenharmony_ci    <vp2-option>           ::= "NV_position_invariant"
9095bd8deadSopenharmony_ci
9105bd8deadSopenharmony_ci    <programText>          ::= <programTextItem> <programText>
9115bd8deadSopenharmony_ci                             | ""
9125bd8deadSopenharmony_ci
9135bd8deadSopenharmony_ci    <programTextItem>      ::= <instruction> ";"
9145bd8deadSopenharmony_ci                             | <vp2-instructionLabel>
9155bd8deadSopenharmony_ci
9165bd8deadSopenharmony_ci    <instruction>          ::= <ARL-instruction>
9175bd8deadSopenharmony_ci                             | <VECTORop-instruction>
9185bd8deadSopenharmony_ci                             | <SCALARop-instruction>
9195bd8deadSopenharmony_ci                             | <BINop-instruction>
9205bd8deadSopenharmony_ci                             | <TRIop-instruction>
9215bd8deadSopenharmony_ci                             | <vp2-BRA-instruction>
9225bd8deadSopenharmony_ci                             | <vp2-RET-instruction>
9235bd8deadSopenharmony_ci                             | <vp2-ARA-instruction>
9245bd8deadSopenharmony_ci
9255bd8deadSopenharmony_ci    <ARL-instruction>      ::= <vp1-ARL-instruction>
9265bd8deadSopenharmony_ci                             | <vp2-ARL-instruction>
9275bd8deadSopenharmony_ci
9285bd8deadSopenharmony_ci    <vp1-ARL-instruction>  ::= "ARL" <maskedAddrReg> "," <scalarSrc>
9295bd8deadSopenharmony_ci
9305bd8deadSopenharmony_ci    <vp2-ARL-instruction>  ::= <vp2-ARLop> <maskedAddrReg> "," <vectorSrc>
9315bd8deadSopenharmony_ci
9325bd8deadSopenharmony_ci    <vp2-ARLop>            ::= "ARL" | "ARLC"
9335bd8deadSopenharmony_ci                             | "ARR" | "ARRC"
9345bd8deadSopenharmony_ci
9355bd8deadSopenharmony_ci    <VECTORop-instruction> ::= <VECTORop> <maskedDstReg> "," <vectorSrc>
9365bd8deadSopenharmony_ci
9375bd8deadSopenharmony_ci    <VECTORop>             ::= "LIT"
9385bd8deadSopenharmony_ci                             | "MOV"
9395bd8deadSopenharmony_ci                             | <vp11-VECTORop>
9405bd8deadSopenharmony_ci                             | <vp2-VECTORop>
9415bd8deadSopenharmony_ci
9425bd8deadSopenharmony_ci    <vp11-VECTORop>        ::= "ABS"
9435bd8deadSopenharmony_ci
9445bd8deadSopenharmony_ci    <vp2-VECTORop>         ::=         "ABSC"
9455bd8deadSopenharmony_ci                             | "FLR" | "FLRC"
9465bd8deadSopenharmony_ci                             | "FRC" | "FRCC"
9475bd8deadSopenharmony_ci                             |         "LITC"
9485bd8deadSopenharmony_ci                             |         "MOVC"
9495bd8deadSopenharmony_ci                             | "SSG" | "SSGC"
9505bd8deadSopenharmony_ci
9515bd8deadSopenharmony_ci    <SCALARop-instruction> ::= <SCALARop> <maskedDstReg> "," <scalarSrc>
9525bd8deadSopenharmony_ci
9535bd8deadSopenharmony_ci    <SCALARop>             ::= "EXP"
9545bd8deadSopenharmony_ci                             | "LOG"
9555bd8deadSopenharmony_ci                             | "RCP"
9565bd8deadSopenharmony_ci                             | "RSQ"
9575bd8deadSopenharmony_ci                             | <vp11-SCALARop>
9585bd8deadSopenharmony_ci                             | <vp2-SCALARop>
9595bd8deadSopenharmony_ci
9605bd8deadSopenharmony_ci    <vp11-SCALARop>        ::= "RCC"
9615bd8deadSopenharmony_ci
9625bd8deadSopenharmony_ci    <vp2-SCALARop>         ::= "COS"  | "COSC"
9635bd8deadSopenharmony_ci                             | "EX2"  | "EX2C"
9645bd8deadSopenharmony_ci                             | "LG2"  | "LG2C"
9655bd8deadSopenharmony_ci                             |          "EXPC"
9665bd8deadSopenharmony_ci                             |          "LOGC"
9675bd8deadSopenharmony_ci                             |          "RCCC"
9685bd8deadSopenharmony_ci                             |          "RCPC"
9695bd8deadSopenharmony_ci                             |          "RSQC"
9705bd8deadSopenharmony_ci                             | "SIN"  | "SINC"
9715bd8deadSopenharmony_ci
9725bd8deadSopenharmony_ci    <BINop-instruction>    ::= <BINop> <maskedDstReg> "," <vectorSrc> ","
9735bd8deadSopenharmony_ci                               <vectorSrc>
9745bd8deadSopenharmony_ci
9755bd8deadSopenharmony_ci    <BINop>                ::= "ADD"
9765bd8deadSopenharmony_ci                             | "DP3"
9775bd8deadSopenharmony_ci                             | "DP4"
9785bd8deadSopenharmony_ci                             | "DST"
9795bd8deadSopenharmony_ci                             | "MAX"
9805bd8deadSopenharmony_ci                             | "MIN"
9815bd8deadSopenharmony_ci                             | "MUL"
9825bd8deadSopenharmony_ci                             | "SGE"
9835bd8deadSopenharmony_ci                             | "SLT"
9845bd8deadSopenharmony_ci                             | <vp11-BINop>
9855bd8deadSopenharmony_ci                             | <vp2-BINop>
9865bd8deadSopenharmony_ci
9875bd8deadSopenharmony_ci    <vp11-BINop>           ::= "DPH"
9885bd8deadSopenharmony_ci                             | "SUB"
9895bd8deadSopenharmony_ci
9905bd8deadSopenharmony_ci    <vp2-BINop>            ::=         "ADDC"
9915bd8deadSopenharmony_ci                             |         "DP3C"
9925bd8deadSopenharmony_ci                             |         "DP4C"
9935bd8deadSopenharmony_ci                             |         "DPHC"
9945bd8deadSopenharmony_ci                             |         "DSTC"
9955bd8deadSopenharmony_ci                             |         "MAXC"
9965bd8deadSopenharmony_ci                             |         "MINC"
9975bd8deadSopenharmony_ci                             |         "MULC"
9985bd8deadSopenharmony_ci                             | "SEQ" | "SEQC"
9995bd8deadSopenharmony_ci                             | "SFL" | "SFLC"
10005bd8deadSopenharmony_ci                             |         "SGEC"
10015bd8deadSopenharmony_ci                             | "SGT" | "SGTC"
10025bd8deadSopenharmony_ci                             |         "SLTC"
10035bd8deadSopenharmony_ci                             | "SLE" | "SLEC"
10045bd8deadSopenharmony_ci                             | "SNE" | "SNEC"
10055bd8deadSopenharmony_ci                             | "STR" | "STRC"
10065bd8deadSopenharmony_ci                             |         "SUBC"
10075bd8deadSopenharmony_ci
10085bd8deadSopenharmony_ci    <TRIop-instruction>    ::= <TRIop> <maskedDstReg> "," <vectorSrc> "," 
10095bd8deadSopenharmony_ci                               <vectorSrc> "," <vectorSrc>
10105bd8deadSopenharmony_ci
10115bd8deadSopenharmony_ci    <TRIop>                ::= "MAD"
10125bd8deadSopenharmony_ci                             | <vp2-TRIop>
10135bd8deadSopenharmony_ci
10145bd8deadSopenharmony_ci    <vp2-TRIop>            ::= "MADC"
10155bd8deadSopenharmony_ci
10165bd8deadSopenharmony_ci    <vp2-BRA-instruction>  ::= <vp2-BRANCHop> <vp2-branchLabel>
10175bd8deadSopenharmony_ci                                 <vp2-branchCondition>
10185bd8deadSopenharmony_ci
10195bd8deadSopenharmony_ci    <vp2-BRANCHop>         ::= "BRA"
10205bd8deadSopenharmony_ci                             | "CAL"
10215bd8deadSopenharmony_ci
10225bd8deadSopenharmony_ci    <vp2-RET-instruction>  ::= "RET" <vp2-branchCondition>
10235bd8deadSopenharmony_ci
10245bd8deadSopenharmony_ci    <vp2-ARA-instruction>  ::= <vp2-ARAop> <maskedAddrReg> "," <addrRegister>
10255bd8deadSopenharmony_ci
10265bd8deadSopenharmony_ci    <vp2-ARAop>            ::= "ARA" | "ARAC"
10275bd8deadSopenharmony_ci
10285bd8deadSopenharmony_ci    <scalarSrc>            ::= <baseScalarSrc>
10295bd8deadSopenharmony_ci                             | <vp2-absScalarSrc>
10305bd8deadSopenharmony_ci
10315bd8deadSopenharmony_ci    <vp2-absScalarSrc>     ::= <optionalSign> "|" <baseScalarSrc> "|"
10325bd8deadSopenharmony_ci
10335bd8deadSopenharmony_ci    <baseScalarSrc>        ::= <optionalSign> <srcRegister> <scalarSuffix>
10345bd8deadSopenharmony_ci
10355bd8deadSopenharmony_ci    <vectorSrc>            ::= <baseVectorSrc>
10365bd8deadSopenharmony_ci                             | <vp2-absVectorSrc>
10375bd8deadSopenharmony_ci
10385bd8deadSopenharmony_ci    <vp2-absVectorSrc>     ::= <optionalSign> "|" <baseVectorSrc> "|"
10395bd8deadSopenharmony_ci
10405bd8deadSopenharmony_ci    <baseVectorSrc>        ::= <optionalSign> <srcRegister> <swizzleSuffix>
10415bd8deadSopenharmony_ci
10425bd8deadSopenharmony_ci    <srcRegister>          ::= <vtxAttribRegister>
10435bd8deadSopenharmony_ci                             | <progParamRegister>
10445bd8deadSopenharmony_ci                             | <tempRegister>
10455bd8deadSopenharmony_ci
10465bd8deadSopenharmony_ci    <maskedDstReg>         ::= <dstRegister> <optionalWriteMask> 
10475bd8deadSopenharmony_ci                                   <optionalCCMask> 
10485bd8deadSopenharmony_ci
10495bd8deadSopenharmony_ci    <dstRegister>          ::= <vtxResultRegister>
10505bd8deadSopenharmony_ci                             | <tempRegister>
10515bd8deadSopenharmony_ci                             | <vp2-nullRegister>
10525bd8deadSopenharmony_ci
10535bd8deadSopenharmony_ci    <vp2-nullRegister>     ::= "CC"
10545bd8deadSopenharmony_ci
10555bd8deadSopenharmony_ci    <vp2-branchCondition>  ::= <optionalCCMask>
10565bd8deadSopenharmony_ci
10575bd8deadSopenharmony_ci    <vtxAttribRegister>    ::= "v" "[" vtxAttribRegNum "]"
10585bd8deadSopenharmony_ci
10595bd8deadSopenharmony_ci    <vtxAttribRegNum>      ::= decimal integer from 0 to 15 inclusive
10605bd8deadSopenharmony_ci                             | "OPOS"
10615bd8deadSopenharmony_ci                             | "WGHT"
10625bd8deadSopenharmony_ci                             | "NRML"
10635bd8deadSopenharmony_ci                             | "COL0"
10645bd8deadSopenharmony_ci                             | "COL1"
10655bd8deadSopenharmony_ci                             | "FOGC"
10665bd8deadSopenharmony_ci                             | "TEX0"
10675bd8deadSopenharmony_ci                             | "TEX1"
10685bd8deadSopenharmony_ci                             | "TEX2"
10695bd8deadSopenharmony_ci                             | "TEX3"
10705bd8deadSopenharmony_ci                             | "TEX4"
10715bd8deadSopenharmony_ci                             | "TEX5"
10725bd8deadSopenharmony_ci                             | "TEX6"
10735bd8deadSopenharmony_ci                             | "TEX7"
10745bd8deadSopenharmony_ci
10755bd8deadSopenharmony_ci    <progParamRegister>    ::= <absProgParamReg>
10765bd8deadSopenharmony_ci                             | <relProgParamReg>
10775bd8deadSopenharmony_ci
10785bd8deadSopenharmony_ci    <absProgParamReg>      ::= "c" "[" <progParamRegNum> "]"
10795bd8deadSopenharmony_ci
10805bd8deadSopenharmony_ci    <progParamRegNum>      ::= <vp1-progParamRegNum>
10815bd8deadSopenharmony_ci                             | <vp2-progParamRegNum>
10825bd8deadSopenharmony_ci
10835bd8deadSopenharmony_ci    <vp1-progParamRegNum>  ::= decimal integer from 0 to 95 inclusive
10845bd8deadSopenharmony_ci
10855bd8deadSopenharmony_ci    <vp2-progParamRegNum>  ::= decimal integer from 0 to 255 inclusive
10865bd8deadSopenharmony_ci
10875bd8deadSopenharmony_ci    <relProgParamReg>      ::= "c" "[" <scalarAddr> <relProgParamOffset> "]"
10885bd8deadSopenharmony_ci
10895bd8deadSopenharmony_ci    <relProgParamOffset>   ::= ""
10905bd8deadSopenharmony_ci                             | "+" <progParamPosOffset>
10915bd8deadSopenharmony_ci                             | "-" <progParamNegOffset>
10925bd8deadSopenharmony_ci
10935bd8deadSopenharmony_ci    <progParamPosOffset>   ::= <vp1-progParamPosOff>
10945bd8deadSopenharmony_ci                             | <vp2-progParamPosOff>
10955bd8deadSopenharmony_ci
10965bd8deadSopenharmony_ci    <vp1-progParamPosOff>  ::= decimal integer from 0 to 63 inclusive
10975bd8deadSopenharmony_ci
10985bd8deadSopenharmony_ci    <vp2-progParamPosOff>  ::= decimal integer from 0 to 255 inclusive
10995bd8deadSopenharmony_ci
11005bd8deadSopenharmony_ci    <progParamNegOffset>   ::= <vp1-progParamNegOff>
11015bd8deadSopenharmony_ci                             | <vp2-progParamNegOff>
11025bd8deadSopenharmony_ci
11035bd8deadSopenharmony_ci    <vp1-progParamNegOff>  ::= decimal integer from 0 to 64 inclusive
11045bd8deadSopenharmony_ci
11055bd8deadSopenharmony_ci    <vp2-progParamNegOff>  ::= decimal integer from 0 to 256 inclusive
11065bd8deadSopenharmony_ci
11075bd8deadSopenharmony_ci    <tempRegister>         ::= "R0"  | "R1"  | "R2"  | "R3"
11085bd8deadSopenharmony_ci                             | "R4"  | "R5"  | "R6"  | "R7"
11095bd8deadSopenharmony_ci                             | "R8"  | "R9"  | "R10" | "R11"
11105bd8deadSopenharmony_ci
11115bd8deadSopenharmony_ci    <vp2-tempRegister>     ::= "R12" | "R13" | "R14" | "R15" 
11125bd8deadSopenharmony_ci
11135bd8deadSopenharmony_ci    <vtxResultRegister>    ::= "o" "[" <vtxResultRegName> "]"
11145bd8deadSopenharmony_ci
11155bd8deadSopenharmony_ci    <vtxResultRegName>     ::= "HPOS"
11165bd8deadSopenharmony_ci                             | "COL0"
11175bd8deadSopenharmony_ci                             | "COL1"
11185bd8deadSopenharmony_ci                             | "BFC0"
11195bd8deadSopenharmony_ci                             | "BFC1"
11205bd8deadSopenharmony_ci                             | "FOGC"
11215bd8deadSopenharmony_ci                             | "PSIZ"
11225bd8deadSopenharmony_ci                             | "TEX0"
11235bd8deadSopenharmony_ci                             | "TEX1"
11245bd8deadSopenharmony_ci                             | "TEX2"
11255bd8deadSopenharmony_ci                             | "TEX3"
11265bd8deadSopenharmony_ci                             | "TEX4"
11275bd8deadSopenharmony_ci                             | "TEX5"
11285bd8deadSopenharmony_ci                             | "TEX6"
11295bd8deadSopenharmony_ci                             | "TEX7"
11305bd8deadSopenharmony_ci                             | <vp2-resultRegName>
11315bd8deadSopenharmony_ci
11325bd8deadSopenharmony_ci    <vp2-resultRegName>    ::= "CLP0"
11335bd8deadSopenharmony_ci                             | "CLP1"
11345bd8deadSopenharmony_ci                             | "CLP2"
11355bd8deadSopenharmony_ci                             | "CLP3"
11365bd8deadSopenharmony_ci                             | "CLP4"
11375bd8deadSopenharmony_ci                             | "CLP5"
11385bd8deadSopenharmony_ci
11395bd8deadSopenharmony_ci    <scalarAddr>           ::= <addrRegister> "." <addrRegisterComp>
11405bd8deadSopenharmony_ci
11415bd8deadSopenharmony_ci    <maskedAddrReg>        ::= <addrRegister> <addrWriteMask>
11425bd8deadSopenharmony_ci
11435bd8deadSopenharmony_ci    <addrRegister>         ::= "A0"
11445bd8deadSopenharmony_ci                             | <vp2-addrRegister>
11455bd8deadSopenharmony_ci
11465bd8deadSopenharmony_ci    <vp2-addrRegister>     ::= "A1"
11475bd8deadSopenharmony_ci
11485bd8deadSopenharmony_ci    <addrRegisterComp>     ::= "x"
11495bd8deadSopenharmony_ci                             | <vp2-addrRegisterComp>
11505bd8deadSopenharmony_ci
11515bd8deadSopenharmony_ci    <vp2-addrRegisterComp> ::= "y"
11525bd8deadSopenharmony_ci                             | "z"
11535bd8deadSopenharmony_ci                             | "w"
11545bd8deadSopenharmony_ci
11555bd8deadSopenharmony_ci    <addrWriteMask>        ::= "." "x"
11565bd8deadSopenharmony_ci                             | <vp2-addrWriteMask>
11575bd8deadSopenharmony_ci
11585bd8deadSopenharmony_ci    <vp2-addrWriteMask>     ::= ""
11595bd8deadSopenharmony_ci                             | "."     "y"
11605bd8deadSopenharmony_ci                             | "." "x" "y"
11615bd8deadSopenharmony_ci                             | "."         "z"
11625bd8deadSopenharmony_ci                             | "." "x"     "z"
11635bd8deadSopenharmony_ci                             | "."     "y" "z"
11645bd8deadSopenharmony_ci                             | "." "x" "y" "z"
11655bd8deadSopenharmony_ci                             | "."             "w"
11665bd8deadSopenharmony_ci                             | "." "x"         "w"
11675bd8deadSopenharmony_ci                             | "."     "y"     "w"
11685bd8deadSopenharmony_ci                             | "." "x" "y"     "w"
11695bd8deadSopenharmony_ci                             | "."         "z" "w"
11705bd8deadSopenharmony_ci                             | "." "x"     "z" "w"
11715bd8deadSopenharmony_ci                             | "."     "y" "z" "w"
11725bd8deadSopenharmony_ci                             | "." "x" "y" "z" "w"
11735bd8deadSopenharmony_ci
11745bd8deadSopenharmony_ci    
11755bd8deadSopenharmony_ci    <optionalSign>         ::= ""
11765bd8deadSopenharmony_ci                             | "-" 
11775bd8deadSopenharmony_ci                             | <vp2-optionalSign>
11785bd8deadSopenharmony_ci
11795bd8deadSopenharmony_ci    <vp2-optionalSign>     ::= "+"
11805bd8deadSopenharmony_ci
11815bd8deadSopenharmony_ci    <vp2-instructionLabel> ::= <vp2-branchLabel> ":"
11825bd8deadSopenharmony_ci
11835bd8deadSopenharmony_ci    <vp2-branchLabel>      ::= <identifier>
11845bd8deadSopenharmony_ci
11855bd8deadSopenharmony_ci    <optionalWriteMask>    ::= ""
11865bd8deadSopenharmony_ci                             | "." "x"
11875bd8deadSopenharmony_ci                             | "."     "y"
11885bd8deadSopenharmony_ci                             | "." "x" "y"
11895bd8deadSopenharmony_ci                             | "."         "z"
11905bd8deadSopenharmony_ci                             | "." "x"     "z"
11915bd8deadSopenharmony_ci                             | "."     "y" "z"
11925bd8deadSopenharmony_ci                             | "." "x" "y" "z"
11935bd8deadSopenharmony_ci                             | "."             "w"
11945bd8deadSopenharmony_ci                             | "." "x"         "w"
11955bd8deadSopenharmony_ci                             | "."     "y"     "w"
11965bd8deadSopenharmony_ci                             | "." "x" "y"     "w"
11975bd8deadSopenharmony_ci                             | "."         "z" "w"
11985bd8deadSopenharmony_ci                             | "." "x"     "z" "w"
11995bd8deadSopenharmony_ci                             | "."     "y" "z" "w"
12005bd8deadSopenharmony_ci                             | "." "x" "y" "z" "w"
12015bd8deadSopenharmony_ci
12025bd8deadSopenharmony_ci    <optionalCCMask>       ::= ""
12035bd8deadSopenharmony_ci                             | <vp2-ccMask>
12045bd8deadSopenharmony_ci
12055bd8deadSopenharmony_ci    <vp2-ccMask>           ::= "(" <vp2-ccMaskRule> <swizzleSuffix> ")"
12065bd8deadSopenharmony_ci
12075bd8deadSopenharmony_ci    <vp2-ccMaskRule>       ::= "EQ" | "GE" | "GT" | "LE" | "LT" | "NE" 
12085bd8deadSopenharmony_ci                             | "TR" | "FL"
12095bd8deadSopenharmony_ci
12105bd8deadSopenharmony_ci    <scalarSuffix>         ::= "." <component>
12115bd8deadSopenharmony_ci
12125bd8deadSopenharmony_ci    <swizzleSuffix>        ::= ""
12135bd8deadSopenharmony_ci                             | "." <component>
12145bd8deadSopenharmony_ci                             | "." <component> <component>
12155bd8deadSopenharmony_ci                                   <component> <component>
12165bd8deadSopenharmony_ci
12175bd8deadSopenharmony_ci    <component>            ::= "x" 
12185bd8deadSopenharmony_ci                             | "y" 
12195bd8deadSopenharmony_ci                             | "z" 
12205bd8deadSopenharmony_ci                             | "w"
12215bd8deadSopenharmony_ci
12225bd8deadSopenharmony_ci    The <identifier> rule matches a sequence of one or more letters ("A"
12235bd8deadSopenharmony_ci    through "Z", "a" through "z", and "_") and digits ("0" through "9); the
12245bd8deadSopenharmony_ci    first character must be a letter.  The underscore ("_") counts as a
12255bd8deadSopenharmony_ci    letter.  Upper and lower case letters are different (names are
12265bd8deadSopenharmony_ci    case-sensitive).
12275bd8deadSopenharmony_ci
12285bd8deadSopenharmony_ci    The <vertexAttribRegNum> rule matches both register numbers 0 through 15
12295bd8deadSopenharmony_ci    and a set of mnemonics that abbreviate the aliasing of conventional
12305bd8deadSopenharmony_ci    per-vertex parameters to vertex attribute register numbers.  Table X.3
12315bd8deadSopenharmony_ci    shows the mapping from mnemonic to vertex attribute register number and
12325bd8deadSopenharmony_ci    what the mnemonic abbreviates.
12335bd8deadSopenharmony_ci
12345bd8deadSopenharmony_ci                   Vertex Attribute
12355bd8deadSopenharmony_ci        Mnemonic   Register Number     Meaning
12365bd8deadSopenharmony_ci        --------   ----------------    --------------------
12375bd8deadSopenharmony_ci         "OPOS"     0                  object position
12385bd8deadSopenharmony_ci         "WGHT"     1                  vertex weight
12395bd8deadSopenharmony_ci         "NRML"     2                  normal
12405bd8deadSopenharmony_ci         "COL0"     3                  primary color
12415bd8deadSopenharmony_ci         "COL1"     4                  secondary color
12425bd8deadSopenharmony_ci         "FOGC"     5                  fog coordinate
12435bd8deadSopenharmony_ci         "TEX0"     8                  texture coordinate 0
12445bd8deadSopenharmony_ci         "TEX1"     9                  texture coordinate 1
12455bd8deadSopenharmony_ci         "TEX2"     10                 texture coordinate 2
12465bd8deadSopenharmony_ci         "TEX3"     11                 texture coordinate 3
12475bd8deadSopenharmony_ci         "TEX4"     12                 texture coordinate 4
12485bd8deadSopenharmony_ci         "TEX5"     13                 texture coordinate 5
12495bd8deadSopenharmony_ci         "TEX6"     14                 texture coordinate 6
12505bd8deadSopenharmony_ci         "TEX7"     15                 texture coordinate 7
12515bd8deadSopenharmony_ci
12525bd8deadSopenharmony_ci        Table X.3:  The mapping between vertex attribute register numbers,
12535bd8deadSopenharmony_ci        mnemonics, and meanings.
12545bd8deadSopenharmony_ci
12555bd8deadSopenharmony_ci    A vertex program fails to load if it does not write at least one component
12565bd8deadSopenharmony_ci    of the HPOS register.
12575bd8deadSopenharmony_ci
12585bd8deadSopenharmony_ci    A vertex program fails to load in the VP1 execution environment if it
12595bd8deadSopenharmony_ci    contains more than 128 instructions.  A vertex program fails to load in
12605bd8deadSopenharmony_ci    the VP2 execution environment if it contains more than 256 instructions.
12615bd8deadSopenharmony_ci    Each block of text matching the <instruction> rule counts as an
12625bd8deadSopenharmony_ci    instruction.
12635bd8deadSopenharmony_ci
12645bd8deadSopenharmony_ci    A vertex program fails to load if any instruction sources more than one
12655bd8deadSopenharmony_ci    unique program parameter register.  An instruction can match the
12665bd8deadSopenharmony_ci    <progParamRegister> rule more than once only if all such matches are
12675bd8deadSopenharmony_ci    identical.
12685bd8deadSopenharmony_ci
12695bd8deadSopenharmony_ci    A vertex program fails to load if any instruction sources more than one
12705bd8deadSopenharmony_ci    unique vertex attribute register.  An instruction can match the
12715bd8deadSopenharmony_ci    <vtxAttribRegister> rule more than once only if all such matches refer to
12725bd8deadSopenharmony_ci    the same register.
12735bd8deadSopenharmony_ci
12745bd8deadSopenharmony_ci    The error INVALID_OPERATION is generated if a vertex program fails to load
12755bd8deadSopenharmony_ci    because it is not syntactically correct or for one of the semantic
12765bd8deadSopenharmony_ci    restrictions listed above.
12775bd8deadSopenharmony_ci
12785bd8deadSopenharmony_ci    The error INVALID_OPERATION is generated if a program is loaded for id
12795bd8deadSopenharmony_ci    when id is currently loaded with a program of a different target.
12805bd8deadSopenharmony_ci
12815bd8deadSopenharmony_ci    A successfully loaded vertex program is parsed into a sequence of
12825bd8deadSopenharmony_ci    instructions.  Each instruction is identified by its tokenized name.  The
12835bd8deadSopenharmony_ci    operation of these instructions when executed is defined in section
12845bd8deadSopenharmony_ci    2.14.1.10.
12855bd8deadSopenharmony_ci
12865bd8deadSopenharmony_ci    A successfully loaded program replaces the program previously assigned to
12875bd8deadSopenharmony_ci    the name specified by id.  If the OUT_OF_MEMORY error is generated by
12885bd8deadSopenharmony_ci    LoadProgramNV, no change is made to the previous contents of the named
12895bd8deadSopenharmony_ci    program.
12905bd8deadSopenharmony_ci
12915bd8deadSopenharmony_ci    Querying the value of PROGRAM_ERROR_POSITION_NV returns a ubyte offset
12925bd8deadSopenharmony_ci    into the last loaded program string indicating where the first error in
12935bd8deadSopenharmony_ci    the program.  If the program fails to load because of a semantic
12945bd8deadSopenharmony_ci    restriction that cannot be determined until the program is fully scanned,
12955bd8deadSopenharmony_ci    the error position will be len, the length of the program.  If the program
12965bd8deadSopenharmony_ci    loads successfully, the value of PROGRAM_ERROR_POSITION_NV is assigned the
12975bd8deadSopenharmony_ci    value negative one.
12985bd8deadSopenharmony_ci
12995bd8deadSopenharmony_ci
13005bd8deadSopenharmony_ci    Section 2.14.1.9,  Vertex Program Binding and Program Management
13015bd8deadSopenharmony_ci
13025bd8deadSopenharmony_ci    The current vertex program is invoked whenever vertex attribute zero is
13035bd8deadSopenharmony_ci    updated (whether by a VertexAttributeNV or Vertex command).  The current
13045bd8deadSopenharmony_ci    vertex program is updated by
13055bd8deadSopenharmony_ci
13065bd8deadSopenharmony_ci      BindProgramNV(enum target, uint id);
13075bd8deadSopenharmony_ci
13085bd8deadSopenharmony_ci    where target must be VERTEX_PROGRAM_NV.  This binds the vertex program
13095bd8deadSopenharmony_ci    named by id as the current vertex program. The error INVALID_OPERATION
13105bd8deadSopenharmony_ci    is generated if id names a program that is not a vertex program
13115bd8deadSopenharmony_ci    (for example, if id names a vertex state program as described in
13125bd8deadSopenharmony_ci    section 2.14.4).  
13135bd8deadSopenharmony_ci
13145bd8deadSopenharmony_ci    Binding to a nonexistent program id does not generate an error.
13155bd8deadSopenharmony_ci    In particular, binding to program id zero does not generate an error.
13165bd8deadSopenharmony_ci    However, because program zero cannot be loaded, program zero is
13175bd8deadSopenharmony_ci    always nonexistent.  If a program id is successfully loaded with a
13185bd8deadSopenharmony_ci    new vertex program and id is also the currently bound vertex program,
13195bd8deadSopenharmony_ci    the new program is considered the currently bound vertex program.
13205bd8deadSopenharmony_ci
13215bd8deadSopenharmony_ci    The INVALID_OPERATION error is generated when both vertex program
13225bd8deadSopenharmony_ci    mode is enabled and Begin is called (or when a command that performs
13235bd8deadSopenharmony_ci    an implicit Begin is called) if the current vertex program is
13245bd8deadSopenharmony_ci    nonexistent or not valid.  A vertex program may not be valid for
13255bd8deadSopenharmony_ci    reasons explained in section 2.14.5.
13265bd8deadSopenharmony_ci
13275bd8deadSopenharmony_ci    Programs are deleted by calling
13285bd8deadSopenharmony_ci
13295bd8deadSopenharmony_ci      void DeleteProgramsNV(sizei n, const uint *ids);
13305bd8deadSopenharmony_ci
13315bd8deadSopenharmony_ci    ids contains n names of programs to be deleted.  After a program
13325bd8deadSopenharmony_ci    is deleted, it becomes nonexistent, and its name is again unused.
13335bd8deadSopenharmony_ci    If a program that is currently bound is deleted, it is as though
13345bd8deadSopenharmony_ci    BindProgramNV has been executed with the same target as the deleted
13355bd8deadSopenharmony_ci    program and program zero.  Unused names in ids are silently ignored,
13365bd8deadSopenharmony_ci    as is the value zero.
13375bd8deadSopenharmony_ci
13385bd8deadSopenharmony_ci    The command
13395bd8deadSopenharmony_ci
13405bd8deadSopenharmony_ci      void GenProgramsNV(sizei n, uint *ids);
13415bd8deadSopenharmony_ci
13425bd8deadSopenharmony_ci    returns n previously unused program names in ids.  These names
13435bd8deadSopenharmony_ci    are marked as used, for the purposes of GenProgramsNV only,
13445bd8deadSopenharmony_ci    but they become existent programs only when the are first loaded
13455bd8deadSopenharmony_ci    using LoadProgramNV.  The error INVALID_VALUE is generated if n
13465bd8deadSopenharmony_ci    is negative.
13475bd8deadSopenharmony_ci
13485bd8deadSopenharmony_ci    An implementation may choose to establish a working set of programs on
13495bd8deadSopenharmony_ci    which binding and ExecuteProgramNV operations (execute programs are
13505bd8deadSopenharmony_ci    explained in section 2.14.4) are performed with higher performance.
13515bd8deadSopenharmony_ci    A program that is currently part of this working set is said to
13525bd8deadSopenharmony_ci    be resident.
13535bd8deadSopenharmony_ci
13545bd8deadSopenharmony_ci    The command
13555bd8deadSopenharmony_ci      
13565bd8deadSopenharmony_ci      boolean AreProgramsResidentNV(sizei n, const uint *ids,
13575bd8deadSopenharmony_ci                                    boolean *residences);
13585bd8deadSopenharmony_ci
13595bd8deadSopenharmony_ci    returns TRUE if all of the n programs named in ids are resident,
13605bd8deadSopenharmony_ci    or if the implementation does not distinguish a working set.  If at
13615bd8deadSopenharmony_ci    least one of the programs named in ids is not resident, then FALSE is
13625bd8deadSopenharmony_ci    returned, and the residence of each program is returned in residences.
13635bd8deadSopenharmony_ci    Otherwise the contents of residences are not changed.  If any of
13645bd8deadSopenharmony_ci    the names in ids are nonexistent or zero, FALSE is returned, the
13655bd8deadSopenharmony_ci    error INVALID_VALUE is generated, and the contents of residences
13665bd8deadSopenharmony_ci    are indeterminate.  The residence status of a single named program
13675bd8deadSopenharmony_ci    can also be queried by calling GetProgramivNV with id set to the
13685bd8deadSopenharmony_ci    name of the program and pname set to PROGRAM_RESIDENT_NV.
13695bd8deadSopenharmony_ci
13705bd8deadSopenharmony_ci    AreProgramsResidentNV indicates only whether a program is
13715bd8deadSopenharmony_ci    currently resident, not whether it could not be made resident.
13725bd8deadSopenharmony_ci    An implementation may choose to make a program resident only on
13735bd8deadSopenharmony_ci    first use, for example.  The client may guide the GL implementation
13745bd8deadSopenharmony_ci    in determining which programs should be resident by requesting a
13755bd8deadSopenharmony_ci    set of programs to make resident.
13765bd8deadSopenharmony_ci
13775bd8deadSopenharmony_ci    The command
13785bd8deadSopenharmony_ci
13795bd8deadSopenharmony_ci      void RequestResidentProgramsNV(sizei n, const uint *ids);
13805bd8deadSopenharmony_ci
13815bd8deadSopenharmony_ci    requests that the n programs named in ids should be made resident.
13825bd8deadSopenharmony_ci    While all the programs are not guaranteed to become resident,
13835bd8deadSopenharmony_ci    the implementation should make a best effort to make as many of
13845bd8deadSopenharmony_ci    the programs resident as possible.  As a result of making the
13855bd8deadSopenharmony_ci    requested programs resident, program names not among the requested
13865bd8deadSopenharmony_ci    programs may become non-resident.  Higher priority for residency
13875bd8deadSopenharmony_ci    should be given to programs listed earlier in the ids array.
13885bd8deadSopenharmony_ci    RequestResidentProgramsNV silently ignores attempts to make resident
13895bd8deadSopenharmony_ci    nonexistent program names or zero.  AreProgramsResidentNV can be
13905bd8deadSopenharmony_ci    called after RequestResidentProgramsNV to determine which programs
13915bd8deadSopenharmony_ci    actually became resident.
13925bd8deadSopenharmony_ci
13935bd8deadSopenharmony_ci
13945bd8deadSopenharmony_ci    Section 2.14.2,  Vertex Program Operation
13955bd8deadSopenharmony_ci
13965bd8deadSopenharmony_ci    In the VP1 execution environment, there are twenty-one vertex program
13975bd8deadSopenharmony_ci    instructions.  Four instructions (ABS, DPH, RCC, and SUB) are available
13985bd8deadSopenharmony_ci    only in the VP1.1 execution environment.  The instructions and their
13995bd8deadSopenharmony_ci    respective input and output parameters are summarized in Table X.4.
14005bd8deadSopenharmony_ci
14015bd8deadSopenharmony_ci      Instruction    Inputs  Output   Description
14025bd8deadSopenharmony_ci      -----------    ------  ------   --------------------------------
14035bd8deadSopenharmony_ci      ABS(*)         v       v        absolute value
14045bd8deadSopenharmony_ci      ADD            v,v     v        add
14055bd8deadSopenharmony_ci      ARL            v       as       address register load
14065bd8deadSopenharmony_ci      DP3            v,v     ssss     3-component dot product
14075bd8deadSopenharmony_ci      DP4            v,v     ssss     4-component dot product
14085bd8deadSopenharmony_ci      DPH(*)         v,v     ssss     homogeneous dot product
14095bd8deadSopenharmony_ci      DST            v,v     v        distance vector
14105bd8deadSopenharmony_ci      EXP            s       v        exponential base 2 (approximate)
14115bd8deadSopenharmony_ci      LIT            v       v        compute light coefficients
14125bd8deadSopenharmony_ci      LOG            s       v        logarithm base 2 (approximate)
14135bd8deadSopenharmony_ci      MAD            v,v,v   v        multiply and add
14145bd8deadSopenharmony_ci      MAX            v,v     v        maximum
14155bd8deadSopenharmony_ci      MIN            v,v     v        minimum
14165bd8deadSopenharmony_ci      MOV            v       v        move
14175bd8deadSopenharmony_ci      MUL            v,v     v        multiply
14185bd8deadSopenharmony_ci      RCC(*)         s       ssss     reciprocal (clamped)
14195bd8deadSopenharmony_ci      RCP            s       ssss     reciprocal
14205bd8deadSopenharmony_ci      RSQ            s       ssss     reciprocal square root
14215bd8deadSopenharmony_ci      SGE            v,v     v        set on greater than or equal
14225bd8deadSopenharmony_ci      SLT            v,v     v        set on less than
14235bd8deadSopenharmony_ci      SUB(*)         v,v     v        subtract
14245bd8deadSopenharmony_ci
14255bd8deadSopenharmony_ci    Table X.4:  Summary of vertex program instructions in the VP1 execution
14265bd8deadSopenharmony_ci    environment.  "v" indicates a floating-point vector input or output, "s"
14275bd8deadSopenharmony_ci    indicates a floating-point scalar input, "ssss" indicates a scalar output
14285bd8deadSopenharmony_ci    replicated across a 4-component vector, "as" indicates a single component
14295bd8deadSopenharmony_ci    of an address register.
14305bd8deadSopenharmony_ci
14315bd8deadSopenharmony_ci
14325bd8deadSopenharmony_ci    In the VP2 execution environment, are thirty-nine vertex program
14335bd8deadSopenharmony_ci    instructions.  Vertex program instructions may have an optional suffix of
14345bd8deadSopenharmony_ci    "C" to allow an update of the condition code register (section 2.14.1.6).
14355bd8deadSopenharmony_ci    For example, there are two instructions to perform vector addition, "ADD"
14365bd8deadSopenharmony_ci    and "ADDC".  The vertex program instructions available in the VP2
14375bd8deadSopenharmony_ci    execution environment and their respective input and output parameters are
14385bd8deadSopenharmony_ci    summarized in Table X.5.
14395bd8deadSopenharmony_ci
14405bd8deadSopenharmony_ci      Instruction    Inputs  Output   Description
14415bd8deadSopenharmony_ci      -----------    ------  ------   --------------------------------
14425bd8deadSopenharmony_ci      ABS[C]         v       v        absolute value
14435bd8deadSopenharmony_ci      ADD[C]         v,v     v        add
14445bd8deadSopenharmony_ci      ARA[C]         av      av       address register add
14455bd8deadSopenharmony_ci      ARL[C]         v       av       address register load
14465bd8deadSopenharmony_ci      ARR[C]         v       av       address register load (with round)
14475bd8deadSopenharmony_ci      BRA            as      none     branch
14485bd8deadSopenharmony_ci      CAL            as      none     subroutine call
14495bd8deadSopenharmony_ci      COS[C]         s       ssss     cosine
14505bd8deadSopenharmony_ci      DP3[C]         v,v     ssss     3-component dot product
14515bd8deadSopenharmony_ci      DP4[C]         v,v     ssss     4-component dot product
14525bd8deadSopenharmony_ci      DPH[C]         v,v     ssss     homogeneous dot product
14535bd8deadSopenharmony_ci      DST[C]         v,v     v        distance vector
14545bd8deadSopenharmony_ci      EX2[C]         s       ssss     exponential base 2
14555bd8deadSopenharmony_ci      EXP[C]         s       v        exponential base 2 (approximate)
14565bd8deadSopenharmony_ci      FLR[C]         v       v        floor
14575bd8deadSopenharmony_ci      FRC[C]         v       v        fraction
14585bd8deadSopenharmony_ci      LG2[C]         s       ssss     logarithm base 2
14595bd8deadSopenharmony_ci      LIT[C]         v       v        compute light coefficients
14605bd8deadSopenharmony_ci      LOG[C]         s       v        logarithm base 2 (approximate)
14615bd8deadSopenharmony_ci      MAD[C]         v,v,v   v        multiply and add
14625bd8deadSopenharmony_ci      MAX[C]         v,v     v        maximum
14635bd8deadSopenharmony_ci      MIN[C]         v,v     v        minimum
14645bd8deadSopenharmony_ci      MOV[C]         v       v        move
14655bd8deadSopenharmony_ci      MUL[C]         v,v     v        multiply
14665bd8deadSopenharmony_ci      RCC[C]         s       ssss     reciprocal (clamped)
14675bd8deadSopenharmony_ci      RCP[C]         s       ssss     reciprocal
14685bd8deadSopenharmony_ci      RET            none    none     subroutine call return
14695bd8deadSopenharmony_ci      RSQ[C]         s       ssss     reciprocal square root
14705bd8deadSopenharmony_ci      SEQ[C]         v,v     v        set on equal
14715bd8deadSopenharmony_ci      SFL[C]         v,v     v        set on false
14725bd8deadSopenharmony_ci      SGE[C]         v,v     v        set on greater than or equal
14735bd8deadSopenharmony_ci      SGT[C]         v,v     v        set on greater than
14745bd8deadSopenharmony_ci      SIN[C]         s       ssss     sine
14755bd8deadSopenharmony_ci      SLE[C]         v,v     v        set on less than or equal
14765bd8deadSopenharmony_ci      SLT[C]         v,v     v        set on less than
14775bd8deadSopenharmony_ci      SNE[C]         v,v     v        set on not equal
14785bd8deadSopenharmony_ci      SSG[C]         v       v        set sign
14795bd8deadSopenharmony_ci      STR[C]         v,v     v        set on true
14805bd8deadSopenharmony_ci      SUB[C]         v,v     v        subtract
14815bd8deadSopenharmony_ci
14825bd8deadSopenharmony_ci    Table X.5:  Summary of vertex program instructions in the VP2 execution
14835bd8deadSopenharmony_ci    environment.  "v" indicates a floating-point vector input or output, "s"
14845bd8deadSopenharmony_ci    indicates a floating-point scalar input, "ssss" indicates a scalar output
14855bd8deadSopenharmony_ci    replicated across a 4-component vector, "av" indicates a full address
14865bd8deadSopenharmony_ci    register, "as" indicates a single component of an address register.
14875bd8deadSopenharmony_ci
14885bd8deadSopenharmony_ci
14895bd8deadSopenharmony_ci    Section 2.14.2.1,  Vertex Program Operands
14905bd8deadSopenharmony_ci
14915bd8deadSopenharmony_ci    Most vertex program instructions operate on floating-point vectors,
14925bd8deadSopenharmony_ci    floating-point scalars, or integer scalars as, indicated in the grammar
14935bd8deadSopenharmony_ci    (see section 2.14.1.8) by the rules <vectorSrc>, <scalarSrc>, and
14945bd8deadSopenharmony_ci    <scalarAddr>, respectively.
14955bd8deadSopenharmony_ci
14965bd8deadSopenharmony_ci    The basic set of floating-point scalar operands is defined by the grammar
14975bd8deadSopenharmony_ci    rule <baseScalarSrc>.  Scalar operands are single components of vertex
14985bd8deadSopenharmony_ci    attribute, program parameter, or temporary registers, as allowed by the
14995bd8deadSopenharmony_ci    <srcRegister> rule.  A vector component is selected by the <scalarSuffix>
15005bd8deadSopenharmony_ci    rule, where the characters "x", "y", "z", and "w" select the x, y, z, and
15015bd8deadSopenharmony_ci    w components, respectively, of the vector.
15025bd8deadSopenharmony_ci
15035bd8deadSopenharmony_ci    The basic set of floating-point vector operands is defined by the grammar
15045bd8deadSopenharmony_ci    rule <baseVectorSrc>.  Vector operands can be obtained from vertex
15055bd8deadSopenharmony_ci    attribute, program parameter, or temporary registers as allowed by the
15065bd8deadSopenharmony_ci    <srcRegister> rule.
15075bd8deadSopenharmony_ci
15085bd8deadSopenharmony_ci    Basic vector operands can be swizzled according to the <swizzleSuffix>
15095bd8deadSopenharmony_ci    rule.  In its most general form, the <swizzleSuffix> rule matches the
15105bd8deadSopenharmony_ci    pattern ".????" where each question mark is replaced with one of "x", "y",
15115bd8deadSopenharmony_ci    "z", or "w".  For such patterns, the x, y, z, and w components of the
15125bd8deadSopenharmony_ci    operand are taken from the vector components named by the first, second,
15135bd8deadSopenharmony_ci    third, and fourth character of the pattern, respectively.  For example, if
15145bd8deadSopenharmony_ci    the swizzle suffix is ".yzzx" and the specified source contains {2,8,9,0},
15155bd8deadSopenharmony_ci    the swizzled operand used by the instruction is {8,9,9,2}.  
15165bd8deadSopenharmony_ci
15175bd8deadSopenharmony_ci    If the <swizzleSuffix> rule matches "", it is treated as though it were
15185bd8deadSopenharmony_ci    ".xyzw".  If the <swizzleSuffix> rule matches (ignoring whitespace) ".x",
15195bd8deadSopenharmony_ci    ".y", ".z", or ".w", these are treated the same as ".xxxx", ".yyyy",
15205bd8deadSopenharmony_ci    ".zzzz", and ".wwww" respectively.
15215bd8deadSopenharmony_ci
15225bd8deadSopenharmony_ci    Floating-point scalar or vector operands can optionally be negated
15235bd8deadSopenharmony_ci    according to the <negate> rules in <baseScalarSrc> and <baseVectorSrc>.
15245bd8deadSopenharmony_ci    If the <negate> matches "-", each operand or operand component is negated.
15255bd8deadSopenharmony_ci
15265bd8deadSopenharmony_ci    In the VP2 execution environment, a component-wise absolute value
15275bd8deadSopenharmony_ci    operation is performed on an operand if the <scalarSrc> or <vectorSrc>
15285bd8deadSopenharmony_ci    rules match <vp2-absScalarSrc> or <vp2-absVectorSrc>.  In this case, the
15295bd8deadSopenharmony_ci    absolute value of each component of the operand is taken.  In addition, if
15305bd8deadSopenharmony_ci    the <negate> rule in <vp2-absScalarSrc> or <vp2-absVectorSrc> matches "-",
15315bd8deadSopenharmony_ci    each component is subsequently negated.
15325bd8deadSopenharmony_ci
15335bd8deadSopenharmony_ci    Integer scalar operands are single components of one of the address
15345bd8deadSopenharmony_ci    register vectors, as identified by the <addrRegister> rule.  A vector
15355bd8deadSopenharmony_ci    component is selected by the <scalarSuffix> rule in the same manner as
15365bd8deadSopenharmony_ci    floating-point scalar operands.  Negation and absolute value operations
15375bd8deadSopenharmony_ci    are not available for integer scalar operands.
15385bd8deadSopenharmony_ci
15395bd8deadSopenharmony_ci    The following pseudo-code spells out the operand generation process.  In
15405bd8deadSopenharmony_ci    the pseudo-code, "float" and "int" are floating-point and integer scalar
15415bd8deadSopenharmony_ci    types, while "floatVec" and "intVec" are four-component vectors.  "source"
15425bd8deadSopenharmony_ci    is the register used for the operand, matching the <srcRegister> or
15435bd8deadSopenharmony_ci    <addrRegister> rules.  "absolute" is TRUE if the operand matches the
15445bd8deadSopenharmony_ci    <vp2-absScalarSrc> or <vp2-absVectorSrc> rules, and FALSE otherwise.
15455bd8deadSopenharmony_ci    "negateBase" is TRUE if the <negate> rule in <baseScalarSrc> or
15465bd8deadSopenharmony_ci    <baseVectorSrc> matches "-" and FALSE otherwise.  "negateAbs" is TRUE if
15475bd8deadSopenharmony_ci    the <negate> rule in <vp2-absScalarSrc> or <vp2-absVectorSrc> matches "-"
15485bd8deadSopenharmony_ci    and FALSE otherwise.  The ".c***", ".*c**", ".**c*", ".***c" modifiers
15495bd8deadSopenharmony_ci    refer to the x, y, z, and w components obtained by the swizzle operation.
15505bd8deadSopenharmony_ci
15515bd8deadSopenharmony_ci      floatVec VectorLoad(floatVec source)
15525bd8deadSopenharmony_ci      {
15535bd8deadSopenharmony_ci          floatVec operand;
15545bd8deadSopenharmony_ci
15555bd8deadSopenharmony_ci          operand.x = source.c***;
15565bd8deadSopenharmony_ci          operand.y = source.*c**;
15575bd8deadSopenharmony_ci          operand.z = source.**c*;
15585bd8deadSopenharmony_ci          operand.w = source.***c;
15595bd8deadSopenharmony_ci          if (negateBase) {
15605bd8deadSopenharmony_ci             operand.x = -operand.x;
15615bd8deadSopenharmony_ci             operand.y = -operand.y;
15625bd8deadSopenharmony_ci             operand.z = -operand.z;
15635bd8deadSopenharmony_ci             operand.w = -operand.w;
15645bd8deadSopenharmony_ci          }
15655bd8deadSopenharmony_ci          if (absolute) {
15665bd8deadSopenharmony_ci             operand.x = abs(operand.x);
15675bd8deadSopenharmony_ci             operand.y = abs(operand.y);
15685bd8deadSopenharmony_ci             operand.z = abs(operand.z);
15695bd8deadSopenharmony_ci             operand.w = abs(operand.w);
15705bd8deadSopenharmony_ci          }
15715bd8deadSopenharmony_ci          if (negateAbs) {
15725bd8deadSopenharmony_ci             operand.x = -operand.x;
15735bd8deadSopenharmony_ci             operand.y = -operand.y;
15745bd8deadSopenharmony_ci             operand.z = -operand.z;
15755bd8deadSopenharmony_ci             operand.w = -operand.w;
15765bd8deadSopenharmony_ci          }
15775bd8deadSopenharmony_ci
15785bd8deadSopenharmony_ci          return operand;
15795bd8deadSopenharmony_ci      }
15805bd8deadSopenharmony_ci
15815bd8deadSopenharmony_ci      float ScalarLoad(floatVec source) 
15825bd8deadSopenharmony_ci      {
15835bd8deadSopenharmony_ci          float operand;
15845bd8deadSopenharmony_ci
15855bd8deadSopenharmony_ci          operand = source.c***;
15865bd8deadSopenharmony_ci          if (negateBase) {
15875bd8deadSopenharmony_ci            operand = -operand;
15885bd8deadSopenharmony_ci          }
15895bd8deadSopenharmony_ci          if (absolute) {
15905bd8deadSopenharmony_ci             operand = abs(operand);
15915bd8deadSopenharmony_ci          }
15925bd8deadSopenharmony_ci          if (negateAbs) {
15935bd8deadSopenharmony_ci            operand = -operand;
15945bd8deadSopenharmony_ci          }
15955bd8deadSopenharmony_ci
15965bd8deadSopenharmony_ci          return operand;
15975bd8deadSopenharmony_ci      }
15985bd8deadSopenharmony_ci
15995bd8deadSopenharmony_ci      intVec AddrVectorLoad(intVec addrReg)
16005bd8deadSopenharmony_ci      {
16015bd8deadSopenharmony_ci          intVec operand;
16025bd8deadSopenharmony_ci
16035bd8deadSopenharmony_ci          operand.x = source.c***;
16045bd8deadSopenharmony_ci          operand.y = source.*c**;
16055bd8deadSopenharmony_ci          operand.z = source.**c*;
16065bd8deadSopenharmony_ci          operand.w = source.***c;
16075bd8deadSopenharmony_ci
16085bd8deadSopenharmony_ci          return operand;
16095bd8deadSopenharmony_ci      }
16105bd8deadSopenharmony_ci
16115bd8deadSopenharmony_ci      int AddrScalarLoad(intVec addrReg)
16125bd8deadSopenharmony_ci      {
16135bd8deadSopenharmony_ci          return source.c***;
16145bd8deadSopenharmony_ci      }
16155bd8deadSopenharmony_ci
16165bd8deadSopenharmony_ci    If an operand is obtained from a program parameter register, by matching
16175bd8deadSopenharmony_ci    the <progParamRegister> rule, the register number can be obtained by
16185bd8deadSopenharmony_ci    absolute or relative addressing.  
16195bd8deadSopenharmony_ci
16205bd8deadSopenharmony_ci    When absolute addressing is used, by matching the <absProgParamReg> rule,
16215bd8deadSopenharmony_ci    the program parameter register number is the number matching the
16225bd8deadSopenharmony_ci    <progParamRegNum>.
16235bd8deadSopenharmony_ci
16245bd8deadSopenharmony_ci    When relative addressing is used, by matching the <relProgParamReg> rule,
16255bd8deadSopenharmony_ci    the program parameter register number is computed during program
16265bd8deadSopenharmony_ci    execution.  An index is computed by adding the integer scalar operand
16275bd8deadSopenharmony_ci    specified by the <scalarAddr> rule to the positive or negative offset
16285bd8deadSopenharmony_ci    specified by the <progParamOffset> rule.  If <progParamOffset> matches "",
16295bd8deadSopenharmony_ci    an offset of zero is used.
16305bd8deadSopenharmony_ci
16315bd8deadSopenharmony_ci    The following pseudo-code spells out the process of loading a program
16325bd8deadSopenharmony_ci    parameter.  "addrReg" refers to the address register used for relative
16335bd8deadSopenharmony_ci    addressing, "absolute" is TRUE if the operand uses absolute addressing and
16345bd8deadSopenharmony_ci    FALSE otherwise.  "paramNumber" is the program parameter number for
16355bd8deadSopenharmony_ci    absolute addressing; "paramOffset" is the program parameter offset for
16365bd8deadSopenharmony_ci    relative addressing.  "paramRegiser" is an array holding the complete set
16375bd8deadSopenharmony_ci    of program parameter registers.
16385bd8deadSopenharmony_ci
16395bd8deadSopenharmony_ci      floatVec ProgramParameterLoad(intVec addrReg)
16405bd8deadSopenharmony_ci      {
16415bd8deadSopenharmony_ci        int index;
16425bd8deadSopenharmony_ci        
16435bd8deadSopenharmony_ci        if (absolute) {
16445bd8deadSopenharmony_ci          index = paramNumber;
16455bd8deadSopenharmony_ci        } else {
16465bd8deadSopenharmony_ci          index = AddrScalarLoad(addrReg) + paramOffset
16475bd8deadSopenharmony_ci        }
16485bd8deadSopenharmony_ci
16495bd8deadSopenharmony_ci        return paramRegister[index];
16505bd8deadSopenharmony_ci      }
16515bd8deadSopenharmony_ci
16525bd8deadSopenharmony_ci
16535bd8deadSopenharmony_ci    Section 2.14.2.2,  Vertex Program Destination Register Update
16545bd8deadSopenharmony_ci
16555bd8deadSopenharmony_ci    Most vertex program instructions write a 4-component result vector to a
16565bd8deadSopenharmony_ci    single temporary, vertex result, or address register.  Writes to
16575bd8deadSopenharmony_ci    individual components of the destination register are controlled by
16585bd8deadSopenharmony_ci    individual component write masks specified as part of the instruction.  In
16595bd8deadSopenharmony_ci    the VP2 execution environment, writes are additionally controlled by the a
16605bd8deadSopenharmony_ci    condition code write mask, which is computed at run time.
16615bd8deadSopenharmony_ci
16625bd8deadSopenharmony_ci    The component write mask is specified by the <optionalWriteMask> rule
16635bd8deadSopenharmony_ci    found in the <maskedDstReg> or <maskedAddrReg> rule.  If the optional mask
16645bd8deadSopenharmony_ci    is "", all components are enabled.  Otherwise, the optional mask names the
16655bd8deadSopenharmony_ci    individual components to enable.  The characters "x", "y", "z", and "w"
16665bd8deadSopenharmony_ci    match the x, y, z, and w components respectively.  For example, an
16675bd8deadSopenharmony_ci    optional mask of ".xzw" indicates that the x, z, and w components should
16685bd8deadSopenharmony_ci    be enabled for writing but the y component should not.  The grammar
16695bd8deadSopenharmony_ci    requires that the destination register mask components must be listed in
16705bd8deadSopenharmony_ci    "xyzw" order.
16715bd8deadSopenharmony_ci
16725bd8deadSopenharmony_ci    In the VP2 execution environment, the condition code write mask is
16735bd8deadSopenharmony_ci    specified by the <optionalCCMask> rule found in the <maskedDstReg> and
16745bd8deadSopenharmony_ci    <maskedAddrReg> rules.  If the condition code mask matches "", all
16755bd8deadSopenharmony_ci    components are enabled.  Otherwise, the condition code register is loaded
16765bd8deadSopenharmony_ci    and swizzled according to the swizzle codes specified by <swizzleSuffix>.
16775bd8deadSopenharmony_ci    Each component of the swizzled condition code is tested according to the
16785bd8deadSopenharmony_ci    rule given by <ccMaskRule>.  <ccMaskRule> may have the values "EQ", "NE",
16795bd8deadSopenharmony_ci    "LT", "GE", LE", or "GT", which mean to enable writes if the corresponding
16805bd8deadSopenharmony_ci    condition code field evaluates to equal, not equal, less than, greater
16815bd8deadSopenharmony_ci    than or equal, less than or equal, or greater than, respectively.
16825bd8deadSopenharmony_ci    Comparisons involving condition codes of "UN" (unordered) evaluate to true
16835bd8deadSopenharmony_ci    for "NE" and false otherwise.  For example, if the condition code is
16845bd8deadSopenharmony_ci    (GT,LT,EQ,GT) and the condition code mask is "(NE.zyxw)", the swizzle
16855bd8deadSopenharmony_ci    operation will load (EQ,LT,GT,GT) and the mask will thus will enable
16865bd8deadSopenharmony_ci    writes on the y, z, and w components.  In addition, "TR" always enables
16875bd8deadSopenharmony_ci    writes and "FL" always disables writes, regardless of the condition code.
16885bd8deadSopenharmony_ci
16895bd8deadSopenharmony_ci    Each component of the destination register is updated with the result of
16905bd8deadSopenharmony_ci    the vertex program instruction if and only if the component is enabled for
16915bd8deadSopenharmony_ci    writes by the component write mask, and the optional condition code mask
16925bd8deadSopenharmony_ci    (if applicable).  Otherwise, the component of the destination register
16935bd8deadSopenharmony_ci    remains unchanged.
16945bd8deadSopenharmony_ci
16955bd8deadSopenharmony_ci    In the VP2 execution environment, a vertex program instruction can also
16965bd8deadSopenharmony_ci    optionally update the condition code register.  The condition code is
16975bd8deadSopenharmony_ci    updated if the condition code register update suffix "C" is present in the
16985bd8deadSopenharmony_ci    instruction.  The instruction "ADDC" will update the condition code; the
16995bd8deadSopenharmony_ci    otherwise equivalent instruction "ADD" will not.  If condition code
17005bd8deadSopenharmony_ci    updates are enabled, each component of the destination register enabled
17015bd8deadSopenharmony_ci    for writes is compared to zero.  The corresponding component of the
17025bd8deadSopenharmony_ci    condition code is set to "LT", "EQ", or "GT", if the written component is
17035bd8deadSopenharmony_ci    less than, equal to, or greater than zero, respectively.  Condition code
17045bd8deadSopenharmony_ci    components are set to "UN" if the written component is NaN.  Values of
17055bd8deadSopenharmony_ci    -0.0 and +0.0 both evaluate to "EQ".  If a component of the destination
17065bd8deadSopenharmony_ci    register is not enabled for writes, the corresponding condition code
17075bd8deadSopenharmony_ci    component is also unchanged.
17085bd8deadSopenharmony_ci
17095bd8deadSopenharmony_ci    In the following example code,
17105bd8deadSopenharmony_ci
17115bd8deadSopenharmony_ci        # R1=(-2, 0, 2, NaN)              R0                  CC
17125bd8deadSopenharmony_ci        MOVC R0, R1;               # ( -2,  0,   2, NaN) (LT,EQ,GT,UN)
17135bd8deadSopenharmony_ci        MOVC R0.xyz, R1.yzwx;      # (  0,  2, NaN, NaN) (EQ,GT,UN,UN)
17145bd8deadSopenharmony_ci        MOVC R0 (NE), R1.zywx;     # (  0,  0, NaN,  -2) (EQ,EQ,UN,LT)
17155bd8deadSopenharmony_ci
17165bd8deadSopenharmony_ci    the first instruction writes (-2,0,2,NaN) to R0 and updates the condition
17175bd8deadSopenharmony_ci    code to (LT,EQ,GT,UN).  The second instruction, only the "x", "y", and "z"
17185bd8deadSopenharmony_ci    components of R0 and the condition code are updated, so R0 ends up with
17195bd8deadSopenharmony_ci    (0,2,NaN,NaN) and the condition code ends up with (EQ,GT,UN,UN).  In the
17205bd8deadSopenharmony_ci    third instruction, the condition code mask disables writes to the x
17215bd8deadSopenharmony_ci    component (its condition code field is "EQ"), so R0 ends up with
17225bd8deadSopenharmony_ci    (0,0,NaN,-2) and the condition code ends up with (EQ,EQ,UN,LT).
17235bd8deadSopenharmony_ci
17245bd8deadSopenharmony_ci    The following pseudocode illustrates the process of writing a result
17255bd8deadSopenharmony_ci    vector to the destination register.  In the pseudocode, "instrmask" refers
17265bd8deadSopenharmony_ci    to the component write mask given by the <optionalWriteMask> rule.  In the
17275bd8deadSopenharmony_ci    VP1 execution environment, "ccMaskRule" is always "" and "updatecc" is
17285bd8deadSopenharmony_ci    always FALSE.  In the VP2 execution environment, "ccMaskRule" refers to
17295bd8deadSopenharmony_ci    the condition code mask rule given by <vp2-optionalCCMask> and "updatecc"
17305bd8deadSopenharmony_ci    is TRUE if and only if condition code updates are enabled.  "result",
17315bd8deadSopenharmony_ci    "destination", and "cc" refer to the result vector, the register selected
17325bd8deadSopenharmony_ci    by <dstRegister> and the condition code, respectively.  Condition codes do
17335bd8deadSopenharmony_ci    not exist in the VP1 execution environment.
17345bd8deadSopenharmony_ci
17355bd8deadSopenharmony_ci      boolean TestCC(CondCode field) {
17365bd8deadSopenharmony_ci          switch (ccMaskRule) {
17375bd8deadSopenharmony_ci          case "EQ":  return (field == "EQ");
17385bd8deadSopenharmony_ci          case "NE":  return (field != "EQ");
17395bd8deadSopenharmony_ci          case "LT":  return (field == "LT");
17405bd8deadSopenharmony_ci          case "GE":  return (field == "GT" || field == "EQ");
17415bd8deadSopenharmony_ci          case "LE":  return (field == "LT" || field == "EQ");
17425bd8deadSopenharmony_ci          case "GT":  return (field == "GT");
17435bd8deadSopenharmony_ci          case "TR":  return TRUE;
17445bd8deadSopenharmony_ci          case "FL":  return FALSE;
17455bd8deadSopenharmony_ci          case "":    return TRUE;
17465bd8deadSopenharmony_ci          }
17475bd8deadSopenharmony_ci      }
17485bd8deadSopenharmony_ci
17495bd8deadSopenharmony_ci      enum GenerateCC(float value) {
17505bd8deadSopenharmony_ci        if (value == NaN) {
17515bd8deadSopenharmony_ci          return UN;
17525bd8deadSopenharmony_ci        } else if (value < 0) {
17535bd8deadSopenharmony_ci          return LT;
17545bd8deadSopenharmony_ci        } else if (value == 0) {
17555bd8deadSopenharmony_ci          return EQ;
17565bd8deadSopenharmony_ci        } else {
17575bd8deadSopenharmony_ci          return GT;
17585bd8deadSopenharmony_ci        }
17595bd8deadSopenharmony_ci      }
17605bd8deadSopenharmony_ci
17615bd8deadSopenharmony_ci      void UpdateDestination(floatVec destination, floatVec result)
17625bd8deadSopenharmony_ci      {
17635bd8deadSopenharmony_ci          floatVec merged;
17645bd8deadSopenharmony_ci          ccVec    mergedCC;
17655bd8deadSopenharmony_ci
17665bd8deadSopenharmony_ci          // Merge the converted result into the destination register, under
17675bd8deadSopenharmony_ci          // control of the compile- and run-time write masks.
17685bd8deadSopenharmony_ci          merged = destination;
17695bd8deadSopenharmony_ci          mergedCC = cc;
17705bd8deadSopenharmony_ci          if (instrMask.x && TestCC(cc.c***)) {
17715bd8deadSopenharmony_ci              merged.x = result.x;
17725bd8deadSopenharmony_ci              if (updatecc) mergedCC.x = GenerateCC(result.x);
17735bd8deadSopenharmony_ci          }
17745bd8deadSopenharmony_ci          if (instrMask.y && TestCC(cc.*c**)) {
17755bd8deadSopenharmony_ci              merged.y = result.y;
17765bd8deadSopenharmony_ci              if (updatecc) mergedCC.y = GenerateCC(result.y);
17775bd8deadSopenharmony_ci          }
17785bd8deadSopenharmony_ci          if (instrMask.z && TestCC(cc.**c*)) {
17795bd8deadSopenharmony_ci              merged.z = result.z;
17805bd8deadSopenharmony_ci              if (updatecc) mergedCC.z = GenerateCC(result.z);
17815bd8deadSopenharmony_ci          }
17825bd8deadSopenharmony_ci          if (instrMask.w && TestCC(cc.***c)) {
17835bd8deadSopenharmony_ci              merged.w = result.w;
17845bd8deadSopenharmony_ci              if (updatecc) mergedCC.w = GenerateCC(result.w);
17855bd8deadSopenharmony_ci          }
17865bd8deadSopenharmony_ci
17875bd8deadSopenharmony_ci          // Write out the new destination register and condition code.
17885bd8deadSopenharmony_ci          destination = merged;
17895bd8deadSopenharmony_ci          cc = mergedCC;
17905bd8deadSopenharmony_ci      }
17915bd8deadSopenharmony_ci
17925bd8deadSopenharmony_ci    Section 2.14.2.3, Vertex Program Execution
17935bd8deadSopenharmony_ci
17945bd8deadSopenharmony_ci    In the VP1 execution environment, vertex programs consist of a sequence of
17955bd8deadSopenharmony_ci    instructions without no support for branching.  Vertex programs begin by
17965bd8deadSopenharmony_ci    executing the first instruction in the program, and execute instructions
17975bd8deadSopenharmony_ci    in the order specified in the program until the last instruction is
17985bd8deadSopenharmony_ci    reached.
17995bd8deadSopenharmony_ci
18005bd8deadSopenharmony_ci    VP2 vertex programs can contain one or more instruction labels, matching
18015bd8deadSopenharmony_ci    the grammar rule <vp2-instructionLabel>.  An instruction label can be
18025bd8deadSopenharmony_ci    referred to explicitly in branch (BRA) or subroutine call (CAL)
18035bd8deadSopenharmony_ci    instructions.  Instruction labels can be defined or used at any point in
18045bd8deadSopenharmony_ci    the body of a program, and can be used in instructions before being
18055bd8deadSopenharmony_ci    defined in the program string.
18065bd8deadSopenharmony_ci
18075bd8deadSopenharmony_ci    VP2 vertex program branching instructions can be conditional.  The branch
18085bd8deadSopenharmony_ci    condition is specified by the <vp2-conditionMask> and may depend on the
18095bd8deadSopenharmony_ci    contents of the condition code register.  Branch conditions are evaluated
18105bd8deadSopenharmony_ci    by evaluating a condition code write mask in exactly the same manner as
18115bd8deadSopenharmony_ci    done for register writes (section 2.14.2.2).  If any of the four
18125bd8deadSopenharmony_ci    components of the condition code write mask are enabled, the branch is
18135bd8deadSopenharmony_ci    taken and execution continues with the instruction following the label
18145bd8deadSopenharmony_ci    specified in the instruction.  Otherwise, the instruction is ignored and
18155bd8deadSopenharmony_ci    vertex program execution continues with the next instruction.  In the
18165bd8deadSopenharmony_ci    following example code,
18175bd8deadSopenharmony_ci
18185bd8deadSopenharmony_ci        MOVC CC, c[0];         # c[0]=(-2, 0, 2, NaN), CC gets (LT,EQ,GT,UN)
18195bd8deadSopenharmony_ci        BRA label1 (LT.xyzw);
18205bd8deadSopenharmony_ci        MOV R0,R1;             # not executed
18215bd8deadSopenharmony_ci      label1:
18225bd8deadSopenharmony_ci        BRA label2 (LT.wyzw);
18235bd8deadSopenharmony_ci        MOV R0,R2;             # executed
18245bd8deadSopenharmony_ci      label2:
18255bd8deadSopenharmony_ci
18265bd8deadSopenharmony_ci    the first BRA instruction loads a condition code of (LT,EQ,GT,UN) while
18275bd8deadSopenharmony_ci    the second BRA instruction loads a condition code of (UN,EQ,GT,UN).  The
18285bd8deadSopenharmony_ci    first branch will be taken because the "x" component evaluates to LT; the
18295bd8deadSopenharmony_ci    second branch will not be taken because no component evaluates to LT.
18305bd8deadSopenharmony_ci
18315bd8deadSopenharmony_ci    VP2 vertex programs can specify subroutine calls.  When a subroutine call
18325bd8deadSopenharmony_ci    (CAL) instruction is executed, a reference to the instruction immediately
18335bd8deadSopenharmony_ci    following the CAL instruction is pushed onto the call stack.  When a
18345bd8deadSopenharmony_ci    subroutine return (RET) instruction is executed, an instruction reference
18355bd8deadSopenharmony_ci    is popped off the call stack and program execution continues with the
18365bd8deadSopenharmony_ci    popped instruction.  A vertex program will terminate if a CAL instruction
18375bd8deadSopenharmony_ci    is executed with four entries already in the call stack or if a RET
18385bd8deadSopenharmony_ci    instruction is executed with an empty call stack.    
18395bd8deadSopenharmony_ci
18405bd8deadSopenharmony_ci    If a VP2 vertex program has an instruction label "main", program execution
18415bd8deadSopenharmony_ci    begins with the instruction immediately following the instruction label.
18425bd8deadSopenharmony_ci    Otherwise, program execution begins with the first instruction of the
18435bd8deadSopenharmony_ci    program.  Instructions will be executed sequentially in the order
18445bd8deadSopenharmony_ci    specified in the program, although branch instructions will affect the
18455bd8deadSopenharmony_ci    instruction execution order, as described above.  A vertex program will
18465bd8deadSopenharmony_ci    terminate after executing a RET instruction with an empty call stack.  A
18475bd8deadSopenharmony_ci    vertex program will also terminate after executing the last instruction in
18485bd8deadSopenharmony_ci    the program, unless that instruction was a taken branch.
18495bd8deadSopenharmony_ci
18505bd8deadSopenharmony_ci    A vertex program will fail to load if an instruction refers to a label
18515bd8deadSopenharmony_ci    that is not defined in the program string.
18525bd8deadSopenharmony_ci
18535bd8deadSopenharmony_ci    A vertex program will terminate abnormally if a subroutine call
18545bd8deadSopenharmony_ci    instruction produces a call stack overflow.  Additionally, a vertex
18555bd8deadSopenharmony_ci    program will terminate abnormally after executing 65536 instructions to
18565bd8deadSopenharmony_ci    prevent hangs caused by infinite loops in the program.
18575bd8deadSopenharmony_ci
18585bd8deadSopenharmony_ci    When a vertex program terminates, normally or abnormally, it will emit a
18595bd8deadSopenharmony_ci    vertex whose attributes are taken from the final values of the vertex
18605bd8deadSopenharmony_ci    result registers (section 2.14.1.5).
18615bd8deadSopenharmony_ci
18625bd8deadSopenharmony_ci
18635bd8deadSopenharmony_ci    Section 2.14.3,  Vertex Program Instruction Set
18645bd8deadSopenharmony_ci
18655bd8deadSopenharmony_ci    The following sections describe the set of supported vertex program
18665bd8deadSopenharmony_ci    instructions.  Instructions available only in the VP1.1 or VP2 execution
18675bd8deadSopenharmony_ci    environment will be noted in the instruction description.  
18685bd8deadSopenharmony_ci
18695bd8deadSopenharmony_ci    Each section will contain pseudocode describing the instruction.
18705bd8deadSopenharmony_ci    Instructions will have up to three operands, referred to as "op0", "op1",
18715bd8deadSopenharmony_ci    and "op2".  The operands are loaded using the mechanisms specified in
18725bd8deadSopenharmony_ci    section 2.14.2.1.  Most instructions will generate a result vector called
18735bd8deadSopenharmony_ci    "result".  The result vector is then written to the destination register
18745bd8deadSopenharmony_ci    specified in the instruction using the mechanisms specified in section
18755bd8deadSopenharmony_ci    2.14.2.2.
18765bd8deadSopenharmony_ci
18775bd8deadSopenharmony_ci    Operands and results are represented as 32-bit single-precision
18785bd8deadSopenharmony_ci    floating-point numbers according to the IEEE 754 floating-point
18795bd8deadSopenharmony_ci    specification.  IEEE denorm encodings, used to represent numbers smaller
18805bd8deadSopenharmony_ci    than 2^-126, are not supported.  All such numbers are flushed to zero.
18815bd8deadSopenharmony_ci    There are three special encodings referred to in this section:  +INF means
18825bd8deadSopenharmony_ci    "positive infinity", -INF means "negative infinity", and NaN refers to
18835bd8deadSopenharmony_ci    "not a number".
18845bd8deadSopenharmony_ci
18855bd8deadSopenharmony_ci    Arithmetic operations are typically carried out in single precision
18865bd8deadSopenharmony_ci    according to the rules specified in the IEEE 754 specification.  Any
18875bd8deadSopenharmony_ci    exceptions and special cases will be noted in the instruction description.
18885bd8deadSopenharmony_ci
18895bd8deadSopenharmony_ci
18905bd8deadSopenharmony_ci    Section 2.14.3.1,  ABS:  Absolute Value
18915bd8deadSopenharmony_ci
18925bd8deadSopenharmony_ci    The ABS instruction performs a component-wise absolute value operation on
18935bd8deadSopenharmony_ci    the single operand to yield a result vector.
18945bd8deadSopenharmony_ci
18955bd8deadSopenharmony_ci      tmp = VectorLoad(op0); 
18965bd8deadSopenharmony_ci      result.x = abs(tmp.x);
18975bd8deadSopenharmony_ci      result.y = abs(tmp.y);
18985bd8deadSopenharmony_ci      result.z = abs(tmp.z);
18995bd8deadSopenharmony_ci      result.w = abs(tmp.w);
19005bd8deadSopenharmony_ci
19015bd8deadSopenharmony_ci    The following special-case rules apply to absolute value operation:
19025bd8deadSopenharmony_ci
19035bd8deadSopenharmony_ci      1. abs(NaN) = NaN.
19045bd8deadSopenharmony_ci      2. abs(-INF) = abs(+INF) = +INF.
19055bd8deadSopenharmony_ci      3. abs(-0.0) = abs(+0.0) = +0.0.
19065bd8deadSopenharmony_ci
19075bd8deadSopenharmony_ci    The ABS instruction is available only in the VP1.1 and VP2 execution
19085bd8deadSopenharmony_ci    environments.  
19095bd8deadSopenharmony_ci
19105bd8deadSopenharmony_ci    In the VP1.0 execution environment, the same functionality can be achieved
19115bd8deadSopenharmony_ci    with "MAX result, src, -src".
19125bd8deadSopenharmony_ci
19135bd8deadSopenharmony_ci    In the VP2 execution environment, the ABS instruction is effectively
19145bd8deadSopenharmony_ci    obsolete, since instructions can take the absolute value of each operand
19155bd8deadSopenharmony_ci    at no cost.
19165bd8deadSopenharmony_ci
19175bd8deadSopenharmony_ci
19185bd8deadSopenharmony_ci    Section 2.14.3.2,  ADD:  Add
19195bd8deadSopenharmony_ci
19205bd8deadSopenharmony_ci    The ADD instruction performs a component-wise add of the two operands to
19215bd8deadSopenharmony_ci    yield a result vector.
19225bd8deadSopenharmony_ci
19235bd8deadSopenharmony_ci      tmp0 = VectorLoad(op0);
19245bd8deadSopenharmony_ci      tmp1 = VectorLoad(op1);
19255bd8deadSopenharmony_ci      result.x = tmp0.x + tmp1.x;
19265bd8deadSopenharmony_ci      result.y = tmp0.y + tmp1.y;
19275bd8deadSopenharmony_ci      result.z = tmp0.z + tmp1.z;
19285bd8deadSopenharmony_ci      result.w = tmp0.w + tmp1.w;
19295bd8deadSopenharmony_ci
19305bd8deadSopenharmony_ci    The following special-case rules apply to addition:
19315bd8deadSopenharmony_ci
19325bd8deadSopenharmony_ci      1. "A+B" is always equivalent to "B+A".
19335bd8deadSopenharmony_ci      2. NaN + <x> = NaN, for all <x>.
19345bd8deadSopenharmony_ci      3. +INF + <x> = +INF, for all <x> except NaN and -INF.
19355bd8deadSopenharmony_ci      4. -INF + <x> = -INF, for all <x> except NaN and +INF.
19365bd8deadSopenharmony_ci      5. +INF + -INF = NaN.
19375bd8deadSopenharmony_ci      6. -0.0 + <x> = <x>, for all <x>.
19385bd8deadSopenharmony_ci      7. +0.0 + <x> = <x>, for all <x> except -0.0.
19395bd8deadSopenharmony_ci
19405bd8deadSopenharmony_ci
19415bd8deadSopenharmony_ci    Section 2.14.3.3,  ARA:  Address Register Add
19425bd8deadSopenharmony_ci
19435bd8deadSopenharmony_ci    The ARA instruction adds two pairs of components of a vector address
19445bd8deadSopenharmony_ci    register operand to produce an integer result vector.  The "x" and "z"
19455bd8deadSopenharmony_ci    components of the result vector contain the sum of the "x" and "z"
19465bd8deadSopenharmony_ci    components of the operand; the "y" and "w" components of the result vector
19475bd8deadSopenharmony_ci    contain the sum of the "y" and "w" components of the operand.  Each
19485bd8deadSopenharmony_ci    component of the result vector is clamped to [-512, +511], the range of
19495bd8deadSopenharmony_ci    representable address register components.
19505bd8deadSopenharmony_ci
19515bd8deadSopenharmony_ci      itmp = AddrVectorLoad(op0);
19525bd8deadSopenharmony_ci      iresult.x = itmp.x + itmp.z;
19535bd8deadSopenharmony_ci      iresult.y = itmp.y + itmp.w;
19545bd8deadSopenharmony_ci      iresult.z = itmp.x + itmp.z;
19555bd8deadSopenharmony_ci      iresult.w = itmp.y + itmp.w;
19565bd8deadSopenharmony_ci      if (iresult.x < -512) iresult.x = -512;
19575bd8deadSopenharmony_ci      if (iresult.x > 511)  iresult.x = 511;
19585bd8deadSopenharmony_ci      if (iresult.y < -512) iresult.y = -512;
19595bd8deadSopenharmony_ci      if (iresult.y > 511)  iresult.y = 511;
19605bd8deadSopenharmony_ci      if (iresult.z < -512) iresult.z = -512;
19615bd8deadSopenharmony_ci      if (iresult.z > 511)  iresult.z = 511;
19625bd8deadSopenharmony_ci      if (iresult.w < -512) iresult.w = -512;
19635bd8deadSopenharmony_ci      if (iresult.w > 511)  iresult.w = 511;
19645bd8deadSopenharmony_ci
19655bd8deadSopenharmony_ci    Component swizzling is not supported when the operand is loaded.
19665bd8deadSopenharmony_ci
19675bd8deadSopenharmony_ci    The ARA instruction is available only in the VP2 execution environment.
19685bd8deadSopenharmony_ci
19695bd8deadSopenharmony_ci
19705bd8deadSopenharmony_ci    Section 2.14.3.4,  ARL:  Address Register Load
19715bd8deadSopenharmony_ci
19725bd8deadSopenharmony_ci    In the VP1 execution environment, the ARL instruction loads a single
19735bd8deadSopenharmony_ci    scalar operand and performs a floor operation to generate an integer
19745bd8deadSopenharmony_ci    scalar to be written to the address register.
19755bd8deadSopenharmony_ci
19765bd8deadSopenharmony_ci      tmp = ScalarLoad(op0);
19775bd8deadSopenharmony_ci      iresult.x = floor(tmp);
19785bd8deadSopenharmony_ci
19795bd8deadSopenharmony_ci    In the VP2 execution environment, the ARL instruction loads a single
19805bd8deadSopenharmony_ci    vector operand and performs a component-wise floor operation to generate
19815bd8deadSopenharmony_ci    an integer result vector.  Each component of the result vector is clamped
19825bd8deadSopenharmony_ci    to [-512, +511], the range of representable address register components.
19835bd8deadSopenharmony_ci    The ARL instruction applies all masking operations to address register
19845bd8deadSopenharmony_ci    writes as are described in section 2.14.2.2.
19855bd8deadSopenharmony_ci
19865bd8deadSopenharmony_ci      tmp = VectorLoad(op0);
19875bd8deadSopenharmony_ci      iresult.x = floor(tmp.x);
19885bd8deadSopenharmony_ci      iresult.y = floor(tmp.y);
19895bd8deadSopenharmony_ci      iresult.z = floor(tmp.z);
19905bd8deadSopenharmony_ci      iresult.w = floor(tmp.w);
19915bd8deadSopenharmony_ci      if (iresult.x < -512) iresult.x = -512;
19925bd8deadSopenharmony_ci      if (iresult.x > 511)  iresult.x = 511;
19935bd8deadSopenharmony_ci      if (iresult.y < -512) iresult.y = -512;
19945bd8deadSopenharmony_ci      if (iresult.y > 511)  iresult.y = 511;
19955bd8deadSopenharmony_ci      if (iresult.z < -512) iresult.z = -512;
19965bd8deadSopenharmony_ci      if (iresult.z > 511)  iresult.z = 511;
19975bd8deadSopenharmony_ci      if (iresult.w < -512) iresult.w = -512;
19985bd8deadSopenharmony_ci      if (iresult.w > 511)  iresult.w = 511;
19995bd8deadSopenharmony_ci
20005bd8deadSopenharmony_ci    The following special-case rules apply to floor computation:
20015bd8deadSopenharmony_ci
20025bd8deadSopenharmony_ci      1. floor(NaN) = NaN.
20035bd8deadSopenharmony_ci      2. floor(<x>) = <x>, for -0.0, +0.0, -INF, and +INF.  In all cases, the
20045bd8deadSopenharmony_ci         sign of the result is equal to the sign of the operand.
20055bd8deadSopenharmony_ci
20065bd8deadSopenharmony_ci
20075bd8deadSopenharmony_ci    Section 2.14.3.5,  ARR:  Address Register Load (with round)
20085bd8deadSopenharmony_ci
20095bd8deadSopenharmony_ci    The ARR instruction loads a single vector operand and performs a
20105bd8deadSopenharmony_ci    component-wise round operation to generate an integer result vector.  Each
20115bd8deadSopenharmony_ci    component of the result vector is clamped to [-512, +511], the range of
20125bd8deadSopenharmony_ci    representable address register components.  The ARR instruction applies
20135bd8deadSopenharmony_ci    all masking operations to address register writes as described in section
20145bd8deadSopenharmony_ci    2.14.2.2.
20155bd8deadSopenharmony_ci
20165bd8deadSopenharmony_ci      tmp = VectorLoad(op0);
20175bd8deadSopenharmony_ci      iresult.x = round(tmp.x);
20185bd8deadSopenharmony_ci      iresult.y = round(tmp.y);
20195bd8deadSopenharmony_ci      iresult.z = round(tmp.z);
20205bd8deadSopenharmony_ci      iresult.w = round(tmp.w);
20215bd8deadSopenharmony_ci      if (iresult.x < -512) iresult.x = -512;
20225bd8deadSopenharmony_ci      if (iresult.x > 511)  iresult.x = 511;
20235bd8deadSopenharmony_ci      if (iresult.y < -512) iresult.y = -512;
20245bd8deadSopenharmony_ci      if (iresult.y > 511)  iresult.y = 511;
20255bd8deadSopenharmony_ci      if (iresult.z < -512) iresult.z = -512;
20265bd8deadSopenharmony_ci      if (iresult.z > 511)  iresult.z = 511;
20275bd8deadSopenharmony_ci      if (iresult.w < -512) iresult.w = -512;
20285bd8deadSopenharmony_ci      if (iresult.w > 511)  iresult.w = 511;
20295bd8deadSopenharmony_ci
20305bd8deadSopenharmony_ci    The rounding function, round(x), returns the nearest integer to <x>.  If
20315bd8deadSopenharmony_ci    the fractional portion of <x> is 0.5, round(x) selects the nearest even
20325bd8deadSopenharmony_ci    integer.
20335bd8deadSopenharmony_ci
20345bd8deadSopenharmony_ci    The ARR instruction is available only in the VP2 execution environment.
20355bd8deadSopenharmony_ci
20365bd8deadSopenharmony_ci
20375bd8deadSopenharmony_ci    Section 2.14.3.6,  BRA:  Branch
20385bd8deadSopenharmony_ci
20395bd8deadSopenharmony_ci    The BRA instruction conditionally transfers control to the instruction
20405bd8deadSopenharmony_ci    following the label specified in the instruction.  The following
20415bd8deadSopenharmony_ci    pseudocode describes the operation of the instruction:
20425bd8deadSopenharmony_ci
20435bd8deadSopenharmony_ci      if (TestCC(cc.c***) || TestCC(cc.*c**) || 
20445bd8deadSopenharmony_ci          TestCC(cc.**c*) || TestCC(cc.***c)) {
20455bd8deadSopenharmony_ci        // continue execution at instruction following <branchLabel>
20465bd8deadSopenharmony_ci      } else {
20475bd8deadSopenharmony_ci        // do nothing
20485bd8deadSopenharmony_ci      }
20495bd8deadSopenharmony_ci
20505bd8deadSopenharmony_ci    In the pseudocode, <branchLabel> is the label specified in the instruction
20515bd8deadSopenharmony_ci    matching the <vp2-branchLabel> grammar rule.
20525bd8deadSopenharmony_ci
20535bd8deadSopenharmony_ci    The BRA instruction is available only in the VP2 execution environment.
20545bd8deadSopenharmony_ci
20555bd8deadSopenharmony_ci
20565bd8deadSopenharmony_ci    Section 2.14.3.7,  CAL:  Subroutine Call
20575bd8deadSopenharmony_ci
20585bd8deadSopenharmony_ci    The CAL instruction conditionally transfers control to the instruction
20595bd8deadSopenharmony_ci    following the label specified in the instruction.  It also pushes a
20605bd8deadSopenharmony_ci    reference to the instruction immediately following the CAL instruction
20615bd8deadSopenharmony_ci    onto the call stack, where execution will continue after executing the
20625bd8deadSopenharmony_ci    matching RET instruction.  The following pseudocode describes the
20635bd8deadSopenharmony_ci    operation of the instruction:
20645bd8deadSopenharmony_ci
20655bd8deadSopenharmony_ci      if (TestCC(cc.c***) || TestCC(cc.*c**) || 
20665bd8deadSopenharmony_ci          TestCC(cc.**c*) || TestCC(cc.***c)) {
20675bd8deadSopenharmony_ci        if (callStackDepth >= 4) {
20685bd8deadSopenharmony_ci          // terminate vertex program
20695bd8deadSopenharmony_ci        } else {
20705bd8deadSopenharmony_ci          callStack[callStackDepth] = nextInstruction;
20715bd8deadSopenharmony_ci          callStackDepth++;
20725bd8deadSopenharmony_ci        }
20735bd8deadSopenharmony_ci        // continue execution at instruction following <branchLabel>
20745bd8deadSopenharmony_ci      } else {
20755bd8deadSopenharmony_ci        // do nothing
20765bd8deadSopenharmony_ci      }
20775bd8deadSopenharmony_ci
20785bd8deadSopenharmony_ci    In the pseudocode, <branchLabel> is the label specified in the instruction
20795bd8deadSopenharmony_ci    matching the <vp2-branchLabel> grammar rule, <callStackDepth> is the
20805bd8deadSopenharmony_ci    current depth of the call stack, <callStack> is an array holding the call
20815bd8deadSopenharmony_ci    stack, and <nextInstruction> is a reference to the instruction immediately
20825bd8deadSopenharmony_ci    following the present one in the program string.
20835bd8deadSopenharmony_ci    
20845bd8deadSopenharmony_ci    The CAL instruction is available only in the VP2 execution environment.
20855bd8deadSopenharmony_ci
20865bd8deadSopenharmony_ci
20875bd8deadSopenharmony_ci    Section 2.14.3.8,  COS:  Cosine
20885bd8deadSopenharmony_ci
20895bd8deadSopenharmony_ci    The COS instruction approximates the cosine of the angle specified by the
20905bd8deadSopenharmony_ci    scalar operand and replicates the approximation to all four components of
20915bd8deadSopenharmony_ci    the result vector.  The angle is specified in radians and does not have to
20925bd8deadSopenharmony_ci    be in the range [0,2*PI].
20935bd8deadSopenharmony_ci
20945bd8deadSopenharmony_ci      tmp = ScalarLoad(op0);
20955bd8deadSopenharmony_ci      result.x = ApproxCosine(tmp);
20965bd8deadSopenharmony_ci      result.y = ApproxCosine(tmp);
20975bd8deadSopenharmony_ci      result.z = ApproxCosine(tmp);
20985bd8deadSopenharmony_ci      result.w = ApproxCosine(tmp);
20995bd8deadSopenharmony_ci
21005bd8deadSopenharmony_ci    The approximation function ApproxCosine is accurate to at least 22 bits
21015bd8deadSopenharmony_ci    with an angle in the range [0,2*PI].
21025bd8deadSopenharmony_ci
21035bd8deadSopenharmony_ci      | ApproxCosine(x) - cos(x) | < 1.0 / 2^22, if 0.0 <= x < 2.0 * PI.
21045bd8deadSopenharmony_ci
21055bd8deadSopenharmony_ci    The error in the approximation will typically increase with the absolute
21065bd8deadSopenharmony_ci    value of the angle when the angle falls outside the range [0,2*PI].
21075bd8deadSopenharmony_ci
21085bd8deadSopenharmony_ci    The following special-case rules apply to cosine approximation:
21095bd8deadSopenharmony_ci
21105bd8deadSopenharmony_ci      1. ApproxCosine(NaN) = NaN.
21115bd8deadSopenharmony_ci      2. ApproxCosine(+/-INF) = NaN.
21125bd8deadSopenharmony_ci      3. ApproxCosine(+/-0.0) = +1.0.
21135bd8deadSopenharmony_ci
21145bd8deadSopenharmony_ci    The COS instruction is available only in the VP2 execution environment.
21155bd8deadSopenharmony_ci
21165bd8deadSopenharmony_ci
21175bd8deadSopenharmony_ci    Section 2.14.3.9,  DP3:  3-component Dot Product
21185bd8deadSopenharmony_ci
21195bd8deadSopenharmony_ci    The DP3 instruction computes a three component dot product of the two
21205bd8deadSopenharmony_ci    operands (using the x, y, and z components) and replicates the dot product
21215bd8deadSopenharmony_ci    to all four components of the result vector.
21225bd8deadSopenharmony_ci
21235bd8deadSopenharmony_ci      tmp0 = VectorLoad(op0);
21245bd8deadSopenharmony_ci      tmp1 = VectorLoad(op1):
21255bd8deadSopenharmony_ci      result.x = (tmp0.x * tmp1.x) + (tmp0.y * tmp1.y) + 
21265bd8deadSopenharmony_ci                 (tmp0.z * tmp1.z);
21275bd8deadSopenharmony_ci      result.y = (tmp0.x * tmp1.x) + (tmp0.y * tmp1.y) + 
21285bd8deadSopenharmony_ci                 (tmp0.z * tmp1.z);
21295bd8deadSopenharmony_ci      result.z = (tmp0.x * tmp1.x) + (tmp0.y * tmp1.y) + 
21305bd8deadSopenharmony_ci                 (tmp0.z * tmp1.z);
21315bd8deadSopenharmony_ci      result.w = (tmp0.x * tmp1.x) + (tmp0.y * tmp1.y) + 
21325bd8deadSopenharmony_ci                 (tmp0.z * tmp1.z);
21335bd8deadSopenharmony_ci
21345bd8deadSopenharmony_ci
21355bd8deadSopenharmony_ci    Section 2.14.3.10,  DP4:  4-component Dot Product
21365bd8deadSopenharmony_ci
21375bd8deadSopenharmony_ci    The DP4 instruction computes a four component dot product of the two
21385bd8deadSopenharmony_ci    operands and replicates the dot product to all four components of the
21395bd8deadSopenharmony_ci    result vector.
21405bd8deadSopenharmony_ci
21415bd8deadSopenharmony_ci      tmp0 = VectorLoad(op0);
21425bd8deadSopenharmony_ci      tmp1 = VectorLoad(op1):
21435bd8deadSopenharmony_ci      result.x = (tmp0.x * tmp1.x) + (tmp0.y * tmp1.y) + 
21445bd8deadSopenharmony_ci                 (tmp0.z * tmp1.z) + (tmp0.w * tmp1.w);
21455bd8deadSopenharmony_ci      result.y = (tmp0.x * tmp1.x) + (tmp0.y * tmp1.y) + 
21465bd8deadSopenharmony_ci                 (tmp0.z * tmp1.z) + (tmp0.w * tmp1.w);
21475bd8deadSopenharmony_ci      result.z = (tmp0.x * tmp1.x) + (tmp0.y * tmp1.y) + 
21485bd8deadSopenharmony_ci                 (tmp0.z * tmp1.z) + (tmp0.w * tmp1.w);
21495bd8deadSopenharmony_ci      result.w = (tmp0.x * tmp1.x) + (tmp0.y * tmp1.y) + 
21505bd8deadSopenharmony_ci                 (tmp0.z * tmp1.z) + (tmp0.w * tmp1.w);
21515bd8deadSopenharmony_ci
21525bd8deadSopenharmony_ci
21535bd8deadSopenharmony_ci    Section 2.14.3.11,  DPH:  Homogeneous Dot Product
21545bd8deadSopenharmony_ci
21555bd8deadSopenharmony_ci    The DPH instruction computes a four-component dot product of the two
21565bd8deadSopenharmony_ci    operands, except that the W component of the first operand is assumed to
21575bd8deadSopenharmony_ci    be 1.0.  The instruction replicates the dot product to all four components
21585bd8deadSopenharmony_ci    of the result vector.
21595bd8deadSopenharmony_ci
21605bd8deadSopenharmony_ci      tmp0 = VectorLoad(op0);
21615bd8deadSopenharmony_ci      tmp1 = VectorLoad(op1):
21625bd8deadSopenharmony_ci      result.x = (tmp0.x * tmp1.x) + (tmp0.y * tmp1.y) + 
21635bd8deadSopenharmony_ci                 (tmp0.z * tmp1.z) + tmp1.w;
21645bd8deadSopenharmony_ci      result.y = (tmp0.x * tmp1.x) + (tmp0.y * tmp1.y) + 
21655bd8deadSopenharmony_ci                 (tmp0.z * tmp1.z) + tmp1.w;
21665bd8deadSopenharmony_ci      result.z = (tmp0.x * tmp1.x) + (tmp0.y * tmp1.y) + 
21675bd8deadSopenharmony_ci                 (tmp0.z * tmp1.z) + tmp1.w;
21685bd8deadSopenharmony_ci      result.w = (tmp0.x * tmp1.x) + (tmp0.y * tmp1.y) + 
21695bd8deadSopenharmony_ci                 (tmp0.z * tmp1.z) + tmp1.w;
21705bd8deadSopenharmony_ci
21715bd8deadSopenharmony_ci    The DPH instruction is available only in the VP1.1 and VP2 execution
21725bd8deadSopenharmony_ci    environments.
21735bd8deadSopenharmony_ci
21745bd8deadSopenharmony_ci
21755bd8deadSopenharmony_ci    Section 2.14.3.12,  DST:  Distance Vector
21765bd8deadSopenharmony_ci
21775bd8deadSopenharmony_ci    The DST instruction computes a distance vector from two specially-
21785bd8deadSopenharmony_ci    formatted operands.  The first operand should be of the form [NA, d^2,
21795bd8deadSopenharmony_ci    d^2, NA] and the second operand should be of the form [NA, 1/d, NA, 1/d],
21805bd8deadSopenharmony_ci    where NA values are not relevant to the calculation and d is a vector
21815bd8deadSopenharmony_ci    length.  If both vectors satisfy these conditions, the result vector will
21825bd8deadSopenharmony_ci    be of the form [1.0, d, d^2, 1/d].
21835bd8deadSopenharmony_ci
21845bd8deadSopenharmony_ci    The exact behavior is specified in the following pseudo-code:
21855bd8deadSopenharmony_ci
21865bd8deadSopenharmony_ci      tmp0 = VectorLoad(op0);
21875bd8deadSopenharmony_ci      tmp1 = VectorLoad(op1);
21885bd8deadSopenharmony_ci      result.x = 1.0;
21895bd8deadSopenharmony_ci      result.y = tmp0.y * tmp1.y;
21905bd8deadSopenharmony_ci      result.z = tmp0.z;
21915bd8deadSopenharmony_ci      result.w = tmp1.w;
21925bd8deadSopenharmony_ci
21935bd8deadSopenharmony_ci    Given an arbitrary vector, d^2 can be obtained using the DP3 instruction
21945bd8deadSopenharmony_ci    (using the same vector for both operands) and 1/d can be obtained from d^2
21955bd8deadSopenharmony_ci    using the RSQ instruction.
21965bd8deadSopenharmony_ci
21975bd8deadSopenharmony_ci    This distance vector is useful for per-vertex light attenuation
21985bd8deadSopenharmony_ci    calculations:  a DP3 operation using the distance vector and an
21995bd8deadSopenharmony_ci    attenuation constants vector as operands will yield the attenuation
22005bd8deadSopenharmony_ci    factor.
22015bd8deadSopenharmony_ci
22025bd8deadSopenharmony_ci
22035bd8deadSopenharmony_ci    Section 2.14.3.13,  EX2:  Exponential Base 2
22045bd8deadSopenharmony_ci
22055bd8deadSopenharmony_ci    The EX2 instruction approximates 2 raised to the power of the scalar
22065bd8deadSopenharmony_ci    operand and replicates it to all four components of the result vector.
22075bd8deadSopenharmony_ci
22085bd8deadSopenharmony_ci      tmp = ScalarLoad(op0);
22095bd8deadSopenharmony_ci      result.x = Approx2ToX(tmp);
22105bd8deadSopenharmony_ci      result.y = Approx2ToX(tmp);
22115bd8deadSopenharmony_ci      result.z = Approx2ToX(tmp);
22125bd8deadSopenharmony_ci      result.w = Approx2ToX(tmp);
22135bd8deadSopenharmony_ci
22145bd8deadSopenharmony_ci    The approximation function is accurate to at least 22 bits:
22155bd8deadSopenharmony_ci
22165bd8deadSopenharmony_ci      | Approx2ToX(x) - 2^x | < 1.0 / 2^22, if 0.0 <= x < 1.0,
22175bd8deadSopenharmony_ci
22185bd8deadSopenharmony_ci    and, in general,
22195bd8deadSopenharmony_ci   
22205bd8deadSopenharmony_ci      | Approx2ToX(x) - 2^x | < (1.0 / 2^22) * (2^floor(x)).
22215bd8deadSopenharmony_ci
22225bd8deadSopenharmony_ci    The following special-case rules apply to exponential approximation:
22235bd8deadSopenharmony_ci
22245bd8deadSopenharmony_ci      1. Approx2ToX(NaN) = NaN.
22255bd8deadSopenharmony_ci      2. Approx2ToX(-INF) = +0.0.
22265bd8deadSopenharmony_ci      3. Approx2ToX(+INF) = +INF.
22275bd8deadSopenharmony_ci      4. Approx2ToX(+/-0.0) = +1.0.
22285bd8deadSopenharmony_ci
22295bd8deadSopenharmony_ci    The EX2 instruction is available only in the VP2 execution environment.
22305bd8deadSopenharmony_ci
22315bd8deadSopenharmony_ci
22325bd8deadSopenharmony_ci    Section 2.14.3.14,  EXP:  Exponential Base 2 (approximate)
22335bd8deadSopenharmony_ci
22345bd8deadSopenharmony_ci    The EXP instruction computes a rough approximation of 2 raised to the
22355bd8deadSopenharmony_ci    power of the scalar operand.  The approximation is returned in the "z"
22365bd8deadSopenharmony_ci    component of the result vector.  A vertex program can also use the "x" and
22375bd8deadSopenharmony_ci    "y" components of the result vector to generate a more accurate
22385bd8deadSopenharmony_ci    approximation by evaluating
22395bd8deadSopenharmony_ci
22405bd8deadSopenharmony_ci        result.x * f(result.y),
22415bd8deadSopenharmony_ci    
22425bd8deadSopenharmony_ci    where f(x) is a user-defined function that approximates 2^x over the
22435bd8deadSopenharmony_ci    domain [0.0, 1.0).  The "w" component of the result vector is always 1.0.
22445bd8deadSopenharmony_ci    
22455bd8deadSopenharmony_ci    The exact behavior is specified in the following pseudo-code:
22465bd8deadSopenharmony_ci
22475bd8deadSopenharmony_ci      tmp = ScalarLoad(op0);
22485bd8deadSopenharmony_ci      result.x = 2^floor(tmp);
22495bd8deadSopenharmony_ci      result.y = tmp - floor(tmp);
22505bd8deadSopenharmony_ci      result.z = RoughApprox2ToX(tmp);
22515bd8deadSopenharmony_ci      result.w = 1.0;
22525bd8deadSopenharmony_ci
22535bd8deadSopenharmony_ci    The approximation function is accurate to at least 11 bits:
22545bd8deadSopenharmony_ci
22555bd8deadSopenharmony_ci      | RoughApprox2ToX(x) - 2^x | < 1.0 / 2^11, if 0.0 <= x < 1.0,
22565bd8deadSopenharmony_ci
22575bd8deadSopenharmony_ci    and, in general,
22585bd8deadSopenharmony_ci   
22595bd8deadSopenharmony_ci      | RoughApprox2ToX(x) - 2^x | < (1.0 / 2^11) * (2^floor(x)).
22605bd8deadSopenharmony_ci
22615bd8deadSopenharmony_ci    The following special cases apply to the EXP instruction:
22625bd8deadSopenharmony_ci
22635bd8deadSopenharmony_ci      1. RoughApprox2ToX(NaN) = NaN.
22645bd8deadSopenharmony_ci      2. RoughApprox2ToX(-INF) = +0.0.
22655bd8deadSopenharmony_ci      3. RoughApprox2ToX(+INF) = +INF.
22665bd8deadSopenharmony_ci      4. RoughApprox2ToX(+/-0.0) = +1.0.
22675bd8deadSopenharmony_ci
22685bd8deadSopenharmony_ci    The EXP instruction is present for compatibility with the original
22695bd8deadSopenharmony_ci    NV_vertex_program instruction set; it is recommended that applications
22705bd8deadSopenharmony_ci    using NV_vertex_program2 use the EX2 instruction instead.
22715bd8deadSopenharmony_ci
22725bd8deadSopenharmony_ci
22735bd8deadSopenharmony_ci    Section 2.14.3.15,  FLR:  Floor
22745bd8deadSopenharmony_ci
22755bd8deadSopenharmony_ci    The FLR instruction performs a component-wise floor operation on the
22765bd8deadSopenharmony_ci    operand to generate a result vector.  The floor of a value is defined as
22775bd8deadSopenharmony_ci    the largest integer less than or equal to the value.  The floor of 2.3 is
22785bd8deadSopenharmony_ci    2.0; the floor of -3.6 is -4.0.
22795bd8deadSopenharmony_ci
22805bd8deadSopenharmony_ci      tmp = VectorLoad(op0);
22815bd8deadSopenharmony_ci      result.x = floor(tmp.x);
22825bd8deadSopenharmony_ci      result.y = floor(tmp.y);
22835bd8deadSopenharmony_ci      result.z = floor(tmp.z);
22845bd8deadSopenharmony_ci      result.w = floor(tmp.w);
22855bd8deadSopenharmony_ci
22865bd8deadSopenharmony_ci    The following special-case rules apply to floor computation:
22875bd8deadSopenharmony_ci
22885bd8deadSopenharmony_ci      1. floor(NaN) = NaN.
22895bd8deadSopenharmony_ci      2. floor(<x>) = <x>, for -0.0, +0.0, -INF, and +INF.  In all cases, the
22905bd8deadSopenharmony_ci         sign of the result is equal to the sign of the operand.
22915bd8deadSopenharmony_ci
22925bd8deadSopenharmony_ci    The FLR instruction is available only in the VP2 execution environment.
22935bd8deadSopenharmony_ci
22945bd8deadSopenharmony_ci
22955bd8deadSopenharmony_ci    Section 2.14.3.16,  FRC:  Fraction
22965bd8deadSopenharmony_ci
22975bd8deadSopenharmony_ci    The FRC instruction extracts the fractional portion of each component of
22985bd8deadSopenharmony_ci    the operand to generate a result vector.  The fractional portion of a
22995bd8deadSopenharmony_ci    component is defined as the result after subtracting off the floor of the
23005bd8deadSopenharmony_ci    component (see FLR), and is always in the range [0.00, 1.00).
23015bd8deadSopenharmony_ci
23025bd8deadSopenharmony_ci    For negative values, the fractional portion is NOT the number written to
23035bd8deadSopenharmony_ci    the right of the decimal point -- the fractional portion of -1.7 is not
23045bd8deadSopenharmony_ci    0.7 -- it is 0.3.  0.3 is produced by subtracting the floor of -1.7 (-2.0)
23055bd8deadSopenharmony_ci    from -1.7.
23065bd8deadSopenharmony_ci
23075bd8deadSopenharmony_ci      tmp = VectorLoad(op0);
23085bd8deadSopenharmony_ci      result.x = tmp.x - floor(tmp.x);
23095bd8deadSopenharmony_ci      result.y = tmp.y - floor(tmp.y);
23105bd8deadSopenharmony_ci      result.z = tmp.z - floor(tmp.z);
23115bd8deadSopenharmony_ci      result.w = tmp.w - floor(tmp.w);
23125bd8deadSopenharmony_ci
23135bd8deadSopenharmony_ci    The following special-case rules, which can be derived from the rules for
23145bd8deadSopenharmony_ci    FLR and ADD apply to fraction computation:
23155bd8deadSopenharmony_ci
23165bd8deadSopenharmony_ci      1. fraction(NaN) = NaN.
23175bd8deadSopenharmony_ci      2. fraction(+/-INF) = NaN.
23185bd8deadSopenharmony_ci      3. fraction(+/-0.0) = +0.0.
23195bd8deadSopenharmony_ci
23205bd8deadSopenharmony_ci    The FRC instruction is available only in the VP2 execution environment.
23215bd8deadSopenharmony_ci
23225bd8deadSopenharmony_ci
23235bd8deadSopenharmony_ci    Section 2.14.3.17,  LG2:  Logarithm Base 2
23245bd8deadSopenharmony_ci
23255bd8deadSopenharmony_ci    The LG2 instruction approximates the base 2 logarithm of the scalar
23265bd8deadSopenharmony_ci    operand and replicates it to all four components of the result vector.
23275bd8deadSopenharmony_ci
23285bd8deadSopenharmony_ci      tmp = ScalarLoad(op0);
23295bd8deadSopenharmony_ci      result.x = ApproxLog2(tmp);
23305bd8deadSopenharmony_ci      result.y = ApproxLog2(tmp);
23315bd8deadSopenharmony_ci      result.z = ApproxLog2(tmp);
23325bd8deadSopenharmony_ci      result.w = ApproxLog2(tmp);
23335bd8deadSopenharmony_ci   
23345bd8deadSopenharmony_ci    The approximation function is accurate to at least 22 bits:
23355bd8deadSopenharmony_ci
23365bd8deadSopenharmony_ci      | ApproxLog2(x) - log_2(x) | < 1.0 / 2^22.
23375bd8deadSopenharmony_ci
23385bd8deadSopenharmony_ci    Note that for large values of x, there are not enough bits in the
23395bd8deadSopenharmony_ci    floating-point storage format to represent a result that precisely.
23405bd8deadSopenharmony_ci
23415bd8deadSopenharmony_ci    The following special-case rules apply to logarithm approximation:
23425bd8deadSopenharmony_ci
23435bd8deadSopenharmony_ci      1. ApproxLog2(NaN) = NaN.
23445bd8deadSopenharmony_ci      2. ApproxLog2(+INF) = +INF.
23455bd8deadSopenharmony_ci      3. ApproxLog2(+/-0.0) = -INF.
23465bd8deadSopenharmony_ci      4. ApproxLog2(x) = NaN, -INF < x < -0.0.
23475bd8deadSopenharmony_ci      5. ApproxLog2(-INF) = NaN.
23485bd8deadSopenharmony_ci
23495bd8deadSopenharmony_ci    The LG2 instruction is available only in the VP2 execution environment.
23505bd8deadSopenharmony_ci
23515bd8deadSopenharmony_ci
23525bd8deadSopenharmony_ci    Section 2.14.3.18,  LIT:  Compute Light Coefficients
23535bd8deadSopenharmony_ci
23545bd8deadSopenharmony_ci    The LIT instruction accelerates per-vertex lighting by computing lighting
23555bd8deadSopenharmony_ci    coefficients for ambient, diffuse, and specular light contributions.  The
23565bd8deadSopenharmony_ci    "x" component of the operand is assumed to hold a diffuse dot product (n
23575bd8deadSopenharmony_ci    dot VP_pli, as in the vertex lighting equations in Section 2.13.1).  The
23585bd8deadSopenharmony_ci    "y" component of the operand is assumed to hold a specular dot product (n
23595bd8deadSopenharmony_ci    dot h_i).  The "w" component of the operand is assumed to hold the
23605bd8deadSopenharmony_ci    specular exponent of the material (s_rm), and is clamped to the range
23615bd8deadSopenharmony_ci    (-128, +128) exclusive.
23625bd8deadSopenharmony_ci
23635bd8deadSopenharmony_ci    The "x" component of the result vector receives the value that should be
23645bd8deadSopenharmony_ci    multiplied by the ambient light/material product (always 1.0).  The "y"
23655bd8deadSopenharmony_ci    component of the result vector receives the value that should be
23665bd8deadSopenharmony_ci    multiplied by the diffuse light/material product (n dot VP_pli).  The "z"
23675bd8deadSopenharmony_ci    component of the result vector receives the value that should be
23685bd8deadSopenharmony_ci    multiplied by the specular light/material product (f_i * (n dot h_i) ^
23695bd8deadSopenharmony_ci    s_rm).  The "w" component of the result is the constant 1.0.
23705bd8deadSopenharmony_ci
23715bd8deadSopenharmony_ci    Negative diffuse and specular dot products are clamped to 0.0, as is done
23725bd8deadSopenharmony_ci    in the standard per-vertex lighting operations.  In addition, if the
23735bd8deadSopenharmony_ci    diffuse dot product is zero or negative, the specular coefficient is
23745bd8deadSopenharmony_ci    forced to zero.
23755bd8deadSopenharmony_ci
23765bd8deadSopenharmony_ci      tmp = VectorLoad(op0);
23775bd8deadSopenharmony_ci      if (t.x < 0) t.x = 0;
23785bd8deadSopenharmony_ci      if (t.y < 0) t.y = 0;
23795bd8deadSopenharmony_ci      if (t.w < -(128.0-epsilon)) t.w = -(128.0-epsilon);
23805bd8deadSopenharmony_ci      else if (t.w > 128-epsilon) t.w = 128-epsilon;
23815bd8deadSopenharmony_ci      result.x = 1.0;
23825bd8deadSopenharmony_ci      result.y = t.x;
23835bd8deadSopenharmony_ci      result.z = (t.x > 0) ? RoughApproxPower(t.y, t.w) : 0.0;
23845bd8deadSopenharmony_ci      result.w = 1.0;
23855bd8deadSopenharmony_ci
23865bd8deadSopenharmony_ci    The exponentiation approximation function is defined in terms of the base
23875bd8deadSopenharmony_ci    2 exponentiation and logarithm approximation operations in the EXP and LOG
23885bd8deadSopenharmony_ci    instructions, including errors and the processing of any special cases.
23895bd8deadSopenharmony_ci    In particular,
23905bd8deadSopenharmony_ci
23915bd8deadSopenharmony_ci      RoughApproxPower(a,b) = RoughApproxExp2(b * RoughApproxLog2(a)).
23925bd8deadSopenharmony_ci
23935bd8deadSopenharmony_ci    The following special-case rules, which can be derived from the rules in
23945bd8deadSopenharmony_ci    the LOG, MUL, and EXP instructions, apply to exponentiation:
23955bd8deadSopenharmony_ci
23965bd8deadSopenharmony_ci      1. RoughApproxPower(NaN, <x>) = NaN,
23975bd8deadSopenharmony_ci      2. RoughApproxPower(<x>, <y>) = NaN, if x <= -0.0,
23985bd8deadSopenharmony_ci      3. RoughApproxPower(+/-0.0, <x>) = +0.0, if x > +0.0, or
23995bd8deadSopenharmony_ci                                         +INF, if x < -0.0,
24005bd8deadSopenharmony_ci      4. RoughApproxPower(+1.0, <x>) = +1.0, if x is not NaN,
24015bd8deadSopenharmony_ci      5. RoughApproxPower(+INF, <x>) = +INF, if x > +0.0, or
24025bd8deadSopenharmony_ci                                       +0.0, if x < -0.0,
24035bd8deadSopenharmony_ci      6. RoughApproxPower(<x>, +/-0.0) = +1.0, if x >= -0.0
24045bd8deadSopenharmony_ci      7. RoughApproxPower(<x>, +INF) = +0.0, if -0.0 <= x < +1.0,
24055bd8deadSopenharmony_ci                                       +INF, if x > +1.0,
24065bd8deadSopenharmony_ci      8. RoughApproxPower(<x>, +INF) = +INF, if -0.0 <= x < +1.0,
24075bd8deadSopenharmony_ci                                       +0.0, if x > +1.0,
24085bd8deadSopenharmony_ci      9. RoughApproxPower(<x>, +1.0) = <x>, if x >= +0.0, and
24095bd8deadSopenharmony_ci      10. RoughApproxPower(<x>, NaN) = NaN.
24105bd8deadSopenharmony_ci
24115bd8deadSopenharmony_ci
24125bd8deadSopenharmony_ci    Section 2.14.3.19,  LOG:  Logarithm Base 2 (Approximate)
24135bd8deadSopenharmony_ci
24145bd8deadSopenharmony_ci    The LOG instruction computes a rough approximation of the base 2 logarithm
24155bd8deadSopenharmony_ci    of the absolute value of the scalar operand.  The approximation is
24165bd8deadSopenharmony_ci    returned in the "z" component of the result vector.  A vertex program can
24175bd8deadSopenharmony_ci    also use the "x" and "y" components of the result vector to generate a
24185bd8deadSopenharmony_ci    more accurate approximation by evaluating
24195bd8deadSopenharmony_ci
24205bd8deadSopenharmony_ci        result.x + f(result.y),
24215bd8deadSopenharmony_ci    
24225bd8deadSopenharmony_ci    where f(x) is a user-defined function that approximates 2^x over the
24235bd8deadSopenharmony_ci    domain [1.0, 2.0).  The "w" component of the result vector is always 1.0.
24245bd8deadSopenharmony_ci
24255bd8deadSopenharmony_ci    The exact behavior is specified in the following pseudo-code:
24265bd8deadSopenharmony_ci
24275bd8deadSopenharmony_ci      tmp = fabs(ScalarLoad(op0));
24285bd8deadSopenharmony_ci      result.x = floor(log2(tmp));
24295bd8deadSopenharmony_ci      result.y = tmp / (2^floor(log2(tmp)));
24305bd8deadSopenharmony_ci      result.z = RoughApproxLog2(tmp);
24315bd8deadSopenharmony_ci      result.w = 1.0;
24325bd8deadSopenharmony_ci   
24335bd8deadSopenharmony_ci    The approximation function is accurate to at least 11 bits:
24345bd8deadSopenharmony_ci
24355bd8deadSopenharmony_ci      | RoughApproxLog2(x) - log_2(x) | < 1.0 / 2^11.
24365bd8deadSopenharmony_ci
24375bd8deadSopenharmony_ci    The following special-case rules apply to the LOG instruction:
24385bd8deadSopenharmony_ci
24395bd8deadSopenharmony_ci      1. RoughApproxLog2(NaN) = NaN.
24405bd8deadSopenharmony_ci      2. RoughApproxLog2(+INF) = +INF.
24415bd8deadSopenharmony_ci      3. RoughApproxLog2(+0.0) = -INF.
24425bd8deadSopenharmony_ci
24435bd8deadSopenharmony_ci    The LOG instruction is present for compatibility with the original
24445bd8deadSopenharmony_ci    NV_vertex_program instruction set; it is recommended that applications
24455bd8deadSopenharmony_ci    using NV_vertex_program2 use the LG2 instruction instead.
24465bd8deadSopenharmony_ci
24475bd8deadSopenharmony_ci
24485bd8deadSopenharmony_ci    Section 2.14.3.20,  MAD:  Multiply And Add
24495bd8deadSopenharmony_ci
24505bd8deadSopenharmony_ci    The MAD instruction performs a component-wise multiply of the first two
24515bd8deadSopenharmony_ci    operands, and then does a component-wise add of the product to the third
24525bd8deadSopenharmony_ci    operand to yield a result vector.
24535bd8deadSopenharmony_ci
24545bd8deadSopenharmony_ci      tmp0 = VectorLoad(op0);
24555bd8deadSopenharmony_ci      tmp1 = VectorLoad(op1);
24565bd8deadSopenharmony_ci      tmp2 = VectorLoad(op2);
24575bd8deadSopenharmony_ci      result.x = tmp0.x * tmp1.x + tmp2.x;
24585bd8deadSopenharmony_ci      result.y = tmp0.y * tmp1.y + tmp2.y;
24595bd8deadSopenharmony_ci      result.z = tmp0.z * tmp1.z + tmp2.z;
24605bd8deadSopenharmony_ci      result.w = tmp0.w * tmp1.w + tmp2.w;
24615bd8deadSopenharmony_ci
24625bd8deadSopenharmony_ci    All special case rules applicable to the ADD and MUL instructions apply to
24635bd8deadSopenharmony_ci    the individual components of the MAD operation as well.
24645bd8deadSopenharmony_ci
24655bd8deadSopenharmony_ci
24665bd8deadSopenharmony_ci    Section 2.14.3.21,  MAX:  Maximum
24675bd8deadSopenharmony_ci
24685bd8deadSopenharmony_ci    The MAX instruction computes component-wise maximums of the values in the
24695bd8deadSopenharmony_ci    two operands to yield a result vector.
24705bd8deadSopenharmony_ci
24715bd8deadSopenharmony_ci      tmp0 = VectorLoad(op0);
24725bd8deadSopenharmony_ci      tmp1 = VectorLoad(op1);
24735bd8deadSopenharmony_ci      result.x = max(tmp0.x, tmp1.x);
24745bd8deadSopenharmony_ci      result.y = max(tmp0.y, tmp1.y);
24755bd8deadSopenharmony_ci      result.z = max(tmp0.z, tmp1.z);
24765bd8deadSopenharmony_ci      result.w = max(tmp0.w, tmp1.w);
24775bd8deadSopenharmony_ci
24785bd8deadSopenharmony_ci    The following special cases apply to the maximum operation:
24795bd8deadSopenharmony_ci
24805bd8deadSopenharmony_ci      1. max(A,B) is always equivalent to max(B,A).
24815bd8deadSopenharmony_ci      2. max(NaN, <x>) == NaN, for all <x>.
24825bd8deadSopenharmony_ci
24835bd8deadSopenharmony_ci
24845bd8deadSopenharmony_ci    Section 2.14.3.22,  MIN:  Minimum
24855bd8deadSopenharmony_ci
24865bd8deadSopenharmony_ci    The MIN instruction computes component-wise minimums of the values in the
24875bd8deadSopenharmony_ci    two operands to yield a result vector.
24885bd8deadSopenharmony_ci
24895bd8deadSopenharmony_ci      tmp0 = VectorLoad(op0);
24905bd8deadSopenharmony_ci      tmp1 = VectorLoad(op1);
24915bd8deadSopenharmony_ci      result.x = min(tmp0.x, tmp1.x);
24925bd8deadSopenharmony_ci      result.y = min(tmp0.y, tmp1.y);
24935bd8deadSopenharmony_ci      result.z = min(tmp0.z, tmp1.z);
24945bd8deadSopenharmony_ci      result.w = min(tmp0.w, tmp1.w);
24955bd8deadSopenharmony_ci
24965bd8deadSopenharmony_ci    The following special cases apply to the minimum operation:
24975bd8deadSopenharmony_ci
24985bd8deadSopenharmony_ci      1. min(A,B) is always equivalent to min(B,A).
24995bd8deadSopenharmony_ci      2. min(NaN, <x>) == NaN, for all <x>.
25005bd8deadSopenharmony_ci
25015bd8deadSopenharmony_ci
25025bd8deadSopenharmony_ci    Section 2.14.3.23,  MOV:  Move
25035bd8deadSopenharmony_ci
25045bd8deadSopenharmony_ci    The MOV instruction copies the value of the operand to yield a result
25055bd8deadSopenharmony_ci    vector.
25065bd8deadSopenharmony_ci
25075bd8deadSopenharmony_ci      result = VectorLoad(op0);
25085bd8deadSopenharmony_ci
25095bd8deadSopenharmony_ci
25105bd8deadSopenharmony_ci    Section 2.14.3.24,  MUL:  Multiply
25115bd8deadSopenharmony_ci
25125bd8deadSopenharmony_ci    The MUL instruction performs a component-wise multiply of the two operands
25135bd8deadSopenharmony_ci    to yield a result vector.
25145bd8deadSopenharmony_ci
25155bd8deadSopenharmony_ci      tmp0 = VectorLoad(op0);
25165bd8deadSopenharmony_ci      tmp1 = VectorLoad(op1);
25175bd8deadSopenharmony_ci      result.x = tmp0.x * tmp1.x;
25185bd8deadSopenharmony_ci      result.y = tmp0.y * tmp1.y;
25195bd8deadSopenharmony_ci      result.z = tmp0.z * tmp1.z;
25205bd8deadSopenharmony_ci      result.w = tmp0.w * tmp1.w;
25215bd8deadSopenharmony_ci
25225bd8deadSopenharmony_ci    The following special-case rules apply to multiplication:
25235bd8deadSopenharmony_ci
25245bd8deadSopenharmony_ci      1. "A*B" is always equivalent to "B*A".
25255bd8deadSopenharmony_ci      2. NaN * <x> = NaN, for all <x>.
25265bd8deadSopenharmony_ci      3. +/-0.0 * +/-INF = NaN.
25275bd8deadSopenharmony_ci      4. +/-0.0 * <x> = +/-0.0, for all <x> except -INF, +INF, and NaN.  The
25285bd8deadSopenharmony_ci         sign of the result is positive if the signs of the two operands match
25295bd8deadSopenharmony_ci         and negative otherwise.
25305bd8deadSopenharmony_ci      5. +/-INF * <x> = +/-INF, for all <x> except -0.0, +0.0, and NaN.  The 
25315bd8deadSopenharmony_ci         sign of the result is positive if the signs of the two operands match
25325bd8deadSopenharmony_ci         and negative otherwise.
25335bd8deadSopenharmony_ci      6. +1.0 * <x> = <x>, for all <x>.
25345bd8deadSopenharmony_ci
25355bd8deadSopenharmony_ci
25365bd8deadSopenharmony_ci    Section 2.14.3.25,  RCC:  Reciprocal (Clamped)
25375bd8deadSopenharmony_ci
25385bd8deadSopenharmony_ci    The RCC instruction approximates the reciprocal of the scalar operand,
25395bd8deadSopenharmony_ci    clamps the result to one of two ranges, and replicates the clamped result
25405bd8deadSopenharmony_ci    to all four components of the result vector.
25415bd8deadSopenharmony_ci
25425bd8deadSopenharmony_ci    If the approximate reciprocal is greater than 0.0, the result is clamped
25435bd8deadSopenharmony_ci    to the range [2^-64, 2^+64].  If the approximate reciprocal is not greater
25445bd8deadSopenharmony_ci    than zero, the result is clamped to the range [-2^+64, -2^-64].
25455bd8deadSopenharmony_ci
25465bd8deadSopenharmony_ci      tmp = ScalarLoad(op0);
25475bd8deadSopenharmony_ci      result.x = ClampApproxReciprocal(tmp);
25485bd8deadSopenharmony_ci      result.y = ClampApproxReciprocal(tmp);
25495bd8deadSopenharmony_ci      result.z = ClampApproxReciprocal(tmp);
25505bd8deadSopenharmony_ci      result.w = ClampApproxReciprocal(tmp);
25515bd8deadSopenharmony_ci
25525bd8deadSopenharmony_ci    The approximation function is accurate to at least 22 bits:
25535bd8deadSopenharmony_ci
25545bd8deadSopenharmony_ci      | ClampApproxReciprocal(x) - (1/x) | < 1.0 / 2^22, if 1.0 <= x < 2.0.
25555bd8deadSopenharmony_ci
25565bd8deadSopenharmony_ci    The following special-case rules apply to reciprocation:
25575bd8deadSopenharmony_ci
25585bd8deadSopenharmony_ci      1. ClampApproxReciprocal(NaN) = NaN.
25595bd8deadSopenharmony_ci      2. ClampApproxReciprocal(+INF) = +2^-64.
25605bd8deadSopenharmony_ci      3. ClampApproxReciprocal(-INF) = -2^-64.
25615bd8deadSopenharmony_ci      4. ClampApproxReciprocal(+0.0) = +2^64.
25625bd8deadSopenharmony_ci      5. ClampApproxReciprocal(-0.0) = -2^64.
25635bd8deadSopenharmony_ci      6. ClampApproxReciprocal(x) = +2^-64, if +2^64 < x < +INF.
25645bd8deadSopenharmony_ci      7. ClampApproxReciprocal(x) = -2^-64, if -INF < x < -2^-64.
25655bd8deadSopenharmony_ci      8. ClampApproxReciprocal(x) = +2^64, if +0.0 < x < +2^-64.
25665bd8deadSopenharmony_ci      9. ClampApproxReciprocal(x) = -2^64, if -2^-64 < x < -0.0.
25675bd8deadSopenharmony_ci
25685bd8deadSopenharmony_ci    The RCC instruction is available only in the VP1.1 and VP2 execution
25695bd8deadSopenharmony_ci    environments.
25705bd8deadSopenharmony_ci
25715bd8deadSopenharmony_ci
25725bd8deadSopenharmony_ci    Section 2.14.3.26,  RCP:  Reciprocal
25735bd8deadSopenharmony_ci
25745bd8deadSopenharmony_ci    The RCP instruction approximates the reciprocal of the scalar operand and
25755bd8deadSopenharmony_ci    replicates it to all four components of the result vector.
25765bd8deadSopenharmony_ci
25775bd8deadSopenharmony_ci      tmp = ScalarLoad(op0);
25785bd8deadSopenharmony_ci      result.x = ApproxReciprocal(tmp);
25795bd8deadSopenharmony_ci      result.y = ApproxReciprocal(tmp);
25805bd8deadSopenharmony_ci      result.z = ApproxReciprocal(tmp);
25815bd8deadSopenharmony_ci      result.w = ApproxReciprocal(tmp);
25825bd8deadSopenharmony_ci
25835bd8deadSopenharmony_ci    The approximation function is accurate to at least 22 bits:
25845bd8deadSopenharmony_ci
25855bd8deadSopenharmony_ci      | ApproxReciprocal(x) - (1/x) | < 1.0 / 2^22, if 1.0 <= x < 2.0.
25865bd8deadSopenharmony_ci
25875bd8deadSopenharmony_ci    The following special-case rules apply to reciprocation:
25885bd8deadSopenharmony_ci
25895bd8deadSopenharmony_ci      1. ApproxReciprocal(NaN) = NaN.
25905bd8deadSopenharmony_ci      2. ApproxReciprocal(+INF) = +0.0.
25915bd8deadSopenharmony_ci      3. ApproxReciprocal(-INF) = -0.0.
25925bd8deadSopenharmony_ci      4. ApproxReciprocal(+0.0) = +INF.
25935bd8deadSopenharmony_ci      5. ApproxReciprocal(-0.0) = -INF.
25945bd8deadSopenharmony_ci
25955bd8deadSopenharmony_ci
25965bd8deadSopenharmony_ci    Section 2.14.3.27,  RET:  Subroutine Call Return
25975bd8deadSopenharmony_ci
25985bd8deadSopenharmony_ci    The RET instruction conditionally returns from a subroutine initiated by a
25995bd8deadSopenharmony_ci    CAL instruction by popping an instruction reference off the top of the
26005bd8deadSopenharmony_ci    call stack and transferring control to the referenced instruction.  The
26015bd8deadSopenharmony_ci    following pseudocode describes the operation of the instruction:
26025bd8deadSopenharmony_ci
26035bd8deadSopenharmony_ci      if (TestCC(cc.c***) || TestCC(cc.*c**) || 
26045bd8deadSopenharmony_ci          TestCC(cc.**c*) || TestCC(cc.***c)) {
26055bd8deadSopenharmony_ci        if (callStackDepth <= 0) {
26065bd8deadSopenharmony_ci          // terminate vertex program
26075bd8deadSopenharmony_ci        } else {
26085bd8deadSopenharmony_ci          callStackDepth--;
26095bd8deadSopenharmony_ci          instruction = callStack[callStackDepth];
26105bd8deadSopenharmony_ci        }
26115bd8deadSopenharmony_ci
26125bd8deadSopenharmony_ci        // continue execution at <instruction>
26135bd8deadSopenharmony_ci      } else {
26145bd8deadSopenharmony_ci        // do nothing
26155bd8deadSopenharmony_ci      }
26165bd8deadSopenharmony_ci
26175bd8deadSopenharmony_ci    In the pseudocode, <callStackDepth> is the depth of the call stack,
26185bd8deadSopenharmony_ci    <callStack> is an array holding the call stack, and <instruction> is a
26195bd8deadSopenharmony_ci    reference to an instruction previously pushed onto the call stack.
26205bd8deadSopenharmony_ci    
26215bd8deadSopenharmony_ci    The RET instruction is available only in the VP2 execution environment.
26225bd8deadSopenharmony_ci
26235bd8deadSopenharmony_ci
26245bd8deadSopenharmony_ci    Section 2.14.3.28,  RSQ:  Reciprocal Square Root
26255bd8deadSopenharmony_ci
26265bd8deadSopenharmony_ci    The RSQ instruction approximates the reciprocal of the square root of the
26275bd8deadSopenharmony_ci    scalar operand and replicates it to all four components of the result
26285bd8deadSopenharmony_ci    vector.
26295bd8deadSopenharmony_ci
26305bd8deadSopenharmony_ci      tmp = ScalarLoad(op0);
26315bd8deadSopenharmony_ci      result.x = ApproxRSQRT(tmp);
26325bd8deadSopenharmony_ci      result.y = ApproxRSQRT(tmp);
26335bd8deadSopenharmony_ci      result.z = ApproxRSQRT(tmp);
26345bd8deadSopenharmony_ci      result.w = ApproxRSQRT(tmp);
26355bd8deadSopenharmony_ci
26365bd8deadSopenharmony_ci    The approximation function is accurate to at least 22 bits:
26375bd8deadSopenharmony_ci
26385bd8deadSopenharmony_ci      | ApproxRSQRT(x) - (1/x) | < 1.0 / 2^22, if 1.0 <= x < 4.0.
26395bd8deadSopenharmony_ci
26405bd8deadSopenharmony_ci    The following special-case rules apply to reciprocal square roots:
26415bd8deadSopenharmony_ci
26425bd8deadSopenharmony_ci      1. ApproxRSQRT(NaN) = NaN.
26435bd8deadSopenharmony_ci      2. ApproxRSQRT(+INF) = +0.0.
26445bd8deadSopenharmony_ci      3. ApproxRSQRT(-INF) = NaN.
26455bd8deadSopenharmony_ci      4. ApproxRSQRT(+0.0) = +INF.
26465bd8deadSopenharmony_ci      5. ApproxRSQRT(-0.0) = -INF.
26475bd8deadSopenharmony_ci      6. ApproxRSQRT(x) = NaN, if -INF < x < -0.0.
26485bd8deadSopenharmony_ci
26495bd8deadSopenharmony_ci
26505bd8deadSopenharmony_ci    Section 2.14.3.29,  SEQ:  Set on Equal
26515bd8deadSopenharmony_ci
26525bd8deadSopenharmony_ci    The SEQ instruction performs a component-wise comparison of the two
26535bd8deadSopenharmony_ci    operands.  Each component of the result vector is 1.0 if the corresponding
26545bd8deadSopenharmony_ci    component of the first operand is equal to that of the second, and 0.0
26555bd8deadSopenharmony_ci    otherwise.
26565bd8deadSopenharmony_ci
26575bd8deadSopenharmony_ci      tmp0 = VectorLoad(op0);
26585bd8deadSopenharmony_ci      tmp1 = VectorLoad(op1);
26595bd8deadSopenharmony_ci      result.x = (tmp0.x == tmp1.x) ? 1.0 : 0.0;
26605bd8deadSopenharmony_ci      result.y = (tmp0.y == tmp1.y) ? 1.0 : 0.0;
26615bd8deadSopenharmony_ci      result.z = (tmp0.z == tmp1.z) ? 1.0 : 0.0;
26625bd8deadSopenharmony_ci      result.w = (tmp0.w == tmp1.w) ? 1.0 : 0.0;
26635bd8deadSopenharmony_ci      if (tmp0.x is NaN or tmp1.x is NaN) result.x = NaN;
26645bd8deadSopenharmony_ci      if (tmp0.y is NaN or tmp1.y is NaN) result.y = NaN;
26655bd8deadSopenharmony_ci      if (tmp0.z is NaN or tmp1.z is NaN) result.z = NaN;
26665bd8deadSopenharmony_ci      if (tmp0.w is NaN or tmp1.w is NaN) result.w = NaN;
26675bd8deadSopenharmony_ci
26685bd8deadSopenharmony_ci    The following special-case rules apply to SEQ:
26695bd8deadSopenharmony_ci
26705bd8deadSopenharmony_ci      1. (<x> == <y>) and (<y> == <x>) always produce the same result.
26715bd8deadSopenharmony_ci      1. (NaN == <x>) is FALSE for all <x>, including NaN.
26725bd8deadSopenharmony_ci      2. (+INF == +INF) and (-INF == -INF) are TRUE.
26735bd8deadSopenharmony_ci      3. (-0.0 == +0.0) and (+0.0 == -0.0) are TRUE.
26745bd8deadSopenharmony_ci
26755bd8deadSopenharmony_ci    The SEQ instruction is available only in the VP2 execution environment.
26765bd8deadSopenharmony_ci
26775bd8deadSopenharmony_ci
26785bd8deadSopenharmony_ci    Section 2.14.3.30,  SFL:  Set on False
26795bd8deadSopenharmony_ci
26805bd8deadSopenharmony_ci    The SFL instruction is a degenerate case of the other "Set on"
26815bd8deadSopenharmony_ci    instructions that sets all components of the result vector to
26825bd8deadSopenharmony_ci    0.0.
26835bd8deadSopenharmony_ci
26845bd8deadSopenharmony_ci      result.x = 0.0;
26855bd8deadSopenharmony_ci      result.y = 0.0;
26865bd8deadSopenharmony_ci      result.z = 0.0;
26875bd8deadSopenharmony_ci      result.w = 0.0;
26885bd8deadSopenharmony_ci
26895bd8deadSopenharmony_ci    The SFL instruction is available only in the VP2 execution environment.
26905bd8deadSopenharmony_ci
26915bd8deadSopenharmony_ci
26925bd8deadSopenharmony_ci    Section 2.14.3.31,  SGE:  Set on Greater Than or Equal
26935bd8deadSopenharmony_ci
26945bd8deadSopenharmony_ci    The SGE instruction performs a component-wise comparison of the two
26955bd8deadSopenharmony_ci    operands.  Each component of the result vector is 1.0 if the corresponding
26965bd8deadSopenharmony_ci    component of the first operands is greater than or equal that of the
26975bd8deadSopenharmony_ci    second, and 0.0 otherwise.
26985bd8deadSopenharmony_ci
26995bd8deadSopenharmony_ci      tmp0 = VectorLoad(op0);
27005bd8deadSopenharmony_ci      tmp1 = VectorLoad(op1);
27015bd8deadSopenharmony_ci      result.x = (tmp0.x >= tmp1.x) ? 1.0 : 0.0;
27025bd8deadSopenharmony_ci      result.y = (tmp0.y >= tmp1.y) ? 1.0 : 0.0;
27035bd8deadSopenharmony_ci      result.z = (tmp0.z >= tmp1.z) ? 1.0 : 0.0;
27045bd8deadSopenharmony_ci      result.w = (tmp0.w >= tmp1.w) ? 1.0 : 0.0;
27055bd8deadSopenharmony_ci      if (tmp0.x is NaN or tmp1.x is NaN) result.x = NaN;
27065bd8deadSopenharmony_ci      if (tmp0.y is NaN or tmp1.y is NaN) result.y = NaN;
27075bd8deadSopenharmony_ci      if (tmp0.z is NaN or tmp1.z is NaN) result.z = NaN;
27085bd8deadSopenharmony_ci      if (tmp0.w is NaN or tmp1.w is NaN) result.w = NaN;
27095bd8deadSopenharmony_ci
27105bd8deadSopenharmony_ci    The following special-case rules apply to SGE:
27115bd8deadSopenharmony_ci
27125bd8deadSopenharmony_ci      1. (NaN >= <x>) and (<x> >= NaN) are FALSE for all <x>.
27135bd8deadSopenharmony_ci      2. (+INF >= +INF) and (-INF >= -INF) are TRUE.
27145bd8deadSopenharmony_ci      3. (-0.0 >= +0.0) and (+0.0 >= -0.0) are TRUE.
27155bd8deadSopenharmony_ci
27165bd8deadSopenharmony_ci
27175bd8deadSopenharmony_ci    Section 2.14.3.32,  SGT:  Set on Greater Than
27185bd8deadSopenharmony_ci
27195bd8deadSopenharmony_ci    The SGT instruction performs a component-wise comparison of the two
27205bd8deadSopenharmony_ci    operands.  Each component of the result vector is 1.0 if the corresponding
27215bd8deadSopenharmony_ci    component of the first operands is greater than that of the second, and
27225bd8deadSopenharmony_ci    0.0 otherwise.
27235bd8deadSopenharmony_ci
27245bd8deadSopenharmony_ci      tmp0 = VectorLoad(op0);
27255bd8deadSopenharmony_ci      tmp1 = VectorLoad(op1);
27265bd8deadSopenharmony_ci      result.x = (tmp0.x > tmp1.x) ? 1.0 : 0.0;
27275bd8deadSopenharmony_ci      result.y = (tmp0.y > tmp1.y) ? 1.0 : 0.0;
27285bd8deadSopenharmony_ci      result.z = (tmp0.z > tmp1.z) ? 1.0 : 0.0;
27295bd8deadSopenharmony_ci      result.w = (tmp0.w > tmp1.w) ? 1.0 : 0.0;
27305bd8deadSopenharmony_ci      if (tmp0.x is NaN or tmp1.x is NaN) result.x = NaN;
27315bd8deadSopenharmony_ci      if (tmp0.y is NaN or tmp1.y is NaN) result.y = NaN;
27325bd8deadSopenharmony_ci      if (tmp0.z is NaN or tmp1.z is NaN) result.z = NaN;
27335bd8deadSopenharmony_ci      if (tmp0.w is NaN or tmp1.w is NaN) result.w = NaN;
27345bd8deadSopenharmony_ci
27355bd8deadSopenharmony_ci    The following special-case rules apply to SGT:
27365bd8deadSopenharmony_ci
27375bd8deadSopenharmony_ci      1. (NaN > <x>) and (<x> > NaN) are FALSE for all <x>.
27385bd8deadSopenharmony_ci      2. (-0.0 > +0.0) and (+0.0 > -0.0) are FALSE.
27395bd8deadSopenharmony_ci
27405bd8deadSopenharmony_ci    The SGT instruction is available only in the VP2 execution environment.
27415bd8deadSopenharmony_ci
27425bd8deadSopenharmony_ci
27435bd8deadSopenharmony_ci    Section 2.14.3.33,  SIN:  Sine
27445bd8deadSopenharmony_ci
27455bd8deadSopenharmony_ci    The SIN instruction approximates the sine of the angle specified by the
27465bd8deadSopenharmony_ci    scalar operand and replicates it to all four components of the result
27475bd8deadSopenharmony_ci    vector.  The angle is specified in radians and does not have to be in the
27485bd8deadSopenharmony_ci    range [0,2*PI].
27495bd8deadSopenharmony_ci
27505bd8deadSopenharmony_ci      tmp = ScalarLoad(op0);
27515bd8deadSopenharmony_ci      result.x = ApproxSine(tmp);
27525bd8deadSopenharmony_ci      result.y = ApproxSine(tmp);
27535bd8deadSopenharmony_ci      result.z = ApproxSine(tmp);
27545bd8deadSopenharmony_ci      result.w = ApproxSine(tmp);
27555bd8deadSopenharmony_ci
27565bd8deadSopenharmony_ci    The approximation function is accurate to at least 22 bits with an angle
27575bd8deadSopenharmony_ci    in the range [0,2*PI].
27585bd8deadSopenharmony_ci
27595bd8deadSopenharmony_ci      | ApproxSine(x) - sin(x) | < 1.0 / 2^22, if 0.0 <= x < 2.0 * PI.
27605bd8deadSopenharmony_ci
27615bd8deadSopenharmony_ci    The error in the approximation will typically increase with the absolute
27625bd8deadSopenharmony_ci    value of the angle when the angle falls outside the range [0,2*PI].
27635bd8deadSopenharmony_ci
27645bd8deadSopenharmony_ci    The following special-case rules apply to cosine approximation:
27655bd8deadSopenharmony_ci
27665bd8deadSopenharmony_ci      1. ApproxSine(NaN) = NaN.
27675bd8deadSopenharmony_ci      2. ApproxSine(+/-INF) = NaN.
27685bd8deadSopenharmony_ci      3. ApproxSine(+/-0.0) = +/-0.0.  The sign of the result is equal to the
27695bd8deadSopenharmony_ci         sign of the single operand.
27705bd8deadSopenharmony_ci
27715bd8deadSopenharmony_ci    The SIN instruction is available only in the VP2 execution environment.
27725bd8deadSopenharmony_ci
27735bd8deadSopenharmony_ci
27745bd8deadSopenharmony_ci    Section 2.14.3.34,  SLE:  Set on Less Than or Equal
27755bd8deadSopenharmony_ci
27765bd8deadSopenharmony_ci    The SLE instruction performs a component-wise comparison of the two
27775bd8deadSopenharmony_ci    operands.  Each component of the result vector is 1.0 if the corresponding
27785bd8deadSopenharmony_ci    component of the first operand is less than or equal to that of the
27795bd8deadSopenharmony_ci    second, and 0.0 otherwise.
27805bd8deadSopenharmony_ci
27815bd8deadSopenharmony_ci      tmp0 = VectorLoad(op0);
27825bd8deadSopenharmony_ci      tmp1 = VectorLoad(op1);
27835bd8deadSopenharmony_ci      result.x = (tmp0.x <= tmp1.x) ? 1.0 : 0.0;
27845bd8deadSopenharmony_ci      result.y = (tmp0.y <= tmp1.y) ? 1.0 : 0.0;
27855bd8deadSopenharmony_ci      result.z = (tmp0.z <= tmp1.z) ? 1.0 : 0.0;
27865bd8deadSopenharmony_ci      result.w = (tmp0.w <= tmp1.w) ? 1.0 : 0.0;
27875bd8deadSopenharmony_ci      if (tmp0.x is NaN or tmp1.x is NaN) result.x = NaN;
27885bd8deadSopenharmony_ci      if (tmp0.y is NaN or tmp1.y is NaN) result.y = NaN;
27895bd8deadSopenharmony_ci      if (tmp0.z is NaN or tmp1.z is NaN) result.z = NaN;
27905bd8deadSopenharmony_ci      if (tmp0.w is NaN or tmp1.w is NaN) result.w = NaN;
27915bd8deadSopenharmony_ci
27925bd8deadSopenharmony_ci    The following special-case rules apply to SLE:
27935bd8deadSopenharmony_ci
27945bd8deadSopenharmony_ci      1. (NaN <= <x>) and (<x> <= NaN) are FALSE for all <x>.
27955bd8deadSopenharmony_ci      2. (+INF <= +INF) and (-INF <= -INF) are TRUE.
27965bd8deadSopenharmony_ci      3. (-0.0 <= +0.0) and (+0.0 <= -0.0) are TRUE.
27975bd8deadSopenharmony_ci
27985bd8deadSopenharmony_ci    The SLE instruction is available only in the VP2 execution environment.
27995bd8deadSopenharmony_ci
28005bd8deadSopenharmony_ci
28015bd8deadSopenharmony_ci    Section 2.14.3.35,  SLT:  Set on Less Than
28025bd8deadSopenharmony_ci
28035bd8deadSopenharmony_ci    The SLT instruction performs a component-wise comparison of the two
28045bd8deadSopenharmony_ci    operands.  Each component of the result vector is 1.0 if the corresponding
28055bd8deadSopenharmony_ci    component of the first operand is less than that of the second, and 0.0
28065bd8deadSopenharmony_ci    otherwise.
28075bd8deadSopenharmony_ci
28085bd8deadSopenharmony_ci      tmp0 = VectorLoad(op0);
28095bd8deadSopenharmony_ci      tmp1 = VectorLoad(op1);
28105bd8deadSopenharmony_ci      result.x = (tmp0.x < tmp1.x) ? 1.0 : 0.0;
28115bd8deadSopenharmony_ci      result.y = (tmp0.y < tmp1.y) ? 1.0 : 0.0;
28125bd8deadSopenharmony_ci      result.z = (tmp0.z < tmp1.z) ? 1.0 : 0.0;
28135bd8deadSopenharmony_ci      result.w = (tmp0.w < tmp1.w) ? 1.0 : 0.0;
28145bd8deadSopenharmony_ci      if (tmp0.x is NaN or tmp1.x is NaN) result.x = NaN;
28155bd8deadSopenharmony_ci      if (tmp0.y is NaN or tmp1.y is NaN) result.y = NaN;
28165bd8deadSopenharmony_ci      if (tmp0.z is NaN or tmp1.z is NaN) result.z = NaN;
28175bd8deadSopenharmony_ci      if (tmp0.w is NaN or tmp1.w is NaN) result.w = NaN;
28185bd8deadSopenharmony_ci
28195bd8deadSopenharmony_ci    The following special-case rules apply to SLT:
28205bd8deadSopenharmony_ci
28215bd8deadSopenharmony_ci      1. (NaN < <x>) and (<x> < NaN) are FALSE for all <x>.
28225bd8deadSopenharmony_ci      2. (-0.0 < +0.0) and (+0.0 < -0.0) are FALSE.
28235bd8deadSopenharmony_ci
28245bd8deadSopenharmony_ci
28255bd8deadSopenharmony_ci    Section 2.14.3.36,  SNE:  Set on Not Equal
28265bd8deadSopenharmony_ci
28275bd8deadSopenharmony_ci    The SNE instruction performs a component-wise comparison of the two
28285bd8deadSopenharmony_ci    operands.  Each component of the result vector is 1.0 if the corresponding
28295bd8deadSopenharmony_ci    component of the first operand is not equal to that of the second, and 0.0
28305bd8deadSopenharmony_ci    otherwise.
28315bd8deadSopenharmony_ci
28325bd8deadSopenharmony_ci      tmp0 = VectorLoad(op0);
28335bd8deadSopenharmony_ci      tmp1 = VectorLoad(op1);
28345bd8deadSopenharmony_ci      result.x = (tmp0.x != tmp1.x) ? 1.0 : 0.0;
28355bd8deadSopenharmony_ci      result.y = (tmp0.y != tmp1.y) ? 1.0 : 0.0;
28365bd8deadSopenharmony_ci      result.z = (tmp0.z != tmp1.z) ? 1.0 : 0.0;
28375bd8deadSopenharmony_ci      result.w = (tmp0.w != tmp1.w) ? 1.0 : 0.0;
28385bd8deadSopenharmony_ci      if (tmp0.x is NaN or tmp1.x is NaN) result.x = NaN;
28395bd8deadSopenharmony_ci      if (tmp0.y is NaN or tmp1.y is NaN) result.y = NaN;
28405bd8deadSopenharmony_ci      if (tmp0.z is NaN or tmp1.z is NaN) result.z = NaN;
28415bd8deadSopenharmony_ci      if (tmp0.w is NaN or tmp1.w is NaN) result.w = NaN;
28425bd8deadSopenharmony_ci
28435bd8deadSopenharmony_ci    The following special-case rules apply to SNE:
28445bd8deadSopenharmony_ci
28455bd8deadSopenharmony_ci      1. (<x> != <y>) and (<y> != <x>) always produce the same result.
28465bd8deadSopenharmony_ci      2. (NaN != <x>) is TRUE for all <x>, including NaN.
28475bd8deadSopenharmony_ci      3. (+INF != +INF) and (-INF != -INF) are FALSE.
28485bd8deadSopenharmony_ci      4. (-0.0 != +0.0) and (+0.0 != -0.0) are TRUE.
28495bd8deadSopenharmony_ci
28505bd8deadSopenharmony_ci    The SNE instruction is available only in the VP2 execution environment.
28515bd8deadSopenharmony_ci
28525bd8deadSopenharmony_ci
28535bd8deadSopenharmony_ci    Section 2.14.3.37,  SSG:  Set Sign
28545bd8deadSopenharmony_ci
28555bd8deadSopenharmony_ci    The SSG instruction generates a result vector containing the signs of each
28565bd8deadSopenharmony_ci    component of the single operand.  Each component of the result vector is
28575bd8deadSopenharmony_ci    1.0 if the corresponding component of the operand is greater than zero,
28585bd8deadSopenharmony_ci    0.0 if the corresponding component of the operand is equal to zero, and
28595bd8deadSopenharmony_ci    -1.0 if the corresponding component of the operand is less than zero.
28605bd8deadSopenharmony_ci
28615bd8deadSopenharmony_ci      tmp = VectorLoad(op0);
28625bd8deadSopenharmony_ci      result.x = SetSign(tmp.x);
28635bd8deadSopenharmony_ci      result.y = SetSign(tmp.y);
28645bd8deadSopenharmony_ci      result.z = SetSign(tmp.z);
28655bd8deadSopenharmony_ci      result.w = SetSign(tmp.w);
28665bd8deadSopenharmony_ci
28675bd8deadSopenharmony_ci    The following special-case rules apply to SSG:
28685bd8deadSopenharmony_ci
28695bd8deadSopenharmony_ci      1. SetSign(NaN) = NaN.
28705bd8deadSopenharmony_ci      2. SetSign(-0.0) = SetSign(+0.0) = 0.0.
28715bd8deadSopenharmony_ci      3. SetSign(-INF) = -1.0.
28725bd8deadSopenharmony_ci      4. SetSign(+INF) = +1.0.
28735bd8deadSopenharmony_ci      5. SetSign(x) = -1.0, if -INF < x < -0.0.
28745bd8deadSopenharmony_ci      6. SetSign(x) = +1.0, if +0.0 < x < +INF.
28755bd8deadSopenharmony_ci
28765bd8deadSopenharmony_ci    The SSG instruction is available only in the VP2 execution environment.
28775bd8deadSopenharmony_ci
28785bd8deadSopenharmony_ci
28795bd8deadSopenharmony_ci    Section 2.14.3.38,  STR:  Set on True
28805bd8deadSopenharmony_ci
28815bd8deadSopenharmony_ci    The STR instruction is a degenerate case of the other "Set on"
28825bd8deadSopenharmony_ci    instructions that sets all components of the result vector to 1.0.
28835bd8deadSopenharmony_ci
28845bd8deadSopenharmony_ci      result.x = 1.0;
28855bd8deadSopenharmony_ci      result.y = 1.0;
28865bd8deadSopenharmony_ci      result.z = 1.0;
28875bd8deadSopenharmony_ci      result.w = 1.0;
28885bd8deadSopenharmony_ci
28895bd8deadSopenharmony_ci    The STR instruction is available only in the VP2 execution environment.
28905bd8deadSopenharmony_ci
28915bd8deadSopenharmony_ci
28925bd8deadSopenharmony_ci    Section 2.14.3.39,  SUB:  Subtract
28935bd8deadSopenharmony_ci
28945bd8deadSopenharmony_ci    The SUB instruction performs a component-wise subtraction of the second
28955bd8deadSopenharmony_ci    operand from the first to yield a result vector.
28965bd8deadSopenharmony_ci
28975bd8deadSopenharmony_ci      tmp0 = VectorLoad(op0);
28985bd8deadSopenharmony_ci      tmp1 = VectorLoad(op1);
28995bd8deadSopenharmony_ci      result.x = tmp0.x - tmp1.x;
29005bd8deadSopenharmony_ci      result.y = tmp0.y - tmp1.y;
29015bd8deadSopenharmony_ci      result.z = tmp0.z - tmp1.z;
29025bd8deadSopenharmony_ci      result.w = tmp0.w - tmp1.w;
29035bd8deadSopenharmony_ci
29045bd8deadSopenharmony_ci    The SUB instruction is completely equivalent to an identical ADD
29055bd8deadSopenharmony_ci    instruction in which the negate operator on the second operand is
29065bd8deadSopenharmony_ci    reversed:
29075bd8deadSopenharmony_ci
29085bd8deadSopenharmony_ci      1. "SUB R0, R1, R2" is equivalent to "ADD R0, R1, -R2".
29095bd8deadSopenharmony_ci      2. "SUB R0, R1, -R2" is equivalent to "ADD R0, R1, R2".
29105bd8deadSopenharmony_ci      3. "SUB R0, R1, |R2|" is equivalent to "ADD R0, R1, -|R2|".
29115bd8deadSopenharmony_ci      4. "SUB R0, R1, -|R2|" is equivalent to "ADD R0, R1, |R2|".
29125bd8deadSopenharmony_ci
29135bd8deadSopenharmony_ci    The SUB instruction is available only in the VP1.1 and VP2 execution
29145bd8deadSopenharmony_ci    environments.
29155bd8deadSopenharmony_ci
29165bd8deadSopenharmony_ci
29175bd8deadSopenharmony_ci    2.14.4  Vertex Arrays for Vertex Attributes
29185bd8deadSopenharmony_ci
29195bd8deadSopenharmony_ci    Data for vertex attributes in vertex program mode may be specified
29205bd8deadSopenharmony_ci    using vertex array commands.  The client may specify and enable any
29215bd8deadSopenharmony_ci    of sixteen vertex attribute arrays.
29225bd8deadSopenharmony_ci
29235bd8deadSopenharmony_ci    The vertex attribute arrays are ignored when vertex program mode
29245bd8deadSopenharmony_ci    is disabled.  When vertex program mode is enabled, vertex attribute
29255bd8deadSopenharmony_ci    arrays are used.
29265bd8deadSopenharmony_ci
29275bd8deadSopenharmony_ci    The command
29285bd8deadSopenharmony_ci
29295bd8deadSopenharmony_ci      void VertexAttribPointerNV(uint index, int size, enum type,
29305bd8deadSopenharmony_ci                                 sizei stride, const void *pointer);
29315bd8deadSopenharmony_ci
29325bd8deadSopenharmony_ci    describes the locations and organizations of the sixteen vertex
29335bd8deadSopenharmony_ci    attribute arrays.  index specifies the particular vertex attribute
29345bd8deadSopenharmony_ci    to be described.  size indicates the number of values per vertex
29355bd8deadSopenharmony_ci    that are stored in the array; size must be one of 1, 2, 3, or 4.
29365bd8deadSopenharmony_ci    type specifies the data type of the values stored in the array.
29375bd8deadSopenharmony_ci    type must be one of SHORT, FLOAT, DOUBLE, or UNSIGNED_BYTE and these
29385bd8deadSopenharmony_ci    values correspond to the array types short, int, float, double, and
29395bd8deadSopenharmony_ci    ubyte respectively.  The INVALID_OPERATION error is generated if
29405bd8deadSopenharmony_ci    type is UNSIGNED_BYTE and size is not 4.  The INVALID_VALUE error
29415bd8deadSopenharmony_ci    is generated if index is greater than 15.  The INVALID_VALUE error
29425bd8deadSopenharmony_ci    is generated if stride is negative.
29435bd8deadSopenharmony_ci
29445bd8deadSopenharmony_ci    The one, two, three, or four values in an array that correspond to a
29455bd8deadSopenharmony_ci    single vertex attribute comprise an array element.  The values within
29465bd8deadSopenharmony_ci    each array element at stored sequentially in memory.  If the stride
29475bd8deadSopenharmony_ci    is specified as zero, then array elements are stored sequentially
29485bd8deadSopenharmony_ci    as well.  Otherwise points to the ith and (i+1)st elements of an array
29495bd8deadSopenharmony_ci    differ by stride basic machine units (typically unsigned bytes),
29505bd8deadSopenharmony_ci    the pointer to the (i+1)st element being greater.  pointer specifies
29515bd8deadSopenharmony_ci    the location in memory of the first value of the first element of
29525bd8deadSopenharmony_ci    the array being specified.
29535bd8deadSopenharmony_ci
29545bd8deadSopenharmony_ci    Vertex attribute arrays are enabled with the EnableClientState command
29555bd8deadSopenharmony_ci    and disabled with the DisableClientState command.  The value of the
29565bd8deadSopenharmony_ci    argument to either command is VERTEX_ATTRIB_ARRAYi_NV where i is an
29575bd8deadSopenharmony_ci    integer between 0 and 15; specifying a value of i enables or
29585bd8deadSopenharmony_ci    disables the vertex attribute array with index i.  The constants
29595bd8deadSopenharmony_ci    obey VERTEX_ATTRIB_ARRAYi_NV = VERTEX_ATTRIB_ARRAY0_NV + i.
29605bd8deadSopenharmony_ci
29615bd8deadSopenharmony_ci    When vertex program mode is enabled, the ArrayElement command operates
29625bd8deadSopenharmony_ci    as described in this section in contrast to the behavior described
29635bd8deadSopenharmony_ci    in section 2.8.  Likewise, any vertex array transfer commands that
29645bd8deadSopenharmony_ci    are defined in terms of ArrayElement (DrawArrays, DrawElements, and
29655bd8deadSopenharmony_ci    DrawRangeElements) assume the operation of ArrayElement described
29665bd8deadSopenharmony_ci    in this section when vertex program mode is enabled.
29675bd8deadSopenharmony_ci
29685bd8deadSopenharmony_ci    When vertex program mode is enabled, the ArrayElement command
29695bd8deadSopenharmony_ci    transfers the ith element of particular enabled vertex arrays as
29705bd8deadSopenharmony_ci    described below.  For each enabled vertex attribute array, it is
29715bd8deadSopenharmony_ci    as though the corresponding command from section 2.14.1.1 were
29725bd8deadSopenharmony_ci    called with a pointer to element i.  For each vertex attribute,
29735bd8deadSopenharmony_ci    the corresponding command is VertexAttrib[size][type]v, where size
29745bd8deadSopenharmony_ci    is one of [1,2,3,4], and type is one of [s,f,d,ub], corresponding
29755bd8deadSopenharmony_ci    to the array types short, int, float, double, and ubyte respectively.
29765bd8deadSopenharmony_ci
29775bd8deadSopenharmony_ci    However, if a given vertex attribute array is disabled, but its
29785bd8deadSopenharmony_ci    corresponding aliased conventional per-vertex parameter's vertex
29795bd8deadSopenharmony_ci    array (as described in section 2.14.1.6) is enabled, then it is
29805bd8deadSopenharmony_ci    as though the corresponding command from section 2.7 or section
29815bd8deadSopenharmony_ci    2.6.2 were called with a pointer to element i.  In this case, the
29825bd8deadSopenharmony_ci    corresponding command is determined as described in section 2.8's
29835bd8deadSopenharmony_ci    description of ArrayElement.
29845bd8deadSopenharmony_ci
29855bd8deadSopenharmony_ci    If the vertex attribute array 0 is enabled, it is as though
29865bd8deadSopenharmony_ci    VertexAttrib[size][type]v(0, ...) is executed last, after the
29875bd8deadSopenharmony_ci    executions of other corresponding commands.  If the vertex attribute
29885bd8deadSopenharmony_ci    array 0 is disabled but the vertex array is enabled, it is as though
29895bd8deadSopenharmony_ci    Vertex[size][type]v is executed last, after the executions of other
29905bd8deadSopenharmony_ci    corresponding commands.
29915bd8deadSopenharmony_ci
29925bd8deadSopenharmony_ci    2.14.5  Vertex State Programs
29935bd8deadSopenharmony_ci
29945bd8deadSopenharmony_ci    Vertex state programs share the same instruction set as and a similar
29955bd8deadSopenharmony_ci    execution model to vertex programs.  While vertex programs are executed
29965bd8deadSopenharmony_ci    implicitly when a vertex transformation is provoked, vertex state programs
29975bd8deadSopenharmony_ci    are executed explicitly, independently of any vertices.  Vertex state
29985bd8deadSopenharmony_ci    programs can write program parameter registers, but may not write vertex
29995bd8deadSopenharmony_ci    result registers.  Vertex state programs have not been extended beyond the
30005bd8deadSopenharmony_ci    the VP1.0 execution environment, and are offered solely for compatibility
30015bd8deadSopenharmony_ci    with that execution environment.
30025bd8deadSopenharmony_ci
30035bd8deadSopenharmony_ci    The purpose of a vertex state program is to update program parameter
30045bd8deadSopenharmony_ci    registers by means of an application-defined program.  Typically, an
30055bd8deadSopenharmony_ci    application will load a set of program parameters and then execute a
30065bd8deadSopenharmony_ci    vertex state program that reads and updates the program parameter
30075bd8deadSopenharmony_ci    registers.  For example, a vertex state program might normalize a set of
30085bd8deadSopenharmony_ci    unnormalized vectors previously loaded as program parameters.  The
30095bd8deadSopenharmony_ci    expectation is that subsequently executed vertex programs would use the
30105bd8deadSopenharmony_ci    normalized program parameters.
30115bd8deadSopenharmony_ci
30125bd8deadSopenharmony_ci    Vertex state programs are loaded with the same LoadProgramNV command (see
30135bd8deadSopenharmony_ci    section 2.14.1.8) used to load vertex programs except that the target must
30145bd8deadSopenharmony_ci    be VERTEX_STATE_PROGRAM_NV when loading a vertex state program.
30155bd8deadSopenharmony_ci
30165bd8deadSopenharmony_ci    Vertex state programs must conform to a more limited grammar than the
30175bd8deadSopenharmony_ci    grammar for vertex programs.  The vertex state program grammar for
30185bd8deadSopenharmony_ci    syntactically valid sequences is the same as the grammar defined in
30195bd8deadSopenharmony_ci    section 2.14.1.8 with the following modified rules:
30205bd8deadSopenharmony_ci
30215bd8deadSopenharmony_ci    <program>              ::= <vp1-program>
30225bd8deadSopenharmony_ci
30235bd8deadSopenharmony_ci    <vp1-program>          ::= "!!VSP1.0" <programBody> "END"
30245bd8deadSopenharmony_ci
30255bd8deadSopenharmony_ci    <dstReg>               ::= <absProgParamReg>
30265bd8deadSopenharmony_ci                             | <temporaryReg>
30275bd8deadSopenharmony_ci
30285bd8deadSopenharmony_ci    <vertexAttribReg>      ::= "v" "[" "0" "]"
30295bd8deadSopenharmony_ci
30305bd8deadSopenharmony_ci    A vertex state program fails to load if it does not write at least
30315bd8deadSopenharmony_ci    one program parameter register.
30325bd8deadSopenharmony_ci
30335bd8deadSopenharmony_ci    A vertex state program fails to load if it contains more than 128
30345bd8deadSopenharmony_ci    instructions.
30355bd8deadSopenharmony_ci
30365bd8deadSopenharmony_ci    A vertex state program fails to load if any instruction sources more
30375bd8deadSopenharmony_ci    than one unique program parameter register.
30385bd8deadSopenharmony_ci
30395bd8deadSopenharmony_ci    A vertex state program fails to load if any instruction sources
30405bd8deadSopenharmony_ci    more than one unique vertex attribute register (this is necessarily
30415bd8deadSopenharmony_ci    true because only vertex attribute 0 is available in vertex state
30425bd8deadSopenharmony_ci    programs).
30435bd8deadSopenharmony_ci
30445bd8deadSopenharmony_ci    The error INVALID_OPERATION is generated if a vertex state program
30455bd8deadSopenharmony_ci    fails to load because it is not syntactically correct or for one
30465bd8deadSopenharmony_ci    of the other reasons listed above.
30475bd8deadSopenharmony_ci
30485bd8deadSopenharmony_ci    A successfully loaded vertex state program is parsed into a sequence
30495bd8deadSopenharmony_ci    of instructions.  Each instruction is identified by its tokenized
30505bd8deadSopenharmony_ci    name.  The operation of these instructions when executed is defined
30515bd8deadSopenharmony_ci    in section 2.14.1.10.
30525bd8deadSopenharmony_ci
30535bd8deadSopenharmony_ci    Executing vertex state programs is legal only outside a Begin/End
30545bd8deadSopenharmony_ci    pair.  A vertex state program may not read any vertex attribute
30555bd8deadSopenharmony_ci    register other than register zero.  A vertex state program may not
30565bd8deadSopenharmony_ci    write any vertex result register.
30575bd8deadSopenharmony_ci
30585bd8deadSopenharmony_ci    The command
30595bd8deadSopenharmony_ci
30605bd8deadSopenharmony_ci      ExecuteProgramNV(enum target, uint id, const float *params);
30615bd8deadSopenharmony_ci
30625bd8deadSopenharmony_ci    executes the vertex state program named by id.  The target must be
30635bd8deadSopenharmony_ci    VERTEX_STATE_PROGRAM_NV and the id must be the name of program loaded
30645bd8deadSopenharmony_ci    with a target type of VERTEX_STATE_PROGRAM_NV.  params points to
30655bd8deadSopenharmony_ci    an array of four floating-point values that are loaded into vertex
30665bd8deadSopenharmony_ci    attribute register zero (the only vertex attribute readable from a
30675bd8deadSopenharmony_ci    vertex state program).
30685bd8deadSopenharmony_ci
30695bd8deadSopenharmony_ci    The INVALID_OPERATION error is generated if the named program is
30705bd8deadSopenharmony_ci    nonexistent, is invalid, or the program is not a vertex state
30715bd8deadSopenharmony_ci    program.  A vertex state program may not be valid for reasons
30725bd8deadSopenharmony_ci    explained in section 2.14.5.
30735bd8deadSopenharmony_ci
30745bd8deadSopenharmony_ci
30755bd8deadSopenharmony_ci    2.14.6,  Program Options
30765bd8deadSopenharmony_ci
30775bd8deadSopenharmony_ci    In the VP1.1 and VP2.0 execution environment, vertex programs may specify
30785bd8deadSopenharmony_ci    one or more program options that modify the execution environment,
30795bd8deadSopenharmony_ci    according to the <option> grammar rule.  The set of options available to
30805bd8deadSopenharmony_ci    the program is described below.
30815bd8deadSopenharmony_ci
30825bd8deadSopenharmony_ci    Section 2.14.6.1, Position-Invariant Vertex Program Option
30835bd8deadSopenharmony_ci
30845bd8deadSopenharmony_ci    If <vp11-option> or <vp2-option> matches "NV_position_invariant", the
30855bd8deadSopenharmony_ci    vertex program is presumed to be position-invariant.  By default, vertex
30865bd8deadSopenharmony_ci    programs are not position-invariant.  Even if programs emulate the
30875bd8deadSopenharmony_ci    conventional OpenGL transformation model, they may still not produce the
30885bd8deadSopenharmony_ci    exact same transform results, due to rounding errors or different
30895bd8deadSopenharmony_ci    operation orders.  Such programs may not work well for multi-pass
30905bd8deadSopenharmony_ci    rendering algorithms where the second and subsequent passes use an EQUAL
30915bd8deadSopenharmony_ci    depth test.
30925bd8deadSopenharmony_ci
30935bd8deadSopenharmony_ci    Position-invariant vertex programs do not compute a final vertex position;
30945bd8deadSopenharmony_ci    instead, the GL computes vertex coordinates as described in section 2.10.
30955bd8deadSopenharmony_ci    This computation should produce exactly the same results as the
30965bd8deadSopenharmony_ci    conventional OpenGL transformation model, assuming vertex weighting and
30975bd8deadSopenharmony_ci    vertex blending are disabled.
30985bd8deadSopenharmony_ci
30995bd8deadSopenharmony_ci    A vertex program that specifies the position-invariant option will fail to
31005bd8deadSopenharmony_ci    load if it writes to the HPOS result register.
31015bd8deadSopenharmony_ci
31025bd8deadSopenharmony_ci    Additionally, in the VP1.1 execution environment, position-invariant
31035bd8deadSopenharmony_ci    programs can not use relative addressing for program parameters.  Any
31045bd8deadSopenharmony_ci    position-invariant VP1.1 program matches the grammar rule
31055bd8deadSopenharmony_ci    <relProgParamReg>, will fail to load.  No such restriction exists for
31065bd8deadSopenharmony_ci    VP2.0 programs.
31075bd8deadSopenharmony_ci
31085bd8deadSopenharmony_ci    For position-invariant programs, the limit on the number of instructions
31095bd8deadSopenharmony_ci    allowed in a program is reduced by four:  position-invariant VP1.1 and
31105bd8deadSopenharmony_ci    VP2.0 programs may have no more than 124 or 252 instructions,
31115bd8deadSopenharmony_ci    respectively.
31125bd8deadSopenharmony_ci
31135bd8deadSopenharmony_ci
31145bd8deadSopenharmony_ci    2.14.7  Tracking Matrices 
31155bd8deadSopenharmony_ci
31165bd8deadSopenharmony_ci    As a convenience to applications, standard GL matrix state can be
31175bd8deadSopenharmony_ci    tracked into program parameter vectors.  This permits vertex programs
31185bd8deadSopenharmony_ci    to access matrices specified through GL matrix commands.
31195bd8deadSopenharmony_ci
31205bd8deadSopenharmony_ci    In addition to GL's conventional matrices, several additional matrices
31215bd8deadSopenharmony_ci    are available for tracking.  These matrices have names of the form
31225bd8deadSopenharmony_ci    MATRIXi_NV where i is between zero and n-1 where n is the value
31235bd8deadSopenharmony_ci    of the MAX_TRACK_MATRICES_NV implementation dependent constant.
31245bd8deadSopenharmony_ci    The MATRIXi_NV constants obey MATRIXi_NV = MATRIX0_NV + i.  The value
31255bd8deadSopenharmony_ci    of MAX_TRACK_MATRICES_NV must be at least eight.  The maximum
31265bd8deadSopenharmony_ci    stack depth for tracking matrices is defined by the
31275bd8deadSopenharmony_ci    MAX_TRACK_MATRIX_STACK_DEPTH_NV and must be at least 1.
31285bd8deadSopenharmony_ci
31295bd8deadSopenharmony_ci    The command
31305bd8deadSopenharmony_ci
31315bd8deadSopenharmony_ci      TrackMatrixNV(enum target, uint address, enum matrix, enum transform);
31325bd8deadSopenharmony_ci
31335bd8deadSopenharmony_ci    tracks a given transformed version of a particular matrix into
31345bd8deadSopenharmony_ci    a contiguous sequence of four vertex program parameter registers
31355bd8deadSopenharmony_ci    beginning at address.  target must be VERTEX_PROGRAM_NV (though
31365bd8deadSopenharmony_ci    tracked matrices apply to vertex state programs as well because both
31375bd8deadSopenharmony_ci    vertex state programs and vertex programs shared the same program
31385bd8deadSopenharmony_ci    parameter registers).  matrix must be one of NONE, MODELVIEW,
31395bd8deadSopenharmony_ci    PROJECTION, TEXTURE, TEXTUREi_ARB (where i is between 0 and n-1
31405bd8deadSopenharmony_ci    where n is the number of texture units supported), COLOR (if
31415bd8deadSopenharmony_ci    the ARB_imaging subset is supported), MODELVIEW_PROJECTION_NV,
31425bd8deadSopenharmony_ci    or MATRIXi_NV.  transform must be one of IDENTITY_NV, INVERSE_NV,
31435bd8deadSopenharmony_ci    TRANSPOSE_NV, or INVERSE_TRANSPOSE_NV.  The INVALID_VALUE error is
31445bd8deadSopenharmony_ci    generated if address is not a multiple of four.
31455bd8deadSopenharmony_ci
31465bd8deadSopenharmony_ci    The MODELVIEW_PROJECTION_NV matrix represents the concatenation of
31475bd8deadSopenharmony_ci    the current modelview and projection matrices.  If M is the current
31485bd8deadSopenharmony_ci    modelview matrix and P is the current projection matrix, then the
31495bd8deadSopenharmony_ci    MODELVIEW_PROJECTION_NV matrix is C and computed as
31505bd8deadSopenharmony_ci
31515bd8deadSopenharmony_ci        C = P M
31525bd8deadSopenharmony_ci
31535bd8deadSopenharmony_ci    Matrix tracking for the specified program parameter register and the
31545bd8deadSopenharmony_ci    next consecutive three registers is disabled when NONE is supplied
31555bd8deadSopenharmony_ci    for matrix.  When tracking is disabled the previously tracked program
31565bd8deadSopenharmony_ci    parameter registers retain the state of their last tracked values.
31575bd8deadSopenharmony_ci    Otherwise, the specified transformed version of matrix is tracked into
31585bd8deadSopenharmony_ci    the specified program parameter register and the next three registers.
31595bd8deadSopenharmony_ci    Whenever the matrix changes, the transformed version of the matrix
31605bd8deadSopenharmony_ci    is updated in the specified range of program parameter registers.
31615bd8deadSopenharmony_ci    If TEXTURE is specified for matrix, the texture matrix for the current
31625bd8deadSopenharmony_ci    active texture unit is tracked.  If TEXTUREi_ARB is specified for
31635bd8deadSopenharmony_ci    matrix, the <i>th texture matrix is tracked.
31645bd8deadSopenharmony_ci
31655bd8deadSopenharmony_ci    Matrices are tracked row-wise meaning that the top row of the
31665bd8deadSopenharmony_ci    transformed matrix is loaded into the program parameter address,
31675bd8deadSopenharmony_ci    the second from the top row of the transformed matrix is loaded into
31685bd8deadSopenharmony_ci    the program parameter address+1, the third from the top row of the
31695bd8deadSopenharmony_ci    transformed matrix is loaded into the program parameter address+2,
31705bd8deadSopenharmony_ci    and the bottom row of the transformed matrix is loaded into the
31715bd8deadSopenharmony_ci    program parameter address+3.  The transformed matrix may be identical
31725bd8deadSopenharmony_ci    to the specified matrix, the inverse of the specified matrix, the
31735bd8deadSopenharmony_ci    transpose of the specified matrix, or the inverse transpose of the
31745bd8deadSopenharmony_ci    specified matrix, depending on the value of transform.
31755bd8deadSopenharmony_ci
31765bd8deadSopenharmony_ci    When matrix tracking is enabled for a particular program parameter
31775bd8deadSopenharmony_ci    register sequence, updates to the program parameter using
31785bd8deadSopenharmony_ci    ProgramParameterNV commands, a vertex program, or a vertex state
31795bd8deadSopenharmony_ci    program are not possible.  The INVALID_OPERATION error is generated
31805bd8deadSopenharmony_ci    if a ProgramParameterNV command is used to update a program parameter
31815bd8deadSopenharmony_ci    register currently tracking a matrix.
31825bd8deadSopenharmony_ci
31835bd8deadSopenharmony_ci    The INVALID_OPERATION error is generated by ExecuteProgramNV when
31845bd8deadSopenharmony_ci    the vertex state program requested for execution writes to a program
31855bd8deadSopenharmony_ci    parameter register that is currently tracking a matrix because the
31865bd8deadSopenharmony_ci    program is considered invalid.
31875bd8deadSopenharmony_ci
31885bd8deadSopenharmony_ci    2.14.8  Required Vertex Program State 
31895bd8deadSopenharmony_ci
31905bd8deadSopenharmony_ci    The state required for vertex programs consists of:
31915bd8deadSopenharmony_ci
31925bd8deadSopenharmony_ci      a bit indicating whether or not program mode is enabled;
31935bd8deadSopenharmony_ci
31945bd8deadSopenharmony_ci      a bit indicating whether or not two-sided color mode is enabled;
31955bd8deadSopenharmony_ci
31965bd8deadSopenharmony_ci      a bit indicating whether or not program-specified point size mode
31975bd8deadSopenharmony_ci      is enabled;
31985bd8deadSopenharmony_ci
31995bd8deadSopenharmony_ci      256 4-component floating-point program parameter registers;
32005bd8deadSopenharmony_ci
32015bd8deadSopenharmony_ci      16 4-component vertex attribute registers (though this state is
32025bd8deadSopenharmony_ci      aliased with the current normal, primary color, secondary color,
32035bd8deadSopenharmony_ci      fog coordinate, weights, and texture coordinate sets);
32045bd8deadSopenharmony_ci
32055bd8deadSopenharmony_ci      24 sets of matrix tracking state for each set of four sequential
32065bd8deadSopenharmony_ci      program parameter registers, consisting of a n-valued integer
32075bd8deadSopenharmony_ci      indicated the tracked matrix or GL_NONE (where n is 5 + the number
32085bd8deadSopenharmony_ci      of texture units supported + the number of tracking matrices
32095bd8deadSopenharmony_ci      supported) and a four-valued integer indicating the transformation
32105bd8deadSopenharmony_ci      of the tracked matrix;
32115bd8deadSopenharmony_ci
32125bd8deadSopenharmony_ci      an unsigned integer naming the currently bound vertex program
32135bd8deadSopenharmony_ci
32145bd8deadSopenharmony_ci      and the state must be maintained to indicate which integers
32155bd8deadSopenharmony_ci      are currently in use as program names.
32165bd8deadSopenharmony_ci
32175bd8deadSopenharmony_ci   Each existent program object consists of a target, a boolean indicating
32185bd8deadSopenharmony_ci   whether the program is resident, an array of type ubyte containing the
32195bd8deadSopenharmony_ci   program string, and the length of the program string array.  Initially,
32205bd8deadSopenharmony_ci   no program objects exist.
32215bd8deadSopenharmony_ci
32225bd8deadSopenharmony_ci   Program mode, two-sided color mode, and program-specified point size
32235bd8deadSopenharmony_ci   mode are all initially disabled.
32245bd8deadSopenharmony_ci
32255bd8deadSopenharmony_ci   The initial state of all 256 program parameter registers is (0,0,0,0).
32265bd8deadSopenharmony_ci
32275bd8deadSopenharmony_ci   The initial state of the 16 vertex attribute registers is (0,0,0,1)
32285bd8deadSopenharmony_ci   except in cases where a vertex attribute register aliases to a
32295bd8deadSopenharmony_ci   conventional GL transform mode vertex parameter in which case
32305bd8deadSopenharmony_ci   the initial state is the initial state of the respective aliased
32315bd8deadSopenharmony_ci   conventional vertex parameter.
32325bd8deadSopenharmony_ci
32335bd8deadSopenharmony_ci   The initial state of the 24 sets of matrix tracking state is NONE
32345bd8deadSopenharmony_ci   for the tracked matrix and IDENTITY_NV for the transformation of the
32355bd8deadSopenharmony_ci   tracked matrix.
32365bd8deadSopenharmony_ci
32375bd8deadSopenharmony_ci   The initial currently bound program is zero.
32385bd8deadSopenharmony_ci
32395bd8deadSopenharmony_ci   The client state required to implement the 16 vertex attribute
32405bd8deadSopenharmony_ci   arrays consists of 16 boolean values, 16 memory pointers, 16 integer
32415bd8deadSopenharmony_ci   stride values, 16 symbolic constants representing array types,
32425bd8deadSopenharmony_ci   and 16 integers representing values per element.  Initially, the
32435bd8deadSopenharmony_ci   boolean values are each disabled, the memory pointers are each null,
32445bd8deadSopenharmony_ci   the strides are each zero, the array types are each FLOAT, and the
32455bd8deadSopenharmony_ci   integers representing values per element are each four."
32465bd8deadSopenharmony_ci
32475bd8deadSopenharmony_ci
32485bd8deadSopenharmony_ciAdditions to Chapter 3 of the OpenGL 1.3 Specification (Rasterization)
32495bd8deadSopenharmony_ci
32505bd8deadSopenharmony_ci    None.
32515bd8deadSopenharmony_ci
32525bd8deadSopenharmony_ciAdditions to Chapter 4 of the OpenGL 1.3 Specification (Per-Fragment
32535bd8deadSopenharmony_ciOperations and the Frame Buffer)
32545bd8deadSopenharmony_ci
32555bd8deadSopenharmony_ci    None.
32565bd8deadSopenharmony_ci
32575bd8deadSopenharmony_ciAdditions to Chapter 5 of the OpenGL 1.3 Specification (Special Functions)
32585bd8deadSopenharmony_ci
32595bd8deadSopenharmony_ci    None.
32605bd8deadSopenharmony_ci
32615bd8deadSopenharmony_ciAdditions to Chapter 6 of the OpenGL 1.3 Specification (State and
32625bd8deadSopenharmony_ciState Requests)
32635bd8deadSopenharmony_ci
32645bd8deadSopenharmony_ci    None.
32655bd8deadSopenharmony_ci
32665bd8deadSopenharmony_ciAdditions to Appendix A of the OpenGL 1.3 Specification (Invariance)
32675bd8deadSopenharmony_ci
32685bd8deadSopenharmony_ci    None.
32695bd8deadSopenharmony_ci
32705bd8deadSopenharmony_ciAdditions to the AGL/GLX/WGL Specifications
32715bd8deadSopenharmony_ci
32725bd8deadSopenharmony_ci    None.
32735bd8deadSopenharmony_ci
32745bd8deadSopenharmony_ciGLX Protocol
32755bd8deadSopenharmony_ci
32765bd8deadSopenharmony_ci    All relevant protocol is defined in the NV_vertex_program extension.
32775bd8deadSopenharmony_ci
32785bd8deadSopenharmony_ciErrors
32795bd8deadSopenharmony_ci
32805bd8deadSopenharmony_ci    This list includes the errors specified in the NV_vertex_program
32815bd8deadSopenharmony_ci    extension, modified as appropriate.
32825bd8deadSopenharmony_ci
32835bd8deadSopenharmony_ci    The error INVALID_VALUE is generated if VertexAttribNV is called where
32845bd8deadSopenharmony_ci    index is greater than 15.
32855bd8deadSopenharmony_ci
32865bd8deadSopenharmony_ci    The error INVALID_VALUE is generated if any ProgramParameterNV has an
32875bd8deadSopenharmony_ci    index is greater than 255 (was 95 in NV_vertex_program).
32885bd8deadSopenharmony_ci
32895bd8deadSopenharmony_ci    The error INVALID_VALUE is generated if VertexAttribPointerNV is called
32905bd8deadSopenharmony_ci    where index is greater than 15.
32915bd8deadSopenharmony_ci
32925bd8deadSopenharmony_ci    The error INVALID_VALUE is generated if VertexAttribPointerNV is called
32935bd8deadSopenharmony_ci    where size is not one of 1, 2, 3, or 4.
32945bd8deadSopenharmony_ci
32955bd8deadSopenharmony_ci    The error INVALID_VALUE is generated if VertexAttribPointerNV is called
32965bd8deadSopenharmony_ci    where stride is negative.
32975bd8deadSopenharmony_ci
32985bd8deadSopenharmony_ci    The error INVALID_OPERATION is generated if VertexAttribPointerNV is
32995bd8deadSopenharmony_ci    called where type is UNSIGNED_BYTE and size is not 4.
33005bd8deadSopenharmony_ci
33015bd8deadSopenharmony_ci    The error INVALID_VALUE is generated if LoadProgramNV is used to load a
33025bd8deadSopenharmony_ci    program with an id of zero.
33035bd8deadSopenharmony_ci
33045bd8deadSopenharmony_ci    The error INVALID_OPERATION is generated if LoadProgramNV is used to load
33055bd8deadSopenharmony_ci    an id that is currently loaded with a program of a different program
33065bd8deadSopenharmony_ci    target.
33075bd8deadSopenharmony_ci
33085bd8deadSopenharmony_ci    The error INVALID_OPERATION is generated if the program passed to
33095bd8deadSopenharmony_ci    LoadProgramNV fails to load because it is not syntactically correct based
33105bd8deadSopenharmony_ci    on the specified target.  The value of PROGRAM_ERROR_POSITION_NV is still
33115bd8deadSopenharmony_ci    updated when this error is generated.
33125bd8deadSopenharmony_ci
33135bd8deadSopenharmony_ci    The error INVALID_OPERATION is generated if LoadProgramNV has a target of
33145bd8deadSopenharmony_ci    VERTEX_PROGRAM_NV and the specified program fails to load because it does
33155bd8deadSopenharmony_ci    not write the HPOS register at least once.  The value of
33165bd8deadSopenharmony_ci    PROGRAM_ERROR_POSITION_NV is still updated when this error is generated.
33175bd8deadSopenharmony_ci
33185bd8deadSopenharmony_ci    The error INVALID_OPERATION is generated if LoadProgramNV has a target of
33195bd8deadSopenharmony_ci    VERTEX_STATE_PROGRAM_NV and the specified program fails to load because it
33205bd8deadSopenharmony_ci    does not write at least one program parameter register.  The value of
33215bd8deadSopenharmony_ci    PROGRAM_ERROR_POSITION_NV is still updated when this error is generated.
33225bd8deadSopenharmony_ci
33235bd8deadSopenharmony_ci    The error INVALID_OPERATION is generated if the vertex program or vertex
33245bd8deadSopenharmony_ci    state program passed to LoadProgramNV fails to load because it contains
33255bd8deadSopenharmony_ci    more than 128 instructions (VP1 programs) or 256 instructions (VP2
33265bd8deadSopenharmony_ci    programs).  The value of PROGRAM_ERROR_POSITION_NV is still updated when
33275bd8deadSopenharmony_ci    this error is generated.
33285bd8deadSopenharmony_ci
33295bd8deadSopenharmony_ci    The error INVALID_OPERATION is generated if a program is loaded with
33305bd8deadSopenharmony_ci    LoadProgramNV for id when id is currently loaded with a program of a
33315bd8deadSopenharmony_ci    different target.
33325bd8deadSopenharmony_ci
33335bd8deadSopenharmony_ci    The error INVALID_OPERATION is generated if BindProgramNV attempts to bind
33345bd8deadSopenharmony_ci    to a program name that is not a vertex program (for example, if the
33355bd8deadSopenharmony_ci    program is a vertex state program).
33365bd8deadSopenharmony_ci
33375bd8deadSopenharmony_ci    The error INVALID_VALUE is generated if GenProgramsNV is called where n is
33385bd8deadSopenharmony_ci    negative.
33395bd8deadSopenharmony_ci
33405bd8deadSopenharmony_ci    The error INVALID_VALUE is generated if AreProgramsResidentNV is called
33415bd8deadSopenharmony_ci    and any of the queried programs are zero or do not exist.
33425bd8deadSopenharmony_ci
33435bd8deadSopenharmony_ci    The error INVALID_OPERATION is generated if ExecuteProgramNV executes a
33445bd8deadSopenharmony_ci    program that does not exist.
33455bd8deadSopenharmony_ci
33465bd8deadSopenharmony_ci    The error INVALID_OPERATION is generated if ExecuteProgramNV executes a
33475bd8deadSopenharmony_ci    program that is not a vertex state program.
33485bd8deadSopenharmony_ci
33495bd8deadSopenharmony_ci    The error INVALID_OPERATION is generated if Begin, RasterPos, or a command
33505bd8deadSopenharmony_ci    that performs an explicit Begin is called when vertex program mode is
33515bd8deadSopenharmony_ci    enabled and the currently bound vertex program writes program parameters
33525bd8deadSopenharmony_ci    that are currently being tracked.
33535bd8deadSopenharmony_ci
33545bd8deadSopenharmony_ci    The error INVALID_OPERATION is generated if ExecuteProgramNV is called and
33555bd8deadSopenharmony_ci    the vertex state program to execute writes program parameters that are
33565bd8deadSopenharmony_ci    currently being tracked.
33575bd8deadSopenharmony_ci
33585bd8deadSopenharmony_ci    The error INVALID_VALUE is generated if TrackMatrixNV has a target of
33595bd8deadSopenharmony_ci    VERTEX_PROGRAM_NV and attempts to track an address is not a multiple of
33605bd8deadSopenharmony_ci    four.
33615bd8deadSopenharmony_ci
33625bd8deadSopenharmony_ci    The error INVALID_VALUE is generated if GetProgramParameterNV is called to
33635bd8deadSopenharmony_ci    query an index greater than 255 (was 95 in NV_vertex_program).
33645bd8deadSopenharmony_ci
33655bd8deadSopenharmony_ci    The error INVALID_VALUE is generated if GetVertexAttribNV is called to
33665bd8deadSopenharmony_ci    query an <index> greater than 15, or if <index> is zero and <pname> is
33675bd8deadSopenharmony_ci    CURRENT_ATTRIB_NV.
33685bd8deadSopenharmony_ci
33695bd8deadSopenharmony_ci    The error INVALID_VALUE is generated if GetVertexAttribPointervNV is
33705bd8deadSopenharmony_ci    called to query an index greater than 15.
33715bd8deadSopenharmony_ci
33725bd8deadSopenharmony_ci    The error INVALID_OPERATION is generated if GetProgramivNV is called and
33735bd8deadSopenharmony_ci    the program named id does not exist.
33745bd8deadSopenharmony_ci
33755bd8deadSopenharmony_ci    The error INVALID_OPERATION is generated if GetProgramStringNV is called
33765bd8deadSopenharmony_ci    and the program named <program> does not exist.
33775bd8deadSopenharmony_ci
33785bd8deadSopenharmony_ci    The error INVALID_VALUE is generated if GetTrackMatrixivNV is called with
33795bd8deadSopenharmony_ci    an <address> that is not divisible by four or greater than or equal to 256
33805bd8deadSopenharmony_ci    (was 96 in NV_vertex_program).
33815bd8deadSopenharmony_ci
33825bd8deadSopenharmony_ci    The error INVALID_VALUE is generated if AreProgramsResidentNV,
33835bd8deadSopenharmony_ci    DeleteProgramsNV, GenProgramsNV, or RequestResidentProgramsNV are called
33845bd8deadSopenharmony_ci    where <n> is negative.
33855bd8deadSopenharmony_ci
33865bd8deadSopenharmony_ci    The error INVALID_VALUE is generated if LoadProgramNV is called where
33875bd8deadSopenharmony_ci    <len> is negative.
33885bd8deadSopenharmony_ci
33895bd8deadSopenharmony_ci    The error INVALID_VALUE is generated if ProgramParameters4dvNV or
33905bd8deadSopenharmony_ci    ProgramParameters4fvNV are called where <count> is negative.
33915bd8deadSopenharmony_ci
33925bd8deadSopenharmony_ci    The error INVALID_VALUE is generated if VertexAttribs{1,2,3,4}{d,f,s}vNV
33935bd8deadSopenharmony_ci    is called where <count> is negative.
33945bd8deadSopenharmony_ci
33955bd8deadSopenharmony_ci    The error INVALID_ENUM is generated if BindProgramNV,
33965bd8deadSopenharmony_ci    GetProgramParameterfvNV, GetProgramParameterdvNV, GetTrackMatrixivNV,
33975bd8deadSopenharmony_ci    ProgramParameter4fNV, ProgramParameter4dNV, ProgramParameter4fvNV,
33985bd8deadSopenharmony_ci    ProgramParameter4dvNV, ProgramParameters4fvNV, ProgramParameters4dvNV,
33995bd8deadSopenharmony_ci    or TrackMatrixNV are called where <target> is not VERTEX_PROGRAM_NV.
34005bd8deadSopenharmony_ci
34015bd8deadSopenharmony_ci    The error INVALID_ENUM is generated if LoadProgramNV or
34025bd8deadSopenharmony_ci    ExecuteProgramNV are called where <target> is not either
34035bd8deadSopenharmony_ci    VERTEX_PROGRAM_NV or VERTEX_STATE_PROGRAM_NV.
34045bd8deadSopenharmony_ci
34055bd8deadSopenharmony_ciNew State
34065bd8deadSopenharmony_ci
34075bd8deadSopenharmony_ci(Modify Table X.5, New State Introduced by NV_vertex_program from the
34085bd8deadSopenharmony_ci NV_vertex_program specification.)
34095bd8deadSopenharmony_ci
34105bd8deadSopenharmony_ciGet Value             Type    Get Command              Initial Value  Description         Sec       Attribute
34115bd8deadSopenharmony_ci--------------------- ------  -----------------------  -------------  ------------------  --------  ------------
34125bd8deadSopenharmony_ciPROGRAM_PARAMETER_NV  256xR4  GetProgramParameterNV    (0,0,0,0)      program parameters  2.14.1.2  -
34135bd8deadSopenharmony_ci
34145bd8deadSopenharmony_ci
34155bd8deadSopenharmony_ci(Modify Table X.7.  Vertex Program Per-vertex Execution State.  "VP1" and
34165bd8deadSopenharmony_ci"VP2" refer to the VP1 and VP2 execution environments, respectively.)
34175bd8deadSopenharmony_ci
34185bd8deadSopenharmony_ciGet Value    Type    Get Command   Initial Value  Description              Sec       Attribute
34195bd8deadSopenharmony_ci---------    ------  -----------   -------------  -----------------------  --------  ---------
34205bd8deadSopenharmony_ci-            12xR4   -             (0,0,0,0)      VP1 temporary registers  2.14.1.4  -
34215bd8deadSopenharmony_ci-            16xR4   -             (0,0,0,0)      VP2 temporary registers  2.14.1.4  -
34225bd8deadSopenharmony_ci-            15xR4   -             (0,0,0,1)      vertex result registers  2.14.1.4  -
34235bd8deadSopenharmony_ci             Z4      -             (0,0,0,0)      VP1 address register     2.14.1.3  -
34245bd8deadSopenharmony_ci             2xZ4    -             (0,0,0,0)      VP2 address registers    2.14.1.3  -
34255bd8deadSopenharmony_ci
34265bd8deadSopenharmony_ci
34275bd8deadSopenharmony_ciRevision History
34285bd8deadSopenharmony_ci
34295bd8deadSopenharmony_ci    Rev.  Date      Author   Changes
34305bd8deadSopenharmony_ci    ----  --------  -------  --------------------------------------------
34315bd8deadSopenharmony_ci    33    03/18/08  pbrown   Fixed incorrectly documented clamp in the RCC
34325bd8deadSopenharmony_ci                             instruction.
34335bd8deadSopenharmony_ci
34345bd8deadSopenharmony_ci    32    05/16/04  pbrown   Documented that it's not possible to results from
34355bd8deadSopenharmony_ci                             LG2 that are any more precise than what is
34365bd8deadSopenharmony_ci                             available in the fp32 storage format.
34375bd8deadSopenharmony_ci
34385bd8deadSopenharmony_ci    31    08/17/03  pbrown   Added several overlooked opcodes (RCC, SUB, SIN)
34395bd8deadSopenharmony_ci                             to the grammar.  They are documented in the spec
34405bd8deadSopenharmony_ci                             body, however.
34415bd8deadSopenharmony_ci
34425bd8deadSopenharmony_ci    30    02/28/03  pbrown   Fixed incorrect condition code example.
34435bd8deadSopenharmony_ci
34445bd8deadSopenharmony_ci    29    12/08/02  pbrown   Fixed minor bug where "ABS" and "DPH" were listed
34455bd8deadSopenharmony_ci                             twice in the grammar. 
34465bd8deadSopenharmony_ci    
34475bd8deadSopenharmony_ci    28    10/29/02  pbrown   Remove support for indirect branching.  Added
34485bd8deadSopenharmony_ci                             missing o[CLPx] outputs to the grammar.  Minor
34495bd8deadSopenharmony_ci                             typo fixes.
34505bd8deadSopenharmony_ci
34515bd8deadSopenharmony_ci    25    07/19/02  pbrown   Fixed several miscellaneous errors in the spec.
34525bd8deadSopenharmony_ci
34535bd8deadSopenharmony_ci    24    06/28/02  pbrown   Fixed several erroneous resource limitations.
34545bd8deadSopenharmony_ci
34555bd8deadSopenharmony_ci    23    06/07/02  pbrown   Removed stray and erroneous abs() from the
34565bd8deadSopenharmony_ci                             documentation of the LG2 instruction.
34575bd8deadSopenharmony_ci
34585bd8deadSopenharmony_ci    22    06/06/02  pbrown   Added missing items from NV_vertex_program1_1, in
34595bd8deadSopenharmony_ci                             particular, program options.  Documented the
34605bd8deadSopenharmony_ci                             VP2.0 position-invariant programs have no
34615bd8deadSopenharmony_ci                             restrictions on indirect addressing.  
34625bd8deadSopenharmony_ci
34635bd8deadSopenharmony_ci    21    06/19/02  pbrown   Cleaned up miscellaneous errors and issues
34645bd8deadSopenharmony_ci                             in the spec.
34655bd8deadSopenharmony_ci
34665bd8deadSopenharmony_ci    20    05/17/02  pbrown   Documented LOG instruction as taking the 
34675bd8deadSopenharmony_ci                             absolute value of the operand, as in VP1.0.  
34685bd8deadSopenharmony_ci                             Fixed special-case rules for MUL.  Added clamps
34695bd8deadSopenharmony_ci                             to special-case clamping rules for RCC.
34705bd8deadSopenharmony_ci
34715bd8deadSopenharmony_ci    18    05/09/02  pbrown   Clarified the handling of NaN/UN in certain
34725bd8deadSopenharmony_ci                             instructions and conditional operations.
34735bd8deadSopenharmony_ci
34745bd8deadSopenharmony_ci    17    04/26/02  pbrown   Fix incorrectly specified algorithm for computing
34755bd8deadSopenharmony_ci                             the y result in the LOG instruction.
34765bd8deadSopenharmony_ci
34775bd8deadSopenharmony_ci    16    04/21/02  pbrown   Added example for "paletted skinning".
34785bd8deadSopenharmony_ci                             Documented size limitation (10 bits) on the
34795bd8deadSopenharmony_ci                             address register and ARA, ARL, and ARR
34805bd8deadSopenharmony_ci                             instructions.  The limits needs to be exposed
34815bd8deadSopenharmony_ci                             because of the ARA instruction.  Cleaned up
34825bd8deadSopenharmony_ci                             documentation on absolute value on input
34835bd8deadSopenharmony_ci                             operations.  Added examples for masked writes and
34845bd8deadSopenharmony_ci                             CC updates, and for branching.  Fixed
34855bd8deadSopenharmony_ci                             out-of-range indexed branch language and
34865bd8deadSopenharmony_ci                             pseudocode to clamp to the actual table size
34875bd8deadSopenharmony_ci                             (rather than the theoretical maximum).
34885bd8deadSopenharmony_ci                             Documented ABS as semi-deprecated in VP2.  Fixed
34895bd8deadSopenharmony_ci                             special cases for MIN, MAX, SEQ, SGE, SGT, SLE,
34905bd8deadSopenharmony_ci                             SLT, and SNE.  Fix completely botched description
34915bd8deadSopenharmony_ci                             of RET.
34925bd8deadSopenharmony_ci 
34935bd8deadSopenharmony_ci    15    04/05/02  pbrown   Updated introduction to indicate that
34945bd8deadSopenharmony_ci                             ARL/ARR/ARA all can update condition code.
34955bd8deadSopenharmony_ci                             Minor fixes and optimizations to the looping
34965bd8deadSopenharmony_ci                             examples.  Add missing "set on" opcodes to the
34975bd8deadSopenharmony_ci                             grammar.  Fixed spec to clamp branch table
34985bd8deadSopenharmony_ci                             indices to [0,15].  Added a couple caveats to
34995bd8deadSopenharmony_ci                             the "ABS" pseudo-instruction.   Documented
35005bd8deadSopenharmony_ci                             "ARR" as using IEEE round to nearest even
35015bd8deadSopenharmony_ci                             mode.  Documented special cases for "SSG".
3502