• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1Name
2
3    NV_fragment_program_option
4
5Name Strings
6
7    GL_NV_fragment_program_option
8
9Contact
10
11    Pat Brown, NVIDIA Corporation (pbrown 'at' nvidia.com)
12
13Status
14
15    Shipping.
16
17Version
18
19    Last Modified:      05/27/2005
20    NVIDIA Revision:    4
21
22Number
23
24    303
25
26Dependencies
27
28    ARB_fragment_program is required.
29
30Overview
31
32    This extension provides additional fragment program functionality
33    to extend the standard ARB_fragment_program language and execution
34    environment.  ARB programs wishing to use this added functionality
35    need only add:
36
37        OPTION NV_fragment_program;
38
39    to the beginning of their fragment programs.
40
41    The functionality provided by this extension, which is roughly
42    equivalent to that provided by the NV_fragment_program extension,
43    includes:
44
45      * increased control over precision in arithmetic computations and
46        storage,
47
48      * data-dependent conditional writemasks,
49
50      * an absolute value operator on scalar and swizzled operand loads,
51
52      * instructions to compute partial derivatives, and perform texture
53        lookups using specified partial derivatives,
54
55      * fully orthogonal "set on" instructions,
56
57      * instructions to compute reflection vector and perform a 2D
58        coordinate transform, and
59
60      * instructions to pack and unpack multiple quantities into a single
61        component.
62
63Issues
64
65    Why is this a separate extension, rather than just an additional
66    feature of NV_fragment_program?
67
68      RESOLVED:  The NV_fragment_program specification was complete
69      (with a published implementation) prior to the completion of
70      ARB_fragment_program.  Future NVIDIA fragment program extensions
71      should contain extensions to the ARB_fragment_program execution
72      environment as a standard feature.
73
74    Should a similar option be provided to expose ARB_fragment_program
75    features not found in NV_fragment_program (e.g., state bindings,
76    certain "macro" instructions) under the NV_fragment_program
77    interface?
78
79      RESOLVED:  No.  Why not just write an ARB program?
80
81    The ARB_fragment_program spec has a minor grammar bug that requires
82    that inline scalar constants used as scalar operands include a
83    component selector.  In other words, you have to say "11.0.x" to
84    use the constant "11.0".  What should we do here?
85
86      RESOLVED:  The NV_fragment_program_option grammar will correct
87      this problem, which should be fixed in future revisions to the
88      ARB language.
89
90New Procedures and Functions
91
92    None.
93
94New Tokens
95
96    None.
97
98Additions to Chapter 2 of the OpenGL 1.2.1 Specification (OpenGL Operation)
99
100    None.
101
102Additions to Chapter 3 of the OpenGL 1.2.1 Specification (Rasterization)
103
104    Modify Section 3.11.2 of ARB_fragment_program (Fragment Program
105    Grammar and Restrictions):
106
107    (mostly add to existing grammar rules, modify a few existing grammar
108    rules -- changes marked with "***")
109
110    <optionName>            ::= "NV_fragment_program"
111
112    <TexInstruction>        ::= <TXDop_instruction>
113
114    <VECTORop>              ::= "DDX"
115                              | "DDY"
116                              | "PK2H"
117                              | "PK2US"
118                              | "PK4B"
119                              | "PK4UB"
120
121    <SCALARop>              ::= "UP2H"
122                              | "UP2US"
123                              | "UP4B"
124                              | "UP4UB"
125
126    <BINop>                 ::= "RFL"
127                              | "SEQ"
128                              | "SFL"
129                              | "SGT"
130                              | "SLE"
131                              | "SNE"
132                              | "STR"
133
134    <TRIop>                 ::= "X2D"
135
136    <TXDop_instruction>     ::= <TXDop> <instResult> "," <instOperandV> ","
137                                <instOperandV> "," <instOperandV> ","
138                                <texTarget>
139
140    <TXDop>                 ::= "TXD"
141
142    <killCond>              ::= <ccTest>
143
144    <instOperandV>          ::= <instOperandAbsV>
145
146    <instOperandAbsV>       ::= <optSign> "|" <instOperandBaseV> "|"
147
148    <instOperandS>          ::= <instOperandAbsS>
149
150    <instOperandAbsS>       ::= <optSign> "|" <instOperandBaseS> "|"
151
152    <instResult>            ::= <instResultCC>
153
154    <instResultCC>          ::= <instResultBase> <ccMask>
155
156    <TEMP_statement>        ::= <varSize> "TEMP" <varNameList>
157
158    <OUTPUT_statement>      ::= <varSize> "OUTPUT" <establishName> "="
159                                  <resultUseD>
160
161    <varSize>               ::= "SHORT"
162                              | "LONG"
163
164    <paramUseV>             ::= <constantScalar>
165                                  (*** instead of <constantScalar>
166                                       <swizzleSuffix>)
167
168    <paramUseS>             ::= <constantScalar>
169                                  (*** instead of <constantScalar>
170                                       <scalarSuffix>)
171
172    <ccMask>                ::= "(" <ccTest> ")"
173
174    <ccTest>                ::= <ccMaskRule> <swizzleSuffix>
175
176    <ccMaskRule>            ::= "EQ"
177                              | "GE"
178                              | "GT"
179                              | "LE"
180                              | "LT"
181                              | "NE"
182                              | "TR"
183                              | "FL"
184
185    (modify language describing reserved keywords) The following strings
186    are reserved keywords and may not be used as identifiers:
187
188        ALIAS, ATTRIB, END, OPTION, OUTPUT, PARAM, TEMP, fragment,
189        program, result, state, and texture.
190
191    Additionally, all the instruction names (and variants) listed in
192    Table X.5 are reserved.
193
194    Modify Section 3.11.3.3, Fragment Program Temporaries
195
196    (replace second paragraph) Fragment program temporary variables
197    can be declared explicitly using the <TEMP_statement> grammar
198    rule.  Each such statement can declare one or more temporaries.
199    Temporary declaration can optionally specify a variable size,
200    using the <varSize> grammar rule.  Variables declared as "SHORT"
201    will represented with at least 16 bits per component (5 bits of
202    exponent, 10 bits of mantissa).  Variables declared as "LONG" will be
203    represented with at least 32 bits per component (8 bits of exponent,
204    23 bits of mantissa).  Fragment program temporary variables can not
205    be declared implicitly.
206
207    Modify Section 3.11.3.4, Fragment Program Results
208
209    (replace second paragraph) Fragment program result variables
210    can be declared explicitly using the <OUTPUT_statement> grammar
211    rule, or implicitly using the <resultBinding> grammar rule in an
212    executable instruction.  Explicit result variable declaration can
213    optionally specify a variable size, using the <varSize> grammar rule.
214    Variables declared as "SHORT" will represented with at least 16
215    bits per component (5 bits of exponent, 10 bits of mantissa).
216    Variables declared as "LONG" will be represented with at least
217    32 bits per component (8 bits of exponent, 23 bits of mantissa).
218    Each fragment program result variable is bound to a fragment attribute
219    used in subsequent back-end processing.  The set of fragment program
220    result variable bindings is given in Table X.3.
221
222    (add to the end of a section) A fragment program will fail to load if
223    contains instructions writing to variables bound to the same result,
224    but declared with different sizes.
225
226    Add New Section 3.11.3.X, Condition Code Register (insert after
227    Section 3.11.3.4, Fragment Program Results)
228
229    The fragment program condition code register is a single
230    four-component vector.  Each component of this register is one of four
231    enumerated values: GT (greater than), EQ (equal), LT (less than),
232    or UN (unordered).  The condition code register can be used to mask
233    writes to registers and to evaluate conditional branches.
234
235    Most fragment program instructions can optionally update the condition
236    code register.  When a fragment program instruction updates the
237    condition code register, a condition code component is set to LT if
238    the corresponding component of the result is less than zero, EQ if it
239    is equal to zero, GT if it is greater than zero, and UN if it is NaN
240    (not a number).
241
242    The condition code register is initialized to a vector of EQ values
243    each time a fragment program executes.
244
245    Modify Section 3.11.4, Fragment Program Execution Environment
246
247    (modify instruction table) There are fifty-two fragment program
248    instructions.  Fragment program instructions may have up to sixteen
249    variants, including a suffix of "R", "H", or "X" to specify arithmetic
250    precision (section 3.11.4.X), a suffix of "C" to allow an update
251    of the condition code register (section 3.11.3.X), and a suffix of
252    "_SAT" to clamp the result vector components to the range [0,1]
253    (section 3.11.4.3).  For example, the sixteen forms of the "ADD"
254    instruction are "ADD", "ADDR", "ADDH", "ADDX", "ADDC", "ADDRC",
255    "ADDHC", "ADDXC", "ADD_SAT", "ADDR_SAT", "ADDH_SAT", "ADDX_SAT",
256    "ADDC_SAT", "ADDRC_SAT", "ADDHC_SAT", and "ADDXC_SAT".The instructions
257    and their respective input and output parameters are summarized in
258    Table X.5.
259
260               Modifiers
261      Instr.   R H X C S  Inputs  Output   Description
262      -------  - - - - -  ------  ------   --------------------------------
263      ABS      X X X X X  v       v        absolute value
264      ADD      X X X X X  v,v     v        add
265      CMP      - - - - X  v,v,v   v        compare
266      COS      X X - X X  s       ssss     cosine with reduction to [-PI,PI]
267      DDX      X X - X X  v       v        partial derivative relative to X
268      DDY      X X - X X  v       v        partial derivative relative to Y
269      DP3      X X X X X  v,v     ssss     3-component dot product
270      DP4      X X X X X  v,v     ssss     4-component dot product
271      DPH      X X X X X  v,v     ssss     homogeneous dot product
272      DST      X X - X X  v,v     v        distance vector
273      EX2      X X - X X  s       ssss     exponential base 2
274      FLR      X X X X X  v       v        floor
275      FRC      X X X X X  v       v        fraction
276      KIL      - - - - -  v or c  -        kill fragment
277      LG2      X X - X X  s       ssss     logarithm base 2
278      LIT      X X - X X  v       v        compute light coefficients
279      LRP      X X X X X  v,v,v   v        linear interpolation
280      MAD      X X X X X  v,v,v   v        multiply and add
281      MAX      X X X X X  v,v     v        maximum
282      MIN      X X X X X  v,v     v        minimum
283      MOV      X X X X X  v       v        move
284      MUL      X X X X X  v,v     v        multiply
285      PK2H     - - - - -  v       ssss     pack two 16-bit floats
286      PK2US    - - - - -  v       ssss     pack two unsigned 16-bit scalars
287      PK4B     - - - - -  v       ssss     pack four signed 8-bit scalars
288      PK4UB    - - - - -  v       ssss     pack four unsigned 8-bit scalars
289      POW      X X - X X  s,s     ssss     exponentiate
290      RCP      X X - X X  s       ssss     reciprocal
291      RFL      X X - X X  v,v     v        reflection vector
292      RSQ      X X - X X  s       ssss     reciprocal square root
293      SCS      - - - - X  s       ss--     sine/cosine without reduction
294      SEQ      X X X X X  v,v     v        set on equal
295      SFL      X X X X X  v,v     v        set on false
296      SGE      X X X X X  v,v     v        set on greater than or equal
297      SGT      X X X X X  v,v     v        set on greater than
298      SIN      X X - X X  s       ssss     sine with reduction to [-PI,PI]
299      SLE      X X X X X  v,v     v        set on less than or equal
300      SLT      X X X X X  v,v     v        set on less than
301      SNE      X X X X X  v,v     v        set on not equal
302      STR      X X X X X  v,v     v        set on true
303      SUB      X X X X X  v,v     v        subtract
304      SWZ      - - - - X  v       v        extended swizzle
305      TEX      - - - X X  v       v        texture sample
306      TXB      - - - X X  v       v        texture sample with bias
307      TXD      - - - X X  v,v,v   v        texture sample w/partials
308      TXP      - - - X X  v       v        texture sample with projection
309      UP2H     - - - X X  s       v        unpack two 16-bit floats
310      UP2US    - - - X X  s       v        unpack two unsigned 16-bit scalars
311      UP4B     - - - X X  s       v        unpack four signed 8-bit scalars
312      UP4UB    - - - X X  s       v        unpack four unsigned 8-bit scalars
313      X2D      X X - X X  v,v,v   v        2D coordinate transformation
314      XPD      - - - - X  v,v     v        cross product
315
316      Table X.5:  Summary of fragment program instructions.  The columns
317      "R", "H", "X", "C", and "S" indicate whether the "R", "H", or "X"
318      precision modifiers, the C condition code update modifier, and the
319      "_SAT" saturation modifier, respectively, are supported for the
320      opcode.  In the input/output columns, "v" indicates a floating-point
321      vector input or output, "s" indicates a floating-point scalar
322      input, "ssss" indicates a scalar output replicated across a
323      4-component result vector, "ss--" indicates two scalar outputs in
324      the first two components, and "c" indicates a condition code test.
325      Instructions describe as "texture sample" also specify a texture
326      image unit identifier and a texture target.
327
328    Modify Section 3.11.4.1, Fragment Program Operands
329
330    (add prior to the discussion of negation) A component-wise absolute
331    value operation can optionally performed on the operand if the operand
332    is surrounded with two "|" characters.  For example, "|src|" indicates
333    that a component-wise absolute value operation should be performed on
334    the variable named "src".  In terms of the grammar, this operation
335    is performed if the <instOperandV> or <instOperandS> grammar rules
336    match <instOperandAbsV> or <instOperandAbsS>, respectively.
337
338    (modify operand load pseudo-code) The following pseudo-code spells
339    out the operand generation process.  In the example, "float" is a
340    floating-point scalar type, while "floatVec" is a four-component
341    vector.  "source" refers to the register used for the operand,
342    matching the <srcReg> rule.  "abs" is TRUE if an absolute value
343    operation should be performed on the operand (<instOperandAbsV> or
344    <instOperandAbsS> rules) "negate" is TRUE if the <optionalSign> rule
345    in <scalarSrcReg> or <swizzleSrcReg> matches "-" and FALSE otherwise.
346    The ".c***", ".*c**", ".**c*", ".***c" modifiers refer to the x,
347    y, z, and w components obtained by the swizzle operation; the ".c"
348    modifier refers to the single component selected for a scalar load.
349
350      floatVec VectorLoad(floatVec source)
351      {
352          floatVec operand;
353
354          operand.x = source.c***;
355          operand.y = source.*c**;
356          operand.z = source.**c*;
357          operand.w = source.***c;
358          if (abs) {
359             operand.x = abs(operand.x);
360             operand.y = abs(operand.y);
361             operand.z = abs(operand.z);
362             operand.w = abs(operand.w);
363          }
364          if (negate) {
365             operand.x = -operand.x;
366             operand.y = -operand.y;
367             operand.z = -operand.z;
368             operand.w = -operand.w;
369          }
370
371          return operand;
372      }
373
374      float ScalarLoad(floatVec source)
375      {
376          float operand;
377
378          operand = source.c;
379          if (abs) {
380            operand = abs(operand);
381          if (negate) {
382            operand = -operand;
383          }
384
385          return operand;
386      }
387
388    Add New Section 3.11.4.X, Fragment Program Operation Precision
389    (insert after Section 3.11.4,2, Fragment Program Parameter Arrays)
390
391    Fragment program implementations may be able to perform instructions
392    with different levels of arithmetic precision.  The "R", "H", and
393    "X" opcode precision modifiers (Section 3.11.4) specify the minimum
394    precision used to perform arithmetic operations.  Instructions with
395    an "R" precision modifiers will be carried out at no less than
396    IEEE single-precision floating-point (8 bits of exponent, 23 bits
397    of mantissa).  Instructions with an "H" precision modifier will
398    be carried out at no less than 16-bit floating-point precision (5
399    bits of exponent, 10 bits of mantissa).  Instructions with an "X"
400    precision modifier will be carried out at no less than signed 12-bit
401    fixed-point precision (two's complement with 10 fraction bits).
402
403    If the result of a computation overflows the range of numbers
404    supported by the instruction precision, the result will be +/-INF
405    (infinity) for "R" and "H" precision, or -2048/1024 or +2047/1024 for
406    "X" precision.
407
408    If no precision modifier is specified, the instruction will be carried
409    out with at least as much precision as the destination variable.
410
411    Rewrite Section 3.11.4.3,  Fragment Program Destination Register
412    Update
413
414    Most fragment program instructions write a 4-component result vector
415    to a single temporary or fragment result register.  Writes to
416    individual components of the destination register are controlled
417    by individual component write masks specified as part of the
418    instruction.
419
420    The component write mask is specified by the <optionalMask> rule
421    found in the <maskedDstReg> rule.  If the optional mask is "",
422    all components are enabled.  Otherwise, the optional mask names
423    the individual components to enable.  The characters "x", "y",
424    "z", and "w" match the x, y, z, and w components, respectively.
425    For example, an optional mask of ".xzw" indicates that the x, z,
426    and w components should be enabled for writing but the y component
427    should not.  The grammar requires that the destination register mask
428    components must be listed in "xyzw" order.
429
430    The condition code write mask is specified by the <ccMask> rule found
431    in the <instResultCC> rule.  The condition code register is loaded and
432    swizzled according to the swizzle codes specified by <swizzleSuffix>.
433    Each component of the swizzled condition code is tested according to
434    the rule given by <ccMaskRule>.  <ccMaskRule> may have the values
435    "EQ", "NE", "LT", "GE", LE", or "GT", which mean to enable writes
436    if the corresponding condition code field evaluates to equal,
437    not equal, less than, greater than or equal, less than or equal,
438    or greater than, respectively.  Comparisons involving condition
439    codes of "UN" (unordered) evaluate to true for "NE" and false
440    otherwise.  For example, if the condition code is (GT,LT,EQ,GT)
441    and the condition code mask is "(NE.zyxw)", the swizzle operation
442    will load (EQ,LT,GT,GT) and the mask will thus will enable writes on
443    the y, z, and w components.  In addition, "TR" always enables writes
444    and "FL" always disables writes, regardless of the condition code.
445    If the condition code mask is empty, it is treated as "(TR)".
446
447    Each component of the destination register is updated with the result
448    of the fragment program instruction if and only if the component is
449    enabled for writes by both the component write mask and the condition
450    code write mask.  Otherwise, the component of the destination register
451    remains unchanged.
452
453    A fragment program instruction can also optionally update the
454    condition code register.  The condition code is updated if
455    the condition code register update suffix "C" is present in the
456    instruction.  The instruction "ADDC" will update the condition code;
457    the otherwise equivalent instruction "ADD" will not.  If condition
458    code updates are enabled, each component of the destination register
459    enabled for writes is compared to zero.  The corresponding component
460    of the condition code is set to "LT", "EQ", or "GT", if the written
461    component is less than, equal to, or greater than zero, respectively.
462    Condition code components are set to "UN" if the written component is
463    NaN (not a number).  Values of -0.0 and +0.0 both evaluate to "EQ".
464    If a component of the destination register is not enabled for writes,
465    the corresponding condition code component is also unchanged.
466
467    In the following example code,
468
469        # R1=(-2, 0, 2, NaN)              R0                  CC
470        MOVC R0, R1;               # ( -2,  0,   2, NaN) (LT,EQ,GT,UN)
471        MOVC R0.xyz, R1.yzwx;      # (  0,  2, NaN, NaN) (EQ,GT,UN,UN)
472        MOVC R0 (NE), R1.zywx;     # (  0,  0, NaN,  -2) (EQ,EQ,UN,LT)
473
474    the first instruction writes (-2,0,2,NaN) to R0 and updates the
475    condition code to (LT,EQ,GT,UN).  The second instruction, only the
476    "x", "y", and "z" components of R0 and the condition code are updated,
477    so R0 ends up with (0,2,NaN,NaN) and the condition code ends up with
478    (EQ,GT,UN,UN).  In the third instruction, the condition code mask
479    disables writes to the x component (its condition code field is "EQ"),
480    so R0 ends up with (0,0,NaN,-2) and the condition code ends up with
481    (EQ,EQ,UN,LT).
482
483    The following pseudocode illustrates the process of writing a result
484    vector to the destination register.  In the pseudocode, "instrmask"
485    refers to the component write mask given by the <optWriteMask>
486    rule.  "ccMaskRule" refers to the condition code mask rule given
487    by <ccMask> and "updatecc" is TRUE if and only if condition code
488    updates are enabled.  "result", "destination", and "cc" refer to
489    the result vector, the register selected by <dstRegister> and the
490    condition code, respectively.  Condition codes do not exist in the
491    VP1 execution environment.
492
493      boolean TestCC(CondCode field) {
494          switch (ccMaskRule) {
495          case "EQ":  return (field == "EQ");
496          case "NE":  return (field != "EQ");
497          case "LT":  return (field == "LT");
498          case "GE":  return (field == "GT" || field == "EQ");
499          case "LE":  return (field == "LT" || field == "EQ");
500          case "GT":  return (field == "GT");
501          case "TR":  return TRUE;
502          case "FL":  return FALSE;
503          case "":    return TRUE;
504          }
505      }
506
507      enum GenerateCC(float value) {
508        if (value == NaN) {
509          return UN;
510        } else if (value < 0) {
511          return LT;
512        } else if (value == 0) {
513          return EQ;
514        } else {
515          return GT;
516        }
517      }
518
519      void UpdateDestination(floatVec destination, floatVec result)
520      {
521          floatVec merged;
522          ccVec    mergedCC;
523
524          // Merge the converted result into the destination register, under
525          // control of the compile- and run-time write masks.
526          merged = destination;
527          mergedCC = cc;
528          if (instrMask.x && TestCC(cc.c***)) {
529              merged.x = result.x;
530              if (updatecc) mergedCC.x = GenerateCC(result.x);
531          }
532          if (instrMask.y && TestCC(cc.*c**)) {
533              merged.y = result.y;
534              if (updatecc) mergedCC.y = GenerateCC(result.y);
535          }
536          if (instrMask.z && TestCC(cc.**c*)) {
537              merged.z = result.z;
538              if (updatecc) mergedCC.z = GenerateCC(result.z);
539          }
540          if (instrMask.w && TestCC(cc.***c)) {
541              merged.w = result.w;
542              if (updatecc) mergedCC.w = GenerateCC(result.w);
543          }
544
545          // Write out the new destination register and condition code.
546          destination = merged;
547          cc = mergedCC;
548      }
549
550    Add to Section 3.11.4.5 of ARB_fragment_program (Fragment Program
551    Options):
552
553    Section 3.11.4.5.3, NV_fragment_program Option
554
555    If a fragment program specifies the "NV_fragment_program" option,
556    the grammar will be extended to support the features found in the
557    NV_fragment_program extension not present in the ARB_fragment_program
558    extension, including:
559
560      * the availability of the following instructions:
561
562          - DDX (partial derivative relative to X),
563          - DDY (partial derivative relative to Y),
564          - PK2H (pack as two half floats),
565          - PK2US (pack as two unsigned shorts),
566          - PK4B (pack as four signed bytes),
567          - PK4UB (pack as four unsigned bytes),
568          - RFL (reflection vector),
569          - SEQ (set on equal to),
570          - SFL (set on false),
571          - SGT (set on greater than),
572          - SLE (set on less than or equal to),
573          - SNE (set on not equal to),
574          - STR (set on true),
575          - TXD (texture lookup with computed partial derivatives),
576          - UP2H (unpack two half floats),
577          - UP2US (unpack two unsigned shorts),
578          - UP4B (unpack four signed bytes),
579          - UP4UB (unpack four unsigned bytes), and
580          - X2D (2D coordinate transformation),
581
582      * opcode precision suffixes "R", "H", and "X", to specify
583        the precision of arithmetic operations ("R" specifies 32-bit
584        floating-point computations, "H" specifies 16-bit floating-point
585        computations, and "X" specifies 12-bit signed fixed-point
586        computations with 10 fraction bits),
587
588      * the availability of the "SHORT" and "LONG" variable precision
589        keywords to control the size of a variable's components,
590
591      * a four-component condition code register to hold the sign of
592        result vector components (useful for comparisons),
593
594      * a condition code update opcode suffix "C", where the results of
595        the instruction are used to update the condition code register,
596
597      * a condition code write mask operator, where the condition code
598        register is swizzled and tested, and the test results are used
599        to mask register writes,
600
601      * an absolute value operator on scalar and swizzled source inputs
602
603    The added functionality is identical to that provided by the
604    NV_fragment_program extension specification.
605
606    Modify Section 3.11.5,  Fragment Program ALU Instruction Set
607
608    Section 3.11.5.30,  DDX:  Derivative Relative to X
609
610    The DDX instruction computes approximate partial derivatives of the
611    four components of the single operand with respect to the X window
612    coordinate to yield a result vector.  The partial derivatives are
613    evaluated at the center of the pixel.
614
615      f = VectorLoad(op0);
616      result = ComputePartialX(f);
617
618    Note that the partial derivates obtained by this instruction are
619    approximate, and derivative-of-derivate instruction sequences may
620    not yield accurate second derivatives.
621
622    Section 3.11.5.31,  DDY:  Derivative Relative to Y
623
624    The DDY instruction computes approximate partial derivatives of the
625    four components of the single operand with respect to the Y window
626    coordinate to yield a result vector.  The partial derivatives are
627    evaluated at the center of the pixel.
628
629      f = VectorLoad(op0);
630      result = ComputePartialY(f);
631
632    Note that the partial derivates obtained by this instruction are
633    approximate, and derivative-of-derivate instruction sequences may
634    not yield accurate second derivatives.
635
636    Section 3.11.5.32,  PK2H:  Pack Two 16-bit Floats
637
638    The PK2H instruction converts the "x" and "y" components of
639    the single operand into 16-bit floating-point format, packs the
640    bit representation of these two floats into a 32-bit value, and
641    replicates that value to all four components of the result vector.
642    The PK2H instruction can be reversed by the UP2H instruction below.
643
644      tmp0 = VectorLoad(op0);
645      /* result obtained by combining raw bits of tmp0.x, tmp0.y */
646      result.x = RawBits(tmp0.x) | (RawBits(tmp0.y) << 16);
647      result.y = RawBits(tmp0.x) | (RawBits(tmp0.y) << 16);
648      result.z = RawBits(tmp0.x) | (RawBits(tmp0.y) << 16);
649      result.w = RawBits(tmp0.x) | (RawBits(tmp0.y) << 16);
650
651    A fragment program will fail to load if it contains a PK2H instruction
652    that writes its results to a variable declared as "SHORT".
653
654    Section 3.11.5.33,  PK2US:  Pack Two Unsigned 16-bit Scalars
655
656    The PK2US instruction converts the "x" and "y" components of the
657    single operand into a packed pair of 16-bit unsigned scalars.
658    The scalars are represented in a bit pattern where all '0' bits
659    corresponds to 0.0 and all '1' bits corresponds to 1.0.  The bit
660    representations of the two converted components are packed into a
661    32-bit value, and that value is replicated to all four components
662    of the result vector.  The PK2US instruction can be reversed by the
663    UP2US instruction below.
664
665      tmp0 = VectorLoad(op0);
666      if (tmp0.x < 0.0) tmp0.x = 0.0;
667      if (tmp0.x > 1.0) tmp0.x = 1.0;
668      if (tmp0.y < 0.0) tmp0.y = 0.0;
669      if (tmp0.y > 1.0) tmp0.y = 1.0;
670      us.x = round(65535.0 * tmp0.x);  /* us is a ushort vector */
671      us.y = round(65535.0 * tmp0.y);
672      /* result obtained by combining raw bits of us. */
673      result.x = ((us.x) | (us.y << 16));
674      result.y = ((us.x) | (us.y << 16));
675      result.z = ((us.x) | (us.y << 16));
676      result.w = ((us.x) | (us.y << 16));
677
678    A fragment program will fail to load if it contains a PK2S instruction
679    that writes its results to a variable declared as "SHORT".
680
681    Section 3.11.5.34,  PK4B:  Pack Four Signed 8-bit Scalars
682
683    The PK4B instruction converts the four components of the single
684    operand into 8-bit signed quantities.  The signed quantities
685    are represented in a bit pattern where all '0' bits corresponds
686    to -128/127 and all '1' bits corresponds to +127/127.  The bit
687    representations of the four converted components are packed into a
688    32-bit value, and that value is replicated to all four components
689    of the result vector.  The PK4B instruction can be reversed by the
690    UP4B instruction below.
691
692      tmp0 = VectorLoad(op0);
693      if (tmp0.x < -128/127) tmp0.x = -128/127;
694      if (tmp0.y < -128/127) tmp0.y = -128/127;
695      if (tmp0.z < -128/127) tmp0.z = -128/127;
696      if (tmp0.w < -128/127) tmp0.w = -128/127;
697      if (tmp0.x > +127/127) tmp0.x = +127/127;
698      if (tmp0.y > +127/127) tmp0.y = +127/127;
699      if (tmp0.z > +127/127) tmp0.z = +127/127;
700      if (tmp0.w > +127/127) tmp0.w = +127/127;
701      ub.x = round(127.0 * tmp0.x + 128.0);  /* ub is a ubyte vector */
702      ub.y = round(127.0 * tmp0.y + 128.0);
703      ub.z = round(127.0 * tmp0.z + 128.0);
704      ub.w = round(127.0 * tmp0.w + 128.0);
705      /* result obtained by combining raw bits of ub. */
706      result.x = ((ub.x) | (ub.y << 8) | (ub.z << 16) | (ub.w << 24));
707      result.y = ((ub.x) | (ub.y << 8) | (ub.z << 16) | (ub.w << 24));
708      result.z = ((ub.x) | (ub.y << 8) | (ub.z << 16) | (ub.w << 24));
709      result.w = ((ub.x) | (ub.y << 8) | (ub.z << 16) | (ub.w << 24));
710
711    A fragment program will fail to load if it contains a PK4B instruction
712    that writes its results to a variable declared as "SHORT".
713
714    Section 3.11.5.35,  PK4UB:  Pack Four Unsigned 8-bit Scalars
715
716    The PK4UB instruction converts the four components of the single
717    operand into a packed grouping of 8-bit unsigned scalars.  The scalars
718    are represented in a bit pattern where all '0' bits corresponds to
719    0.0 and all '1' bits corresponds to 1.0.  The bit representations
720    of the four converted components are packed into a 32-bit value, and
721    that value is replicated to all four components of the result vector.
722    The PK4UB instruction can be reversed by the UP4UB instruction below.
723
724      tmp0 = VectorLoad(op0);
725      if (tmp0.x < 0.0) tmp0.x = 0.0;
726      if (tmp0.x > 1.0) tmp0.x = 1.0;
727      if (tmp0.y < 0.0) tmp0.y = 0.0;
728      if (tmp0.y > 1.0) tmp0.y = 1.0;
729      if (tmp0.z < 0.0) tmp0.z = 0.0;
730      if (tmp0.z > 1.0) tmp0.z = 1.0;
731      if (tmp0.w < 0.0) tmp0.w = 0.0;
732      if (tmp0.w > 1.0) tmp0.w = 1.0;
733      ub.x = round(255.0 * tmp0.x);  /* ub is a ubyte vector */
734      ub.y = round(255.0 * tmp0.y);
735      ub.z = round(255.0 * tmp0.z);
736      ub.w = round(255.0 * tmp0.w);
737      /* result obtained by combining raw bits of ub. */
738      result.x = ((ub.x) | (ub.y << 8) | (ub.z << 16) | (ub.w << 24));
739      result.y = ((ub.x) | (ub.y << 8) | (ub.z << 16) | (ub.w << 24));
740      result.z = ((ub.x) | (ub.y << 8) | (ub.z << 16) | (ub.w << 24));
741      result.w = ((ub.x) | (ub.y << 8) | (ub.z << 16) | (ub.w << 24));
742
743    A fragment program will fail to load if it contains a PK4UB
744    instruction that writes its results to a variable declared as
745    "SHORT".
746
747    Section 3.11.5.36,  RFL:  Reflection Vector
748
749    The RFL instruction computes the reflection of the second vector
750    operand (the "direction" vector) about the vector specified by the
751    first vector operand (the "axis" vector).  Both operands are treated
752    as 3D vectors (the w components are ignored).  The result vector is
753    another 3D vector (the "reflected direction" vector).  The length
754    of the result vector, ignoring rounding errors, should equal that
755    of the second operand.
756
757      axis = VectorLoad(op0);
758      direction = VectorLoad(op1);
759      tmp.w = (axis.x * axis.x + axis.y * axis.y +
760               axis.z * axis.z);
761      tmp.x = (axis.x * direction.x + axis.y * direction.y +
762               axis.z * direction.z);
763      tmp.x = 2.0 * tmp.x;
764      tmp.x = tmp.x / tmp.w;
765      result.x = tmp.x * axis.x - direction.x;
766      result.y = tmp.x * axis.y - direction.y;
767      result.z = tmp.x * axis.z - direction.z;
768
769    A fragment program will fail to load if the w component of the result
770    is enabled in the component write mask.
771
772    Section 3.11.5.37,  SEQ:  Set on Equal
773
774    The SEQ instruction performs a component-wise comparison of the
775    two operands.  Each component of the result vector is 1.0 if the
776    corresponding component of the first operand is equal to that of
777    the second, and 0.0 otherwise.
778
779      tmp0 = VectorLoad(op0);
780      tmp1 = VectorLoad(op1);
781      result.x = (tmp0.x == tmp1.x) ? 1.0 : 0.0;
782      result.y = (tmp0.y == tmp1.y) ? 1.0 : 0.0;
783      result.z = (tmp0.z == tmp1.z) ? 1.0 : 0.0;
784      result.w = (tmp0.w == tmp1.w) ? 1.0 : 0.0;
785
786    Section 3.11.5.38,  SFL:  Set on False
787
788    The SFL instruction is a degenerate case of the other "Set on"
789    instructions that sets all components of the result vector to 0.0.
790
791      result.x = 0.0;
792      result.y = 0.0;
793      result.z = 0.0;
794      result.w = 0.0;
795
796    Section 3.11.5.39,  SGT:  Set on Greater Than
797
798    The SGT instruction performs a component-wise comparison of the
799    two operands.  Each component of the result vector is 1.0 if the
800    corresponding component of the first operands is greater than that
801    of the second, and 0.0 otherwise.
802
803      tmp0 = VectorLoad(op0);
804      tmp1 = VectorLoad(op1);
805      result.x = (tmp0.x > tmp1.x) ? 1.0 : 0.0;
806      result.y = (tmp0.y > tmp1.y) ? 1.0 : 0.0;
807      result.z = (tmp0.z > tmp1.z) ? 1.0 : 0.0;
808      result.w = (tmp0.w > tmp1.w) ? 1.0 : 0.0;
809
810    Section 3.11.5.40,  SLE:  Set on Less Than or Equal
811
812    The SLE instruction performs a component-wise comparison of the
813    two operands.  Each component of the result vector is 1.0 if the
814    corresponding component of the first operand is less than or equal
815    to that of the second, and 0.0 otherwise.
816
817      tmp0 = VectorLoad(op0);
818      tmp1 = VectorLoad(op1);
819      result.x = (tmp0.x <= tmp1.x) ? 1.0 : 0.0;
820      result.y = (tmp0.y <= tmp1.y) ? 1.0 : 0.0;
821      result.z = (tmp0.z <= tmp1.z) ? 1.0 : 0.0;
822      result.w = (tmp0.w <= tmp1.w) ? 1.0 : 0.0;
823
824    Section 3.11.5.41,  SNE:  Set on Not Equal
825
826    The SNE instruction performs a component-wise comparison of the
827    two operands.  Each component of the result vector is 1.0 if the
828    corresponding component of the first operand is not equal to that
829    of the second, and 0.0 otherwise.
830
831      tmp0 = VectorLoad(op0);
832      tmp1 = VectorLoad(op1);
833      result.x = (tmp0.x != tmp1.x) ? 1.0 : 0.0;
834      result.y = (tmp0.y != tmp1.y) ? 1.0 : 0.0;
835      result.z = (tmp0.z != tmp1.z) ? 1.0 : 0.0;
836      result.w = (tmp0.w != tmp1.w) ? 1.0 : 0.0;
837
838    Section 3.11.5.42,  STR:  Set on True
839
840    The STR instruction is a degenerate case of the other "Set on"
841    instructions that sets all components of the result vector to 1.0.
842
843      result.x = 1.0;
844      result.y = 1.0;
845      result.z = 1.0;
846      result.w = 1.0;
847
848    Section 3.11.5.43,  UP2H:  Unpack Two 16-Bit Floats
849
850    The UP2H instruction unpacks two 16-bit floats stored together in
851    a 32-bit scalar operand.  The first 16-bit float (stored in the 16
852    least significant bits) is written into the "x" and "z" components
853    of the result vector; the second is written into the "y" and "w"
854    components of the result vector.
855
856    This operation undoes the type conversion and packing performed by
857    the PK2H instruction.
858
859      tmp = ScalarLoad(op0);
860      result.x = (fp16) (RawBits(tmp) & 0xFFFF);
861      result.y = (fp16) ((RawBits(tmp) >> 16) & 0xFFFF);
862      result.z = (fp16) (RawBits(tmp) & 0xFFFF);
863      result.w = (fp16) ((RawBits(tmp) >> 16) & 0xFFFF);
864
865    A fragment program will fail to load if it contains a UP2H instruction
866    whose operand is a variable declared as "SHORT".
867
868    Section 3.11.5.44,  UP2US:  Unpack Two Unsigned 16-Bit Scalars
869
870    The UP2US instruction unpacks two 16-bit unsigned values packed
871    together in a 32-bit scalar operand.  The unsigned quantities are
872    encoded where a bit pattern of all '0' bits corresponds to 0.0 and
873    a pattern of all '1' bits corresponds to 1.0.  The "x" and "z"
874    components of the result vector are obtained from the 16 least
875    significant bits of the operand; the "y" and "w" components are
876    obtained from the 16 most significant bits.
877
878    This operation undoes the type conversion and packing performed by
879    the PK2US instruction.
880
881      tmp = ScalarLoad(op0);
882      result.x = ((RawBits(tmp) >> 0)  & 0xFFFF) / 65535.0;
883      result.y = ((RawBits(tmp) >> 16) & 0xFFFF) / 65535.0;
884      result.z = ((RawBits(tmp) >> 0)  & 0xFFFF) / 65535.0;
885      result.w = ((RawBits(tmp) >> 16) & 0xFFFF) / 65535.0;
886
887    A fragment program will fail to load if it contains a UP2S instruction
888    whose operand is a variable declared as "SHORT".
889
890    Section 3.11.5.45,  UP4B:  Unpack Four Signed 8-Bit Values
891
892    The UP4B instruction unpacks four 8-bit signed values packed together
893    in a 32-bit scalar operand.  The signed quantities are encoded where
894    a bit pattern of all '0' bits corresponds to -128/127 and a pattern
895    of all '1' bits corresponds to +127/127.  The "x" component of the
896    result vector is the converted value corresponding to the 8 least
897    significant bits of the operand; the "w" component corresponds to
898    the 8 most significant bits.
899
900    This operation undoes the type conversion and packing performed by
901    the PK4B instruction.
902
903      tmp = ScalarLoad(op0);
904      result.x = (((RawBits(tmp) >> 0) & 0xFF) - 128) / 127.0;
905      result.y = (((RawBits(tmp) >> 8) & 0xFF) - 128) / 127.0;
906      result.z = (((RawBits(tmp) >> 16) & 0xFF) - 128) / 127.0;
907      result.w = (((RawBits(tmp) >> 24) & 0xFF) - 128) / 127.0;
908
909    A fragment program will fail to load if it contains a UP4B instruction
910    whose operand is a variable declared as "SHORT".
911
912    Section 3.11.5.46,  UP4UB:  Unpack Four Unsigned 8-Bit Scalars
913
914    The UP4UB instruction unpacks four 8-bit unsigned values packed
915    together in a 32-bit scalar operand.  The unsigned quantities are
916    encoded where a bit pattern of all '0' bits corresponds to 0.0 and a
917    pattern of all '1' bits corresponds to 1.0.  The "x" component of the
918    result vector is obtained from the 8 least significant bits of the
919    operand; the "w" component is obtained from the 8 most significant
920    bits.
921
922    This operation undoes the type conversion and packing performed by
923    the PK4UB instruction.
924
925      tmp = ScalarLoad(op0);
926      result.x = ((RawBits(tmp) >> 0)  & 0xFF) / 255.0;
927      result.y = ((RawBits(tmp) >> 8)  & 0xFF) / 255.0;
928      result.z = ((RawBits(tmp) >> 16) & 0xFF) / 255.0;
929      result.w = ((RawBits(tmp) >> 24) & 0xFF) / 255.0;
930
931    A fragment program will fail to load if it contains a UP4UB
932    instruction whose operand is a variable declared as "SHORT".
933
934    Section 3.11.5.47,  X2D:  2D Coordinate Transformation
935
936    The X2D instruction multiplies the 2D offset vector specified by the
937    "x" and "y" components of the second vector operand by the 2x2 matrix
938    specified by the four components of the third vector operand, and adds
939    the transformed offset vector to the 2D vector specified by the "x"
940    and "y" components of the first vector operand.  The first component
941    of the sum is written to the "x" and "z" components of the result;
942    the second component is written to the "y" and "w" components of
943    the result.
944
945      tmp0 = VectorLoad(op0);
946      tmp1 = VectorLoad(op1);
947      tmp2 = VectorLoad(op2);
948      result.x = tmp0.x + tmp1.x * tmp2.x + tmp1.y * tmp2.y;
949      result.y = tmp0.y + tmp1.x * tmp2.z + tmp1.y * tmp2.w;
950      result.z = tmp0.x + tmp1.x * tmp2.x + tmp1.y * tmp2.y;
951      result.w = tmp0.y + tmp1.x * tmp2.z + tmp1.y * tmp2.w;
952
953    Modify Section, 3.11.6.4 KIL: Kill fragment
954
955    Rather than mapping a coordinate set to a color, this function
956    prevents a fragment from receiving any future processing.  If any
957    component of its source vector is negative, the processing of this
958    fragment will be discontinued and no further outputs to this fragment
959    will occur.  Subsequent stages of the GL pipeline will be skipped
960    for this fragment.
961
962    A KIL instruction may be specified using either a vector operand
963    or a condition code test.  If a vector operand is specified, the
964    following is performed:
965
966      tmp = VectorLoad(op0);
967      if ((tmp.x < 0) || (tmp.y < 0) ||
968          (tmp.z < 0) || (tmp.w < 0))
969      {
970          exit;
971      }
972
973    If a condition code is specified, the following is performed:
974
975      if (TestCC(rc.c***) || TestCC(rc.*c**) ||
976          TestCC(rc.**c*) || TestCC(rc.***c))
977      {
978         exit;
979      }
980
981
982    Add Section 3.11.6.5, TXD: Texture Lookup with Derivatives
983
984    The TXD instruction takes the first three components of its first
985    vector operand and maps them to s, t, and r.  These coordinates are
986    used to sample from the specified texture target on the specified
987    texture image unit in a manner consistent with its parameters.
988
989    The level of detail is computed as specified in section 3.8.
990    In this calculation, ds/dx, dt/dx, and dr/dx are given by the x,
991    y, and z components, respectively, of the second vector operand.
992    ds/dy, dt/dy, and dr/dy are given by the x, y, and z components of
993    the third vector operand.
994
995    The resulting sample is mapped to RGBA as described in table 3.21
996    and written to the result vector.
997
998      tmp = VectorLoad(op0);
999      result = TextureSample(tmp.x, tmp.y, tmp.z, 0.0, op1, op2);
1000
1001Additions to Chapter 4 of the OpenGL 1.2.1 Specification (Per-Fragment
1002Operations and the Frame Buffer)
1003
1004    None.
1005
1006Additions to Chapter 5 of the OpenGL 1.2.1 Specification (Special
1007Functions)
1008
1009    None.
1010
1011Additions to Chapter 6 of the OpenGL 1.2.1 Specification (State and
1012State Requests)
1013
1014    None.
1015
1016Additions to Appendix A of the OpenGL 1.2.1 Specification (Invariance)
1017
1018    None.
1019
1020Additions to the AGL/GLX/WGL Specifications
1021
1022    None.
1023
1024Dependencies on ARB_fragment_program
1025
1026    This specification is based on a modified version of the grammar
1027    published in the ARB_fragment_program specification.  This modified
1028    grammar (see below) includes a few structural changes to better
1029    accommodate new functionality from this and other extensions,
1030    but should be functionally equivalent to the ARB_fragment_program
1031    grammar.
1032
1033    <program>               ::= <optionSequence> <statementSequence> "END"
1034
1035    <optionSequence>        ::= <optionSequence> <option>
1036                              | /* empty */
1037
1038    <option>                ::= "OPTION" <optionName> ";"
1039
1040    <optionName>            ::= "ARB_fog_exp"
1041                              | "ARB_fog_exp2"
1042                              | "ARB_fog_linear"
1043                              | "ARB_precision_hint_fastest"
1044                              | "ARB_precision_hint_nicest"
1045
1046    <statementSequence>     ::= <statement> <statementSequence>
1047                              | /* empty */
1048
1049    <statement>             ::= <instruction> ";"
1050                              | <namingStatement> ";"
1051
1052    <instruction>           ::= <ALUInstruction>
1053                              | <TexInstruction>
1054
1055    <ALUInstruction>        ::= <VECTORop_instruction>
1056                              | <SCALARop_instruction>
1057                              | <BINSCop_instruction>
1058                              | <BINop_instruction>
1059                              | <TRIop_instruction>
1060                              | <SWZop_instruction>
1061
1062    <TexInstruction>        ::= <TEXop_instruction>
1063                              | <KILop_instruction>
1064
1065    <VECTORop_instruction>  ::= <VECTORop> <instResult> "," <instOperandV>
1066
1067    <VECTORop>              ::= "ABS"
1068                              | "FLR"
1069                              | "FRC"
1070                              | "LIT"
1071                              | "MOV"
1072
1073    <SCALARop_instruction>  ::= <SCALARop> <instResult> "," <instOperandS>
1074
1075    <SCALARop>              ::= "COS"
1076                              | "EX2"
1077                              | "LG2"
1078                              | "RCP"
1079                              | "RSQ"
1080                              | "SCS"
1081                              | "SIN"
1082
1083    <BINSCop_instruction>   ::= <BINSCop> <instResult> "," <instOperandS> ","
1084                                <instOperandS>
1085
1086    <BINSCop>               ::= "POW"
1087
1088    <BINop_instruction>     ::= <BINop> <instResult> "," <instOperandV> ","
1089                                <instOperandV>
1090
1091    <BINop>                 ::= "ADD"
1092                              | "DP3"
1093                              | "DP4"
1094                              | "DPH"
1095                              | "DST"
1096                              | "MAX"
1097                              | "MIN"
1098                              | "MUL"
1099                              | "SGE"
1100                              | "SLT"
1101                              | "SUB"
1102                              | "XPD"
1103
1104    <TRIop_instruction>     ::= <TRIop> <instResult> "," <instOperandV> ","
1105                                <instOperandV> "," <instOperandV>
1106
1107    <TRIop>                 ::= "CMP"
1108                              | "MAD"
1109                              | "LRP"
1110
1111    <SWZop_instruction>     ::= <SWZop> <instResult> "," <instOperandVNS> ","
1112                                <extendedSwizzle>
1113
1114    <SWZop>                 ::= "SWZ"
1115
1116    <TEXop_instruction>     ::= <TEXop> <instResult> "," <instOperandV> ","
1117                                <texTarget>
1118
1119    <TEXop>                 ::= "TEX"
1120                              | "TXP"
1121                              | "TXB"
1122
1123    <KILop_instruction>     ::= <KILop> <killCond>
1124
1125    <KILop>                 ::= "KIL"
1126
1127    <texTarget>             ::= <texImageUnit> "," <texTargetType>
1128
1129    <texImageUnit>          ::= "texture" <optTexImageUnitNum>
1130
1131    <optTexImageUnitNum>    ::= /* empty */
1132                              | "[" <texImageUnitNum> "]"
1133
1134    <texImageUnitNum>       ::= <integer>
1135                                /*[0,MAX_TEXTURE_IMAGE_UNITS_ARB-1]*/
1136
1137    <texTargetType>         ::= "1D"
1138                              | "2D"
1139                              | "3D"
1140                              | "CUBE"
1141                              | "RECT"
1142
1143    <killCond>              ::= <instOperandV>
1144
1145    <instOperandV>          ::= <instOperandBaseV>
1146
1147    <instOperandBaseV>      ::= <optSign> <attribUseV>
1148                              | <optSign> <tempUseV>
1149                              | <optSign> <paramUseV>
1150
1151    <instOperandS>          ::= <instOperandBaseS>
1152
1153    <instOperandBaseS>      ::= <optSign> <attribUseS>
1154                              | <optSign> <tempUseS>
1155                              | <optSign> <paramUseS>
1156
1157    <instOperandVNS>        ::= <attribUseVNS>
1158                              | <tempUseVNS>
1159                              | <paramUseVNS>
1160
1161    <instResult>            ::= <instResultBase>
1162
1163    <instResultBase>        ::= <tempUseW>
1164                              | <resultUseW>
1165
1166    <namingStatement>       ::= <ATTRIB_statement>
1167                              | <PARAM_statement>
1168                              | <TEMP_statement>
1169                              | <OUTPUT_statement>
1170                              | <ALIAS_statement>
1171
1172    <ATTRIB_statement>      ::= "ATTRIB" <establishName> "=" <attribUseD>
1173
1174    <PARAM_statement>       ::= <PARAM_singleStmt>
1175                              | <PARAM_multipleStmt>
1176
1177    <PARAM_singleStmt>      ::= "PARAM" <establishName> <paramSingleInit>
1178
1179    <PARAM_multipleStmt>    ::= "PARAM" <establishName> "[" <optArraySize> "]"
1180                                <paramMultipleInit>
1181
1182    <optArraySize>          ::= /* empty */
1183                              | <integer> /* [1,MAX_PROGRAM_PARAMETERS_ARB]*/
1184
1185    <paramSingleInit>       ::= "=" <paramUseDB>
1186
1187    <paramMultipleInit>     ::= "=" "{" <paramMultInitList> "}"
1188
1189    <paramMultInitList>     ::= <paramUseDM>
1190                              | <paramUseDM> "," <paramMultInitList>
1191
1192    <TEMP_statement>        ::= "TEMP" <varNameList>
1193
1194    <OUTPUT_statement>      ::= "OUTPUT" <establishName> "=" <resultUseD>
1195
1196    <ALIAS_statement>       ::= "ALIAS" <establishName> "=" <establishedName>
1197
1198    <establishedName>       ::= <tempVarName>
1199                              | <addrVarName>
1200                              | <attribVarName>
1201                              | <paramArrayVarName>
1202                              | <paramSingleVarName>
1203                              | <resultVarName>
1204
1205    <varNameList>           ::= <establishName>
1206                              | <establishName> "," <varNameList>
1207
1208    <establishName>         ::= <identifier>
1209
1210    <attribUseV>            ::= <attribBasic> <swizzleSuffix>
1211                              | <attribVarName> <swizzleSuffix>
1212                              | <attribColor> <swizzleSuffix>
1213                              | <attribColor> "." <colorType> <swizzleSuffix>
1214
1215    <attribUseS>            ::= <attribBasic> <scalarSuffix>
1216                              | <attribVarName> <scalarSuffix>
1217                              | <attribColor> <scalarSuffix>
1218                              | <attribColor> "." <colorType> <scalarSuffix>
1219
1220    <attribUseVNS>          ::= <attribBasic>
1221                              | <attribVarName>
1222                              | <attribColor>
1223                              | <attribColor> "." <colorType>
1224
1225    <attribUseD>            ::= <attribBasic>
1226                              | <attribColor>
1227                              | <attribColor> "." <colorType>
1228
1229    <attribBasic>           ::= "fragment" "." <attribFragBasic>
1230
1231    <attribFragBasic>       ::= "texcoord" <optTexCoordNum>
1232                              | "fogcoord"
1233                              | "position"
1234
1235    <attribColor>           ::= "fragment" "." "color"
1236
1237    <paramUseV>             ::= <paramSingleVarName> <swizzleSuffix>
1238                              | <paramArrayVarName> "[" <arrayMem> "]"
1239                                <swizzleSuffix>
1240                              | <stateSingleItem> <swizzleSuffix>
1241                              | <programSingleItem> <swizzleSuffix>
1242                              | <constantVector> <swizzleSuffix>
1243                              | <constantScalar> <swizzleSuffix>
1244
1245    <paramUseS>             ::= <paramSingleVarName> <scalarSuffix>
1246                              | <paramArrayVarName> "[" <arrayMem> "]"
1247                                <scalarSuffix>
1248                              | <stateSingleItem> <scalarSuffix>
1249                              | <programSingleItem> <scalarSuffix>
1250                              | <constantVector> <scalarSuffix>
1251                              | <constantScalar> <scalarSuffix>
1252
1253    <paramUseVNS>           ::= <paramSingleVarName>
1254                              | <paramArrayVarName> "[" <arrayMem> "]"
1255                              | <stateSingleItem>
1256                              | <programSingleItem>
1257                              | <constantVector>
1258                              | <constantScalar>
1259
1260    <paramUseDB>            ::= <stateSingleItem>
1261                              | <programSingleItem>
1262                              | <constantVector>
1263                              | <signedConstantScalar>
1264
1265    <paramUseDM>            ::= <stateMultipleItem>
1266                              | <programMultipleItem>
1267                              | <constantVector>
1268                              | <signedConstantScalar>
1269
1270    <stateMultipleItem>     ::= <stateSingleItem>
1271                              | "state" "." <stateMatrixRows>
1272
1273    <stateSingleItem>       ::= "state" "." <stateMaterialItem>
1274                              | "state" "." <stateLightItem>
1275                              | "state" "." <stateLightModelItem>
1276                              | "state" "." <stateLightProdItem>
1277                              | "state" "." <stateFogItem>
1278                              | "state" "." <stateMatrixRow>
1279                              | "state" "." <stateTexEnvItem>
1280                              | "state" "." <stateDepthItem>
1281
1282    <stateMaterialItem>     ::= "material" "." <stateMatProperty>
1283                              | "material" "." <faceType> "."
1284                                <stateMatProperty>
1285
1286    <stateMatProperty>      ::= "ambient"
1287                              | "diffuse"
1288                              | "specular"
1289                              | "emission"
1290                              | "shininess"
1291
1292    <stateLightItem>        ::= "light" "[" <stateLightNumber> "]" "."
1293                                <stateLightProperty>
1294
1295    <stateLightProperty>    ::= "ambient"
1296                              | "diffuse"
1297                              | "specular"
1298                              | "position"
1299                              | "attenuation"
1300                              | "spot" "." <stateSpotProperty>
1301                              | "half"
1302
1303    <stateSpotProperty>     ::= "direction"
1304
1305    <stateLightModelItem>   ::= "lightmodel" <stateLModProperty>
1306
1307    <stateLModProperty>     ::= "." "ambient"
1308                              | "." "scenecolor"
1309                              | "." <faceType> "." "scenecolor"
1310
1311    <stateLightProdItem>    ::= "lightprod" "[" <stateLightNumber> "]" "."
1312                                <stateLProdProperty>
1313                              | "lightprod" "[" <stateLightNumber> "]" "."
1314                                <faceType> "." <stateLProdProperty>
1315
1316    <stateLProdProperty>    ::= "ambient"
1317                              | "diffuse"
1318                              | "specular"
1319
1320    <stateLightNumber>      ::= <integer> /* [0,MAX_LIGHTS-1] */
1321
1322    <stateFogItem>          ::= "fog" "." <stateFogProperty>
1323
1324    <stateFogProperty>      ::= "color"
1325                              | "params"
1326
1327    <stateMatrixRows>       ::= <stateMatrixItem>
1328                              | <stateMatrixItem> "." <stateMatModifier>
1329                              | <stateMatrixItem> "." "row" "["
1330                                <stateMatrixRowNum> ".." <stateMatrixRowNum>
1331                                "]"
1332                              | <stateMatrixItem> "." <stateMatModifier> "."
1333                                "row" "[" <stateMatrixRowNum> ".."
1334                                <stateMatrixRowNum> "]"
1335
1336    <stateMatrixRow>        ::= <stateMatrixItem> "." "row" "["
1337                                <stateMatrixRowNum> "]"
1338                              | <stateMatrixItem> "." <stateMatModifier> "."
1339                                "row" "[" <stateMatrixRowNum> "]"
1340
1341    <stateMatrixItem>       ::= "matrix" "." <stateMatrixName>
1342
1343    <stateMatModifier>      ::= "inverse"
1344                              | "transpose"
1345                              | "invtrans"
1346
1347    <stateMatrixName>       ::= "modelview" <stateOptModMatNum>
1348                              | "projection"
1349                              | "mvp"
1350                              | "texture" <optTexCoordNum>
1351                              | "palette" "[" <statePaletteMatNum> "]"
1352                              | "program" "[" <stateProgramMatNum> "]"
1353
1354    <stateMatrixRowNum>     ::= <integer> /* [0,3] */
1355
1356    <stateOptModMatNum>     ::= /* empty */
1357                              | "[" <stateModMatNum> "]"
1358
1359    <stateModMatNum>        ::= <integer> /*[0,MAX_VERTEX_UNITS_ARB-1]*/
1360
1361    <statePaletteMatNum>    ::= <integer> /*[0,MAX_PALETTE_MATRICES_ARB-1]*/
1362
1363    <stateProgramMatNum>    ::= <integer> /*[0,MAX_PROGRAM_MATRICES_ARB-1]*/
1364
1365    <stateTexEnvItem>       ::= "texenv" <optLegacyTexUnitNum> "."
1366                                <stateTexEnvProperty>
1367
1368    <stateTexEnvProperty>   ::= "color"
1369
1370    <stateDepthItem>        ::= "depth" "." <stateDepthProperty>
1371
1372    <stateDepthProperty>    ::= "range"
1373
1374    <programSingleItem>     ::= <progEnvParam>
1375                              | <progLocalParam>
1376
1377    <programMultipleItem>   ::= <progEnvParams>
1378                              | <progLocalParams>
1379
1380    <progEnvParams>         ::= "program" "." "env" "[" <progEnvParamNums> "]"
1381
1382    <progEnvParamNums>      ::= <progEnvParamNum>
1383                              | <progEnvParamNum> ".." <progEnvParamNum>
1384
1385    <progEnvParam>          ::= "program" "." "env" "[" <progEnvParamNum> "]"
1386
1387    <progLocalParams>       ::= "program" "." "local" "[" <progLocalParamNums>
1388                                "]"
1389
1390    <progLocalParamNums>    ::= <progLocalParamNum>
1391                              | <progLocalParamNum> ".." <progLocalParamNum>
1392
1393    <progLocalParam>        ::= "program" "." "local" "[" <progLocalParamNum>
1394                                "]"
1395
1396    <progEnvParamNum>       ::= <integer>
1397                                /*[0,MAX_PROGRAM_ENV_PARAMETERS_ARB-1]*/
1398
1399    <progLocalParamNum>     ::= <integer>
1400                                /*[0,MAX_PROGRAM_LOCAL_PARAMETERS_ARB-1]*/
1401
1402    <constantVector>        ::= "{" <constantVectorList> "}"
1403
1404    <constantVectorList>    ::= <signedConstantScalar>
1405                              | <signedConstantScalar> ","
1406                                <signedConstantScalar>
1407                              | <signedConstantScalar> ","
1408                                <signedConstantScalar> ","
1409                                <signedConstantScalar>
1410                              | <signedConstantScalar> ","
1411                                <signedConstantScalar> ","
1412                                <signedConstantScalar> ","
1413                                <signedConstantScalar>
1414
1415    <signedConstantScalar>  ::= <optSign> <constantScalar>
1416
1417    <constantScalar>        ::= <floatConstant>
1418
1419    <floatConstant>         ::= <float>
1420
1421    <tempUseV>              ::= <tempVarName> <swizzleSuffix>
1422
1423    <tempUseS>              ::= <tempVarName> <scalarSuffix>
1424
1425    <tempUseVNS>            ::= <tempVarName>
1426
1427    <tempUseW>              ::= <tempVarName> <optWriteMask>
1428
1429    <resultUseW>            ::= <resultBasic> <optWriteMask>
1430                              | <resultVarName> <optWriteMask>
1431
1432    <resultUseD>            ::= <resultBasic>
1433
1434    <resultBasic>           ::= "result" "." <resultFragBasic>
1435
1436    <resultFragBasic>       ::= "color" <resultOptColorNum>
1437                              | "depth"
1438
1439    <resultOptColorNum>     ::= /* empty */
1440
1441    <arrayMem>              ::= <arrayMemAbs>
1442
1443    <arrayMemAbs>           ::= <integer>
1444
1445    <optWriteMask>          ::= /* empty */
1446                              | <xyzwMask>
1447                              | <rgbaMask>
1448
1449    <xyzwMask>              ::= "." "x"
1450                              | "." "y"
1451                              | "." "xy"
1452                              | "." "z"
1453                              | "." "xz"
1454                              | "." "yz"
1455                              | "." "xyz"
1456                              | "." "w"
1457                              | "." "xw"
1458                              | "." "yw"
1459                              | "." "xyw"
1460                              | "." "zw"
1461                              | "." "xzw"
1462                              | "." "yzw"
1463                              | "." "xyzw"
1464
1465    <rgbaMask>              ::= "." "r"
1466                              | "." "g"
1467                              | "." "rg"
1468                              | "." "b"
1469                              | "." "rb"
1470                              | "." "gb"
1471                              | "." "rgb"
1472                              | "." "a"
1473                              | "." "ra"
1474                              | "." "ga"
1475                              | "." "rga"
1476                              | "." "ba"
1477                              | "." "rba"
1478                              | "." "gba"
1479                              | "." "rgba"
1480
1481    <swizzleSuffix>         ::= /* empty */
1482                              | "." <component>
1483                              | "." <xyzwComponent> <xyzwComponent>
1484                                <xyzwComponent> <xyzwComponent>
1485                              | "." <rgbaComponent> <rgbaComponent>
1486                                <rgbaComponent> <rgbaComponent>
1487
1488    <extendedSwizzle>       ::= <extSwizComp> "," <extSwizComp> ","
1489                                <extSwizComp> "," <extSwizComp>
1490
1491    <extSwizComp>           ::= <optSign> <xyzwExtSwizSel>
1492                              | <optSign> <rgbaExtSwizSel>
1493
1494    <xyzwExtSwizSel>        ::= "0"
1495                              | "1"
1496                              | <xyzwComponent>
1497
1498    <rgbaExtSwizSel>        ::= <rgbaComponent>
1499
1500    <scalarSuffix>          ::= "." <component>
1501
1502    <component>             ::= <xyzwComponent>
1503                              | <rgbaComponent>
1504
1505    <xyzwComponent>         ::= "x"
1506                              | "y"
1507                              | "z"
1508                              | "w"
1509
1510    <rgbaComponent>         ::= "r"
1511                              | "g"
1512                              | "b"
1513                              | "a"
1514
1515    <optSign>               ::= /* empty */
1516                              | "-"
1517                              | "+"
1518
1519    <faceType>              ::= "front"
1520                              | "back"
1521
1522    <colorType>             ::= "primary"
1523                              | "secondary"
1524
1525    <optTexCoordNum>        ::= /* empty */
1526                              | "[" <texCoordNum> "]"
1527
1528    <texCoordNum>           ::= <integer> /*[0,MAX_TEXTURE_COORDS_ARB-1]*/
1529
1530    <optLegacyTexUnitNum>   ::= /* empty */
1531                              | "[" <legacyTexUnitNum> "]"
1532
1533    <legacyTexUnitNum>      ::= <integer> /*[0,MAX_TEXTURE_UNITS-1]*/
1534
1535    The <integer>, <float>, and <identifier> grammar rules match
1536    integer constants, floating point constants, and identifier names
1537    as described in the ARB_vertex_program specification.  The <float>
1538    grammar rule here is identical to the <floatConstant> grammar rule
1539    in ARB_vertex_program.
1540
1541    The grammar rules <tempVarName>, <addrVarName>, <attribVarName>,
1542    <paramArrayVarName>, <paramSingleVarName>, <resultVarName> refer
1543    to the names of temporary, address register, attribute, program
1544    parameter array, program parameter, and result variables declared
1545    in the program text.
1546
1547GLX Protocol
1548
1549    None.
1550
1551Errors
1552
1553    None.
1554
1555New State
1556
1557    None.
1558
1559Revision History
1560
1561    Rev.  Date      Author   Changes
1562    ----  --------  -------  --------------------------------------------
1563    4     05/27/05  pbrown   Removed required NV_fragment_program dependency;
1564                             that extension actually isn't needed although the
1565                             functionality it provides obviously is.
1566
1567    3     07/08/04  pbrown   Fixed entries for KIL and RFL in the opcode
1568                             table.
1569
1570    2     05/16/04  pbrown   Documented terminals in modified fragment program
1571                             grammar.
1572
1573    1     --------  pbrown   Internal pre-release revisions.
1574