| Name |
| |
| ARB_fragment_program |
| |
| Name Strings |
| |
| GL_ARB_fragment_program |
| |
| Contributors |
| |
| Bob Beretta |
| Pat Brown |
| Matt Craighead |
| Cass Everitt |
| Evan Hart |
| Jon Leech |
| Bill Licea-Kane |
| Bimal Poddar |
| Jeremy Sandmel |
| Jon Paul Schelter |
| Avinash Seetharamaiah |
| Nick Triantos |
| |
| and contributors to the ARB_vertex_program working group, |
| the product of which provided the basis for this spec |
| |
| Contact |
| |
| Benj Lipchak, AMD (benj.lipchak 'at' amd.com) |
| |
| Notice |
| |
| Copyright (c) 2002-2013 The Khronos Group Inc. Copyright terms at |
| http://www.khronos.org/registry/speccopyright.html |
| |
| Specification Update Policy |
| |
| Khronos-approved extension specifications are updated in response to |
| issues and bugs prioritized by the Khronos OpenGL Working Group. For |
| extensions which have been promoted to a core Specification, fixes will |
| first appear in the latest version of that core Specification, and will |
| eventually be backported to the extension document. This policy is |
| described in more detail at |
| https://www.khronos.org/registry/OpenGL/docs/update_policy.php |
| |
| IP Status |
| |
| Microsoft claims to own intellectual property related to this |
| extension. |
| |
| Status |
| |
| Complete. Approved by ARB on September 18, 2002 |
| |
| Version |
| |
| Last Modified Date: October 8, 2013 |
| Revision: 28 |
| |
| Number |
| |
| ARB Extension #27 |
| |
| Dependencies |
| |
| The extension is written against the OpenGL 1.3 Specification. |
| |
| OpenGL 1.3 is required. |
| |
| EXT_texture_lod_bias or OpenGL 1.4 is required. |
| |
| OpenGL 1.4 affects the definition of this extension. |
| |
| ARB_vertex_blend and EXT_vertex_weighting affect the definition of |
| this extension. |
| |
| ARB_matrix_palette affects the definition of this extension. |
| |
| ARB_transpose_matrix affects the definition of this extension. |
| |
| EXT_fog_coord affects the definition of this extension. |
| |
| EXT_texture_rectangle affects the definition of this extension. |
| |
| ARB_shadow interacts with this extension. |
| |
| ARB_vertex_program interacts with this extension. |
| |
| ATI_fragment_shader interacts with this extension. |
| |
| NV_fragment_program interacts with this extension. |
| |
| |
| Overview |
| |
| Unextended OpenGL mandates a certain set of configurable per- |
| fragment computations defining texture application, texture |
| environment, color sum, and fog operations. Several extensions have |
| added further per-fragment computations to OpenGL. For example, |
| extensions have defined new texture environment capabilities |
| (ARB_texture_env_add, ARB_texture_env_combine, ARB_texture_env_dot3, |
| ARB_texture_env_crossbar), per-fragment depth comparisons |
| (ARB_depth_texture, ARB_shadow, ARB_shadow_ambient, |
| EXT_shadow_funcs), per-fragment lighting (EXT_fragment_lighting, |
| EXT_light_texture), and environment mapped bump mapping |
| (ATI_envmap_bumpmap). |
| |
| Each such extension adds a small set of relatively inflexible per- |
| fragment computations. |
| |
| This inflexibility is in contrast to the typical flexibility |
| provided by the underlying programmable floating point engines |
| (whether micro-coded fragment engines, DSPs, or CPUs) that are |
| traditionally used to implement OpenGL's texturing computations. |
| The purpose of this extension is to expose to the OpenGL application |
| writer a significant degree of per-fragment programmability for |
| computing fragment parameters. |
| |
| For the purposes of discussing this extension, a fragment program is |
| a sequence of floating-point 4-component vector operations that |
| determines how a set of program parameters (not specific to an |
| individual fragment) and an input set of per-fragment parameters are |
| transformed to a set of per-fragment result parameters. |
| |
| The per-fragment computations for standard OpenGL given a particular |
| set of texture and fog application modes (along with any state for |
| extensions defining per-fragment computations) is, in essence, a |
| fragment program. However, the sequence of operations is defined |
| implicitly by the current OpenGL state settings rather than defined |
| explicitly as a sequence of instructions. |
| |
| This extension provides an explicit mechanism for defining fragment |
| program instruction sequences for application-defined fragment |
| programs. In order to define such fragment programs, this extension |
| defines a fragment programming model including a floating-point |
| 4-component vector instruction set and a relatively large set of |
| floating-point 4-component registers. |
| |
| The extension's fragment programming model is designed for efficient |
| hardware implementation and to support a wide variety of fragment |
| programs. By design, the entire set of existing fragment programs |
| defined by existing OpenGL per-fragment computation extensions can |
| be implemented using the extension's fragment programming model. |
| |
| Issues |
| |
| This extension is closely related to ARB_vertex_program, and is in |
| sync with revision 36 of that spec. ARB_fragment_program will |
| continue to track changes made to ARB_vertex_program. |
| |
| (1) Should we provide precision queries? |
| |
| RESOLVED: We've decided not to include precision queries. |
| Implementations are expected to meet or exceed the precision |
| guidelines set forth in the core GL spec, section 2.1.1, p. 6, |
| as ammended by this extension. |
| |
| To summarize section 2.1.1, the maximum representable magnitude of |
| colors must be at least 2^10, while the maximum representable |
| magnitude of other floating-point values must be at least 2^32. |
| The individual results of floating-point operations must be |
| accurate to about 1 part in 10^5. |
| |
| Here are the reasons why precision queries were not included: |
| 1. It is unclear what the queries should be: |
| a) min, max, [0,1) granularity |
| b) min +, max +, min -, max -, [0,1) granularity |
| c) IEEE mantissa bits, IEEE exponent bits |
| 2. Due to instruction emulation, there is no way to query the |
| actual precision that can be expected. Should the query |
| return the best-case or worst-case precision? |
| 3. Implementations may support multiple precisions, on a per- |
| instruction basis or across the board. How would this be |
| exposed? |
| 4. Current implementations are able to meet the minimum |
| requirements specified in the core GL, thanks to its |
| sufficiently loose wording "... so that the individual |
| results of floating-point operations are accurate to ABOUT |
| 1 part in 10^5." (Emphasis added.) |
| 5. A conformance test can act as watchdog to ensure |
| implementations are not cutting corners on precision. |
| 6. Adding precision queries would require a new entrypoint. |
| |
| See issue 22 regarding reduced-precision modes. |
| |
| (2) Should the LOD biased texture sample be optional? |
| |
| RESOLVED: TXB support is mandatory. This exposes useful |
| functionality which enables blurring and sharpening effects. It |
| will be more useful to entirely override derivatives (scale |
| factor) rather than just biasing the level-of-detail. This would |
| be a future extension to fragment programs. |
| |
| It should be noted here that the bias introduced per-fragment by |
| TXB is added to any per-object or per-stage LOD bias. If per- |
| fragment LOD bias is not necessary, using the per-object and/or |
| per-stage LOD biases may perform better. |
| |
| (3) Should we include the ability to bind to the color matrix? How |
| about others? Program matrices? |
| |
| RESOLVED: We will not specifically add anything that depends on |
| the ARB_imaging subset. So we have not included matrix bindings |
| to the color matrix (or parameter bindings to the color biases, |
| etc.). However, we have included matrix binding support and |
| support for all of the matrices present in ARB_vertex_program. |
| |
| (4) Should we include the ability to bind to just a texcoord |
| attribute's S,T components? (Or just S, or S,T,P for that matter?) |
| |
| RESOLVED: No. Issue #15 below obviates this issue by making the |
| texture coordinate usage within a program explicit, thereby making |
| optimizations to reduce the number of interpolated texture |
| coordinates something an implementation can do at compile time |
| instead of having to do it during every texture target change. |
| |
| (5) What other instructions should be added? Should any be removed? |
| |
| RESOLVED: The differences between the ARB_vertex_program |
| instruction set and the ARB_fragment_program instruction set are |
| minimal. ARB_fragment_program removes the LOG and EXP rough |
| approximation instructions and the ARL address register load |
| instruction. ARB_fragment_program adds the SIN/COS/SCS |
| trigonometric instructions, the LRP linear interpolation |
| instruction, the CMP compare instruction, and the TEX/TXP/TXB/KIL |
| texture instructions. |
| |
| (6) Should depth output be a program option or a mandatory feature? |
| |
| RESOLVED: Depth output capability should be mandatory. |
| |
| (6a) How should per-vertex geometric depth clipping be handled when |
| replacing depth in a fragment program? |
| |
| RESOLVED: Per-vertex geometric depth clipping should be performed |
| by the GL as usual, so no spec change is required. The ideal |
| behavior would be to disable near and far clipping planes when |
| replacing depth, but not all implementations can natively support |
| disabling individual clip planes. |
| |
| (6b) How should depth output from the fragment program be further |
| processed before being handed to the per-fragment operations? |
| |
| RESOLVED: Depth gets clamped by GL to [0,1]. App has access to |
| depth range as a bindable parameter if it wants to either scale |
| and bias its depth to fall within the depth range, or to kill |
| fragments outside the depth range. |
| |
| (7) If a fragment program does not write a color value, what should |
| be the final color of the fragment? |
| |
| RESOLVED: The final fragment color is undefined. Note that it may |
| be perfectly reasonable to have a program that computes depth |
| values but not colors. Fragment colors are often irrelevant if |
| color writes are disabled (via ColorMask). |
| |
| (7a) If a fragment program does not write a depth value, what should |
| be the final depth value of the fragment? |
| |
| RESOLVED: "Depth fly-over" (using the conventional depth produced |
| by rasterization) should happen whenever a depth-replacing program |
| is not in use. A depth-replacing program is defined as a program |
| that writes to result.depth in at least one instruction. The |
| presence of a depth declaration alone DOES NOT designate a depth- |
| replacing program. The intention is that a future extension |
| introducing conditional execution will still consider a program to |
| be depth-replacing even if the instruction(s) writing to |
| result.depth do(es) not execute. |
| |
| Other considered definitions of depth-replacing program: |
| 1. The presence of a depth declaration -OR- the use of |
| result.depth as an instruction destination anywhere in the |
| program designates a depth-replacing program. |
| 2. Every program is a depth-replacing program, but the GL |
| initializes the depth output to be the depth produced by |
| rasterization. The app may then overwrite the depth output. |
| 3. Every program is a depth-replacing program, and the app is |
| solely responsible for copying the depth input to depth |
| output if desired. |
| |
| (8) Should relative addressing, like that defined in |
| ARB_vertex_program, be supported in this spec? |
| |
| RESOLVED: No, relative addressing won't be included in this spec. |
| |
| (9) Should full-featured operand component swizzling, like that |
| defined in ARB_vertex_program, be supported in this spec? |
| |
| RESOLVED: Yes, full swizzling is mandatory. |
| |
| (10) Should texture instructions contain specific limitations on |
| operations that can be performed? For example, should write masks |
| or operand component swizzling be disallowed? |
| |
| RESOLVED: Texture instructions are specified to be very similar to |
| ALU instructions. They have been given 3-letter names, they allow |
| writemasking and saturation (which would be useful for floating- |
| point texture formats), source swizzles and negates, and the |
| ability to use parameters as sources. |
| |
| (11) Should we standardize options for stencil or aux data buffer |
| outputs? |
| |
| RESOLVED: Stencil and aux data buffers will be saved for a |
| possible future extension to fragment programs. |
| |
| (12) Should depth output be pulled from the 3rd or 4th component? |
| |
| RESOLVED: 3rd component, as the 3rd component is also used for |
| depth input from the "fragment.position" attribute. |
| |
| (13) Which stages are subsumed by fragment programs? |
| |
| RESOLVED: Texturing, color sum, and fog. |
| |
| (14) What should the minimum resource limits be? |
| |
| RESOLVED: 10 attributes, 24 parameters, 4 texture indirections, |
| 48 ALU instructions, 24 texture instructions, and 16 temporaries. |
| |
| (15) OpenGL provides a hierarchy of texture enables (cube map, 3D, |
| 2D, 1D). Should the texture sampling instructions here override |
| that hierarchy and select specific texture targets? |
| |
| RESOLVED: Yes. This removes a potential pitfall for developers: |
| leaving the hierarchy of enables in an undesired state. It makes |
| programs more readable as the intent of the sample is more |
| obvious. Finally, it allows compilers to be more aggressive as |
| to which texcoord components are "don't cares" without having to |
| recompile programs when fixed-function texenables change. One |
| drawback is that programs cannot be reused for both 2D and 3D |
| texturing, for example, by simply changing the texture enables. |
| |
| Texture sampling can be specified by instructions like |
| |
| TEX myTexel, fragment.texcoord[1], texture[2], 3D; |
| |
| which would indicate to use texture coordinate set number 1 to |
| sample from the texture object bound to the TEXTURE_3D target on |
| texture image unit 2. |
| |
| Each texture unit can have only one "active" target. Programs are |
| not allowed to reference different texture targets in the same |
| texture image unit. In the example above, any other texture |
| instructions using texture image unit 2 must specify the 3D |
| texture target. |
| |
| Note that every texture image unit always has a texture bound to |
| every texture target, whether it is a named texture object or a |
| default texture. However, the texture may not be complete as |
| defined in section 3.8.9 of the core GL spec. See issue 23. |
| |
| (16) Should aux texture units be additional units on top of existing |
| full-featured texture units, or should this spec fully deprecate |
| "legacy" texture units and only expose texture coordinate sets and |
| texture image units? |
| |
| Background: Some implementations are able to expose more |
| "texture image units" (texture maps and associated parameters) |
| than "texture coordinate sets" (current texcoords, texgen, and |
| texture matrices). A conventional GL "texture unit" encompasses |
| both a texture image unit and a texture coordinate set as well as |
| texture environment state. |
| |
| RESOLVED: Yes, deprecate "legacy" texture units. This is a more |
| flexible model. |
| |
| (17) Should fragment programs affect all fragments, or just those |
| produced by the rasterization of points, lines, and triangles? |
| |
| RESOLVED: Every fragment generated by the GL is subject to |
| fragment program mode. This includes point, line, and polygon |
| primitives as well as pixel rectangles and bitmaps. |
| |
| (18) Should per-fragment position and fogcoord be bindable as |
| fragment attributes? |
| |
| RESOLVED: Yes, interpolated fogcoord will make per-fragment |
| fog application possible, in addition to full fog stage |
| subsummation. Interpolated window position, especially depth, |
| enables interesting depth-replacing algorithms. |
| |
| (19) What characters should be used to identify individual |
| components in swizzle selectors and write masks? |
| |
| RESOLVED: ARB_vertex_program provides "xyzw". This extension |
| supports "xyzw" and also provides "rgba" for better readability |
| when dealing with RGBA color values. Adding support for special |
| identifiers for dealing with texture coordinates was considered |
| and rejected. "strq" could be used to identify texture coordinate |
| components, but the "r" would conflict with the "r" from "rgba". |
| "stpq" would be another possibility, but could be a source of |
| confusion. |
| |
| (20) Should implementations be required to support all programs that |
| fit within the exported limits on the number of resources (e.g., |
| instructions, temporaries) that can be present in a program, even if |
| it means falling back to software? Should implementations be |
| required to reject programs that could never be accelerated? |
| |
| RESOLVED: No and no. An implementation is allowed to fail |
| ProgramStringARB due to the program exceeding native resources. |
| Note that this failure must be invariant with respect to all other |
| OpenGL state. In other words, a program cannot succeed to load |
| with default state, but then fail to load when certain GL state |
| is altered. However, an implementation is not required to fail |
| when a program would exceed native resources, and is in fact |
| encouraged to fallback to a software path. See issue 21 for a way |
| of determining if this has happened. |
| |
| This notable departure from ARB_vertex_program was made as an |
| accommodation to vendors who could not justify implementing a |
| software fallback path which would be relatively slow even |
| compared to an ARB_vertex_program software fallback path. |
| |
| Two issues with this decision: |
| 1. The API limits become hints, and one can no longer tell by |
| visual inspection whether or not a program will load on |
| every implementation. |
| 2. Program loading will now depend on the optimizer, which may |
| vary from release to release of an implementation. A |
| program that succeeded to load when an ISV first wrote it |
| may fail to load in a future driver version, and vice versa. |
| |
| (21) How can applications determine if their programs are too large |
| to run on the native (likely hardware) implementation, and therefore may |
| run with reduced performance? |
| |
| RESOLVED: The following code snippet uses a native resource |
| query to guarantee a program is loaded natively (or not at all): |
| |
| GLboolean ProgramStringIsNative(GLenum target, GLenum format, |
| GLsizei len, const void *string) |
| { |
| GLint errorPos, isNative; |
| glProgramStringARB(target, format, len, string); |
| glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &errorPos); |
| glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, |
| GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB, &isNative); |
| if ((errorPos == -1) && (isNative == 1)) |
| return GL_TRUE; |
| else |
| return GL_FALSE; |
| } |
| |
| Note that a program that successfully loads, and falls under the |
| native limits, is still not guaranteed to execute in hardware. |
| Lack of other resources (e.g., texture memory) or the use of other |
| OpenGL features not natively supported by the implementation |
| (e.g., textures with borders) may also prevent the program from |
| executing in hardware. |
| |
| (22) Should we provide applications with a method to control the |
| level of precision used to carry out fragment program computations? |
| |
| RESOLVED: Yes. The GL implementation ultimately has control over |
| the level of precision used for fragment program computations. |
| However, the "ARB_precision_hint_fastest" and |
| "ARB_precision_hint_nicest" program options allow applications to |
| guide the GL implementation in its precision selection. The |
| "fastest" option encourages the GL to minimize execution time, |
| with possibly reduced precision. The "nicest" option encourages |
| the GL to maximize precision, with possibly increased execution |
| time. |
| |
| If the precision hint is not "fastest", GL implementations should |
| perform low-precision operations only if they could not |
| appreciably affect the final results of the program. Regardless |
| of the precision hint, GL implementations are discouraged from |
| reducing the precision of computations so aggressively that final |
| rendering results could be seriously compromised due to overflow |
| of intermediate values or insufficient number of mantissa bits. |
| |
| Some implementations may provide only a single level of precision, |
| in which case these hints may have no effect. However, all |
| implementations will accept these options, even if they are |
| silently ignored. |
| |
| More explicit control of precision, such as provided in "C" with |
| data types such as "short", "int", "float", "double", may also be |
| a desirable feature, but this level of detail is left to a |
| separate extension. |
| |
| (23) What is the result of a sample from an incomplete texture? |
| The definition of texture completeness can be found in section 3.8.9 |
| of the core GL spec. |
| |
| RESOLVED: The result of a sample from an incomplete texture is the |
| constant vector (0,0,0,1). The benefit of defining the result to |
| be a constant is that broken apps are guaranteed to generate |
| unexpected (black) results from their bad samples. If we were to |
| leave the result undefined, some implementations may generate |
| expected results some of the time, for example when magfiltering, |
| giving app developers a false sense of correctness in their apps. |
| |
| (24) What is a texture indirection, and how is it counted? |
| |
| RESOLVED: On some implementations, fragment programs that have |
| complex texture dependency chains may not be supported, even if |
| the instruction counts fit within the exported limits. A texture |
| dependency occurs when a texture instruction depends on the |
| result of a previous instruction (ALU or texture) for use as its |
| texture coordinate. |
| |
| A texture indirection can be considered a node in the texture |
| dependency chain. Each node contains a set of texture |
| instructions which execute in parallel, followed by a sequence of |
| ALU instructions. A dependent texture instruction is one that |
| uses a temporary as an input coordinate rather than an attribute |
| or a parameter. A program with no dependent texture instructions |
| (or no texture instructions at all) will have a single node in |
| its texture dependency chain, and thus a single indirection. |
| |
| API-level texture indirections are counted by keeping track of |
| which temporaries are read and written within the current node in |
| the texture dependency chain. When a texture instruction is |
| encountered, an indirection may be added and a new node started |
| if either of the following two conditions is true: |
| |
| 1. the source coordinate of the texture instruction is a |
| temporary that has already been written in the current node, |
| either by a previous texture instruction or ALU instruction; |
| |
| 2. the result of the texture instruction is a temporary that |
| has already been read or written in the current node by an |
| ALU instruction. |
| |
| The texture instruction provoking a new indirection and all |
| subsequent instructions are added to the new node. This process |
| is repeated until the end of the program is encountered. Below |
| is some pseudo-code to describe this: |
| |
| indirections = 1; |
| tempsOutput = 0; |
| aluTemps = 0; |
| while (i = getInst()) |
| { |
| if (i.type == TEX) |
| { |
| if (((i.input.type == TEMP) && |
| (tempsOutput & (1 << i.input.index))) || |
| ((i.op != KILL) && (i.output.type == TEMP) && |
| (aluTemps & (1 << i.output.index)))) |
| { |
| indirections++; |
| tempsOutput = 0; |
| aluTemps = 0; |
| } |
| } else { |
| if (i.input1.type == TEMP) |
| aluTemps |= (1 << i.input1.index); |
| if (i.input2 && i.input2.type == TEMP) |
| aluTemps |= (1 << i.input2.index); |
| if (i.input3 && i.input3.type == TEMP) |
| aluTemps |= (1 << i.input3.index); |
| if (i.output.type == TEMP) |
| aluTemps |= (1 << i.output.index); |
| } |
| if ((i.op != KILL) && (i.output.type == TEMP)) |
| tempsOutput |= (1 << i.output.index); |
| } |
| |
| For example, the following programs would have 1, 2, and 3 |
| texture indirections, respectively: |
| |
| !!ARBfp1.0 |
| # No texture instructions, but always 1 indirection |
| MOV result.color, fragment.color; |
| END |
| |
| !!ARBfp1.0 |
| # A simple dependent texture instruction, 2 indirections |
| TEMP myColor; |
| MUL myColor, fragment.texcoord[0], fragment.texcoord[1]; |
| TEX result.color, myColor, texture[0], 2D; |
| END |
| |
| !!ARBfp1.0 |
| # A more complex example with 3 indirections |
| TEMP myColor1, myColor2; |
| TEX myColor1, fragment.texcoord[0], texture[0], 2D; |
| MUL myColor1, myColor1, myColor1; |
| TEX myColor2, fragment.texcoord[1], texture[1], 2D; |
| # so far we still only have 1 indirection |
| TEX myColor2, myColor1, texture[2], 2D; # This is #2 |
| TEX result.color, myColor2, texture[3], 2D; # And #3 |
| END |
| |
| Note that writemasks for the temporaries written and swizzles |
| for the temporaries read are not taken into consideration when |
| counting indirections. This makes hand-counting of indirections |
| by a developer an easier task. |
| |
| Native texture indirections may be counted differently by an |
| implementation to reflect its exact restrictions, to reflect the |
| true dependencies taking into account writemasks and swizzles, |
| and to reflect optimizations such as instruction reordering. |
| |
| For implementations with no restrictions on the number of |
| indirections, the maximum indirection count will equal the |
| maximum texture instruction count. |
| |
| (25) How can a program reduce SCS's scalar operand to the |
| fundamental period [-PI,PI]? |
| |
| RESOLVED: Unlike the individual SIN and COS instructions, SCS |
| requires that its argument be reduced ahead of time to the |
| fundamental period. The reason SCS doesn't perform this |
| operation automatically is that it may make unnecessary redundant |
| work for programs that already have their operand in the correct |
| range. Other programs that do need to reduce their operand |
| simply need to add a block of code before the SCS instruction: |
| |
| PARAM myParams = { 0.5, -3.14159, 6.28319, 0.15915 }; |
| MAD myOperand.x, myOperand.x, myParams.w, myParams.x; # a = (a/(2*PI))+0.5 |
| FRC myOperand.x, myOperand.x; # a = frac(a) |
| MAD myOperand.x, myOperand.x, myParams.z, myParams.y # a = (a*2*PI)-PI |
| ... |
| SCS myResult, myOperand.x; |
| |
| (26) Is depth output from a fragment program guaranteed to be |
| invariant with respect to depth produced via conventional |
| rasterization? |
| |
| RESOLVED: No. The floating-point representation of depth values |
| output from a fragment program may lead to the output of depth |
| with less precision than the depth output by convention GL |
| rasterization. For example, a floating-point representation with |
| 16 bits of mantissa will certainly produce depth with lesser |
| precision than that of conventional rasterization used in |
| conjunction with a 24-bit depth buffer, where all values are |
| maintained as integers. Be aware of this when mixing conventional |
| GL rendering with fragment program rendering. |
| |
| (27) How can conventional GL fog application be achieved within a |
| fragment program? |
| |
| RESOLVED: Program options have been introduced that allow a |
| program to request fog to be applied to the final clamped fragment |
| color before being passed along to the antialiasing application |
| stage. This makes it easy for: |
| 1. developers to request conventional fog behavior |
| 2. implementations with dedicated fog hardware to use it |
| 3. implementations without dedicated fog hardware, so they need |
| not track fog state after compilation, and constantly |
| recompile when fog state changes. |
| |
| The three mandatory options are ARB_fog_exp, ARB_fog_exp2, and |
| ARB_fog_linear. As these options are mutually exclusive by |
| nature, specifying more than one is not useful. If more than one |
| is specified, the last one encountered in the <optionSequence> |
| will be the one to actually modify the execution environment. |
| |
| (28) Why have all of the enums, entrypoints, GLX protocol, and spec |
| language shared with ARB_vertex_program been reproduced here? |
| |
| RESOLVED: The two extensions are independent of one another, in |
| so far as an implementation need not support both of them in order |
| to support one of them. Everything needed to implement or make |
| use of ARB_fragment_program is present in this spec without the |
| need to refer to the ARB_vertex_program spec. When and if these |
| two extensions are incorporated into the core OpenGL, the |
| significant overlap of the two will be collapsed into a single |
| instance of the shared parts. |
| |
| (29) How might an implementation implement the fog options? To What |
| does the extra resource consumption described in 3.11.4.5.1 |
| correspond? |
| |
| RESOLVED: The following code snippets reflect possible |
| implementations of the fog options. While an implementation may |
| use other instruction sequences to achieve the same result, or may |
| use external fog hardware if available, all implementations must |
| enforce the API-level resource consumption as described: 2 params, |
| 1 temp, 1 attribute, and 3, 4, or 2 instructions. "finalColor" in |
| the examples below is the color that would otherwise be |
| "result.color", with components clamped to the range [0,1]. |
| "result.color.a" is assumed to have already been written, as fog |
| blending does not affect the alpha component. |
| |
| EXP: |
| # Exponential fog |
| # f = exp(-d*z) |
| # |
| PARAM p = {DENSITY/LN(2), NOT USED, NOT USED, NOT USED}; |
| PARAM fogColor = state.fog.color; |
| TEMP fogFactor; |
| ATTRIB fogCoord = fragment.fogcoord.x; |
| MUL fogFactor.x, p.x, fogCoord.x; |
| EX2_SAT fogFactor.x, -fogFactor.x; |
| LRP result.color.rgb, fogFactor.x, finalColor, fogColor; |
| |
| EXP2: |
| # |
| # 2nd-order Exponential fog |
| # f = exp(-(d*z)^2) |
| # |
| PARAM p = {DENSITY/SQRT(LN(2)), NOT USED, NOT USED, NOT USED}; |
| PARAM fogColor = state.fog.color; |
| TEMP fogFactor; |
| ATTRIB fogCoord = fragment.fogcoord.x; |
| MUL fogFactor.x, p.x, fogCoord.x; |
| MUL fogFactor.x, fogFactor.x, fogFactor.x; |
| EX2_SAT fogFactor.x, -fogFactor.x; |
| LRP result.color.rgb, fogFactor.x, finalColor, fogColor; |
| |
| LINEAR: |
| # |
| # Linear fog |
| # f = (end-z)/(end-start) |
| # |
| PARAM p = {-1/(END-START), END/(END-START), NOT USED, NOT USED}; |
| PARAM fogColor = state.fog.color; |
| TEMP fogFactor; |
| ATTRIB fogCoord = fragment.fogcoord.x; |
| MAD_SAT fogFactor.x, p.x, fogCoord.x, p.y; |
| LRP result.color.rgb, fogFactor.x, finalColor, fogColor; |
| |
| (30) Why is the order of operands for the CMP instruction different |
| than the order used by another popular graphics API? |
| |
| RESOLVED: No other graphics API was used as a basis for the |
| design of ARB_fragment_program except ARB_vertex_program, which |
| did not have a CMP instruction. This independent evolution |
| naturally led to differences in minor details such as order of |
| operands. This discrepancy is noted here to help developers |
| familiar with the other API to avoid this potential pitfall. |
| |
| (31) Is depth offset applied to the window z value before it enters |
| the fragment program? |
| |
| RESOLVED: As in the base OpenGL specification, the depth offset |
| generated by polygon offset is added during polygon rasterization. |
| The depth value provided to shaders in the fragment.position.z |
| attribute already includes polygon offset, if enabled. If the |
| depth value is replaced by a fragment program, the polygon offset |
| value will NOT be recomputed and added back after fragment program |
| execution. |
| |
| NOTE: This is probably not desirable for fragment programs that |
| modify depth values since the partials used to generate the offset |
| may not match the partials of the computed depth value. |
| |
| |
| New Procedures and Functions |
| |
| void ProgramStringARB(enum target, enum format, sizei len, |
| const void *string); |
| |
| void BindProgramARB(enum target, uint program); |
| |
| void DeleteProgramsARB(sizei n, const uint *programs); |
| |
| void GenProgramsARB(sizei n, uint *programs); |
| |
| void ProgramEnvParameter4dARB(enum target, uint index, |
| double x, double y, double z, double w); |
| void ProgramEnvParameter4dvARB(enum target, uint index, |
| const double *params); |
| void ProgramEnvParameter4fARB(enum target, uint index, |
| float x, float y, float z, float w); |
| void ProgramEnvParameter4fvARB(enum target, uint index, |
| const float *params); |
| |
| void ProgramLocalParameter4dARB(enum target, uint index, |
| double x, double y, double z, double w); |
| void ProgramLocalParameter4dvARB(enum target, uint index, |
| const double *params); |
| void ProgramLocalParameter4fARB(enum target, uint index, |
| float x, float y, float z, float w); |
| void ProgramLocalParameter4fvARB(enum target, uint index, |
| const float *params); |
| |
| void GetProgramEnvParameterdvARB(enum target, uint index, |
| double *params); |
| void GetProgramEnvParameterfvARB(enum target, uint index, |
| float *params); |
| |
| void GetProgramLocalParameterdvARB(enum target, uint index, |
| double *params); |
| void GetProgramLocalParameterfvARB(enum target, uint index, |
| float *params); |
| |
| void GetProgramivARB(enum target, enum pname, int *params); |
| |
| void GetProgramStringARB(enum target, enum pname, void *string); |
| |
| boolean IsProgramARB(uint program); |
| |
| |
| New Tokens |
| |
| Accepted by the <cap> parameter of Disable, Enable, and IsEnabled, |
| by the <pname> parameter of GetBooleanv, GetIntegerv, GetFloatv, |
| and GetDoublev, and by the <target> parameter of ProgramStringARB, |
| BindProgramARB, ProgramEnvParameter4[df][v]ARB, |
| ProgramLocalParameter4[df][v]ARB, GetProgramEnvParameter[df]vARB, |
| GetProgramLocalParameter[df]vARB, GetProgramivARB and |
| GetProgramStringARB. |
| |
| FRAGMENT_PROGRAM_ARB 0x8804 |
| |
| Accepted by the <format> parameter of ProgramStringARB: |
| |
| PROGRAM_FORMAT_ASCII_ARB 0x8875 |
| |
| Accepted by the <pname> parameter of GetProgramivARB: |
| |
| PROGRAM_LENGTH_ARB 0x8627 |
| PROGRAM_FORMAT_ARB 0x8876 |
| PROGRAM_BINDING_ARB 0x8677 |
| PROGRAM_INSTRUCTIONS_ARB 0x88A0 |
| MAX_PROGRAM_INSTRUCTIONS_ARB 0x88A1 |
| PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A2 |
| MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A3 |
| PROGRAM_TEMPORARIES_ARB 0x88A4 |
| MAX_PROGRAM_TEMPORARIES_ARB 0x88A5 |
| PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A6 |
| MAX_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A7 |
| PROGRAM_PARAMETERS_ARB 0x88A8 |
| MAX_PROGRAM_PARAMETERS_ARB 0x88A9 |
| PROGRAM_NATIVE_PARAMETERS_ARB 0x88AA |
| MAX_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AB |
| PROGRAM_ATTRIBS_ARB 0x88AC |
| MAX_PROGRAM_ATTRIBS_ARB 0x88AD |
| PROGRAM_NATIVE_ATTRIBS_ARB 0x88AE |
| MAX_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AF |
| MAX_PROGRAM_LOCAL_PARAMETERS_ARB 0x88B4 |
| MAX_PROGRAM_ENV_PARAMETERS_ARB 0x88B5 |
| PROGRAM_UNDER_NATIVE_LIMITS_ARB 0x88B6 |
| |
| PROGRAM_ALU_INSTRUCTIONS_ARB 0x8805 |
| PROGRAM_TEX_INSTRUCTIONS_ARB 0x8806 |
| PROGRAM_TEX_INDIRECTIONS_ARB 0x8807 |
| PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x8808 |
| PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x8809 |
| PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x880A |
| MAX_PROGRAM_ALU_INSTRUCTIONS_ARB 0x880B |
| MAX_PROGRAM_TEX_INSTRUCTIONS_ARB 0x880C |
| MAX_PROGRAM_TEX_INDIRECTIONS_ARB 0x880D |
| MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x880E |
| MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x880F |
| MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x8810 |
| |
| Accepted by the <pname> parameter of GetProgramStringARB: |
| |
| PROGRAM_STRING_ARB 0x8628 |
| |
| Accepted by the <pname> parameter of GetBooleanv, GetIntegerv, |
| GetFloatv, and GetDoublev: |
| |
| PROGRAM_ERROR_POSITION_ARB 0x864B |
| CURRENT_MATRIX_ARB 0x8641 |
| TRANSPOSE_CURRENT_MATRIX_ARB 0x88B7 |
| CURRENT_MATRIX_STACK_DEPTH_ARB 0x8640 |
| MAX_PROGRAM_MATRICES_ARB 0x862F |
| MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB 0x862E |
| |
| MAX_TEXTURE_COORDS_ARB 0x8871 |
| MAX_TEXTURE_IMAGE_UNITS_ARB 0x8872 |
| |
| Accepted by the <name> parameter of GetString: |
| |
| PROGRAM_ERROR_STRING_ARB 0x8874 |
| |
| Accepted by the <mode> parameter of MatrixMode: |
| |
| MATRIX0_ARB 0x88C0 |
| MATRIX1_ARB 0x88C1 |
| MATRIX2_ARB 0x88C2 |
| MATRIX3_ARB 0x88C3 |
| MATRIX4_ARB 0x88C4 |
| MATRIX5_ARB 0x88C5 |
| MATRIX6_ARB 0x88C6 |
| MATRIX7_ARB 0x88C7 |
| MATRIX8_ARB 0x88C8 |
| MATRIX9_ARB 0x88C9 |
| MATRIX10_ARB 0x88CA |
| MATRIX11_ARB 0x88CB |
| MATRIX12_ARB 0x88CC |
| MATRIX13_ARB 0x88CD |
| MATRIX14_ARB 0x88CE |
| MATRIX15_ARB 0x88CF |
| MATRIX16_ARB 0x88D0 |
| MATRIX17_ARB 0x88D1 |
| MATRIX18_ARB 0x88D2 |
| MATRIX19_ARB 0x88D3 |
| MATRIX20_ARB 0x88D4 |
| MATRIX21_ARB 0x88D5 |
| MATRIX22_ARB 0x88D6 |
| MATRIX23_ARB 0x88D7 |
| MATRIX24_ARB 0x88D8 |
| MATRIX25_ARB 0x88D9 |
| MATRIX26_ARB 0x88DA |
| MATRIX27_ARB 0x88DB |
| MATRIX28_ARB 0x88DC |
| MATRIX29_ARB 0x88DD |
| MATRIX30_ARB 0x88DE |
| MATRIX31_ARB 0x88DF |
| |
| |
| Additions to Chapter 2 of the OpenGL 1.3 Specification (OpenGL |
| Operation) |
| |
| Modify Section 2.1.1, Floating-Point Computation (p. 6) |
| |
| (modify first paragraph, p. 6) ... The maximum representable |
| magnitude of a floating-point number used to represent position, |
| normal, or texture coordinates must be at least 2^32; the maximum |
| representable magnitude for colors must be at least 2^10. ... |
| |
| |
| Modify Section 2.7, Vertex Specification (p. 19) |
| |
| (modify second paragraph, p. 20) Implementations support more than |
| one set of texture coordinates. The commands |
| |
| void MultiTexCoord{1234}{sifd}(enum texture, T coords); |
| void MultiTexCoord{1234}{sifd}v(enum texture, T coords); |
| |
| take the coordinate set to be modified as the <texture> parameter. |
| <texture> is a symbolic constant of the form TEXTUREi, indicating |
| that texture coordinate set i is to be modified. The constants obey |
| TEXTUREi = TEXTURE0 + i (i is in the range 0 to k-1, where k is the |
| implementation-dependent number of texture units defined by |
| MAX_TEXTURE_COORDS_ARB). |
| |
| |
| Modify Section 2.8, Vertex Arrays (p. 21) |
| |
| (modify first paragraph, p. 21) ... The client may specify up to 5 |
| plus the value of MAX_TEXTURE_COORDS_ARB arrays: one each to store |
| vertex coordinates... |
| |
| |
| (modify first paragraph, p. 23) The command |
| |
| void ClientActiveTexture(enum texture); |
| |
| is used to select the vertex array client state parameters to be |
| modified by the TexCoordPointer command and the array affected by |
| EnableClientState and DisableClientState with parameter |
| TEXTURE_COORD_ARRAY. This command sets the client state variable |
| CLIENT_ACTIVE_TEXTURE. Each texture coordinate set has a client |
| state vector which is selected when this command is invoked. This |
| state vector includes the vertex array state. This call also |
| selects the texture coordinate set state used for queries of client |
| state. |
| |
| |
| (modify first paragraph, p. 28) If the number of supported texture |
| coordinate sets (the value of MAX_TEXTURE_COORDS_ARB) is k, ... |
| |
| |
| Modify Section 2.10.2, Matrices (p. 31) |
| |
| (modify first paragraph, p. 31) The projection matrix and model-view |
| matrix are set and modified with a variety of commands. The |
| affected matrix is determined by the current matrix mode. The |
| current matrix mode is set with |
| |
| void MatrixMode(enum mode); |
| |
| which takes one of the pre-defined constants TEXTURE, MODELVIEW, |
| COLOR, PROJECTION, or MATRIX<i>_ARB as the argument. In the case of |
| MATRIX<i>_ARB, <i> is an integer between 0 and <n>-1 indicating one |
| of <n> program matrices where <n> is the value of the implementation |
| defined constant MAX_PROGRAM_MATRICES_ARB. Such program matrices |
| are described in section 3.11.7. TEXTURE is described later in |
| section 2.10.2, and COLOR is described in section 3.6.3. If the |
| current matrix mode is MODELVIEW, then matrix operations apply to |
| the model-view matrix; if PROJECTION, then they apply to the |
| projection matrix. |
| |
| |
| (modify first paragraph, p. 34) For each texture coordinate set, a |
| 4x4 matrix is applied to the corresponding texture coordinates... |
| |
| |
| (modify first and second paragraphs, p. 35) The command |
| |
| void ActiveTexture(enum texture); |
| |
| specifies the active texture unit selector, ACTIVE_TEXTURE. Each |
| texture unit contains up to two distinct sub-units: a texture |
| coordinate processing unit (consisting of a texture matrix stack and |
| texture coordinate generation state) and a texture image unit |
| (consisting of all the texture state defined in Section 3.8). In |
| implementations with a different number of supported texture |
| coordinate sets and texture image units, some texture units may |
| consist of only one of the two sub-units. |
| |
| The active texture unit selector specifies the texture coordinate |
| set accessed by commands involving texture coordinate processing. |
| Such commands include those accessing the current matrix stack (if |
| MATRIX_MODE is TEXTURE), TexGen (section 2.10.4), Enable/Disable (if |
| any texture coordinate generation enum is selected), as well as |
| queries of the current texture coordinates and current raster |
| texture coordinates. If the texture coordinate set number |
| corresponding to the current value of ACTIVE_TEXTURE is greater than |
| or equal to the implementation-dependent constant |
| MAX_TEXTURE_COORDS_ARB, the error INVALID_OPERATION is generated by |
| any such command. |
| |
| The active texture unit selector also selects the texture image unit |
| accessed by commands involving texture image processing (section |
| 3.8). Such commands include all variants of TexEnv, TexParameter, |
| and TexImage commands, BindTexture, Enable/Disable for any texture |
| target (e.g., TEXTURE_2D), and queries of all such state. If the |
| texture image unit number corresponding to the current value of |
| ACTIVE_TEXTURE is greater than or equal to the implementation- |
| dependent constant MAX_TEXTURE_IMAGE_UNITS_ARB, the error |
| INVALID_OPERATION is generated by any such command. |
| |
| ActiveTexture generates the error INVALID_ENUM if an invalid |
| <texture> is specified. <texture> is a symbolic constant of the |
| form TEXTUREi, indicating that texture unit i is to be modified. |
| The constants obey TEXTUREi = TEXTURE0 + i (i is in the range 0 to |
| k-1, where k is the larger of the MAX_TEXTURE_COORDS_ARB and |
| MAX_TEXTURE_IMAGE_UNITS_ARB). For compatibility with old OpenGL |
| specifications, the implementation-dependent constant |
| MAX_TEXTURE_UNITS specifies the number of conventional texture units |
| supported by the implementation. Its value must be no larger than |
| the minimum of MAX_TEXTURE_COORDS_ARB and |
| MAX_TEXTURE_IMAGE_UNITS_ARB. |
| |
| |
| (modify last paragraph, p. 35) The state required to implement |
| transformations consists of a <n>-value integer indicating the |
| current matrix mode (where <n> is 4 + the number of supported |
| texture and program matrices), a stack of at least two 4x4 matrices |
| for each of COLOR, PROJECTION, and TEXTURE with associated stack |
| pointers, <n> stacks (where <n> is at least 8) of at least one 4x4 |
| matrix for each MATRIX<i>_ARB with associated stack pointers, and a |
| stack of at least 32 4x4 matrices with an associated stack pointer |
| for MODELVIEW. Initially, there is only one matrix on each stack, |
| and all matrices are set to the identity. The initial matrix mode |
| is MODELVIEW. The initial value of ACTIVE_TEXTURE is TEXTURE0. |
| |
| |
| Additions to Chapter 3 of the OpenGL 1.3 Specification (Rasterization) |
| |
| Modify Chapter 3, Introduction (p. 58) |
| |
| (modify first paragraph, p. 58) ... Figure 3.1 diagrams the |
| rasterization process. The color value assigned to a fragment is |
| initially determined by the rasterization operations (sections 3.3 |
| through 3.7) and modified by either the execution of the texturing, |
| color sum, and fog operations as defined in sections 3.8, 3.9, and |
| 3.10, or of a fragment program defined in section 3.11. The final |
| depth value is initially determined by the rasterization operations |
| and may be modified or replaced by a fragment program. |
| |
| (modify Figure 3.1) |
| |
| _ +---------------+ FRAGMENT_PROGRAM_ARB |
| /|| Point | enable |
| / | Rasterization |\ | |
| / +---------------+ \ V o-------------+ |
| From / +---------------+ \ | |
| Primitive ---> | Line |---+++--->o o | |
| Assembly \ | Rasterization | / || | | |
| \ +---------------+ / || | | |
| \ +---------------+/ || +-----+-----+ +----+-----+ |
| \|| Polygon | || | Texturing | | Fragment | |
| - | Rasterization | / | +-----+-----+ | Program | |
| +---------------+ / | | +----+-----+ |
| +---------------+ / | +-----+-----+ | |
| | Pixel |/ | | Color Sum | | |
| DrawPixels --> | Rectangle | / +-----+-----+ | |
| | Rasterization | / | V |
| +---------------+ / +-----+-----+ |
| +---------------+ / | Fog |---> Fragments |
| Bitmap ----> | Bitmap |/ +-----------+ |
| | Rasterization | |
| +---------------+ |
| |
| |
| Modify Section 3.3, Points (p. 63) |
| |
| (modify first and second paragraphs, p. 64) All fragments produced |
| in rasterizing a non-antialiased point are assigned the same |
| associated data, which are those of the vertex corresponding to the |
| point. (delete reference to divide by q) |
| |
| If antialiasing is enabled, then ... The data associated with each |
| fragment are otherwise the data associated with the point being |
| rasterized. (delete reference to divide by q) |
| |
| |
| Modify Section 3.4.1, Basic Line Segment Rasterization (p. 66) |
| |
| (modify first paragraph, p. 68) ... (Note that t=0 at p_a and t=1 at |
| p_b). The value of an associated datum f from the fragment center, |
| whether it be R, G, B, or A (in RGBA mode) or a color index (in |
| color index mode) or the s, t, r, or q texture coordinate or the |
| clip w coordinate (the depth value, window z, must be found using |
| equation 3.3, below), is found as |
| |
| f = (1-t)*(f_a/w_a) + t*(f_b/w_b) (3.2) |
| ----------------------------- |
| (1-t)*(1/w_a) + t*(1/w_b) |
| |
| where f_a and f_b are the data associated with the starting and |
| ending endpoints of the segment, respectively; w_a and w_b are the |
| clip w coordinates of the starting and ending endpoints of the |
| segments, respectively. Note that linear interpolation would use |
| |
| f = (1-t)*f_a + t*f_b. (3.3) |
| |
| ... A GL implementation may choose to approximate equation 3.2 with |
| 3.3, but this will normally lead to inacceptable distortion effects |
| when interpolating texture coordinates or clip w coordinates. |
| |
| |
| Modify Section 3.5.1, Basic Polygon Rasterization (p. 73) |
| |
| (modify third and fourth paragraphs, p. 74) Denote a datum at p_a, |
| p_b, or p_c as f_a, f_b, or f_c, respectively. Then the value f of |
| a datum at a fragment produced by rasterizing a triangle is given by |
| |
| f = a*(f_a/w_a) + b*(f_b/w_b) + c*(f_c/w_c) (3.4) |
| --------------------------------------- |
| a*(1/w_a) + b*(1/w_b) + c*(1/w_c) |
| |
| where w_a, w_b, and w_c are the clip w coordinates of p_a, p_b, and |
| p_c, respectively. a, b, and c are the barycentric coordinates of |
| the fragment for which the data are produced. a, b, and c must |
| correspond precisely to the ... at the fragment's center. |
| |
| Just as with line segment rasterization, equation 3.4 may be |
| approximated by |
| |
| f = a*f_a + b*f_b + c*f_c; |
| |
| this may yield ... for texture coordinates or clip w coordinates. |
| |
| |
| Modify Section 3.6.4, Rasterization of Pixel Rectangles (p. 91) |
| |
| (modify third paragraph, p. 103) A fragment arising from a group ... |
| the color and texture coordinates are given by those associated with |
| the current raster position. (delete reference to divide by q) |
| Groups arising from DrawPixels... |
| |
| |
| Modify Section 3.7, Bitmaps (p. 113) |
| |
| (modify third paragraph, p. 114) Otherwise, a rectangular array ... |
| The associated data for each fragment are those associated with the |
| current raster position. (delete reference to divide by q) Once |
| the fragments have been produced ... |
| |
| |
| Modify Section 3.8, Texturing (p. 115) |
| |
| (add new paragraphs before first paragraph, p. 115) Texture |
| coordinate sets are mapped to RGBA colors for application to |
| primitives in one of two modes. The first mode, described in this |
| and subsequent sections, is GL's conventional multitexture pipeline, |
| describing texture environment and texture application. The second |
| mode, referred to as fragment program mode and described in section |
| 3.11, applies textures, color sum, and fog as specified in an |
| application-supplied fragment program. |
| |
| The fragment program mode is enabled and disabled using the generic |
| Enable and Disable commands, respectively, with the symbolic |
| constant FRAGMENT_PROGRAM_ARB. The required state is one bit |
| indicating whether the fragment program mode is enabled or disabled. |
| In the initial state, the fragment program mode is disabled. When |
| fragment program mode is enabled, texturing, color sum, and fog |
| application stages are ignored and a general purpose program is |
| executed instead. |
| |
| (modify first and second paragraph, p. 115) Conventional texturing |
| is employed when fragment program mode is disabled. Texturing maps |
| ... color of an image at the location indicated by a fragment's |
| texture coordinates to modify the fragment's primary RGBA color. |
| Texturing does not affect the secondary color. |
| |
| An implementation may support texturing using more than one image at |
| a time. In this case the fragment carries multiple sets of texture |
| coordinates which are used to index ... |
| |
| (add paragraph before 1st paragraph, p. 116) Except when in fragment |
| program mode (section 3.11), the (s,t,r) texture coordinates used |
| for texturing are the values s/q, t/q, and r/q, respectively, where |
| s, t, r, and q are the texture coordinates associated with the |
| fragment. When in fragment program mode, the (s,t,r) texture |
| coordinates are specified by the program. If q is less than or |
| equal to zero, the results of texturing are undefined. |
| |
| |
| Modify Section 3.8.7, Texture Minification (p. 135) |
| |
| (add new paragraph after first paragraph, p. 137) When fragment |
| program mode is enabled, the derivatives of the coordinates may be |
| ill-defined or non-existent. As a result, the implementation is |
| free to approximate these derivatives with such techniques as |
| differencing. The only requirement is that texture samples be |
| equivalent across the two modes. In other words, the texture sample |
| chosen for a fragment of a primitive must be invariant between |
| fragment program mode and conventional mode subject to the rules |
| set forth in Appendix A, Invariance. |
| |
| |
| Modify Section 3.8.13, Texture Application (p. 149) |
| |
| (modify fourth paragraph, p. 152) Texturing is enabled and disabled |
| individually for each texture unit. If texturing is disabled for |
| one of the units, then the fragment resulting from the previous unit |
| is passed unaltered to the following unit. Individual texture units |
| beyond those specified by MAX_TEXTURE_UNITS may be incomplete and |
| are always treated as disabled. |
| |
| |
| Insert a new Section 3.11, (p. 154), between existing sections 3.10 |
| and 3.11. Renumber 3.11, Antialiasing Application, to 3.12. |
| |
| 3.11 Fragment Programs |
| |
| The conventional GL texturing model described in section 3.8 is a |
| configurable but essentially hard-wired sequence of per-fragment |
| computations based on a canonical set of per-fragment parameters |
| and texturing-related state such as texture images, texture |
| parameters, and texture environment parameters. The general success |
| and utility of the conventional GL texturing model reflects its |
| basic correspondence to the typical texturing requirements of 3D |
| applications. |
| |
| However when the conventional GL texturing model is not sufficient, |
| the fragment program mode provides a substantially more flexible |
| model for generating fragment colors. The fragment program mode |
| permits applications to define their own fragment programs. |
| |
| A fragment program is a character string that specifies a sequence |
| of operations to perform. Fragment program instructions are |
| typically 4-component vector operations that operate on per-fragment |
| attributes and program parameters. Fragment programs execute on a |
| per-fragment basis and operate on each fragment completely |
| independently from any other fragments. Fragment programs execute a |
| finite fixed sequence of instructions with no branching or looping. |
| Fragment programs execute without data hazards so results computed |
| in one instruction can be used immediately afterwards. The result |
| of a fragment program is a set of fragment result registers that |
| becomes the color used by antialiasing application and/or a depth |
| value used in place of the interpolated depth value generated by |
| conventional rasterization. |
| |
| In fragment program mode, the color sum is subsumed by the fragment |
| program. An application desiring the primary and secondary colors |
| to be summed must explicitly include this operation in its program. |
| |
| Fragment programs are defined to operate only in RGBA mode. The |
| results of fragment program execution are undefined if the GL is in |
| color index mode. |
| |
| |
| 3.11.1 Program Objects |
| |
| The GL provides one or more program targets, each identifying a |
| portion of the GL that can be controlled through application- |
| specified programs. The program target for fragment programs is |
| FRAGMENT_PROGRAM_ARB. Each program target has an associated program |
| object, called the current program object. Each program target also |
| has a default program object, which is initially the current program |
| object. |
| |
| Each program object has an associated program string. The command |
| |
| ProgramStringARB(enum target, enum format, sizei len, |
| const void *string); |
| |
| updates the program string for the current program object for |
| <target>. <format> describes the format of the program string, |
| which must currently be PROGRAM_FORMAT_ASCII_ARB. <string> is a |
| pointer to the array of bytes representing the program string being |
| loaded, which need not be null-terminated. The length of the array |
| is given by <len>. If <string> is null-terminated, <len> should not |
| include the terminator. |
| |
| When a program string is loaded, it is interpreted according to |
| syntactic and semantic rules corresponding to the program target |
| specified by <target>. If a program violates the syntactic or |
| semantic restrictions of the program target, ProgramStringARB |
| generates the error INVALID_OPERATION. An implementation may also |
| generate the error INVALID_OPERATION if the program would exceed |
| the native resource limits defined in section 6.1.12. A program |
| which fails to load due to exceeding native resource limits must |
| always fail, regardless of any other GL state. |
| |
| Additionally, ProgramString will update the program error position |
| (PROGRAM_ERROR_POSITION_ARB) and error string |
| (PROGRAM_ERROR_STRING_ARB). If a program fails to load, the value |
| of the program error position is set to the ubyte offset into the |
| specified program string indicating where the first program error |
| was detected. If the program fails to load because of a semantic |
| restriction that is not detected until the program is fully |
| scanned, the error position is set to the value of <len>. If a |
| program loads successfully, the error position is set to the value |
| negative one. The implementation-dependent program error string |
| contains one or more error or warning messages. If a program loads |
| succesfully, the error string may either contain warning messages or |
| be empty. |
| |
| Each program object has an associated array of program local |
| parameters. The number and type of program local parameters is |
| target- and implementation-dependent. For fragment programs, |
| program local parameters are four-component floating-point vectors. |
| The number of vectors is given by the implementation-dependent |
| constant MAX_PROGRAM_LOCAL_PARAMETERS_ARB, which must be at least |
| 24. The commands |
| |
| void ProgramLocalParameter4fARB(enum target, uint index, |
| float x, float y, float z, float w); |
| void ProgramLocalParameter4fvARB(enum target, uint index, |
| const float *params); |
| void ProgramLocalParameter4dARB(enum target, uint index, |
| double x, double y, double z, double w); |
| void ProgramLocalParameter4dvARB(enum target, uint index, |
| const double *params); |
| |
| update the values of the program local parameter numbered <index> |
| belonging to the program object currently bound to <target>. For |
| ProgramLocalParameter4fARB and ProgramLocalParameter4dARB, the four |
| components of the parameter are updated with the values of <x>, <y>, |
| <z>, and <w>, respectively. For ProgramLocalParameter4fvARB and |
| ProgramLocalParameter4dvARB, the four components of the parameter |
| are updated with the array of four values pointed to by <params>. |
| The error INVALID_VALUE is generated if <index> is greater than or |
| equal to the number of program local parameters supported by |
| <target>. |
| |
| Additionally, each program target has an associated array of program |
| environment parameters. Unlike program local parameters, program |
| environment parameters are shared by all program objects of a given |
| target. The number and type of program environment parameters is |
| target- and implementation-dependent. For fragment programs, |
| program environment parameters are four-component floating-point |
| vectors. The number of vectors is given by the implementation- |
| dependent constant MAX_PROGRAM_ENV_PARAMETERS_ARB, which must be at |
| least 24. The commands |
| |
| void ProgramEnvParameter4fARB(enum target, uint index, |
| float x, float y, float z, float w); |
| void ProgramEnvParameter4fvARB(enum target, uint index, |
| const float *params); |
| void ProgramEnvParameter4dARB(enum target, uint index, |
| double x, double y, double z, double w); |
| void ProgramEnvParameter4dvARB(enum target, uint index, |
| const double *params); |
| |
| update the values of the program environment parameter numbered |
| <index> for the given program target <target>. For |
| ProgramEnvParameter4fARB and ProgramEnvParameter4dARB, the four |
| components of the parameter are updated with the values of <x>, <y>, |
| <z>, and <w>, respectively. For ProgramEnvParameter4fvARB and |
| ProgramEnvParameter4dvARB, the four components of the parameter are |
| updated with the array of four values pointed to by <params>. The |
| error INVALID_VALUE is generated if <index> is greater than or equal |
| to the number of program environment parameters supported by |
| <target>. |
| |
| Each program target has a default program object. Additionally, |
| named program objects can be created and operated upon. The name |
| space for program objects is the positive integers and is shared by |
| programs of all targets. The name zero is reserved by the GL. |
| |
| A named program object is created by binding an unused program |
| object name to a valid program target. The binding is effected by |
| calling |
| |
| BindProgramARB(enum target, uint program); |
| |
| with <target> set to the desired program target and <program> set to |
| the unused program name. The resulting program object has a program |
| target given by <target> and is assigned target-specific default |
| values (see section 3.11.8 for fragment programs). BindProgramARB |
| may also be used to bind an existing program object to a program |
| target. If <program> is zero, the default program object for |
| <target> is bound. If <program> is the name of an existing program |
| object whose associated program target is <target>, the named |
| program object is bound. The error INVALID_OPERATION is generated |
| if <program> names an existing program object whose associated |
| program target is anything other than <target>. |
| |
| Programs objects are deleted by calling |
| |
| void DeleteProgramsARB(sizei n, const uint *programs); |
| |
| <programs> contains <n> names of programs to be deleted. After a |
| program object is deleted, its name is again unused. If a program |
| object that is bound to any target is deleted, it is as though |
| BindProgramARB is first executed with same target and a <program> of |
| zero. Unused names in <programs> are silently ignored, as is the |
| value zero. |
| |
| The command |
| |
| void GenProgramsARB(sizei n, uint *programs); |
| |
| returns <n> currently unused program names in <programs>. These |
| names are marked as used, for the purposes of GenProgramsARB only, |
| but objects are created only when they are first bound using |
| BindProgramARB. |
| |
| |
| 3.11.2 Fragment Program Grammar and Semantic Restrictions |
| |
| Fragment program strings are specified as an array of ASCII |
| characters containing the program text. When a fragment program is |
| loaded by a call to ProgramStringARB, the program string is parsed |
| into a set of tokens possibly separated by whitespace. Spaces, |
| tabs, newlines, carriage returns, and comments are considered |
| whitespace. Comments begin with the character "#" and are |
| terminated by a newline, a carriage return, or the end of the |
| program array. |
| |
| The Backus-Naur Form (BNF) grammar below specifies the syntactically |
| valid sequences for fragment programs. The set of valid tokens can |
| be inferred from the grammar. The token "" represents an empty |
| string and is used to indicate optional rules. A program is invalid |
| if it contains any undefined tokens or characters. |
| |
| A fragment program is required to begin with the header string |
| "!!ARBfp1.0", without any preceding whitespace. This string |
| identifies the subsequent program text as a fragment program |
| (version 1.0) that should be parsed according to the following |
| grammar and semantic rules. Program string parsing begins with the |
| character immediately following the header string. |
| |
| <program> ::= <optionSequence> <statementSequence> "END" |
| |
| <optionSequence> ::= <optionSequence> <option> |
| | "" |
| |
| <option> ::= "OPTION" <identifier> ";" |
| |
| <statementSequence> ::= <statementSequence> <statement> |
| | "" |
| |
| <statement> ::= <instruction> ";" |
| | <namingStatement> ";" |
| |
| <instruction> ::= <ALUInstruction> |
| | <TexInstruction> |
| |
| <ALUInstruction> ::= <VECTORop_instruction> |
| | <SCALARop_instruction> |
| | <BINSCop_instruction> |
| | <BINop_instruction> |
| | <TRIop_instruction> |
| | <SWZ_instruction> |
| |
| <TexInstruction> ::= <SAMPLE_instruction> |
| | <KIL_instruction> |
| |
| <VECTORop_instruction> ::= <VECTORop> <maskedDstReg> "," |
| <vectorSrcReg> |
| |
| <VECTORop> ::= "ABS" | "ABS_SAT" |
| | "FLR" | "FLR_SAT" |
| | "FRC" | "FRC_SAT" |
| | "LIT" | "LIT_SAT" |
| | "MOV" | "MOV_SAT" |
| |
| <SCALARop_instruction> ::= <SCALARop> <maskedDstReg> "," |
| <scalarSrcReg> |
| |
| <SCALARop> ::= "COS" | "COS_SAT" |
| | "EX2" | "EX2_SAT" |
| | "LG2" | "LG2_SAT" |
| | "RCP" | "RCP_SAT" |
| | "RSQ" | "RSQ_SAT" |
| | "SIN" | "SIN_SAT" |
| | "SCS" | "SCS_SAT" |
| |
| <BINSCop_instruction> ::= <BINSCop> <maskedDstReg> "," |
| <scalarSrcReg> "," <scalarSrcReg> |
| |
| <BINSCop> ::= "POW" | "POW_SAT" |
| |
| <BINop_instruction> ::= <BINop> <maskedDstReg> "," |
| <vectorSrcReg> "," <vectorSrcReg> |
| |
| <BINop> ::= "ADD" | "ADD_SAT" |
| | "DP3" | "DP3_SAT" |
| | "DP4" | "DP4_SAT" |
| | "DPH" | "DPH_SAT" |
| | "DST" | "DST_SAT" |
| | "MAX" | "MAX_SAT" |
| | "MIN" | "MIN_SAT" |
| | "MUL" | "MUL_SAT" |
| | "SGE" | "SGE_SAT" |
| | "SLT" | "SLT_SAT" |
| | "SUB" | "SUB_SAT" |
| | "XPD" | "XPD_SAT" |
| |
| <TRIop_instruction> ::= <TRIop> <maskedDstReg> "," |
| <vectorSrcReg> "," <vectorSrcReg> "," |
| <vectorSrcReg> |
| |
| <TRIop> ::= "CMP" | "CMP_SAT" |
| | "LRP" | "LRP_SAT" |
| | "MAD" | "MAD_SAT" |
| |
| <SWZ_instruction> ::= <SWZop> <maskedDstReg> "," |
| <srcReg> "," <extendedSwizzle> |
| |
| <SWZop> ::= "SWZ" | "SWZ_SAT" |
| |
| <SAMPLE_instruction> ::= <SAMPLEop> <maskedDstReg> "," |
| <vectorSrcReg> "," <texImageUnit> "," |
| <texTarget> |
| |
| <SAMPLEop> ::= "TEX" | "TEX_SAT" |
| | "TXP" | "TXP_SAT" |
| | "TXB" | "TXB_SAT" |
| |
| <KIL_instruction> ::= "KIL" <vectorSrcReg> |
| |
| <texImageUnit> ::= "texture" <optTexImageUnitNum> |
| |
| <texTarget> ::= "1D" |
| | "2D" |
| | "3D" |
| | "CUBE" |
| | "RECT" |
| |
| <optTexImageUnitNum> ::= "" |
| | "[" <texImageUnitNum> "]" |
| |
| <texImageUnitNum> ::= <integer> from 0 to |
| MAX_TEXTURE_IMAGE_UNITS_ARB-1 |
| |
| <scalarSrcReg> ::= <optionalSign> <srcReg> <scalarSuffix> |
| |
| <vectorSrcReg> ::= <optionalSign> <srcReg> <optionalSuffix> |
| |
| <maskedDstReg> ::= <dstReg> <optionalMask> |
| |
| <extendedSwizzle> ::= <xyzwExtendedSwizzle> |
| | <rgbaExtendedSwizzle> |
| |
| <xyzwExtendedSwizzle> ::= <xyzwExtSwizComp> "," <xyzwExtSwizComp> "," |
| <xyzwExtSwizComp> "," <xyzwExtSwizComp> |
| |
| <rgbaExtendedSwizzle> ::= <rgbaExtSwizComp> "," <rgbaExtSwizComp> "," |
| <rgbaExtSwizComp> "," <rgbaExtSwizComp> |
| |
| <xyzwExtSwizComp> ::= <optionalSign> <xyzwExtSwizSel> |
| |
| <rgbaExtSwizComp> ::= <optionalSign> <rgbaExtSwizSel> |
| |
| <xyzwExtSwizSel> ::= "0" |
| | "1" |
| | <xyzwComponent> |
| |
| <rgbaExtSwizSel> ::= "0" |
| | "1" |
| | <rgbaComponent> |
| |
| <srcReg> ::= <fragmentAttribReg> |
| | <temporaryReg> |
| | <progParamReg> |
| |
| <dstReg> ::= <temporaryReg> |
| | <fragmentResultReg> |
| |
| <fragmentAttribReg> ::= <establishedName> |
| | <fragAttribBinding> |
| |
| <temporaryReg> ::= <establishedName> |
| |
| <progParamReg> ::= <progParamSingle> |
| | <progParamArray> "[" <progParamArrayAbs> "]" |
| | <paramSingleItemUse> |
| |
| <progParamSingle> ::= <establishedName> |
| |
| <progParamArray> ::= <establishedName> |
| |
| <progParamArrayAbs> ::= <integer> |
| |
| <fragmentResultReg> ::= <establishedName> |
| | <resultBinding> |
| |
| <scalarSuffix> ::= "." <component> |
| |
| <optionalSuffix> ::= "" |
| | "." <component> |
| | "." <xyzwComponent> <xyzwComponent> |
| <xyzwComponent> <xyzwComponent> |
| | "." <rgbaComponent> <rgbaComponent> |
| <rgbaComponent> <rgbaComponent> |
| |
| <component> ::= <xyzwComponent> |
| | <rgbaComponent> |
| |
| <xyzwComponent> ::= "x" | "y" | "z" | "w" |
| |
| <rgbaComponent> ::= "r" | "g" | "b" | "a" |
| |
| <optionalMask> ::= "" |
| | <xyzwMask> |
| | <rgbaMask> |
| |
| <xyzwMask> ::= "." "x" |
| | "." "y" |
| | "." "xy" |
| | "." "z" |
| | "." "xz" |
| | "." "yz" |
| | "." "xyz" |
| | "." "w" |
| | "." "xw" |
| | "." "yw" |
| | "." "xyw" |
| | "." "zw" |
| | "." "xzw" |
| | "." "yzw" |
| | "." "xyzw" |
| |
| <rgbaMask> ::= "." "r" |
| | "." "g" |
| | "." "rg" |
| | "." "b" |
| | "." "rb" |
| | "." "gb" |
| | "." "rgb" |
| | "." "a" |
| | "." "ra" |
| | "." "ga" |
| | "." "rga" |
| | "." "ba" |
| | "." "rba" |
| | "." "gba" |
| | "." "rgba" |
| |
| <namingStatement> ::= <ATTRIB_statement> |
| | <PARAM_statement> |
| | <TEMP_statement> |
| | <OUTPUT_statement> |
| | <ALIAS_statement> |
| |
| <ATTRIB_statement> ::= "ATTRIB" <establishName> "=" |
| <fragAttribBinding> |
| |
| <fragAttribBinding> ::= "fragment" "." <fragAttribItem> |
| |
| <fragAttribItem> ::= "color" <optColorType> |
| | "texcoord" <optTexCoordNum> |
| | "fogcoord" |
| | "position" |
| |
| <PARAM_statement> ::= <PARAM_singleStmt> |
| | <PARAM_multipleStmt> |
| |
| <PARAM_singleStmt> ::= "PARAM" <establishName> <paramSingleInit> |
| |
| <PARAM_multipleStmt> ::= "PARAM" <establishName> "[" <optArraySize> "]" |
| <paramMultipleInit> |
| |
| <optArraySize> ::= "" |
| | <integer> from 1 to MAX_PROGRAM_PARAMETERS_ARB |
| (maximum number of allowed program |
| parameter bindings) |
| |
| <paramSingleInit> ::= "=" <paramSingleItemDecl> |
| |
| <paramMultipleInit> ::= "=" "{" <paramMultInitList> "}" |
| |
| <paramMultInitList> ::= <paramMultipleItem> |
| | <paramMultipleItem> "," <paramMultInitList> |
| |
| <paramSingleItemDecl> ::= <stateSingleItem> |
| | <programSingleItem> |
| | <paramConstDecl> |
| |
| <paramSingleItemUse> ::= <stateSingleItem> |
| | <programSingleItem> |
| | <paramConstUse> |
| |
| <paramMultipleItem> ::= <stateMultipleItem> |
| | <programMultipleItem> |
| | <paramConstDecl> |
| |
| <stateMultipleItem> ::= <stateSingleItem> |
| | "state" "." <stateMatrixRows> |
| |
| <stateSingleItem> ::= "state" "." <stateMaterialItem> |
| | "state" "." <stateLightItem> |
| | "state" "." <stateLightModelItem> |
| | "state" "." <stateLightProdItem> |
| | "state" "." <stateTexEnvItem> |
| | "state" "." <stateFogItem> |
| | "state" "." <stateDepthItem> |
| | "state" "." <stateMatrixRow> |
| |
| <stateMaterialItem> ::= "material" <optFaceType> "." <stateMatProperty> |
| |
| <stateMatProperty> ::= "ambient" |
| | "diffuse" |
| | "specular" |
| | "emission" |
| | "shininess" |
| |
| <stateLightItem> ::= "light" "[" <stateLightNumber> "]" "." |
| <stateLightProperty> |
| |
| <stateLightProperty> ::= "ambient" |
| | "diffuse" |
| | "specular" |
| | "position" |
| | "attenuation" |
| | "spot" "." <stateSpotProperty> |
| | "half" |
| |
| <stateSpotProperty> ::= "direction" |
| |
| <stateLightModelItem> ::= "lightmodel" <stateLModProperty> |
| |
| <stateLModProperty> ::= "." "ambient" |
| | <optFaceType> "." "scenecolor" |
| |
| <stateLightProdItem> ::= "lightprod" "[" <stateLightNumber> "]" |
| <optFaceType> "." <stateLProdProperty> |
| |
| <stateLProdProperty> ::= "ambient" |
| | "diffuse" |
| | "specular" |
| |
| <stateLightNumber> ::= <integer> from 0 to MAX_LIGHTS-1 |
| |
| <stateTexEnvItem> ::= "texenv" <optLegacyTexUnitNum> "." |
| <stateTexEnvProperty> |
| |
| <stateTexEnvProperty> ::= "color" |
| |
| <optLegacyTexUnitNum> ::= "" |
| | "[" <legacyTexUnitNum> "]" |
| |
| <legacyTexUnitNum> ::= <integer> from 0 to MAX_TEXTURE_UNITS-1 |
| |
| <stateFogItem> ::= "fog" "." <stateFogProperty> |
| |
| <stateFogProperty> ::= "color" |
| | "params" |
| |
| <stateDepthItem> ::= "depth" "." <stateDepthProperty> |
| |
| <stateDepthProperty> ::= "range" |
| |
| <stateMatrixRow> ::= <stateMatrixItem> "." "row" "[" |
| <stateMatrixRowNum> "]" |
| |
| <stateMatrixRows> ::= <stateMatrixItem> <optMatrixRows> |
| |
| <optMatrixRows> ::= "" |
| | "." "row" "[" <stateMatrixRowNum> ".." |
| <stateMatrixRowNum> "]" |
| |
| <stateMatrixItem> ::= "matrix" "." <stateMatrixName> |
| <stateOptMatModifier> |
| |
| <stateOptMatModifier> ::= "" |
| | "." <stateMatModifier> |
| |
| <stateMatModifier> ::= "inverse" |
| | "transpose" |
| | "invtrans" |
| |
| <stateMatrixRowNum> ::= <integer> from 0 to 3 |
| |
| <stateMatrixName> ::= "modelview" <stateOptModMatNum> |
| | "projection" |
| | "mvp" |
| | "texture" <optTexCoordNum> |
| | "palette" "[" <statePaletteMatNum> "]" |
| | "program" "[" <stateProgramMatNum> "]" |
| |
| <stateOptModMatNum> ::= "" |
| | "[" <stateModMatNum> "]" |
| |
| <stateModMatNum> ::= <integer> from 0 to MAX_VERTEX_UNITS_ARB-1 |
| |
| <optTexCoordNum> ::= "" |
| | "[" <texCoordNum> "]" |
| |
| <texCoordNum> ::= <integer> from 0 to MAX_TEXTURE_COORDS_ARB-1 |
| |
| <statePaletteMatNum> ::= <integer> from 0 to MAX_PALETTE_MATRICES_ARB-1 |
| |
| <stateProgramMatNum> ::= <integer> from 0 to MAX_PROGRAM_MATRICES_ARB-1 |
| |
| <programSingleItem> ::= <progEnvParam> |
| | <progLocalParam> |
| |
| <programMultipleItem> ::= <progEnvParams> |
| | <progLocalParams> |
| |
| <progEnvParams> ::= "program" "." "env" |
| "[" <progEnvParamNums> "]" |
| |
| <progEnvParamNums> ::= <progEnvParamNum> |
| | <progEnvParamNum> ".." <progEnvParamNum> |
| |
| <progEnvParam> ::= "program" "." "env" |
| "[" <progEnvParamNum> "]" |
| |
| <progLocalParams> ::= "program" "." "local" |
| "[" <progLocalParamNums> "]" |
| |
| <progLocalParamNums> ::= <progLocalParamNum> |
| | <progLocalParamNum> ".." <progLocalParamNum> |
| |
| <progLocalParam> ::= "program" "." "local" |
| "[" <progLocalParamNum> "]" |
| |
| <progEnvParamNum> ::= <integer> from 0 to |
| MAX_PROGRAM_ENV_PARAMETERS_ARB - 1 |
| |
| <progLocalParamNum> ::= <integer> from 0 to |
| MAX_PROGRAM_LOCAL_PARAMETERS_ARB - 1 |
| |
| <paramConstDecl> ::= <paramConstScalarDecl> |
| | <paramConstVector> |
| |
| <paramConstUse> ::= <paramConstScalarUse> |
| | <paramConstVector> |
| |
| <paramConstScalarDecl> ::= <signedFloatConstant> |
| |
| <paramConstScalarUse> ::= <floatConstant> |
| |
| <paramConstVector> ::= "{" <signedFloatConstant> "}" |
| | "{" <signedFloatConstant> "," |
| <signedFloatConstant> "}" |
| | "{" <signedFloatConstant> "," |
| <signedFloatConstant> "," |
| <signedFloatConstant> "}" |
| | "{" <signedFloatConstant> "," |
| <signedFloatConstant> "," |
| <signedFloatConstant> "," |
| <signedFloatConstant> "}" |
| |
| <signedFloatConstant> ::= <optionalSign> <floatConstant> |
| |
| <floatConstant> ::= see text |
| |
| <optionalSign> ::= "" |
| | "-" |
| | "+" |
| |
| <TEMP_statement> ::= "TEMP" <varNameList> |
| |
| <varNameList> ::= <establishName> |
| | <establishName> "," <varNameList> |
| |
| <OUTPUT_statement> ::= "OUTPUT" <establishName> "=" |
| <resultBinding> |
| |
| <resultBinding> ::= "result" "." "color" |
| | "result" "." "depth" |
| |
| <optFaceType> ::= "" |
| | "." "front" |
| | "." "back" |
| |
| <optColorType> ::= "" |
| | "." "primary" |
| | "." "secondary" |
| |
| <ALIAS_statement> ::= "ALIAS" <establishName> "=" |
| <establishedName> |
| |
| <establishName> ::= <identifier> |
| |
| <establishedName> ::= <identifier> |
| |
| <identifier> ::= see text |
| |
| The <integer> rule matches an integer constant. The integer |
| consists of a sequence of one or more digits ("0" through "9"). |
| |
| The <floatConstant> rule matches a floating-point constant |
| consisting of an integer part, a decimal point, a fraction part, an |
| "e" or "E", and an optionally signed integer exponent. The integer |
| and fraction parts both consist of a sequence of one or more digits |
| ("0" through "9"). Either the integer part or the fraction parts |
| (not both) may be missing; either the decimal point or the "e" (or |
| "E") and the exponent (not both) may be missing. |
| |
| The <identifier> rule matches a sequence of one or more letters ("A" |
| through "Z", "a" through "z"), digits ("0" through "9), underscores |
| ("_"), or dollar signs ("$"); the first character must not be a |
| number. Upper and lower case letters are considered different |
| (names are case-sensitive). The following strings are reserved |
| keywords and may not be used as identifiers: |
| |
| ABS, ABS_SAT, ADD, ADD_SAT, ALIAS, ATTRIB, CMP, CMP_SAT, COS, |
| COS_SAT, DP3, DP3_SAT, DP4, DP4_SAT, DPH, DPH_SAT, DST, DST_SAT, |
| END, EX2, EX2_SAT, FLR, FLR_SAT, FRC, FRC_SAT, KIL, LG2, |
| LG2_SAT, LIT, LIT_SAT, LRP, LRP_SAT, MAD, MAD_SAT, MAX, MAX_SAT, |
| MIN, MIN_SAT, MOV, MOV_SAT, MUL, MUL_SAT, OPTION, OUTPUT, PARAM, |
| POW, POW_SAT, RCP, RCP_SAT, RSQ, RSQ_SAT, SIN, SIN_SAT, SCS, |
| SCS_SAT, SGE, SGE_SAT, SLT, SLT_SAT, SUB, SUB_SAT, SWZ, SWZ_SAT, |
| TEMP, TEX, TEX_SAT, TXB, TXB_SAT, TXP, TXP_SAT, XPD, XPD_SAT, |
| fragment, program, result, state, and texture. |
| |
| The error INVALID_OPERATION is generated if a fragment program fails |
| to load because it is not syntactically correct or for one of the |
| semantic restrictions described in the following sections. |
| |
| A successfully loaded fragment program is parsed into a sequence of |
| instructions. Each instruction is identified by its tokenized name. |
| The operation of these instructions when executed is defined in |
| section 3.11.5. |
| |
| A successfully loaded program string replaces the program string |
| previously loaded into the specified program object. If the |
| OUT_OF_MEMORY error is generated by ProgramStringARB, no change is |
| made to the previous contents of the current program object. |
| |
| |
| 3.11.3 Fragment Program Variables |
| |
| Fragment programs may access a number of different variables during |
| their execution. The following sections define the variables that |
| can be declared and used by a fragment program. |
| |
| Explicit variable declarations allow a fragment program to establish |
| a variable name that can be used to refer to a specified resource in |
| subsequent instructions. A fragment program will fail to load if it |
| declares the same variable name more than once or if it refers to a |
| variable name that has not been previously declared in the program |
| string. |
| |
| Implicit variable declarations allow a fragment program to use the |
| name of certain available resources by name. |
| |
| |
| 3.11.3.1 Fragment Attributes |
| |
| Fragment program attribute variables are a set of four-component |
| floating-point vectors holding the attributes of the fragment being |
| processed. Fragment attribute variables are read-only during |
| fragment program execution. |
| |
| Fragment attribute variables can be declared explicitly using the |
| <ATTRIB_statement> grammar rule, or implicitly using the |
| <fragAttribBinding> grammar rule in an executable instruction. |
| |
| Each fragment attribute variable is bound to a single item of |
| fragment state according to the <fragAttrBinding> grammar rule. The |
| set of GL state that can be bound to a fragment attribute variable |
| is given in Table X.1. Fragment attribute variables are initialized |
| at each fragment program invocation with the current values of the |
| bound state. |
| |
| Fragment Attribute Binding Components Underlying State |
| -------------------------- ---------- ---------------------------- |
| fragment.color (r,g,b,a) primary color |
| fragment.color.primary (r,g,b,a) primary color |
| fragment.color.secondary (r,g,b,a) secondary color |
| fragment.texcoord (s,t,r,q) texture coordinate, unit 0 |
| fragment.texcoord[n] (s,t,r,q) texture coordinate, unit n |
| fragment.fogcoord (f,0,0,1) fog distance/coordinate |
| fragment.position (x,y,z,1/w) window position |
| |
| Table X.1: Fragment Attribute Bindings. The "Components" column |
| indicates the mapping of the state in the "Underlying State" |
| column. Bindings containing "[n]" require an integer value of <n> |
| to select an individual item. |
| |
| If a fragment attribute binding matches "fragment.color" or |
| "fragment.color.primary", the "x", "y", "z", and "w" components of |
| the fragment attribute variable are filled with the "r", "g", "b", |
| and "a" components, respectively, of the fragment color. Each |
| fixed-point color component undergoes an implied conversion to |
| floating point. This conversion must leave the values 0 and 1 |
| invariant. |
| |
| If a fragment attribute binding matches "fragment.color.secondary", |
| the "x", "y", "z", and "w" components of the fragment attribute |
| variable are filled with the "r", "g", "b", and "a" components, |
| respectively, of the fragment secondary color. Each fixed-point |
| color component undergoes an implied conversion to floating point. |
| This conversion must leave the values 0 and 1 invariant. |
| |
| If a fragment attribute binding matches "fragment.texcoord" or |
| "fragment.texcoord[n]", the "x", "y", "z", and "w" components of the |
| fragment attribute variable are filled with the "s", "t", "r", and |
| "q" components, respectively, of the fragment texture coordinates |
| for texture unit <n>. If "[n]" is omitted, texture unit zero is |
| used. |
| |
| If a fragment attribute binding matches "fragment.fogcoord", the "x" |
| component of the fragment attribute variable is filled with either |
| the fragment eye distance or the fog coordinate, depending on |
| whether the fog source is set to FRAGMENT_DEPTH_EXT or |
| FOG_COORDINATE_EXT, respectively. The "y", "z", and "w" coordinates |
| are filled with 0, 0, and 1, respectively. |
| |
| If a fragment attribute binding matches "fragment.position", the "x" |
| and "y" components of the fragment attribute variable are filled |
| with the (x,y) window coordinates of the fragment center, relative |
| to the lower left corner of the window. The "z" component is filled |
| with the fragment's z window coordinate. This z window coordinate |
| undergoes an implied conversion to floating point. This conversion |
| must leave the values 0 and 1 invariant. The "w" component is |
| filled with the reciprocal of the fragment's clip w coordinate. |
| |
| On some implementations, the components of fragment.position may be |
| generated by interpolating per-vertex position values. This may |
| produce x and y window coordinates that don't exactly match those of |
| the fragment center and z window coordinates that do not exactly |
| match those generated by fixed-function rasterization. Therefore, |
| there is no guaranteed invariance between the final z window |
| coordinates of fragments processed by fragment programs that write |
| depth values and fragments processed by any other means, even if the |
| fragment programs in question simply copy the z value from the |
| fragment.position binding. |
| |
| |
| 3.11.3.2 Fragment Program Parameters |
| |
| Fragment program parameter variables are a set of four-component |
| floating-point vectors used as constants during fragment program |
| execution. Fragment program parameters retain their values across |
| fragment program invocations, although their values can change |
| between invocations due to GL state changes. |
| |
| Single program parameter variables and arrays of program parameter |
| variables can be declared explicitly using the <PARAM_statement> |
| grammar rule. Single program parameter variables can also be |
| declared implicitly using the <paramSingleItemUse> grammar rule in |
| an executable instruction. |
| |
| Each single program parameter variable is bound to a constant vector |
| or to a GL state vector according to the <paramSingleInit> grammar |
| rule. Individual items of a program parameter array are bound to |
| constant vectors or GL state vectors according to the |
| <programMultipleInit> grammar rule. The set of GL state that can be |
| bound to program parameter variables are given in Tables X.2.1 |
| through X.2.4. |
| |
| |
| Constant Bindings |
| |
| A program parameter variable can be bound to a scalar or vector |
| constant using the <paramConstDecl> grammar rule (explicit |
| declarations) or the <paramConstUse> grammar rule (implicit |
| declarations). |
| |
| If a program parameter binding matches the <paramConstScalarDecl> or |
| <paramConstScalarUse> grammar rules, the corresponding program |
| parameter variable is bound to the vector (X,X,X,X), where X is the |
| value of the specified constant. Note that the |
| <paramConstScalarUse> grammar rule, used only in implicit |
| declarations, allows only non-negative constants. This |
| disambiguates cases like "-2", which could conceivably be taken to |
| mean either the vector "(2,2,2,2)" with all components negated or |
| "(-2,-2,-2,-2)" without negation. Only the former interpretation is |
| allowed by the grammar. |
| |
| If a program parameter binding matches <paramConstVector>, the |
| corresponding program parameter variable is bound to the vector |
| (X,Y,Z,W), where X, Y, Z, and W are the values corresponding to the |
| first, second, third, and fourth match of <signedFloatConstant>. If |
| fewer than four constants are specified, Y, Z, and W assume the |
| values 0.0, 0.0, and 1.0, if their respective constants are not |
| specified. |
| |
| Program parameter variables initialized to constant values can never |
| be modified. |
| |
| |
| Program Environment/Local Parameter Bindings |
| |
| Binding Components Underlying State |
| ----------------------------- ---------- ---------------------------- |
| program.env[a] (x,y,z,w) program environment |
| parameter a |
| program.local[a] (x,y,z,w) program local parameter a |
| program.env[a..b] (x,y,z,w) program environment |
| parameters a through b |
| program.local[a..b] (x,y,z,w) program local parameters |
| a through b |
| |
| Table X.2.1: Program Environment/Local Parameter Bindings. <a> |
| and <b> indicate parameter numbers, where <a> must be less than or |
| equal to <b>. |
| |
| If a program parameter binding matches "program.env[a]" or |
| "program.local[a]", the four components of the program parameter |
| variable are filled with the four components of program environment |
| parameter <a> or program local parameter <a>, respectively. |
| |
| Additionally, for program parameter array bindings, |
| "program.env[a..b]" and "program.local[a..b]" are equivalent to |
| specifying program environment parameters <a> through <b> in order |
| or program local parameters <a> through <b> in order, respectively. |
| In either case, a program will fail to load if <a> is greater than |
| <b>. |
| |
| |
| Material Property Bindings |
| |
| Binding Components Underlying State |
| ----------------------------- ---------- ---------------------------- |
| state.material.ambient (r,g,b,a) front ambient material color |
| state.material.diffuse (r,g,b,a) front diffuse material color |
| state.material.specular (r,g,b,a) front specular material color |
| state.material.emission (r,g,b,a) front emissive material color |
| state.material.shininess (s,0,0,1) front material shininess |
| state.material.front.ambient (r,g,b,a) front ambient material color |
| state.material.front.diffuse (r,g,b,a) front diffuse material color |
| state.material.front.specular (r,g,b,a) front specular material color |
| state.material.front.emission (r,g,b,a) front emissive material color |
| state.material.front.shininess (s,0,0,1) front material shininess |
| state.material.back.ambient (r,g,b,a) back ambient material color |
| state.material.back.diffuse (r,g,b,a) back diffuse material color |
| state.material.back.specular (r,g,b,a) back specular material color |
| state.material.back.emission (r,g,b,a) back emissive material color |
| state.material.back.shininess (s,0,0,1) back material shininess |
| |
| Table X.2.2: Material Property Bindings. If a material face is |
| not specified in the binding, the front property is used. |
| |
| If a program parameter binding matches any of the material |
| properties listed in Table X.2.2, the program parameter variable is |
| filled according to the table. For ambient, diffuse, specular, or |
| emissive colors, the "x", "y", "z", and "w" components are filled |
| with the "r", "g", "b", and "a" components, respectively, of the |
| corresponding material color. For material shininess, the "x" |
| component is filled with the material's specular exponent, and the |
| "y", "z", and "w" components are filled with 0, 0, and 1, |
| respectively. Bindings containing ".back" refer to the back |
| material; all other bindings refer to the front material. |
| |
| Material properties can be changed inside a Begin/End pair, either |
| directly by calling Material, or indirectly through color material. |
| However, such property changes are not guaranteed to update program |
| parameter bindings until the following End command. Program |
| parameter variables bound to material properties changed inside a |
| Begin/End pair are undefined until the following End command. |
| |
| |
| Light Property Bindings |
| |
| Binding Components Underlying State |
| ----------------------------- ---------- ---------------------------- |
| state.light[n].ambient (r,g,b,a) light n ambient color |
| state.light[n].diffuse (r,g,b,a) light n diffuse color |
| state.light[n].specular (r,g,b,a) light n specular color |
| state.light[n].position (x,y,z,w) light n position |
| state.light[n].attenuation (a,b,c,e) light n attenuation constants |
| and spot light exponent |
| state.light[n].spot.direction (x,y,z,c) light n spot direction and |
| cutoff angle cosine |
| state.light[n].half (x,y,z,1) light n infinite half-angle |
| state.lightmodel.ambient (r,g,b,a) light model ambient color |
| state.lightmodel.scenecolor (r,g,b,a) light model front scene color |
| state.lightmodel . (r,g,b,a) light model front scene color |
| front.scenecolor |
| state.lightmodel . (r,g,b,a) light model back scene color |
| back.scenecolor |
| state.lightprod[n].ambient (r,g,b,a) light n / front material |
| ambient color product |
| state.lightprod[n].diffuse (r,g,b,a) light n / front material |
| diffuse color product |
| state.lightprod[n].specular (r,g,b,a) light n / front material |
| specular color product |
| state.lightprod[n]. (r,g,b,a) light n / front material |
| front.ambient ambient color product |
| state.lightprod[n]. (r,g,b,a) light n / front material |
| front.diffuse diffuse color product |
| state.lightprod[n]. (r,g,b,a) light n / front material |
| front.specular specular color product |
| state.lightprod[n]. (r,g,b,a) light n / back material |
| back.ambient ambient color product |
| state.lightprod[n]. (r,g,b,a) light n / back material |
| back.diffuse diffuse color product |
| state.lightprod[n]. (r,g,b,a) light n / back material |
| back.specular specular color product |
| |
| Table X.2.3: Light Property Bindings. <n> indicates a light |
| number. |
| |
| If a program parameter binding matches "state.light[n].ambient", |
| "state.light[n].diffuse", or "state.light[n].specular", the "x", |
| "y", "z", and "w" components of the program parameter variable are |
| filled with the "r", "g", "b", and "a" components, respectively, of |
| the corresponding light color. |
| |
| If a program parameter binding matches "state.light[n].position", |
| the "x", "y", "z", and "w" components of the program parameter |
| variable are filled with the "x", "y", "z", and "w" components, |
| respectively, of the light position. |
| |
| If a program parameter binding matches "state.light[n].attenuation", |
| the "x", "y", and "z" components of the program parameter variable |
| are filled with the constant, linear, and quadratic attenuation |
| parameters of the specified light, respectively (section 2.13.1). |
| The "w" component of the program parameter variable is filled with |
| the spot light exponent of the specified light. |
| |
| If a program parameter binding matches |
| "state.light[n].spot.direction", the "x", "y", and "z" components of |
| the program parameter variable are filled with the "x", "y", and "z" |
| components of the spot light direction of the specified light, |
| respectively (section 2.13.1). The "w" component of the program |
| parameter variable is filled with the cosine of the spot light |
| cutoff angle of the specified light. |
| |
| If a program parameter binding matches "state.light[n].half", the |
| "x", "y", and "z" components of the program parameter variable are |
| filled with the x, y, and z components, respectively, of the |
| normalized infinite half-angle vector |
| |
| h_inf = || P + (0, 0, 1) ||. |
| |
| The "w" component is filled with 1. In the computation of h_inf, P |
| consists of the x, y, and z coordinates of the normalized vector |
| from the eye position P_e to the eye-space light position P_pli |
| (section 2.13.1). h_inf is defined to correspond to the normalized |
| half-angle vector when using an infinite light (w coordinate of the |
| position is zero) and an infinite viewer (v_bs is FALSE). For local |
| lights or a local viewer, h_inf is well-defined but does not match |
| the normalized half-angle vector, which will vary depending on the |
| vertex position. |
| |
| If a program parameter binding matches "state.lightmodel.ambient", |
| the "x", "y", "z", and "w" components of the program parameter |
| variable are filled with the "r", "g", "b", and "a" components of |
| the light model ambient color, respectively. |
| |
| If a program parameter binding matches "state.lightmodel.scenecolor" |
| or "state.lightmodel.front.scenecolor", the "x", "y", and "z" |
| components of the program parameter variable are filled with the |
| "r", "g", and "b" components respectively of the "front scene color" |
| |
| c_scene = a_cs * a_cm + e_cm, |
| |
| where a_cs is the light model ambient color, a_cm is the front |
| ambient material color, and e_cm is the front emissive material |
| color. The "w" component of the program parameter variable is |
| filled with the alpha component of the front diffuse material color. |
| If a program parameter binding matches |
| "state.lightmodel.back.scenecolor", a similar back scene color, |
| computed using back-facing material properties, is used. The front |
| and back scene colors match the values that would be assigned to |
| vertices using conventional lighting if all lights were disabled. |
| |
| If a program parameter binding matches anything beginning with |
| "state.lightprod[n]", the "x", "y", and "z" components of the |
| program parameter variable are filled with the "r", "g", and "b" |
| components, respectively, of the corresponding light product. The |
| three light product components are the products of the corresponding |
| color components of the specified material property and the light |
| color of the specified light (see Table X.2.3). The "w" component |
| of the program parameter variable is filled with the alpha component |
| of the specified material property. |
| |
| Light products depend on material properties, which can be changed |
| inside a Begin/End pair. Such property changes are not guaranteed |
| to take effect until the following End command. Program parameter |
| variables bound to light products whose corresponding material |
| property changes inside a Begin/End pair are undefined until the |
| following End command. |
| |
| |
| Texture Environment Property Bindings |
| |
| Binding Components Underlying State |
| ------------------------- ---------- ---------------------------- |
| state.texenv[n].color (r,g,b,a) texture environment n color |
| |
| Table X.2.4: Texture Environment Property Bindings. "[n]" is |
| optional -- texture unit <n> is used if specified; texture unit 0 |
| is used otherwise. |
| |
| If a program parameter binding matches "state.texenv[n].color", the |
| "x", "y", "z", and "w" components of the program parameter variable |
| are filled with the "r", "g", "b", and "a" components, respectively, |
| of the corresponding texture environment color. Note that only |
| "legacy" texture units, as queried by MAX_TEXTURE_UNITS, include |
| texture environment state. Texture image units and texture |
| coordinate sets do not have associated texture environment state. |
| |
| |
| Fog Property Bindings |
| |
| Binding Components Underlying State |
| --------------------------- ---------- ---------------------------- |
| state.fog.color (r,g,b,a) RGB fog color (section 3.11) |
| state.fog.params (d,s,e,r) fog density, linear start |
| and end, and 1/(end-start) |
| (section 3.11) |
| |
| Table X.2.5: Fog Property Bindings |
| |
| If a program parameter binding matches "state.fog.color", the "x", |
| "y", "z", and "w" components of the program parameter variable are |
| filled with the "r", "g", "b", and "a" components, respectively, of |
| the fog color (section 3.11). |
| |
| If a program parameter binding matches "state.fog.params", the "x", |
| "y", and "z" components of the program parameter variable are filled |
| with the fog density, linear fog start, and linear fog end |
| parameters (section 3.11), respectively. The "w" component is |
| filled with 1/(end-start), where end and start are the linear fog |
| end and start parameters, respectively. |
| |
| |
| Depth Property Bindings |
| |
| Binding Components Underlying State |
| --------------------------- ---------- ---------------------------- |
| state.depth.range (n,f,d,1) Depth range near, far, and |
| (far-near) (section 2.10.1) |
| |
| Table X.2.6: Depth Property Bindings |
| |
| If a program parameter binding matches "state.depth.range", the "x" |
| and "y" components of the program parameter variable are filled with |
| the mappings of near and far clipping planes to window coordinates, |
| respectively. The "z" component is filled with the difference of |
| the mappings of near and far clipping planes, far minus near. The |
| "w" component is filled with 1. |
| |
| |
| Matrix Property Bindings |
| |
| Binding Underlying State |
| ------------------------------------ --------------------------- |
| * state.matrix.modelview[n] modelview matrix n |
| state.matrix.projection projection matrix |
| state.matrix.mvp modelview-projection matrix |
| * state.matrix.texture[n] texture matrix n |
| state.matrix.palette[n] modelview palette matrix n |
| state.matrix.program[n] program matrix n |
| |
| Table X.2.7: Base Matrix Property Bindings. The "[n]" syntax |
| indicates a specific matrix number. For modelview and texture |
| matrices, a matrix number is optional, and matrix zero will be |
| used if the matrix number is omitted. These base bindings may |
| further be modified by a inverse/transpose selector and a row |
| selector. |
| |
| If the beginning of a program parameter binding matches any of the |
| matrix binding names listed in Table X.2.7, the binding corresponds |
| to a 4x4 matrix. If the parameter binding is followed by |
| ".inverse", ".transpose", or ".invtrans" (<stateMatModifier> grammar |
| rule), the inverse, transpose, or transpose of the inverse, |
| respectively, of the matrix specified in Table X.2.7 is selected. |
| Otherwise, the matrix specified in Table X.2.7 is selected. If the |
| specified matrix is poorly-conditioned (singular or nearly so), its |
| inverse matrix is undefined. The binding name "state.matrix.mvp" |
| refers to the product of modelview matrix zero and the projection |
| matrix, defined as |
| |
| MVP = P * M0, |
| |
| where P is the projection matrix and M0 is modelview matrix zero. |
| |
| If the selected matrix is followed by ".row[<a>]" (matching the |
| <stateMatrixRow> grammar rule), the "x", "y", "z", and "w" |
| components of the program parameter variable are filled with the |
| four entries of row <a> of the selected matrix. In the example, |
| |
| PARAM m0 = state.matrix.modelview[1].row[0]; |
| PARAM m1 = state.matrix.projection.transpose.row[3]; |
| |
| the variable "m0" is set to the first row (row 0) of modelview |
| matrix 1 and "m1" is set to the last row (row 3) of the transpose of |
| the projection matrix. |
| |
| For program parameter array bindings, multiple rows of the selected |
| matrix can be bound via the <stateMatrixRows> grammar rule. If the |
| selected matrix binding is followed by ".row[<a>..<b>]", the result |
| is equivalent to specifying matrix rows <a> through <b>, in order. |
| A program will fail to load if <a> is greater than <b>. If no row |
| selection is specified (<optMatrixRows> matches ""), matrix rows 0 |
| through 3 are bound in order. In the example, |
| |
| PARAM m2[] = { state.matrix.program[0].row[1..2] }; |
| PARAM m3[] = { state.matrix.program[0].transpose }; |
| |
| the array "m2" has two entries, containing rows 1 and 2 of program |
| matrix zero, and "m3" has four entries, containing all four rows of |
| the transpose of program matrix zero. |
| |
| |
| Program Parameter Arrays |
| |
| A program parameter array variable can be declared explicitly by |
| matching the <PARAM_multipleStmt> grammar rule. Programs can |
| optionally specify the number of individual program parameters in |
| the array, using the <optArraySize> grammar rule. Program parameter |
| arrays may not be declared implicity. |
| |
| Individual parameter variables in a program parameter array are |
| bound to GL state vectors or constant vectors as specified by the |
| grammar rule <paramMultInitList>. Each individual parameter in the |
| array is bound in turn as described above. |
| |
| The total number of entries in the array is equal to the number of |
| parameters bound in the initializer list. A fragment program that |
| specifies an array size (<optArraySize> matches <integer>) that does |
| not match the number of parameter bindings in the initialization |
| list will fail to load. |
| |
| Program parameter array variables may only be accessed using |
| absolute addressing by matching the <progParamArrayAbs> grammar |
| rule. Array accesses are checked against the limits of the array. |
| If any fragment program instruction accesses a program parameter |
| array with an out-of-range index (greater than or equal to the size |
| of the array), the fragment program will fail to load. |
| |
| Individual state vectors can have no more than one unique binding in |
| any given program. The GL will automatically combine multiple |
| bindings of the same state vector into a single unique binding. |
| |
| |
| 3.11.3.3 Fragment Program Temporaries |
| |
| Fragment program temporary variables are a set of four-component |
| floating-point vectors used to hold temporary results during |
| fragment program execution. Temporaries do not persist between |
| program invocations, and are undefined at the beginning of each |
| fragment program invocation. |
| |
| Fragment program temporary variables can be declared explicitly |
| using the <TEMP_statement> grammar rule. Each such statement can |
| declare one or more temporaries. Fragment program temporary |
| variables can not be declared implicitly. |
| |
| |
| 3.11.3.4 Fragment Program Results |
| |
| Fragment program result variables are a set of four component |
| floating-point vectors used to hold the final results of a fragment |
| program. Fragment program result variables are write-only during |
| fragment program execution. |
| |
| Fragment program result variables can be declared explicitly using |
| the <OUTPUT_statement> grammar rule, or implicitly using the |
| <resultBinding> grammar rule in an executable instruction. Each |
| fragment program result variable is bound to a fragment attribute |
| used in subsequent back-end processing. The set of fragment program |
| result variable bindings is given in Table X.3. |
| |
| Binding Components Description |
| ----------------------------- ---------- ---------------------------- |
| result.color (r,g,b,a) color |
| result.depth (*,*,d,*) depth coordinate |
| |
| Table X.3: Fragment Result Variable Bindings. Components labeled |
| "*" are unused. |
| |
| If a result variable binding matches "result.color", updates to the |
| "x", "y", "z", and "w" components of the result variable modify the |
| "r", "g", "b", and "a" components, respectively, of the fragment's |
| output color. If "result.color" is not both bound by the fragment |
| program and written by some instruction of the program, the output |
| color of the fragment program is undefined. |
| |
| If a result variable binding matches "result.depth", updates to the |
| "z" component of the result variable modify the fragment's output |
| depth value. If "result.depth" is not both bound by the fragment |
| program and written by some instruction of the program, the |
| interpolated depth value produced by rasterization is used as if |
| fragment program mode is not enabled. Writes to any component of |
| depth other than the "z" component have no effect. |
| |
| |
| 3.11.3.5 Fragment Program Aliases |
| |
| Fragment programs can create aliases by matching the |
| <ALIAS_statement> grammar rule. Aliases allow programs to use |
| multiple variable names to refer to a single underlying variable. |
| For example, the statement |
| |
| ALIAS var1 = var0 |
| |
| establishes a variable name named "var1". Subsequent references to |
| "var1" in the program text are treated as references to "var0". The |
| left hand side of an ALIAS statement must be a new variable name, |
| and the right hand side must be an established variable name. |
| |
| Aliases are not considered variable declarations, so do not count |
| against the limits on the number of variable declarations allowed in |
| the program text. |
| |
| |
| 3.11.3.6 Fragment Program Resource Limits |
| |
| The fragment program execution environment provides implementation- |
| dependent resource limits on the number of ALU instructions, texture |
| instructions, total instructions (ALU or texture), temporary |
| variable declarations, program parameter bindings, or texture |
| indirections. A program that exceeds any of these resource limits |
| will fail to load. The resource limits for fragment programs can be |
| queried by calling GetProgramiv (section 6.1.12) with a target of |
| FRAGMENT_PROGRAM_ARB. |
| |
| The limit on fragment program ALU instructions can be queried with |
| a <pname> of MAX_PROGRAM_ALU_INSTRUCTIONS_ARB, and must be at least |
| 48. Each ALU instruction in the program (matches of the |
| <ALUInstruction> grammar rule) counts against this limit. |
| |
| The limit on fragment program texture instructions can be queried |
| with a <pname> of MAX_PROGRAM_TEX_INSTRUCTIONS_ARB, and must be at |
| least 24. Each texture instruction in the program (matches of the |
| <TexInstruction> grammar rule) counts against this limit. |
| |
| The limit on fragment program total instructions can be queried with |
| a <pname> of MAX_PROGRAM_INSTRUCTIONS_ARB, and must be at least 72. |
| Each instruction in the program (matching the <instruction> grammar |
| rule) counts against this limit. Note that the limit on total |
| instructions is not necessarily equal to the sum of the limits on |
| ALU instructions and texture instructions. |
| |
| The limit on fragment program texture indirections can be queried |
| with a <pname> of MAX_PROGRAM_TEX_INDIRECTIONS_ARB, and must be at |
| least 4. Texture indirections are described in 3.11.6. If an |
| implementation has no limit on texture indirections, the limit will |
| be equal to the limit on texture instructions. |
| |
| The limit on fragment program temporary variable declarations can be |
| queried with a <pname> of MAX_PROGRAM_TEMPORARIES_ARB, and must be at |
| least 16. Each temporary declared in the program, using the |
| <TEMP_statement> grammar rule, counts against this limit. Aliases |
| of declared temporaries do not. |
| |
| The limit on fragment program attribute bindings can be queried with |
| a <pname> of MAX_PROGRAM_ATTRIBS_ARB and must be at least 10. Each |
| distinct vertex attribute bound explicitly or implicitly in the |
| program counts against this limit; vertex attributes bound multiple |
| times count only once. |
| |
| The limit on fragment program parameter bindings can be queried with |
| a <pname> of MAX_PROGRAM_PARAMETERS_ARB, and must be at least 24. |
| Each distinct GL state vector bound explicitly or implicitly in the |
| program counts against this limit; GL state vectors bound multiple |
| times count only once. Every other constant vector bound in the |
| program is counted if and only if an identical constant vector has |
| not already been counted. Two constant vectors are considered |
| identical if the four component values are numerically equivalent. |
| Recall that scalar constants bound in a program are treated as |
| vector constants with the scalar value replicated. |
| |
| In addition to the limits described above, the GL provides a similar |
| set of implementation-dependent native resource limits. These |
| limits, specified in Section 6.1.12, provide guidance as to whether |
| the program is small enough to use a "native" mode where fragment |
| programs may be executed with higher performance. The native |
| resource limits and usage counts are implementation-dependent and |
| may not exactly correspond to limits and counts described above. |
| A program's native resource consumption may be reduced by program |
| optimizations performed by the GL. Native resource consumption may |
| be increased due to emulation of instructions or any other program |
| features not natively supported by an implementation. Notably, an |
| additional texture indirection may be consumed due to an |
| implementation's lack of native support for texture instructions |
| with source coordinate swizzles or parameter source coordinates, |
| which may require emulation by prepending ALU instructions. An |
| implementation may also fail to natively support all combinations of |
| attributes described in Table X.1, even if the total number of |
| bound attributes is fewer than the native attribute limit. In this |
| case the program is still considered to exceed the native resource |
| limits, as queried by PROGRAM_UNDER_NATIVE_LIMITS_ARB (section |
| 6.1.12). |
| |
| To assist in resource counting, the GL additionally provides |
| GetProgram queries to determine the resource usage and native |
| resource usage of the currently bound program, and to determine |
| whether the bound program exceeds any native resource limit. |
| |
| Programs that exceed any native resource limit may or may not load |
| depending on the implementation. |
| |
| |
| 3.11.4 Fragment Program Execution Environment |
| |
| If fragment program mode is enabled, the currently bound fragment |
| program is executed when any fragment is produced by rasterization. |
| |
| If fragment program mode is enabled and the currently bound program |
| object does not contain a valid fragment program, the error |
| INVALID_OPERATION will be generated by Begin, RasterPos, and any |
| command that implicitly calls Begin (e.g., DrawArrays). |
| |
| Fragment programs execute a sequence of instructions without |
| branching. Fragment programs begin by executing the first |
| instruction in the program, and execute instructions in the order |
| specified in the program until the last instruction is completed. |
| |
| There are 33 fragment program instructions. The instructions and |
| their respective input and output parameters are summarized in |
| Table X.5. |
| |
| Instruction Inputs Output Description |
| ----------- ------ ------ -------------------------------- |
| ABS v v absolute value |
| ADD v,v v add |
| CMP v,v,v v compare |
| COS s ssss cosine with reduction to [-PI,PI] |
| DP3 v,v ssss 3-component dot product |
| DP4 v,v ssss 4-component dot product |
| DPH v,v ssss homogeneous dot product |
| DST v,v v distance vector |
| EX2 s ssss exponential base 2 |
| FLR v v floor |
| FRC v v fraction |
| KIL v v kill fragment |
| LG2 s ssss logarithm base 2 |
| LIT v v compute light coefficients |
| LRP v,v,v v linear interpolation |
| MAD v,v,v v multiply and add |
| MAX v,v v maximum |
| MIN v,v v minimum |
| MOV v v move |
| MUL v,v v multiply |
| POW s,s ssss exponentiate |
| RCP s ssss reciprocal |
| RSQ s ssss reciprocal square root |
| SCS s ss-- sine/cosine without reduction |
| SGE v,v v set on greater than or equal |
| SIN s ssss sine with reduction to [-PI,PI] |
| SLT v,v v set on less than |
| SUB v,v v subtract |
| SWZ v v extended swizzle |
| TEX v,u,t v texture sample |
| TXB v,u,t v texture sample with bias |
| TXP v,u,t v texture sample with projection |
| XPD v,v v cross product |
| |
| Table X.5: Summary of fragment program instructions. "v" |
| indicates a floating-point vector input or output, "s" indicates a |
| floating-point scalar input, "ssss" indicates a scalar output |
| replicated across a 4-component result vector, "ss--" indicates |
| two scalar outputs in the first two components, "u" indicates a |
| texture image unit identifier, and "t" indicates a texture target. |
| |
| |
| 3.11.4.1 Fragment Program Operands |
| |
| Most fragment program instructions operate on floating-point vectors |
| or scalars, as indicated by the grammar rules <vectorSrcReg> and |
| <scalarSrcReg>, respectively. |
| |
| Vector and scalar operands can be obtained from fragment attribute, |
| program parameter, or temporary registers, as indicated by the |
| <srcReg> rule. For scalar operands, a single vector component is |
| selected by the <scalarSuffix> rule, where the characters "x", "y", |
| "z", and "w", or "r", "g", "b", and "a" select the first, second, |
| third, and fourth components, respectively, of the vector. |
| |
| Vector operands can be swizzled according to the <optionalSuffix> |
| rule. In its most general form, the <optionalSuffix> rule matches |
| the pattern ".????" where each question mark is replaced with one of |
| "x", "y", "z", "w", "r", "g", "b", or "a". For such patterns, the |
| first, second, third, and fourth components of the operand are taken |
| from the vector components named by the first, second, third, and |
| fourth character of the pattern, respectively. For example, if the |
| swizzle suffix is ".yzzx" or ".gbbr" and the specified source |
| contains {2,8,9,0}, the swizzled operand used by the instruction is |
| {8,9,9,2}. |
| |
| If the <optionalSuffix> rule matches "", it is treated as though it |
| were ".xyzw". If the <optionalSuffix> rule matches (ignoring |
| whitespace) ".x", ".y", ".z", or ".w", these are treated the same as |
| ".xxxx", ".yyyy", ".zzzz", and ".wwww" respectively. Likewise, if |
| the <optionalSuffix> rule matches ".r", ".g", ".b", or ".a", these |
| are treated the same as ".rrrr", ".gggg", ".bbbb", and ".aaaa" |
| respectively. |
| |
| Floating-point scalar or vector operands can optionally be negated |
| according to the <optionalSign> rule in <scalarSrcReg> and |
| <vectorSrcReg>. If the <optionalSign> matches "-", each operand or |
| operand component is negated. |
| |
| The following pseudo-code spells out the operand generation process. |
| In the example, "float" is a floating-point scalar type, while |
| "floatVec" is a four-component vector. "source" refers to the |
| register used for the operand, matching the <srcReg> rule. "negate" |
| is TRUE if the <optionalSign> rule in <scalarSrcReg> or |
| <vectorSrcReg> matches "-" and FALSE otherwise. The ".c***", |
| ".*c**", ".**c*", ".***c" modifiers refer to the x, y, z, and w |
| components obtained by the swizzle operation; the ".c" modifier |
| refers to the single component selected for a scalar load. |
| |
| floatVec VectorLoad(floatVec source) |
| { |
| floatVec operand; |
| |
| operand.x = source.c***; |
| operand.y = source.*c**; |
| operand.z = source.**c*; |
| operand.w = source.***c; |
| if (negate) { |
| operand.x = -operand.x; |
| operand.y = -operand.y; |
| operand.z = -operand.z; |
| operand.w = -operand.w; |
| } |
| |
| return operand; |
| } |
| |
| float ScalarLoad(floatVec source) |
| { |
| float operand; |
| |
| operand = source.c; |
| if (negate) { |
| operand = -operand; |
| } |
| |
| return operand; |
| } |
| |
| |
| 3.11.4.2 Fragment Program Parameter Arrays |
| |
| A fragment program can load a single element of a program parameter |
| array using only absolute addressing. Program parameter arrays are |
| accessed when the <progParamArrayAbs> rule is matched. The offset |
| of the selected entry in the array is given by the number matching |
| <progParamRegNum>. If the offset exceeds the size of the |
| array, the results of the access are undefined, but may not lead to |
| program or GL termination. |
| |
| |
| 3.11.4.3 Fragment Program Destination Register Update |
| |
| Fragment program instructions write a 4-component result vector to a |
| single temporary or fragment result register. Writes to individual |
| components of the destination register are controlled by individual |
| component write masks specified as part of the instruction. |
| Optional clamping of each component of the destination register to |
| the range [0,1] is controlled by an opcode modifier. |
| |
| The component write mask is specified by the <optionalMask> rule |
| found in the <maskedDstReg> rule. If the optional mask is "", all |
| components are enabled. Otherwise, the optional mask names the |
| individual components to enable. The characters "x", "y", "z", and |
| "w", or "r", "g", "b", and "a" match the first, second, third, and |
| fourth components, respectively. For example, an optional mask of |
| ".xzw" indicates that the x, z, and w components should be enabled |
| for writing but the y component should not. The grammar requires |
| that the destination register mask components must be listed in |
| "xyzw", or "rgba" order. Component names from one set (xyzw or |
| rgba) cannot be mixed with component names from another set. For |
| example, ".rgw" is not a valid writemask. |
| |
| Each component of the destination register is updated with the |
| result of the fragment program instruction if and only if the |
| component is enabled for writes by the component write mask. |
| Otherwise, the component of the destination register remains |
| unchanged. |
| |
| If the instruction opcode has the "_SAT" suffix, requesting |
| saturated result vectors, each component of the result vector |
| enabled in the writemask is clamped to the range [0,1] before being |
| updated in the destination register. |
| |
| The following pseudocode illustrates the process of writing a result |
| vector to the destination register. In the pseudocode, "instrmask" |
| refers to the component write mask given by the <optionalMask> rule. |
| "clamp" is TRUE if the instruction specifies that the result should |
| be clamped. "result" and "destination" refer to the result vector |
| and the register selected by <dstReg>, respectively. |
| |
| void UpdateDestination(floatVec destination, floatVec result) |
| { |
| floatVec merged; |
| |
| // Clamp the result vector components to [0,1], if requested. |
| if (instrClamp) { |
| if (result.x < 0) result.x = 0; |
| else if (result.x > 1) result.x = 1; |
| if (result.y < 0) result.y = 0; |
| else if (result.y > 1) result.y = 1; |
| if (result.z < 0) result.z = 0; |
| else if (result.z > 1) result.z = 1; |
| if (result.w < 0) result.w = 0; |
| else if (result.w > 1) result.w = 1; |
| } |
| |
| // Merge the converted result into the destination register, |
| // under control of the compile-time write mask. |
| merged = destination; |
| if (instrMask.x) { |
| merged.x = result.x; |
| } |
| if (instrMask.y) { |
| merged.y = result.y; |
| } |
| if (instrMask.z) { |
| merged.z = result.z; |
| } |
| if (instrMask.w) { |
| merged.w = result.w; |
| } |
| |
| // Write out the new destination register. |
| destination = merged; |
| } |
| |
| |
| 3.11.4.4 Fragment Program Result Processing |
| |
| As a fragment program executes, it will write to either one or two |
| result registers that are mapped to the fragment's color and depth. |
| |
| The fragment's color components are first clamped to the range [0,1] |
| then converted to fixed point as in section 2.13.9. If the fragment |
| program does not write result.color, the color will be undefined in |
| subsequent stages. |
| |
| If the fragment program contains an instruction to write to |
| result.depth, the fragment's depth is replaced by the value of the |
| "z" component of result.depth. This z value is first clamped to the |
| range [0,1] then converted to fixed-point as if it were a window z |
| value (section 2.10.1). If the fragment program does not write |
| result.depth, the fragment's original depth is unmodified. |
| |
| |
| 3.11.4.5 Fragment Program Options |
| |
| The <optionSequence> grammar rule provides a mechanism for programs |
| to indicate that one or more extended language features are used by |
| the program. All program options used by the program must be |
| declared at the beginning of the program string. Each program |
| option specified in a program string will modify the syntactic or |
| semantic rules used to interpet the program and the execution |
| environment used to execute the program. Program options not |
| present in the program string are ignored, even if they are |
| supported by the GL. |
| |
| The <identifier> token in the <option> rule must match the name of a |
| program option supported by the implementation. To avoid option |
| name conflicts, option identifiers are required to begin with a |
| vendor prefix. A program will fail to load if it specifies a |
| program option not supported by the GL. |
| |
| Fragment program options should confine their semantic changes to |
| the domain of fragment programs. Support for a fragment program |
| option should not change the specification and behavior of fragment |
| programs not requesting use of that option. |
| |
| |
| 3.11.4.5.1 Fog Application Fragment Program Options |
| |
| If a fragment program specifies one of the options "ARB_fog_exp", |
| "ARB_fog_exp2", or "ARB_fog_linear", the program will apply fog to |
| the program's final clamped color using a fog mode of EXP, EXP2, or |
| LINEAR, respectively, as described in section 3.10. |
| |
| When a fog option is specified in a fragment program, semantic |
| restrictions are added to indicate that a fragment program |
| will fail to load if the number of temporaries it contains exceeds |
| the implementation-dependent limit minus 1, if the number of |
| attributes it contains exceeds the implementation-dependent limit |
| minus 1, or if the number of parameters it contains exceeds the |
| implementation-dependent limit minus 2. |
| |
| Additionally, when the ARB_fog_exp option is specified in a fragment |
| program, a semantic restriction is added to indicate that a fragment |
| program will fail to load if the number of instructions or ALU |
| instructions it contains exceeds the implementation-dependent limit |
| minus 3. When the ARB_fog_exp2 option is specified in a fragment |
| program, a semantic restriction is added to indicate that a fragment |
| program will fail to load if the number of instructions or ALU |
| instructions it contains exceeds the implementation-dependent limit |
| minus 4. When the ARB_fog_linear option is specified in a fragment |
| program, a semantic restriction is added to indicate that a fragment |
| program will fail to load if the number of instructions or ALU |
| instructions it contains exceeds the implementation-dependent limit |
| minus 2. |
| |
| Only one fog application option may be specified by any given |
| fragment program. A fragment program that specifies more than one |
| of the program options "ARB_fog_exp", "ARB_fog_exp2", and |
| "ARB_fog_linear", will fail to load. |
| |
| |
| 3.11.4.5.2 Precision Hint Options |
| |
| Fragment program computations are carried out at an implementation- |
| dependent precision. However, some implementations may be able to |
| perform fragment program computations at more than one precision, |
| and may be able to trade off computation precision for performance. |
| |
| If a fragment program specifies the "ARB_precision_hint_fastest" |
| program option, implementations should select precision to minimize |
| program execution time, with possibly reduced precision. If a |
| fragment program specifies the "ARB_precision_hint_nicest" program |
| option, implementations should maximize the precision, with possibly |
| increased execution time. |
| |
| Only one precision control option may be specified by any given |
| fragment program. A fragment program that specifies both the |
| "ARB_precision_hint_fastest" and "ARB_precision_hint_nicest" program |
| options will fail to load. |
| |
| |
| 3.11.5 Fragment Program ALU Instruction Set |
| |
| The following sections describe the set of supported fragment |
| program instructions. Each section contains pseudocode describing |
| the instruction. Instructions will have up to three operands, |
| referred to as "op0", "op1", and "op2". The operands are loaded |
| using the mechanisms specified in section 3.11.4.1. The variables |
| "tmp", "tmp0", "tmp1", and "tmp2" describe scalars or vectors used |
| to hold intermediate results in the instruction. Instructions will |
| generate a result vector called "result". The result vector is then |
| written to the destination register specified in the instruction as |
| described in section 3.11.4.3. |
| |
| |
| 3.11.5.1 ABS: Absolute Value |
| |
| The ABS instruction performs a component-wise absolute value |
| operation on the single operand to yield a result vector. |
| |
| tmp = VectorLoad(op0); |
| result.x = fabs(tmp.x); |
| result.y = fabs(tmp.y); |
| result.z = fabs(tmp.z); |
| result.w = fabs(tmp.w); |
| |
| |
| 3.11.5.2 ADD: Add |
| |
| The ADD instruction performs a component-wise add of the two |
| operands to yield a result vector. |
| |
| tmp0 = VectorLoad(op0); |
| tmp1 = VectorLoad(op1); |
| result.x = tmp0.x + tmp1.x; |
| result.y = tmp0.y + tmp1.y; |
| result.z = tmp0.z + tmp1.z; |
| result.w = tmp0.w + tmp1.w; |
| |
| The following rules apply to addition: |
| |
| 1. <x> + <y> == <y> + <x>, for all <x> and <y>. |
| 2. <x> + 0.0 == <x>, for all <x>. |
| |
| |
| 3.11.5.3 CMP: Compare |
| |
| The CMP instructions performs a component-wise comparison of the |
| first operand against zero, and copies the values of the second or |
| third operands based on the results of the compare. |
| |
| tmp0 = VectorLoad(op0); |
| tmp1 = VectorLoad(op1); |
| tmp2 = VectorLoad(op2); |
| result.x = (tmp0.x < 0.0) ? tmp1.x : tmp2.x; |
| result.y = (tmp0.y < 0.0) ? tmp1.y : tmp2.y; |
| result.z = (tmp0.z < 0.0) ? tmp1.z : tmp2.z; |
| result.w = (tmp0.w < 0.0) ? tmp1.w : tmp2.w; |
| |
| |
| 3.11.5.4 COS: Cosine |
| |
| The COS instruction approximates the trigonometric cosine of the |
| angle specified by the scalar operand and replicates it to all four |
| components of the result vector. The angle is specified in radians |
| and does not have to be in the range [-PI,PI]. |
| |
| tmp = ScalarLoad(op0); |
| result.x = ApproxCosine(tmp); |
| result.y = ApproxCosine(tmp); |
| result.z = ApproxCosine(tmp); |
| result.w = ApproxCosine(tmp); |
| |
| |
| 3.11.5.5 DP3: Three-Component Dot Product |
| |
| The DP3 instruction computes a three-component dot product of the |
| two operands (using the first three components) and replicates the |
| dot product to all four components of the result vector. |
| |
| tmp0 = VectorLoad(op0); |
| tmp1 = VectorLoad(op1); |
| dot = (tmp0.x * tmp1.x) + (tmp0.y * tmp1.y) + (tmp0.z * tmp1.z); |
| result.x = dot; |
| result.y = dot; |
| result.z = dot; |
| result.w = dot; |
| |
| |
| 3.11.5.6 DP4: Four-Component Dot Product |
| |
| The DP4 instruction computes a four-component dot product of the two |
| operands and replicates the dot product to all four components of |
| the result vector. |
| |
| tmp0 = VectorLoad(op0); |
| tmp1 = VectorLoad(op1): |
| dot = (tmp0.x * tmp1.x) + (tmp0.y * tmp1.y) + |
| (tmp0.z * tmp1.z) + (tmp0.w * tmp1.w); |
| result.x = dot; |
| result.y = dot; |
| result.z = dot; |
| result.w = dot; |
| |
| |
| 3.11.5.7 DPH: Homogeneous Dot Product |
| |
| The DPH instruction computes a three-component dot product of the |
| two operands (using the x, y, and z components), adds the w |
| component of the second operand, and replicates the sum to all four |
| components of the result vector. This is equivalent to a four- |
| component dot product where the w component of the first operand is |
| forced to 1.0. |
| |
| tmp0 = VectorLoad(op0); |
| tmp1 = VectorLoad(op1): |
| dot = (tmp0.x * tmp1.x) + (tmp0.y * tmp1.y) + |
| (tmp0.z * tmp1.z) + tmp1.w; |
| result.x = dot; |
| result.y = dot; |
| result.z = dot; |
| result.w = dot; |
| |
| |
| 3.11.5.8 DST: Distance Vector |
| |
| The DST instruction computes a distance vector from two specially- |
| formatted operands. The first operand should be of the form [NA, |
| d^2, d^2, NA] and the second operand should be of the form [NA, 1/d, |
| NA, 1/d], where NA values are not relevant to the calculation and d |
| is a vector length. If both vectors satisfy these conditions, the |
| result vector will be of the form [1.0, d, d^2, 1/d]. |
| |
| The exact behavior is specified in the following pseudo-code: |
| |
| tmp0 = VectorLoad(op0); |
| tmp1 = VectorLoad(op1); |
| result.x = 1.0; |
| result.y = tmp0.y * tmp1.y; |
| result.z = tmp0.z; |
| result.w = tmp1.w; |
| |
| Given an arbitrary vector, d^2 can be obtained using the DP3 |
| instruction (using the same vector for both operands) and 1/d can be |
| obtained from d^2 using the RSQ instruction. |
| |
| This distance vector is useful for per-fragment light attenuation |
| calculations: a DP3 operation using the distance vector and an |
| attenuation constants vector as operands will yield the attenuation |
| factor. |
| |
| |
| 3.11.5.9 EX2: Exponential Base 2 |
| |
| The EX2 instruction approximates 2 raised to the power of the scalar |
| operand and replicates the approximation to all four components of |
| the result vector. |
| |
| tmp = ScalarLoad(op0); |
| result.x = Approx2ToX(tmp); |
| result.y = Approx2ToX(tmp); |
| result.z = Approx2ToX(tmp); |
| result.w = Approx2ToX(tmp); |
| |
| |
| 3.11.5.10 FLR: Floor |
| |
| The FLR instruction performs a component-wise floor operation on the |
| operand to generate a result vector. The floor of a value is |
| defined as the largest integer less than or equal to the value. The |
| floor of 2.3 is 2.0; the floor of -3.6 is -4.0. |
| |
| tmp = VectorLoad(op0); |
| result.x = floor(tmp.x); |
| result.y = floor(tmp.y); |
| result.z = floor(tmp.z); |
| result.w = floor(tmp.w); |
| |
| |
| 3.11.5.11 FRC: Fraction |
| |
| The FRC instruction extracts the fractional portion of each |
| component of the operand to generate a result vector. The |
| fractional portion of a component is defined as the result after |
| subtracting off the floor of the component (see FLR), and is always |
| in the range [0.0, 1.0). |
| |
| For negative values, the fractional portion is NOT the number |
| written to the right of the decimal point -- the fractional portion |
| of -1.7 is not 0.7 -- it is 0.3. 0.3 is produced by subtracting the |
| floor of -1.7 (-2.0) from -1.7. |
| |
| tmp = VectorLoad(op0); |
| result.x = fraction(tmp.x); |
| result.y = fraction(tmp.y); |
| result.z = fraction(tmp.z); |
| result.w = fraction(tmp.w); |
| |
| |
| 3.11.5.12 LG2: Logarithm Base 2 |
| |
| The LG2 instruction approximates the base 2 logarithm of the scalar |
| operand and replicates it to all four components of the result |
| vector. |
| |
| tmp = ScalarLoad(op0); |
| result.x = ApproxLog2(tmp); |
| result.y = ApproxLog2(tmp); |
| result.z = ApproxLog2(tmp); |
| result.w = ApproxLog2(tmp); |
| |
| If the scalar operand is zero or negative, the result is undefined. |
| |
| |
| 3.11.5.13 LIT: Light Coefficients |
| |
| The LIT instruction accelerates per-fragment lighting by computing |
| lighting coefficients for ambient, diffuse, and specular light |
| contributions. The "x" component of the single operand is assumed |
| to hold a diffuse dot product (n dot VP_pli, as in the vertex |
| lighting equations in Section 2.13.1). The "y" component of the |
| operand is assumed to hold a specular dot product (n dot h_i). The |
| "w" component of the operand is assumed to hold the specular |
| exponent of the material (s_rm), and is clamped to the range (-128, |
| +128) exclusive. |
| |
| The "x" component of the result vector receives the value that |
| should be multiplied by the ambient light/material product (always |
| 1.0). The "y" component of the result vector receives the value |
| that should be multiplied by the diffuse light/material product |
| (n dot VP_pli). The "z" component of the result vector receives the |
| value that should be multiplied by the specular light/material |
| product (f_i * (n dot h_i) ^ s_rm). The "w" component of the result |
| is the constant 1.0. |
| |
| Negative diffuse and specular dot products are clamped to 0.0, as is |
| done in the standard per-vertex lighting operations. In addition, |
| if the diffuse dot product is zero or negative, the specular |
| coefficient is forced to zero. |
| |
| tmp = VectorLoad(op0); |
| if (tmp.x < 0) tmp.x = 0; |
| if (tmp.y < 0) tmp.y = 0; |
| if (tmp.w < -(128.0-epsilon)) tmp.w = -(128.0-epsilon); |
| else if (tmp.w > 128-epsilon) tmp.w = 128-epsilon; |
| result.x = 1.0; |
| result.y = tmp.x; |
| result.z = (tmp.x > 0) ? RoughApproxPower(tmp.y, tmp.w) : 0.0; |
| result.w = 1.0; |
| |
| The exponentiation approximation function may be defined in terms of |
| the base 2 exponentiation and logarithm approximation operations in |
| the EX2 and LG2 instructions, where |
| |
| ApproxPower(a,b) = ApproxExp2(b * ApproxLog2(a)). |
| |
| In particular, the approximation may not be any more accurate than |
| the underlying EX2 and LG2 operations. |
| |
| Also, since 0^0 is defined to be 1, RoughApproxPower(0.0, 0.0) will |
| produce 1.0. |
| |
| |
| 3.11.5.14 LRP: Linear Interpolation |
| |
| The LRP instruction performs a component-wise linear interpolation |
| between the second and third operands using the first operand as the |
| blend factor. |
| |
| tmp0 = VectorLoad(op0); |
| tmp1 = VectorLoad(op1); |
| tmp2 = VectorLoad(op2); |
| result.x = tmp0.x * tmp1.x + (1 - tmp0.x) * tmp2.x; |
| result.y = tmp0.y * tmp1.y + (1 - tmp0.y) * tmp2.y; |
| result.z = tmp0.z * tmp1.z + (1 - tmp0.z) * tmp2.z; |
| result.w = tmp0.w * tmp1.w + (1 - tmp0.w) * tmp2.w; |
| |
| |
| 3.11.5.15 MAD: Multiply and Add |
| |
| The MAD instruction performs a component-wise multiply of the first two |
| operands, and then does a component-wise add of the product to the |
| third operand to yield a result vector. |
| |
| tmp0 = VectorLoad(op0); |
| tmp1 = VectorLoad(op1); |
| tmp2 = VectorLoad(op2); |
| result.x = tmp0.x * tmp1.x + tmp2.x; |
| result.y = tmp0.y * tmp1.y + tmp2.y; |
| result.z = tmp0.z * tmp1.z + tmp2.z; |
| result.w = tmp0.w * tmp1.w + tmp2.w; |
| |
| The multiplication and addition operations in this instruction are |
| subject to the same rules as described for the MUL and ADD |
| instructions. |
| |
| |
| 3.11.5.16 MAX: Maximum |
| |
| The MAX instruction computes component-wise maximums of the values |
| in the two operands to yield a result vector. |
| |
| tmp0 = VectorLoad(op0); |
| tmp1 = VectorLoad(op1); |
| result.x = (tmp0.x > tmp1.x) ? tmp0.x : tmp1.x; |
| result.y = (tmp0.y > tmp1.y) ? tmp0.y : tmp1.y; |
| result.z = (tmp0.z > tmp1.z) ? tmp0.z : tmp1.z; |
| result.w = (tmp0.w > tmp1.w) ? tmp0.w : tmp1.w; |
| |
| |
| 3.11.5.17 MIN: Minimum |
| |
| The MIN instruction computes component-wise minimums of the values |
| in the two operands to yield a result vector. |
| |
| tmp0 = VectorLoad(op0); |
| tmp1 = VectorLoad(op1); |
| result.x = (tmp0.x > tmp1.x) ? tmp1.x : tmp0.x; |
| result.y = (tmp0.y > tmp1.y) ? tmp1.y : tmp0.y; |
| result.z = (tmp0.z > tmp1.z) ? tmp1.z : tmp0.z; |
| result.w = (tmp0.w > tmp1.w) ? tmp1.w : tmp0.w; |
| |
| |
| 3.11.5.18 MOV: Move |
| |
| The MOV instruction copies the value of the operand to yield a |
| result vector. |
| |
| result = VectorLoad(op0); |
| |
| |
| 3.11.5.19 MUL: Multiply |
| |
| The MUL instruction performs a component-wise multiply of the two |
| operands to yield a result vector. |
| |
| tmp0 = VectorLoad(op0); |
| tmp1 = VectorLoad(op1); |
| result.x = tmp0.x * tmp1.x; |
| result.y = tmp0.y * tmp1.y; |
| result.z = tmp0.z * tmp1.z; |
| result.w = tmp0.w * tmp1.w; |
| |
| The following rules apply to multiplication: |
| |
| 1. <x> * <y> == <y> * <x>, for all <x> and <y>. |
| 2. +/-0.0 * <x> = +/-0.0, at least for all <x> that correspond to |
| representable numbers (IEEE "not a number" and "infinity" |
| encodings may be exceptions). |
| 3. +1.0 * <x> = <x>, for all <x>. |
| |
| Multiplication by zero and one should be invariant, as it may be |
| used to evaluate conditional expressions without branching. |
| |
| |
| 3.11.5.20 POW: Exponentiate |
| |
| The POW instruction approximates the value of the first scalar |
| operand raised to the power of the second scalar operand and |
| replicates it to all four components of the result vector. |
| |
| tmp0 = ScalarLoad(op0); |
| tmp1 = ScalarLoad(op1); |
| result.x = ApproxPower(tmp0, tmp1); |
| result.y = ApproxPower(tmp0, tmp1); |
| result.z = ApproxPower(tmp0, tmp1); |
| result.w = ApproxPower(tmp0, tmp1); |
| |
| The exponentiation approximation function may be implemented using |
| the base 2 exponentiation and logarithm approximation operations in |
| the EX2 and LG2 instructions. In particular, |
| |
| ApproxPower(a,b) = ApproxExp2(b * ApproxLog2(a)). |
| |
| Note that a logarithm may be involved even for cases where the |
| exponent is an integer. This means that it may not be possible to |
| exponentiate correctly with a negative base. In constrast, it is |
| possible in a "normal" mathematical formulation to raise negative |
| numbers to integral powers (e.g., (-3)^2== 9, and (-0.5)^-2==4). |
| |
| |
| 3.11.5.21 RCP: Reciprocal |
| |
| The RCP instruction approximates the reciprocal of the scalar |
| operand and replicates it to all four components of the result |
| vector. |
| |
| tmp = ScalarLoad(op0); |
| result.x = ApproxReciprocal(tmp); |
| result.y = ApproxReciprocal(tmp); |
| result.z = ApproxReciprocal(tmp); |
| result.w = ApproxReciprocal(tmp); |
| |
| The following rule applies to reciprocation: |
| |
| 1. ApproxReciprocal(+1.0) = +1.0. |
| |
| |
| 3.11.5.22 RSQ: Reciprocal Square Root |
| |
| The RSQ instruction approximates the reciprocal of the square root |
| of the absolute value of the scalar operand and replicates it to all |
| four components of the result vector. |
| |
| tmp = fabs(ScalarLoad(op0)); |
| result.x = ApproxRSQRT(tmp); |
| result.y = ApproxRSQRT(tmp); |
| result.z = ApproxRSQRT(tmp); |
| result.w = ApproxRSQRT(tmp); |
| |
| |
| 3.11.5.23 SCS: Sine/Cosine |
| |
| The SCS instruction approximates the trigonometric sine and cosine |
| of the angle specified by the scalar operand and places the cosine |
| in the x component and the sine in the y component of the result |
| vector. The z and w components of the result vector are undefined. |
| The angle is specified in radians and must be in the range [-PI,PI]. |
| |
| tmp = ScalarLoad(op0); |
| result.x = ApproxCosine(tmp); |
| result.y = ApproxSine(tmp); |
| |
| If the scalar operand is not in the range [-PI,PI], the result |
| vector is undefined. |
| |
| |
| 3.11.5.24 SGE: Set On Greater or Equal Than |
| |
| The SGE instruction performs a component-wise comparison of the two |
| operands. Each component of the result vector is 1.0 if the |
| corresponding component of the first operands is greater than or |
| equal that of the second, and 0.0 otherwise. |
| |
| tmp0 = VectorLoad(op0); |
| tmp1 = VectorLoad(op1); |
| result.x = (tmp0.x >= tmp1.x) ? 1.0 : 0.0; |
| result.y = (tmp0.y >= tmp1.y) ? 1.0 : 0.0; |
| result.z = (tmp0.z >= tmp1.z) ? 1.0 : 0.0; |
| result.w = (tmp0.w >= tmp1.w) ? 1.0 : 0.0; |
| |
| |
| 3.11.5.25 SIN: Sine |
| |
| The SIN instruction approximates the trigonometric sine of the angle |
| specified by the scalar operand and replicates it to all four |
| components of the result vector. The angle is specified in radians |
| and does not have to be in the range [-PI,PI]. |
| |
| tmp = ScalarLoad(op0); |
| result.x = ApproxSine(tmp); |
| result.y = ApproxSine(tmp); |
| result.z = ApproxSine(tmp); |
| result.w = ApproxSine(tmp); |
| |
| |
| 3.11.5.26 SLT: Set On Less Than |
| |
| The SLT instruction performs a component-wise comparison of the two |
| operands. Each component of the result vector is 1.0 if the |
| corresponding component of the first operand is less than that of |
| the second, and 0.0 otherwise. |
| |
| tmp0 = VectorLoad(op0); |
| tmp1 = VectorLoad(op1); |
| result.x = (tmp0.x < tmp1.x) ? 1.0 : 0.0; |
| result.y = (tmp0.y < tmp1.y) ? 1.0 : 0.0; |
| result.z = (tmp0.z < tmp1.z) ? 1.0 : 0.0; |
| result.w = (tmp0.w < tmp1.w) ? 1.0 : 0.0; |
| |
| |
| 3.11.5.27 SUB: Subtract |
| |
| The SUB instruction performs a component-wise subtraction of the |
| second operand from the first to yield a result vector. |
| |
| tmp0 = VectorLoad(op0); |
| tmp1 = VectorLoad(op1); |
| result.x = tmp0.x - tmp1.x; |
| result.y = tmp0.y - tmp1.y; |
| result.z = tmp0.z - tmp1.z; |
| result.w = tmp0.w - tmp1.w; |
| |
| |
| 3.11.5.28 SWZ: Extended Swizzle |
| |
| The SWZ instruction loads the single vector operand, and performs a |
| swizzle operation more powerful than that provided for loading |
| normal vector operands to yield an instruction vector. |
| |
| After the operand is loaded, the "x", "y", "z", and "w" components |
| of the result vector are selected by the first, second, third, and |
| fourth matches of the <xyzwExtSwizComp> or <rgbaExtSwizComp> pattern |
| in the <extendedSwizzle> rule. |
| |
| A result component can be selected from any of the four components |
| of the operand or the constants 0.0 and 1.0. The result component |
| can also be optionally negated. The following pseudocode describes |
| the component selection method. "operand" refers to the vector |
| operand. "select" is an enumerant where the values ZERO, ONE, X, Y, |
| Z, and W correspond to the <xyzwExtSwizSel> rule matching "0", "1", "x", |
| "y", "z", and "w", respectively, or the <rgbaExtSwizSel> rule |
| matching "0", 1", "r", "g", "b", and "a", respectively. "negate" is |
| TRUE if and only if the <optionalSign> rule in <xyzwExtSwizComp> |
| or <rgbaExtSwizComp> matches "-". |
| |
| float ExtSwizComponent(floatVec operand, enum select, boolean negate) |
| { |
| float result; |
| switch (select) { |
| case ZERO: result = 0.0; break; |
| case ONE: result = 1.0; break; |
| case X: result = operand.x; break; |
| case Y: result = operand.y; break; |
| case Z: result = operand.z; break; |
| case W: result = operand.w; break; |
| } |
| if (negate) { |
| result = -result; |
| } |
| return result; |
| } |
| |
| The entire extended swizzle operation is then defined using the |
| following pseudocode: |
| |
| tmp = VectorLoad(op0); |
| result.x = ExtSwizComponent(tmp, xSelect, xNegate); |
| result.y = ExtSwizComponent(tmp, ySelect, yNegate); |
| result.z = ExtSwizComponent(tmp, zSelect, zNegate); |
| result.w = ExtSwizComponent(tmp, wSelect, wNegate); |
| |
| "xSelect", "xNegate", "ySelect", "yNegate", "zSelect", "zNegate", |
| "wSelect", and "wNegate" correspond to the "select" and "negate" |
| values above for the four <xyzwExtSwizComp> or <rgbaExtSwizComp> |
| matches. |
| |
| Since this instruction allows for component selection and negation |
| for each individual component, the grammar does not allow the use of |
| the normal swizzle and negation operations allowed for vector |
| operands in other instructions. |
| |
| |
| 3.11.5.29 XPD: Cross Product |
| |
| The XPD instruction computes the cross product using the first three |
| components of its two vector operands to generate the x, y, and z |
| components of the result vector. The w component of the result |
| vector is undefined. |
| |
| tmp0 = VectorLoad(op0); |
| tmp1 = VectorLoad(op1); |
| result.x = tmp0.y * tmp1.z - tmp0.z * tmp1.y; |
| result.y = tmp0.z * tmp1.x - tmp0.x * tmp1.z; |
| result.z = tmp0.x * tmp1.y - tmp0.y * tmp1.x; |
| |
| |
| 3.11.6 Fragment Program Texture Instruction Set |
| |
| The first three texture instructions described below specify the |
| mapping of 4-tuple vectors to colors of an image. The sampling of |
| the texture works as described in section 3.8, except that texture |
| environments and texture functions are not applicable, and the |
| texture enables hierarchy is replaced by explicit references to |
| the desired texture target (i.e., 1D, 2D, 3D, cube map, rectangle). |
| These texture instructions specify how the 4-tuple is mapped into |
| the coordinates used for sampling. The following function is used |
| to describe the texture sampling in the descriptions below: |
| |
| vec4 TextureSample(float s, float t, float r, float lodBias, |
| int texImageUnit, enum texTarget); |
| |
| Note that not all three texture coordinates, s, t, and r, are |
| used by all texture targets. In particular, 1D texture targets only |
| use the s component, and 2D and rectangle (non-power-of-two) texture |
| targets only use the s and t components. The descriptions of the |
| texture instructions below supply all three components, as would be |
| the case with 3D or cube map targets. |
| |
| If a fragment program samples from a texture target on a texture |
| image unit where the bound texture object is not complete, as |
| defined in section 3.8.9, the result will be the vector |
| (R, G, B, A) = (0, 0, 0, 1). |
| |
| A fragment program will fail to load if it attempts to sample from |
| multiple texture targets on the same texture image unit. For |
| example, the following program would fail to load: |
| |
| !!ARBfp1.0 |
| TEX result.color, fragment.texcoord[0], texture[0], 2D; |
| TEX result.depth, fragment.texcoord[1], texture[0], 3D; |
| END |
| |
| The fourth texture instruction described below, KIL, does not sample |
| from a texture, but rather prevents further processing of the |
| current fragment if any component of its 4-tuple vector is less than |
| zero. |
| |
| A dependent texture instruction is one that samples using a texture |
| coordinate residing in a temporary, rather than in an attribute or |
| a parameter. A program may have a chain of dependent texture |
| instructions, where the result of the first texture instruction is |
| used as the coordinate for a second texture instruction, which is in |
| turn used as the coordinate for a third texture instruction, and so |
| on. Each node in this chain is termed an indirection, and can be |
| thought of as a set of texture samples that execute in parallel |
| followed by a sequence of ALU instructions. |
| |
| Some implementations may have limitations on how long the dependency |
| chain may be, and so indirections are counted as a resource just |
| like instructions or temporaries are counted. All programs have at |
| least one indirection, or one node in this chain, even if the |
| program performs no texture operation. Each instruction encountered |
| is included in this node until a texture instruction is encountered |
| |
| - whose texture coordinate is a temporary that has been previously |
| written in the current node; or |
| |
| - whose result vector is a temporary that is also the operand or |
| result vector of a previous ALU instruction in the current node. |
| |
| A new node is then started, including the texture instruction and |
| all subsequent instructions, and the process repeats for all |
| instructions in the program. Note that for simplicity in counting, |
| result writemasks and operand suffixes are not taken into |
| consideration when counting indirections. |
| |
| |
| 3.11.6.1 TEX: Map coordinate to color |
| |
| The TEX instruction takes the first three components of |
| its source vector, and maps them to s, t, and r. These coordinates |
| are used to sample from the specified texture target on the |
| specified texture image unit in a manner consistent with its |
| parameters. The resulting sample is mapped to RGBA as described in |
| table 3.21 and written to the result vector. |
| |
| tmp = VectorLoad(op0); |
| result = TextureSample(tmp.x, tmp.y, tmp.z, 0.0, op1, op2); |
| |
| |
| 3.11.6.2 TXP: Project coordinate and map to color |
| |
| The TXP instruction divides the first three components of its source |
| vector by the fourth component and maps the results to s, t, and r. |
| These coordinates are used to sample from the specified texture |
| target on the specified texture image unit in a manner consistent |
| with its parameters. The resulting sample is mapped to RGBA as |
| described in table 3.21 and written to the result vector. If the |
| value of the fourth component of the source vector is less than or |
| equal to zero, the result vector is undefined. |
| |
| tmp = VectorLoad(op0); |
| tmp.x = tmp.x / tmp.w; |
| tmp.y = tmp.y / tmp.w; |
| tmp.z = tmp.z / tmp.w; |
| result = TextureSample(tmp.x, tmp.y, tmp.z, 0.0, op1, op2); |
| |
| |
| 3.11.6.3 TXB: Map coordinate to color while biasing its LOD |
| |
| The TXB instruction takes the first three components of its source |
| vector and maps them to s, t, and r. These coordinates are used to |
| sample from the specified texture target on the specified texture |
| image unit in a manner consistent with its parameters. |
| Additionally, the fourth component of the source vector is applied |
| to equation 3.14 as fragment_bias below to further bias the level of |
| detail. |
| |
| lambda'(x,y) = log2[p(x,y)] + |
| clamp(texobj_bias + texunit_bias + fragment_bias) |
| |
| The resulting sample is mapped to RGBA as described in table 3.21 |
| and written to the result vector. |
| |
| tmp = VectorLoad(op0); |
| result = TextureSample(tmp.x, tmp.y, tmp.z, tmp.w, op1, op2); |
| |
| |
| 3.11.6.4 KIL: Kill fragment |
| |
| Rather than mapping a coordinate set to a color, this function |
| prevents a fragment from receiving any future processing. If any |
| component of its source vector is negative, the processing of this |
| fragment will be discontinued and no further outputs to this |
| fragment will occur. Subsequent stages of the GL pipeline will be |
| skipped for this fragment. |
| |
| tmp = VectorLoad(op0); |
| if ((tmp.x < 0) || (tmp.y < 0) || |
| (tmp.z < 0) || (tmp.w < 0)) |
| { |
| exit; |
| } |
| |
| |
| 3.11.7 Program Matrices |
| |
| In addition to GL's conventional matrices, several additional |
| program matrices are available for use as program parameters. These |
| matrices have names of the form MATRIX<i>_ARB where <i> is between |
| zero and <n>-1 where <n> is the value of the implementation- |
| dependent constant MAX_PROGRAM_MATRICES_ARB. The MATRIX<i>_ARB |
| constants obey MATRIX<i>_ARB = MATRIX0_ARB + <i>. The value of |
| MAX_PROGRAM_MATRICES_ARB must be at least eight. The maximum stack |
| depth for program matrices is defined by the |
| MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB and must be at least 1. |
| |
| |
| 3.11.8 Required Fragment Program State |
| |
| The state required to support program objects of all targets |
| consists of: |
| |
| an integer for the program error position, initially -1; |
| |
| an array of ubytes for the program error string, initially empty; |
| |
| and the state that must be maintained to indicate which integers |
| are currently in use as program object names. |
| |
| The state required to support the fragment program target consists |
| of: |
| |
| a bit indicating whether or not fragment program mode is enabled, |
| initially disabled; |
| |
| a set of MAX_PROGRAM_ENV_PARAMETERS_ARB four-component floating- |
| point program environment parameters, initially set to (0,0,0,0); |
| |
| an unsigned integer naming the currently bound fragment program, |
| initially zero; |
| |
| The state required for each fragment program object consists of: |
| |
| an unsigned integer indicating the program object name; |
| |
| an array of type ubyte containing the program string, initially |
| empty; |
| |
| an unsigned integer holding the length of the program string, |
| initially zero; |
| |
| an enum indicating the program string format, initially |
| PROGRAM_FORMAT_ASCII_ARB; |
| |
| a bit indicating whether or not the program exceeds the native |
| limits; |
| |
| six unsigned integers holding the number of instruction (ALU, |
| texture, and total), texture indirection, temporary variable, and |
| program parameter binding resources used by the program, initially |
| all zero; |
| |
| six unsigned integers holding the number of native instruction |
| (ALU, texture, and total), texture indirection, temporary |
| variable, and program parameter binding resources used by the |
| program, initially all zero; |
| |
| and a set of MAX_PROGRAM_LOCAL_PARAMETERS_ARB four-component |
| floating-point program local parameters, initially set to |
| (0,0,0,0). |
| |
| Initially, no fragment program objects exist. |
| |
| |
| Additions to Chapter 4 of the OpenGL 1.3 Specification (Per-Fragment |
| Operations and the Frame Buffer) |
| |
| None |
| |
| |
| Additions to Chapter 5 of the OpenGL 1.3 Specification (Special |
| Functions) |
| |
| Modify Section 5.4, Display Lists (p. 191) |
| |
| (modify third paragraph, p. 195) ... These are IsList, GenLists, |
| ..., IsProgramARB, GenProgramsARB, and DeleteProgramsARB, as well as |
| IsEnabled and all the Get commands (chapter 6). |
| |
| |
| Additions to Chapter 6 of the OpenGL 1.3 Specification (State and |
| State Requests) |
| |
| Modify Section 6.1.2, Data Conversions (p. 198) |
| |
| (add before last paragraph, p. 198) The matrix selected by the |
| current matrix mode can be queried by calling GetBooleanv, |
| GetIntegerv, GetFloatv, and GetDoublev with <pname> set to |
| CURRENT_MATRIX_ARB; the matrix will be returned in transposed form |
| with <pname> set to TRANSPOSE_CURRENT_MATRIX_ARB. The depth of the |
| selected matrix stack can be queried with <pname> set to |
| CURRENT_MATRIX_STACK_DEPTH_ARB. Querying CURRENT_MATRIX_ARB and |
| CURRENT_MATRIX_STACK_DEPTH_ARB is the only means for querying the |
| matrix and matrix stack depth of the program matrices described in |
| section 3.11.7. |
| |
| |
| (add to end of last paragraph, p. 199) Queries of texture state |
| variables corresponding to texture coordinate processing unit |
| (namely, TexGen state and enables, and matrices) will produce an |
| INVALID_OPERATION error if the value of ACTIVE_TEXTURE is greater |
| than or equal to MAX_TEXTURE_COORDS_ARB. All other texture state |
| queries will result in an INVALID_OPERATION error if the value of |
| ACTIVE_TEXTURE is greater than or equal to |
| MAX_TEXTURE_IMAGE_UNITS_ARB. |
| |
| |
| Modify Section 6.1.11, Pointer and String Queries (p. 206) |
| |
| (modify last paragraph, p. 206) ... The possible values for <name> |
| are VENDOR, RENDERER, VERSION, EXTENSIONS, and |
| PROGRAM_ERROR_STRING_ARB. |
| |
| |
| (add after last paragraph of section, p. 207) Queries of |
| PROGRAM_ERROR_STRING_ARB return a pointer to an implementation- |
| dependent program load error string. If the last call to |
| ProgramStringARB failed to load a program, the returned string |
| describes at least one reason why the program failed to load. If |
| the last call to ProgramStringARB successfully loaded a program, the |
| returned string may be empty (containing only a zero terminator) or |
| may contain one or more implementation-dependent warning messages. |
| The contents of the error string are guaranteed to remain constant |
| only until the next ProgramStringARB command, which may overwrite |
| the error string. |
| |
| |
| Insert a new Section 6.1.12, Program Queries (p. 207), between |
| existing sections 6.1.11 and 6.1.12. |
| |
| 6.1.12 Program Queries |
| |
| The commands |
| |
| void GetProgramEnvParameterdvARB(enum target, uint index, |
| double *params); |
| void GetProgramEnvParameterfvARB(enum target, uint index, |
| float *params); |
| |
| obtain the current value for the program environment parameter |
| numbered <index> for the given program target <target>, and places |
| the information in the array <params>. The error INVALID_ENUM is |
| generated if <target> specifies a nonexistent program target or a |
| program target that does not support program environment parameters. |
| The error INVALID_VALUE is generated if <index> is greater than or |
| equal to the implementation-dependent number of supported program |
| environment parameters for the program target. |
| |
| When <target> is FRAGMENT_PROGRAM_ARB, each program parameter |
| returned is an array of four values. |
| |
| The commands |
| |
| void GetProgramLocalParameterdvARB(enum target, uint index, |
| double *params); |
| void GetProgramLocalParameterfvARB(enum target, uint index, |
| float *params); |
| |
| obtain the current value for the program local parameter numbered |
| <index> belonging to the program object currently bound to <target>, |
| and places the information in the array <params>. The error |
| INVALID_ENUM is generated if <target> specifies a nonexistent |
| program target or a program target that does not support program |
| local parameters. The error INVALID_VALUE is generated if <index> |
| is greater than or equal to the implementation-dependent number of |
| supported program local parameters for the program target. |
| |
| When the program target type is FRAGMENT_PROGRAM_ARB, each program |
| local parameter returned is an array of four values. |
| |
| The command |
| |
| void GetProgramivARB(enum target, enum pname, int *params); |
| |
| obtains program state for the program target <target>, writing the |
| state into the array given by <params>. GetProgramivARB can be used |
| to determine the properties of the currently bound program object or |
| implementation limits for <target>. |
| |
| If <pname> is PROGRAM_LENGTH_ARB, PROGRAM_FORMAT_ARB, or |
| PROGRAM_BINDING_ARB, GetProgramivARB returns one integer holding the |
| program string length (in bytes), program string format, and program |
| name, respectively, for the program object currently bound to |
| <target>. |
| |
| If <pname> is MAX_PROGRAM_LOCAL_PARAMETERS_ARB or |
| MAX_PROGRAM_ENV_PARAMETERS_ARB, GetProgramivARB returns one integer |
| holding the maximum number of program local parameters or program |
| environment parameters, respectively, supported for the program |
| target <target>. |
| |
| If <pname> is MAX_PROGRAM_INSTRUCTIONS_ARB, |
| MAX_PROGRAM_ALU_INSTRUCTIONS_ARB, MAX_PROGRAM_TEX_INSTRUCTIONS_ARB, |
| MAX_PROGRAM_TEX_INDIRECTIONS_ARB, MAX_PROGRAM_TEMPORARIES_ARB, |
| MAX_PROGRAM_PARAMETERS_ARB, or MAX_PROGRAM_ATTRIBS_ARB, |
| GetProgramivARB returns a single integer giving the maximum number |
| of total instructions, ALU instructions, texture instructions, |
| texture indirections, temporaries, parameters, and attributes that |
| can be used by a program of type <target>. If <pname> is |
| PROGRAM_INSTRUCTIONS_ARB, PROGRAM_ALU_INSTRUCTIONS_ARB, |
| PROGRAM_TEX_INSTRUCTIONS_ARB, PROGRAM_TEX_INDIRECTIONS_ARB, |
| PROGRAM_TEMPORARIES_ARB, PROGRAM_PARAMETERS_ARB, or |
| PROGRAM_ATTRIBS_ARB, GetProgramivARB returns a single integer giving |
| the number of total instructions, ALU instructions, texture |
| instructions, texture indirections, temporaries, parameters, and |
| attributes used by the current program for <target>. |
| |
| If <pname> is MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, |
| MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB, |
| MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB, |
| MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB, |
| MAX_PROGRAM_NATIVE_TEMPORARIES_ARB, |
| MAX_PROGRAM_NATIVE_PARAMETERS_ARB, or |
| MAX_PROGRAM_NATIVE_ATTRIBS_ARB, GetProgramivARB returns a single |
| integer giving the maximum number of native instruction, ALU |
| instruction, texture instruction, texture indirection, temporary, |
| parameter, and attribute resources available to a program of type |
| <target>. If <pname> is PROGRAM_NATIVE_INSTRUCTIONS_ARB, |
| PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB, |
| PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB, |
| PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB, |
| PROGRAM_NATIVE_TEMPORARIES_ARB, PROGRAM_NATIVE_PARAMETERS_ARB, or |
| PROGRAM_NATIVE_ATTRIBS_ARB, GetProgramivARB returns a single integer |
| giving the number of native instruction, ALU instruction, texture |
| instruction, texture indirection, temporary, parameter, and |
| attribute resources consumed by the program currently bound to |
| <target>. Native resource counts will reflect the results of |
| implementation-dependent scheduling and optimization algorithms |
| applied by the GL, as well as emulation of non-native features. If |
| <pname> is PROGRAM_UNDER_NATIVE_LIMITS_ARB, GetProgramivARB returns |
| 0 if the native resource consumption of the program currently bound |
| to <target> exceeds the number of available resources for any |
| resource type, and 1 otherwise. |
| |
| The command |
| |
| void GetProgramStringARB(enum target, enum pname, void *string); |
| |
| obtains the program string for the program object bound to <target> |
| and places the information in the array <string>. <pname> must be |
| PROGRAM_STRING_ARB. <n> ubytes are returned into the array program |
| where <n> is the length of the program in ubytes, as returned by |
| GetProgramivARB when <pname> is PROGRAM_LENGTH_ARB. The program |
| string is always returned using the format given when the program |
| string was specified. |
| |
| The command |
| |
| boolean IsProgramARB(uint program); |
| |
| returns TRUE if <program> is the name of a program object. If |
| <program> is zero or is a non-zero value that is not the name of a |
| program object, or if an error condition occurs, IsProgramARB |
| returns FALSE. A name returned by GenProgramsARB, but not yet |
| bound, is not the name of a program object. |
| |
| |
| Modify Section 6.2, State Tables (p. 216) |
| |
| (add to caption of Table 6.5) When accessing the current texture |
| coordinates (CURRENT_TEXTURE_COORDS) or the texture coordinates |
| associated with raster position (CURRENT_RASTER_TEXTURE_COORDS), the |
| active texture unit selector (ACTIVE_TEXTURE) must be less than the |
| implementation dependent maximum number of texture coordinate sets |
| (MAX_TEXTURE_COORDS_ARB). |
| |
| (add to caption of Table 6.8) When accessing the texture matrix |
| stack (TEXTURE_MATRIX, TRANSPOSE_TEXTURE_MATRIX) or the texture |
| matrix stack pointer (TEXTURE_STACK_DEPTH), the active texture unit |
| selector (ACTIVE_TEXTURE) must be less than the implementation |
| dependent maximum number of texture coordinate sets |
| (MAX_TEXTURE_COORDS_ARB). |
| |
| (split Table 6.17 into two tables, Texture Environment and Texture |
| Coordinate Generation; move active texture unit selector and texture |
| coordinate generation state to table 6.18; renumber subsequent |
| tables) |
| |
| (add to captions of Tables 6.14, 6.15, 6.16) The active texture unit |
| selector (ACTIVE_TEXTURE) identifies which texture object is |
| accessed, and must be less than the implementation dependent maximum |
| number of texture image units (MAX_TEXTURE_IMAGE_UNITS_ARB). |
| |
| (add to caption of Table 6.18) With the exception of ACTIVE_TEXTURE, |
| the active texture unit selector (ACTIVE_TEXTURE) identifies which |
| texture coordinate set is accessed, and must be less than the |
| implementation dependent maximum number of texture coordinate sets |
| (MAX_TEXTURE_COORDS_ARB). |
| |
| Additions to Appendix A of the OpenGL 1.3 Specification (Invariance) |
| |
| Add to end of Section A.3 (p. 242): |
| |
| Rule 4. Fragment program instructions not relevant to the |
| calculation of any result must have no effect on that result. |
| |
| Rule 5. Fragment program instructions relevant to the calculation |
| of any result must always produce the identical result. |
| |
| Instructions relevant to the calculation of a result are any |
| instructions in a sequence of instructions that eventually determine |
| the source values for the calculation under consideration. |
| |
| There is no guaranteed invariance between fragment colors generated |
| by conventional GL texturing mode and fragment colors generated by |
| fragment program mode. Multi-pass rendering algorithms that require |
| rendering invariances to operate correctly should not mix |
| conventional GL fragment texturing mode with fragment program mode |
| for different rendering passes. However, such algorithms will |
| operate correctly if the algorithms limit themselves to a single |
| mode of fragment color generation. |
| |
| There is no guaranteed invariance between the final z window |
| coordinates of fragments processed by fragment programs that write |
| depth values and fragments processed by any other means, even if the |
| fragment programs in question simply copy the z value from the |
| "fragment.position" binding. Multi-pass rendering algorithms that |
| use depth-replacing fragment programs should use depth-replacing |
| fragment programs on each pass to guarantee identical z values. |
| |
| The texture sample chosen for a fragment of a primitive must be |
| invariant between fragment program mode and conventional texture |
| application mode subject to these conditions: |
| |
| 1. All state with the exception of fragment program state is |
| identical |
| |
| 2. The primitives generating the fragments are identical |
| |
| 3. The sample in the fragment program mode is the result of a |
| 'TEX' instruction (or a 'TXP' instruction with a unity q) |
| |
| 4. The texture coordinate operand for the texture instruction uses |
| the same texture coordinate set as the conventional mode sample |
| |
| 5. The texture coordinate operand for the texture instruction has |
| not been the result of any other operations in the fragment |
| program |
| |
| |
| Additions to the AGL/GLX/WGL Specifications |
| |
| Program objects are shared between AGL/GLX/WGL rendering contexts if |
| and only if the rendering contexts share display lists. No change |
| is made to the AGL/GLX/WGL API. |
| |
| Changes to program objects shared between multiple rendering |
| contexts will be serialized (i.e., the changes will occur in a |
| specific order). |
| |
| Changes to a program object made by one rendering context are not |
| guaranteed to take effect in another rendering context until the |
| other calls BindProgram to bind the program object. |
| |
| When a program object is deleted by one rendering context, the |
| object itself is not destroyed until it is no longer the current |
| program object in any context. However, the name of the deleted |
| object is removed from the program object name space, so the next |
| attempt to bind a program using the same name will create a new |
| program object. Recall that destroying a program object bound in |
| the current rendering context effectively unbinds the object being |
| destroyed. |
| |
| |
| Dependencies on OpenGL 1.4 |
| |
| If OpenGL 1.4 is not supported, the modified equation for the |
| calculation of level of detail by the TXB instruction in 3.11.6.3 |
| should read |
| |
| lambda'(x,y) = log2[p(x,y)] + |
| clamp(texunit_bias + fragment_bias) |
| |
| Dependencies on EXT_vertex_weighting and ARB_vertex_blend |
| |
| If EXT_vertex_weighting and ARB_vertex_blend are both not supported, |
| all discussions of multiple modelview matrices should be removed. |
| |
| In particular, the line in the grammar |
| |
| <stateMatrixName> ::= "modelview" <stateOptModMatNum> |
| |
| should be changed to |
| |
| <stateMatrixName> ::= "modelview" |
| |
| and the rules <stateOptModMatNum> and <stateModMatNum> should be |
| deleted. The first line of Table X.2.7 should be modified to read: |
| |
| Binding Underlying State |
| ------------------------------------ --------------------------- |
| state.matrix.modelview modelview matrix |
| |
| The caption for Table X.2.7 should be modified to exclude optional |
| modelview matrix number. Subsequent references to "modelview matrix |
| zero" and "modelview matrix 1" should be changed to "modelview |
| matrix" and the example "state.matrix.modelview[1].row[0]" should be |
| changed to "state.matrix.modelview.row[0]". |
| |
| |
| Dependencies on ARB_matrix_palette: |
| |
| If ARB_matrix_palette is not supported, all discussions of the |
| matrix palette should be removed. |
| |
| In particular, the line |
| |
| "palette" "[" <statePaletteMatNum> "]" |
| |
| should be removed from the <stateMatrixName> grammar rule, and the |
| <statePaletteMatNum> grammar rule should be removed entirely. |
| "state.matrix.palette[n]" should be removed from Table X.2.7. |
| |
| |
| Dependencies on ARB_transpose_matrix |
| |
| If ARB_transpose_matrix is not supported, the discussion of |
| TRANSPOSE_CURRENT_MATRIX_ARB in the edits to section 6.1.2 should be |
| removed. |
| |
| |
| Dependencies on EXT_fog_coord |
| |
| If EXT_fog_coord is not supported, references to "fog coordinate" |
| in the definition of the "fragment.fogcoord" attribute should be |
| removed. |
| |
| Dependencies on EXT_texture_rectangle |
| |
| If NV_texture_rectangle is not supported, the discussion of the |
| rectangle (non-power-of-two) texture target in section 3.11.6 should |
| be removed, and the line |
| |
| "RECT" |
| |
| should be removed from the <texTarget> grammar rule. |
| |
| |
| Interactions with ARB_shadow |
| |
| The texture comparison introduced by ARB_shadow can be expressed in |
| terms of a fragment program, and in fact use the same internal |
| resources on some implementations. Therefore, if fragment program |
| mode is enabled, the GL behaves as if TEXTURE_COMPARE_MODE_ARB is |
| NONE. |
| |
| |
| Interactions with ARB_vertex_program |
| |
| The program object management entrypoints described in sections |
| 2.14.1 (for vertex programs) and 3.11.1 (for fragment programs) |
| are shared by both program targets. The PROGRAM_ERROR_STRING_ARB |
| and program queries in sections 6.1.11 and 6.1.12 are also shared, |
| as are all common tokens. |
| |
| The Errors section should be modified to generate INVALID_OPERATION |
| from the Get command with argument CURRENT_MATRIX_ARB, |
| TRANSPOSE_CURRENT_MATRIX_ARB, and CURRENT_MATRIX_STACK_DEPTH_ARB |
| when the current matrix mode is TEXTURE. |
| |
| In the presence of ARB_vertex_program, ARB_fragment_program must |
| recognize and return appropriate values for the GetProgram <pname> |
| tokens introduced in that spec but not otherwise shared by |
| ARB_fragment_program: |
| |
| PROGRAM_ADDRESS_REGISTERS_ARB 0x88B0 |
| MAX_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B1 |
| PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B2 |
| MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B3 |
| |
| The following tables list new program object state and |
| implementation-dependent state: |
| |
| Get Value Type Get Command Initial Value Description Sec Attrib |
| -------------------- ----- ------------------- --------------- ---------------------- -------- ------ |
| PROGRAM_ADDRESS_REGISTERS_ARB Z+ GetProgramivARB 0 bound program 6.1.12 - |
| address registers |
| PROGRAM_NATIVE_ADDRESS_ Z+ GetProgramivARB 0 bound program native 6.1.12 - |
| REGISTERS_ARB address registers |
| |
| Table X.7. Program Object State. Program object queries return attributes of |
| the program object currently bound to the program target <target>. |
| |
| |
| Minimum |
| Get Value Type Get Command Value Description Sec. Attrib |
| --------- ---- ----------- ------- ----------- ---- ------ |
| MAX_PROGRAM_ADDRESS_REGISTERS_ARB Z+ GetProgramivARB 0 maximum program 6.1.12 - |
| address registers |
| MAX_PROGRAM_NATIVE_A
|