| Name |
| |
| ATI_fragment_shader |
| |
| Name Strings |
| |
| GL_ATI_fragment_shader |
| |
| Contributors |
| |
| Dan Ginsburg |
| Evan Hart |
| Jason Mitchell |
| |
| Contact |
| |
| Benj Lipchak, AMD (benj.lipchak 'at' amd.com) |
| |
| Status |
| |
| Shipping (version 1.0) |
| |
| Version |
| |
| Last Modified Date: November 4, 2006 |
| Author Revision: 1.8 |
| |
| Number |
| |
| 245 |
| |
| Dependencies |
| |
| ARB_multitexture is required by this extension. |
| ARB_shadow interacts with this extension. |
| The extension is written against the OpenGL 1.2.1 Specification. |
| |
| Overview |
| |
| This extension exposes a powerful fragment shading model which |
| provides a very general means of expressing fragment color blending |
| and dependent texture address modification. The programming is |
| a register-based model in which there is a fixed number of |
| instructions, texture lookups, read/write registers, and constants. |
| |
| The fragment shader extension provides a unified instruction set |
| for operating on address or color data and eliminates the |
| distinction between the two. This extension provides all the |
| interfaces necessary to fully expose this programmable fragment |
| shader in GL. |
| |
| Although conceived as a device-independent extension which would |
| expose the capabilities of future generations of hardware, changing |
| trends in programmable hardware have affected the lifespan of this |
| extension. For this reason you will now find a fixed set of |
| features and resources exposed, and the queries to determine this |
| set have been deprecated. |
| |
| Issues |
| |
| None |
| |
| |
| New Procedures and Functions |
| |
| uint GenFragmentShadersATI (uint range); |
| |
| void BindFragmentShaderATI (uint id); |
| |
| void DeleteFragmentShaderATI (uint id); |
| |
| void BeginFragmentShaderATI (void); |
| |
| void EndFragmentShaderATI (void); |
| |
| void PassTexCoordATI (uint dst, uint coord, enum swizzle); |
| |
| void SampleMapATI (uint dst, uint interp, enum swizzle); |
| |
| void ColorFragmentOp1ATI (enum op, uint dst, uint dstMask, |
| uint dstMod, uint arg1, uint arg1Rep, |
| uint arg1Mod); |
| |
| void ColorFragmentOp2ATI (enum op, uint dst, uint dstMask, |
| uint dstMod, uint arg1, uint arg1Rep, |
| uint arg1Mod, uint arg2, uint arg2Rep, |
| uint arg2Mod); |
| |
| void ColorFragmentOp3ATI (enum op, uint dst, uint dstMask, |
| uint dstMod, uint arg1, uint arg1Rep, |
| uint arg1Mod, uint arg2, uint arg2Rep, |
| uint arg2Mod, uint arg3, uint arg3Rep, |
| uint arg3Mod); |
| |
| void AlphaFragmentOp1ATI (enum op, uint dst, uint dstMod, |
| uint arg1, uint arg1Rep, uint arg1Mod); |
| |
| void AlphaFragmentOp2ATI (enum op, uint dst, uint dstMod, |
| uint arg1, uint arg1Rep, uint arg1Mod, |
| uint arg2, uint arg2Rep, uint arg2Mod); |
| |
| void AlphaFragmentOp3ATI (enum op, uint dst, uint dstMod, |
| uint arg1, uint arg1Rep, uint arg1Mod, |
| uint arg2, uint arg2Rep, uint arg2Mod, |
| uint arg3, uint arg3Rep, uint arg3Mod); |
| |
| void SetFragmentShaderConstantATI (uint dst, const float *value); |
| |
| |
| New Tokens |
| |
| Accepted by the <cap> parameter of Enable, Disable, and IsEnabled, |
| and by the <pname> parameter of GetBooleanv, GetIntegerv, GetFloatv, |
| and GetDoublev: |
| |
| FRAGMENT_SHADER_ATI 0x8920 |
| |
| Accepted by the <dst> and <argN> parameters of |
| ColorFragmentOp[1..3]ATI and AlphaFragmentOp[1..3]ATI, and by the |
| <dst> and <coord> parameters of PassTexCoordATI, and by the <dst> |
| and <interp> parameters of SampleMapATI: |
| |
| REG_0_ATI 0x8921 |
| REG_1_ATI 0x8922 |
| REG_2_ATI 0x8923 |
| REG_3_ATI 0x8924 |
| REG_4_ATI 0x8925 |
| REG_5_ATI 0x8926 |
| |
| Accepted by the <dst> parameter of SetFragmentShaderConstantATI and |
| the <argN> parameter of ColorFragmentOp[1..3]ATI and |
| AlphaFragmentOp[1..3]ATI: |
| |
| CON_0_ATI 0x8941 |
| CON_1_ATI 0x8942 |
| CON_2_ATI 0x8943 |
| CON_3_ATI 0x8944 |
| CON_4_ATI 0x8945 |
| CON_5_ATI 0x8946 |
| CON_6_ATI 0x8947 |
| CON_7_ATI 0x8948 |
| |
| Accepted by the <op> parameter of ColorFragmentOp1ATI and |
| AlphaFragmentOp1ATI: |
| |
| MOV_ATI 0x8961 |
| |
| Accepted by the <op> parameter of ColorFragmentOp2ATI and |
| AlphaFragmentOp2ATI: |
| |
| ADD_ATI 0x8963 |
| MUL_ATI 0x8964 |
| SUB_ATI 0x8965 |
| DOT3_ATI 0x8966 |
| DOT4_ATI 0x8967 |
| |
| Accepted by the <op> parameter of ColorFragmentOp3ATI and |
| AlphaFragmentOp3ATI: |
| |
| MAD_ATI 0x8968 |
| LERP_ATI 0x8969 |
| CND_ATI 0x896A |
| CND0_ATI 0x896B |
| DOT2_ADD_ATI 0x896C |
| |
| Accepted by the <argN> parameter of ColorFragmentOp[1..3]ATI and |
| AlphaFragmentOp[1..3]ATI: |
| |
| ZERO |
| ONE |
| PRIMARY_COLOR_ARB |
| SECONDARY_INTERPOLATOR_ATI 0x896D |
| |
| Accepted by the <interp> parameter of SampleMapATI and the <coord> |
| parameter of PassTexCoordATI: |
| |
| TEXTURE0_ARB |
| TEXTURE1_ARB |
| TEXTURE2_ARB |
| TEXTURE3_ARB |
| TEXTURE4_ARB |
| TEXTURE5_ARB |
| TEXTURE6_ARB |
| TEXTURE7_ARB |
| |
| Accepted by the <swizzle> parameter of SampleMapATI and |
| PassTexCoordATI: |
| |
| SWIZZLE_STR_ATI 0x8976 |
| SWIZZLE_STQ_ATI 0x8977 |
| SWIZZLE_STR_DR_ATI 0x8978 |
| SWIZZLE_STQ_DQ_ATI 0x8979 |
| |
| Accepted by the <dstMask> parameter of ColorFragmentOp[1..3]ATI: |
| |
| NONE |
| RED_BIT_ATI 0x00000001 |
| GREEN_BIT_ATI 0x00000002 |
| BLUE_BIT_ATI 0x00000004 |
| |
| Accepted by the <argNRep> parameter of ColorFragmentOp[1..3]ATI and |
| AlphaFragmentOp[1..3]ATI: |
| |
| NONE |
| RED |
| GREEN |
| BLUE |
| ALPHA |
| |
| Accepted by the <dstMod> parameter of ColorFragmentOp[1..3]ATI and |
| AlphaFragmentOp[1..3]ATI: |
| |
| NONE |
| 2X_BIT_ATI 0x00000001 |
| 4X_BIT_ATI 0x00000002 |
| 8X_BIT_ATI 0x00000004 |
| HALF_BIT_ATI 0x00000008 |
| QUARTER_BIT_ATI 0x00000010 |
| EIGHTH_BIT_ATI 0x00000020 |
| SATURATE_BIT_ATI 0x00000040 |
| |
| |
| Accepted by the <argNMod> parameter of ColorFragmentOp[1..3]ATI and |
| AlphaFragmentOp[1..3]ATI: |
| |
| 2X_BIT_ATI 0x00000001 |
| COMP_BIT_ATI 0x00000002 |
| NEGATE_BIT_ATI 0x00000004 |
| BIAS_BIT_ATI 0x00000008 |
| |
| |
| Additions to Chapter 2 of the OpenGL 1.2.1 Specification (OpenGL |
| Operation) |
| |
| None |
| |
| |
| Additions to Chapter 3 of the OpenGL 1.2.1 Specification (Rasterization) |
| |
| Add New Subsection after 3.8.10, (p. 138) |
| |
| 3.8.11 Fragment Shaders |
| |
| By default, the current texture environment is used to determine |
| how textures are combined for rasterization. However, by enabling |
| FRAGMENT_SHADER_ATI, the currently bound fragment shader is used to |
| determine how textures are combined. The fragment shader replaces |
| the traditional texture environment by exposing a fragment shading |
| model which provides a very general means of expressing fragment |
| color blending and dependent texture address modification. The |
| distinction between texture address and color data becomes |
| irrelevant in the fragment shader as the two can be used |
| interchangeably. |
| |
| A shader is defined between a BeginFragmentShaderATI and |
| EndFragmentShaderATI block. These commands are defined as follows: |
| |
| void BeginFragmentShaderATI(void); |
| void EndFragmentShaderATI(void); |
| |
| Although there is no restriction as to which GL operations may be |
| specified between BeginFragmentShaderATI and EndFragmentShaderATI, |
| only the following operations will be compiled into a shader: |
| PassTexCoordATI, SampleMapATI, ColorFragmentOp[1..3]ATI, |
| AlphaFragmentOp[1..3]ATI, and SetFragmentShaderContantATI. |
| |
| In addition to a default fragment shader, named shaders can be |
| created. The namespace for shaders is unsigned integers with zero |
| reserved by the GL. A shader is created by binding an unused name |
| using: |
| |
| void BindFragmentShaderATI(uint id); |
| |
| where <id> is the unused name. Once a shader has been created it |
| can be rebound as the active shader by calling |
| BindFragmentShaderATI. A shader can be deleted, freeing the name, |
| by calling: |
| |
| void DeleteFragmentShaderATI(uint id); |
| |
| where <id> is the name to be deleted. Unique names can be generated |
| using: |
| |
| uint GenFragmentShadersATI(uint range); |
| |
| where <range> is the number of contiguous ids that should be |
| created. It returns an integer n such that <range> contiguous empty |
| shader ids, with values n, n+1, ..., n+<range>-1, are created. If |
| <range> is 0, if there is no group of <range> contiguous names |
| available, or if any error is generated, no shaders are generated, |
| and 0 is returned. |
| |
| If FRAGMENT_SHADER_ATI is enabled, but the currently bound shader is |
| invalid, the results of drawing commands are undefined. A shader |
| may be invalid because it is currently being specified (i.e., a |
| drawing command within a Begin/EndFragmentShader pair), or due to |
| some error during the specification of a shader. |
| |
| There are three types of data that can be in a fragment shader: |
| registers, constants, and interpolators. The 6 REG_x_ATI registers |
| can be used as source or destination in any color or alpha |
| instruction. The final result of the shader is whatever value is in |
| REG_0_ATI. This value will be the final color of the output |
| fragment passed. |
| |
| There are 8 constant registers available, CON_0_ATI through |
| CON_7_ATI. CON_x_ATI constants can be used as source in any color |
| or alpha instruction, but at most 2 different constants may be used |
| as source arguments in each instruction. |
| |
| Additionally, the primary and secondary color interpolators are |
| available as source in any color or alpha instruction, but only in |
| the last pass of the shader (i.e., the only pass of a one-pass |
| shader or the second pass of a two-pass shader). |
| |
| Either one or two passes may be specified in a shader. Each pass |
| may use up to 8 pairs of instructions for a total of at most 16 |
| pairs in the shader. A pair consists of one color instruction and |
| one alpha instruction. |
| |
| The first instructions specified in each pass of a shader are "free" |
| instructions in that they don't count against the 8 instructions |
| available in each pass. They are routing instructions which specify |
| from where the contents of the registers come. The first occurance |
| of one of these free instructions marks the beginning of a pass in |
| the shader. They are specified with SampleMapATI and |
| PassTexCoordATI. |
| |
| The entry point: |
| |
| void PassTexCoordATI (uint dst, uint coord, enum swizzle); |
| |
| specifies that the value present in <coord> is passed directly into |
| the contents of <dst> (one of the registers REG_x_ATI). This value |
| is then available for use as a source argument to subsequent color |
| and alpha instructions following in the same pass. <coord> may |
| either be the texture coordinates on a texture unit (TEXTUREx_ARB), |
| or in the case of a two-pass shader's second pass, it may be the |
| value of a register set in the first pass (REG_x_ATI). |
| |
| Note that in order to preserve the contents of a register from the |
| first pass to the second, there must be a PassTexCoordATI |
| instruction in the setup for the second pass that assigns that |
| register to itself. For example: |
| |
| PassTexCoordATI(REG_1_ATI, REG_1_ATI, SWIZZLE_STR_ATI); |
| |
| will preserve the first 3 components of REG_1_ATI for use in the |
| second pass. |
| |
| The entry point: |
| |
| void SampleMapATI (uint dst, uint interp, enum swizzle); |
| |
| specifies that the value present in the texture data bound on the |
| unit associated with <dst> will be written to that register. A |
| value for <dst> of REG_x_ATI means that TEXTUREx_ARB will be |
| sampled, and the result written to REG_x_ATI. The <interp> |
| parameter specifies which texture coordinate interpolator is used to |
| sample the map. A value of REG_x_ATI for <interp> in the second |
| pass of a two-pass shader will do dependent texture read sampling |
| using the value in register x. Otherwise, specifying TEXTUREx_ARB |
| will sample the map using the texture coordinates on unit x. |
| |
| Only the first 3 components of <coord> or <interp> are used in |
| PassTexCoordATI and SampleMapATI, respectively. The swizzle |
| parameter is used to select which of the 4 original components of |
| the source register or texture coordinates will be mapped to the 3 |
| available positions, and whether or not a projection will occur. |
| |
| Table 3.20 shows the <swizzle> modes: |
| |
| |
| Coordinates Used for 1D or Coordinates Used for |
| Swizzle 2D SampleMap and PassTexCoord 3D or cubemap SampleMap |
| ------- ----------------------------- ----------------------- |
| SWIZZLE_STR_ATI (s, t, r, undefined) (s, t, r, undefined) |
| SWIZZLE_STQ_ATI (s, t, q, undefined) (s, t, q, undefined) |
| SWIZZLE_STR_DR_ATI (s/r, t/r, 1/r, undefined) (undefined) |
| SWIZZLE_STQ_DQ_ATI (s/q, t/q, 1/q, undefined) (undefined) |
| |
| Table 3.20 Coordinate swizzles |
| |
| |
| Each texture coordinate source (TEXTUREx_ARB) used as a <coord> |
| and/or <interp> can only draw upon STR or STQ components throughout |
| the shader. For example, if TEXTURE2_ARB is used in a SampleMapATI |
| with <swizzle> SWIZZLE_STR_ATI, it cannot be used again later with a |
| <swizzle> of SWIZZLE_STQ_ATI. The projection, however, may vary. |
| It would be okay to later use TEXTURE2_ARB with a <swizzle> of |
| SWIZZLE_STR_DR_ATI. |
| |
| Additionally, when the <coord> or <interp> is a register (in the |
| second pass of a two-pass shader), only SWIZZLE_STR_ATI and |
| SWIZZLE_STR_DR_ATI are allowed. Note that if this is a |
| PassTexCoord, the fourth component (alpha channel if the register |
| contains RGBA) is not passed along and the fourth component of <dst> |
| becomes undefined. |
| |
| The color and alpha instructions performed in the shader are |
| specified with the following entry points: |
| |
| void ColorFragmentOp1ATI (enum op, uint dst, uint dstMask, uint dstMod, |
| uint arg1, uint arg1Rep, uint arg1Mod); |
| void ColorFragmentOp2ATI (enum op, uint dst, uint dstMask, uint dstMod, |
| uint arg1, uint arg1Rep, uint arg1Mod, |
| uint arg2, uint arg2Rep, uint arg2Mod); |
| void ColorFragmentOp3ATI (enum op, uint dst, uint dstMask, uint dstMod, |
| uint arg1, uint arg1Rep, uint arg1Mod, |
| uint arg2, uint arg2Rep, uint arg2Mod, |
| uint arg3, uint arg3Rep, uint arg3Mod); |
| void AlphaFragmentOp1ATI (enum op, uint dst, uint dstMod, |
| uint arg1, uint arg1Rep, uint arg1Mod); |
| void AlphaFragmentOp2ATI (enum op, uint dst, uint dstMod, |
| uint arg1, uint arg1Rep, uint arg1Mod, |
| uint arg2, uint arg2Rep, uint arg2Mod); |
| void AlphaFragmentOp3ATI (enum op, uint dst, uint dstMod, |
| uint arg1, uint arg1Rep, uint arg1Mod, |
| uint arg2, uint arg2Rep, uint arg2Mod, |
| uint arg3, uint arg3Rep, uint arg3Mod); |
| |
| A ColorFragmentOp[1..3]ATI followed by an AlphaFragmentOp[1..3]ATI |
| is considered to be an instruction pair, and 8 such pairs may be |
| specified per pass. The color and alpha instructions of a pair are |
| executed in parallel: the result of the color instruction cannot |
| affect the source arguments of the alpha instruction. Both a color |
| and an alpha instruction need not be specified for every pair; the |
| necessary color or alpha no-op is automatically inserted by the GL |
| to complete each instruction pair. |
| |
| The <op> parameter specifies the instruction to perform on the |
| sources. |
| |
| Table 3.21 shows the effect of each <op>. R(d), G(d), and B(d) are |
| the destination values when using the instruction on color and A(d) |
| is the destination value when using the instruction on alpha. |
| |
| |
| Op Result |
| -- ------ |
| ADD_ATI R(d) = R(a1) + R(a2) |
| G(d) = G(a1) + G(a2) |
| B(d) = B(a1) + B(a2) |
| A(d) = A(a1) + A(a2) |
| |
| SUB_ATI R(d) = R(a1) - R(a2) |
| G(d) = G(a1) - G(a2) |
| B(d) = B(a1) - B(a2) |
| A(d) = A(a1) - A(a2) |
| |
| MUL_ATI R(d) = R(a1) * R(a2) |
| G(d) = G(a1) * G(a2) |
| B(d) = B(a1) * B(a2) |
| A(d) = A(a1) * A(a2) |
| |
| MAD_ATI R(d) = R(a1) * R(a2) + R(a3) |
| G(d) = G(a1) * G(a2) + G(a3) |
| B(d) = B(a1) * B(a2) + B(a3) |
| A(d) = A(a1) * A(a2) + A(a3) |
| |
| LERP_ATI*** R(d) = R(a1) * R(a2) + (1 - R(a1)) * R(a3) |
| G(d) = G(a1) * G(a2) + (1 - G(a1)) * G(a3) |
| B(d) = B(a1) * B(a2) + (1 - B(a1)) * B(a3) |
| A(d) = A(a1) * A(a2) + (1 - A(a1)) * A(a3) |
| |
| MOV_ATI R(d) = R(a1) |
| G(d) = G(a1) |
| B(d) = B(a1) |
| A(d) = A(a1) |
| |
| CND_ATI R(d) = (R(a3) > 0.5) ? R(a1) : R(a2) |
| G(d) = (G(a3) > 0.5) ? G(a1) : G(a2) |
| B(d) = (B(a3) > 0.5) ? B(a1) : B(a2) |
| A(d) = (A(a3) > 0.5) ? A(a1) : A(a2) |
| |
| CND0_ATI R(d) = (R(a3) >= 0) ? R(a1) : R(a2) |
| G(d) = (G(a3) >= 0) ? G(a1) : G(a2) |
| B(d) = (B(a3) >= 0) ? B(a1) : B(a2) |
| A(d) = (A(a3) >= 0) ? A(a1) : A(a2) |
| |
| DOT2_ADD_ATI* R(d) = G(d) = B(d) = A(d) = R(a1) * R(a2) + |
| G(a1) * G(a2) + |
| B(a3) |
| |
| DOT3_ATI* R(d) = G(d) = B(d) = A(d) = R(a1) * R(a2) + |
| G(a1) * G(a2) + |
| B(a1) * B(a2) |
| |
| DOT4_ATI* ** R(d) = G(d) = B(d) = A(d) = R(a1) * R(a2) + |
| G(a1) * G(a2) + |
| B(a1) * B(a2) + |
| A(a1) * A(a2) |
| |
| Table 3.21 Color and Alpha Fragment Shader Instructions |
| |
| Special Notes: |
| * - DOT2_ADD_ATI/DOT3_ATI/DOT4_ATI can only be specified as |
| an alpha instruction directly after being specified as |
| a color instruction. When specified as an alpha |
| instruction, the parameters are ignored, although they |
| should be valid enumerants in order to compile. The |
| result of the color instruction will simply be placed |
| in the alpha <dst>. |
| |
| ** - After a DOT4_ATI color instruction is specified, the |
| only alpha instruction that can immediately follow is a |
| DOT4_ATI. This is because the DOT4 color instruction |
| implicitely uses an alpha instruction to calculate the |
| result. If another type of alpha instruction is |
| desired after a DOT4_ATI color instruction is issued, |
| there are two choices: either issue another color |
| instruction first, or issue the DOT4_ATI alpha |
| instruction followed by the desired alpha instruction. |
| |
| *** - The blend factor (a1) of LERP_ATI must be in the range |
| [0,1] or the results are undefined. |
| |
| The <dst> parameter specifies to which register (REG_x_ATI) the |
| result of the instruction is written. |
| |
| The <dstMask> parameter specifies which of the color components in |
| <dst> will be written (ColorFragmentOp[1..3]ATI only). This can |
| either be NONE, in which case there is no mask and everything is |
| written, or the bitwise-or of RED_BIT_ATI, GREEN_BIT_ATI, and |
| BLUE_BIT_ATI. |
| |
| The <dstMod> parameter specifies which modifications are performed |
| on each component of the destination. The result can be modulated |
| by specifying either 2X_BIT_ATI, 4X_BIT_ATI, 8X_BIT_ATI, |
| HALF_BIT_ATI, QUARTER_BIT_ATI, or EIGHTH_BIT_ATI. These are all |
| mutually exclusive, and can optionally be bitwise-or'd with |
| SATURATE_BIT_ATI, which clamps the result after any modulation |
| occurs. |
| |
| Table 3.22 shows the result of each <dstMod> modification. |
| |
| |
| Modifier Result |
| -------- ------ |
| NONE d = d |
| 2X_BIT_ATI d = 2 * d |
| 4X_BIT_ATI d = 4 * d |
| 8X_BIT_ATI d = 8 * d |
| HALF_BIT_ATI d = d / 2 |
| QUARTER_BIT_ATI d = d / 4 |
| EIGHTH_BIT_ATI d = d / 8 |
| SATURATE_BIT_ATI d = clamp(d) to range [0, 1] |
| |
| Table 3.22 Result of destination modification |
| |
| |
| Note that the internal precision of the fragment shader allows |
| values in the range [-8, 8]. |
| |
| The <argN> parameter specifies the source argument. The source can |
| come from REG_x_ATI, CON_x_ATI, ZERO, ONE, PRIMARY_COLOR_ARB, or |
| SECONDARY_INTERPOLATOR_ATI. Note that in a two-pass shader, |
| PRIMARY_COLOR_ARB and SECONDARY_INTERPOLATOR_ATI cannot be used in |
| the first pass of the shader. |
| |
| Each argument has an <argNRep> parameter which specifies the |
| replication of each component. |
| |
| Table 3.23 shows the result of each <argNRep> source replication. |
| |
| |
| Replication Result |
| ----------- ----- |
| NONE R(s) = R(s) |
| G(s) = G(s) |
| B(s) = B(s) |
| A(s) = A(s) |
| |
| RED R(s) = R(s) |
| G(s) = R(s) |
| B(s) = R(s) |
| A(s) = R(s) |
| |
| GREEN R(s) = G(s) |
| G(s) = G(s) |
| B(s) = G(s) |
| A(s) = G(s) |
| |
| BLUE R(s) = B(s) |
| G(s) = B(s) |
| B(s) = B(s) |
| A(s) = B(s) |
| |
| ALPHA R(s) = A(s) |
| G(s) = A(s) |
| B(s) = A(s) |
| A(s) = A(s) |
| |
| Table 3.23 Result of source replication |
| |
| |
| Each argument also has an <argNMod> parameter which specifies |
| modifiers to each component. A value of NONE specifies that no |
| modifiers are present. Otherwise, the bitwise-or of NEGATE_BIT_ATI, |
| BIAS_BIT_ATI, and 2X_BIT_ATI can be specified as modifiers. |
| |
| Table 3.24 shows the result of each <argNMod> source modifier. |
| |
| |
| Modifier Result |
| -------- ------ |
| NONE s = s |
| NEGATE_BIT_ATI s = -s |
| COMP_BIT_ATI s = 1 - s |
| BIAS_BIT_ATI s = s - 0.5 |
| 2X_BIT_ATI s = 2 * s |
| |
| Table 3.24 Result of source modification |
| |
| |
| If multiple source modifiers are applied, the order of operations is |
| COMP, BIAS, SCALE, then NEGATE. The following equation shows the |
| order of operations if all modifiers were to be applied: |
| |
| s = -(2 * ((1.0 - s) - 0.5)) |
| |
| In order to set the constants that can be used by shader |
| instructions, the entry point: |
| |
| void SetFragmentShaderConstantATI (uint dst, const float *value); |
| |
| is used. The <dst> parameter specifies which of the constants |
| (CON_x_ATI) to set. The <value> pointer must contain four floating |
| point values in the range [0, 1] to set the components of the |
| constant. Constant registers loaded with floating point values |
| outside of this range will have undefined values. Calls to this |
| function which occur inside a shader definition are automatically |
| bound when the shader is bound. This means that shader constants |
| have scope: if SetFragmentShaderConstantATI is called outside a |
| shader definition, it is bound globally. However, if that same |
| shader constant is set inside the shader, it overrides the global |
| definition when bound. |
| |
| |
| Additions to Chapter 4 of the OpenGL 1.2.1 Specification (Per-Fragment |
| Operations and the Framebuffer) |
| |
| None |
| |
| |
| Additions to Chapter 5 of the OpenGL 1.2.1 Specification (Special |
| Functions) |
| |
| Modify Section 5.4, Display Lists (p. 175) |
| |
| (modify last paragraph, p. 178) ... These are: IsList, GenLists, |
| ..., GenFragmentShadersATI, DeleteFragmentShadersATI, |
| BeginFragmentShaderATI, EndFragmentShaderATI, PassTexCoordATI, |
| SampleMapATI, ColorFragmentOp[1..3]ATI, AlphaFragmentOp[1..3]ATI, |
| as well as IsEnabled and all of the Get commands (see Chapter 6). |
| |
| |
| Additions to Chapter 6 of the OpenGL 1.2.1 Specification (State and |
| State Requests) |
| |
| None |
| |
| |
| Additions to Appendix A of the OpenGL 1.2.1 Specification (Invariance) |
| |
| None |
| |
| |
| Additions to the AGL/GLX/WGL Specifications |
| |
| None |
| |
| |
| Interactions with ARB_shadow |
| |
| The texture comparison introduced by ARB_shadow can be expressed in |
| terms of a fragment shader, and in fact use the same internal |
| resources on some implementations. Therefore, if fragment shader |
| mode is enabled, the GL behaves as if TEXTURE_COMPARE_MODE_ARB is |
| NONE. |
| |
| |
| Errors |
| |
| The error INVALID_VALUE is generated if GenFragmentShadersATI is |
| called where <range> is zero. |
| |
| The error INVALID_OPERATION is generated if GenFragmentShadersATI, |
| BindFragmentShaderATI, DeleteFragmentShaderATI, or |
| BeginFragmentShaderATI are specified inside a |
| Begin/EndFragmentShaderATI pair. |
| |
| The error INVALID_OPERATION is generated if EndFragmentShaderATI, |
| PassTexCoordATI, SampleMapATI, ColorFragmentOp[1..3]ATI, or |
| AlphaFragmentOp[1..3]ATI is specified outside a |
| Begin/EndFragmentShaderATI pair. |
| |
| The error INVALID_OPERATION is generated by EndFragmentShaderATI if |
| <argN> passed to ColorFragmentOp[1..3]ATI or |
| AlphaFragmentOp[1..3]ATI is PRIMARY_COLOR_ARB or |
| SECONDARY_INTERPOLATOR_ATI on the first pass of a two-pass shader, |
| or if the shader cannot be compiled due to some other |
| implementation-dependent limitation. EndFragmentShaderATI will |
| still have a side-effect if this error is encountered: the |
| Begin/EndFragmentShaderATI pair will be closed, and the current |
| shader will be undefined. |
| |
| The error INVALID_OPERATION is generated by PassTexCoordATI or |
| SampleMapATI if two shader passes have already been specified, or if |
| the same <dst> register is specified twice in the same pass. |
| |
| The error INVALID_OPERATION is generated by PassTexCoordATI or |
| SampleMapATI if <coord> passed to PassTexCoordATI or <interp> passed |
| to SampleMapATI is a register in the first pass, or a register with |
| SWIZZLE_STQ_ATI or SWIZZLE_STQ_DQ_ATI <swizzle> in the second pass, |
| or if different <swizzle> parameters are specified for the same |
| <coord> or <interp> in the same pass. |
| |
| The error INVALID_OPERATION is generated by ColorFragmentOp[1..3]ATI |
| or AlphaFragmentOp[1..3]ATI if more than 8 instructions have been |
| specified for a shader pass. |
| |
| The error INVALID_OPERATION is generated by ColorFragmentOp[1..3]ATI |
| if <argN> is SECONDARY_INTERPOLATOR_ATI and <argNRep> is ALPHA, or |
| by AlphaFragmentOp[1..3]ATI if <argN> is SECONDARY_INTERPOLATOR_ATI |
| and <argNRep> is ALPHA or NONE, or by ColorFragmentOp2ATI if <op> is |
| DOT4_ATI and <argN> is SECONDARY_INTERPOLATOR_ATI and <argNRep> is |
| ALPHA or NONE. |
| |
| The error INVALID_OPERATION is generated by ColorFragmentOp3ATI or |
| AlphaFragmentOp3ATI if all three <argN> parameters are constants, |
| and all three are different. |
| |
| The error INVALID_OPERATION is generated by AlphaFragmentOp[2..3]ATI |
| if <op> is DOT3_ATI, DOT4_ATI, or DOT2_ADD_ATI and there was no |
| matching ColorFragmentOp[2..3]ATI immediately preceding, or if <op> |
| is not DOT4_ATI and the immediately preceding ColorFragmentOp2ATI |
| specifies an <op> of DOT4_ATI. |
| |
| The error INVALID_ENUM is generated if <dst> passed to |
| PassTexCoordATI, SampleMapATI, ColorFragmentOp[1..3]ATI, or |
| AlphaFragmentOp[1..3]ATI is not a valid register or is greater than |
| the number of texture units available on the implementation. |
| |
| The error INVALID_ENUM is generated if <coord> passed to |
| PassTexCoordATI or <interp> passed to SampleMapATI is not a valid |
| register or texture unit, or the register or texture unit is greater |
| than the number of texture units available on the implementation. |
| |
| The error INVALID_ENUM is generated if <argN> passed to |
| ColorFragmentOp[1..3]ATI or AlphaFragmentOp[1..3]ATI is not a valid |
| constant, interpolator, or register. |
| |
| The error INVALID_ENUM is generated if <dstMod> passed to |
| ColorFragmentOp[1..3]ATI or AlphaFragmentOp[1..3]ATI contains |
| multiple mutually exclusive modifier bits, not counting |
| SATURATE_BIT_ATI. |
| |
| |
| New State |
| |
| Initial |
| Get Value Type Get Command Value Description Sec. Attribute |
| --------- ---- ----------- ------- ----------- ------ --------- |
| FRAGMENT_SHADER_ATI B IsEnabled False Fragment shader enable 3.8.11 enable |
| |
| Table X.6. New Accessible State Introduced by ATI_fragment_shader. |
| |
| |
| Get Value Type Get Command Initial Value Description Sec Attribute |
| --------- ------ ----------- ------------- ------------------- ------ --------- |
| - 6xR4 - undefined temporary registers 3.8.11 - |
| |
| Table X.9. Fragment Shader Per-fragment Execution State. All per-fragment |
| execution state registers are uninitialized at the beginning of program |
| execution. |
| |
| |
| New Implementation Dependent State |
| |
| None |
| |
| |
| Deprecated Functionality |
| |
| The following queryable implementation-dependent constants are |
| described here for backward-compatibility. They are now specified |
| to always return fixed values on all implementations, and are thus |
| obsolete. |
| |
| The number of available registers can be queried by doing a glGet on |
| NUM_FRAGMENT_REGISTERS_ATI. This refers to the number of |
| REG_x_ATI's, and is now fixed at 6. |
| |
| The number of available constants can be queried by doing a glGet on |
| NUM_FRAGMENT_CONSTANTS. This refers to the number of CON_x_ATI's, |
| and is now fixed at 8. |
| |
| The number of passes, instructions per pass, and total instructions |
| available to a shader can be queried using glGet. Querying for |
| NUM_PASSES_ATI returns the maximum number of passes that the shader |
| can perform, now fixed at 2. Querying for |
| NUM_INSTRUCTIONS_PER_PASS_ATI returns the maximum number of |
| instructions available on a given pass, now fixed at 8. Finally, |
| NUM_INSTRUCTIONS_TOTAL_ATI returns the maximum number of total |
| instructions available to a shader, now fixed at 16 (2 per pass). |
| |
| COLOR_ALPHA_PAIRING_ATI can be queried by glGet to determine if each |
| ColorFragmentOp[1..3]ATI/AlphaFragmentOp[1..3]ATI pair counts as one |
| instruction against the limit, or if each color and alpha |
| instruction is counted individually (i.e., each pair counts as two |
| instructions). This query now always returns TRUE: each pair counts |
| as one instruction against the 8 instructions allowed per pass. |
| |
| The number of components available in a coordinate interpolator, |
| passed in as <interp> to SampleMapATI or <coord> to PassTexCoord, |
| can be queried using NUM_INTERPOLATOR_COMPONENTS_ATI. This query |
| now always returns 3, meaning the fourth component is ignored. |
| |
| The number of components passed in the registers via PassTexCoord |
| from the first pass to the second can be queried using |
| NUM_LOOPBACK_COMPONENTS_ATI. This query now always returns 3, |
| meaning the fourth component of <dst> is undefined. |
| |
| |
| Sample Usage |
| |
| The following is an example that simulates a chrome surface: |
| |
| shadername = glGenFragmentShadersATI(1); |
| glBindFragmentShaderATI(shadername); |
| glBeginFragmentShaderATI(); |
| |
| // Pass 1 |
| glPassTexCoordATI(GL_REG_1_ATI, GL_TEXTURE1_ARB, GL_SWIZZLE_STR_ATI); // N |
| glPassTexCoordATI(GL_REG_2_ATI, GL_TEXTURE2_ARB, GL_SWIZZLE_STR_ATI); // light to vertex vector in light space |
| glPassTexCoordATI(GL_REG_3_ATI, GL_TEXTURE3_ARB, GL_SWIZZLE_STR_ATI); // H |
| glSampleMapATI(GL_REG_4_ATI, GL_TEXTURE4_ARB, GL_SWIZZLE_STR_ATI); // L (sample cubemap normalizer) |
| |
| // reg4 = N.L |
| glColorFragmentOp2ATI(GL_DOT3_ATI, GL_REG_4_ATI, GL_NONE, GL_NONE, |
| GL_REG_1_ATI, GL_NONE, GL_NONE, |
| GL_REG_4_ATI, GL_NONE, GL_2X_BIT_ATI|GL_BIAS_BIT_ATI); |
| |
| // reg1 = N.H |
| glColorFragmentOp2ATI(GL_DOT3_ATI, GL_REG_1_ATI, GL_NONE, GL_NONE, |
| GL_REG_1_ATI, GL_NONE, GL_NONE, |
| GL_REG_3_ATI, GL_NONE, GL_NONE); |
| |
| // reg1(green) = H.H (aka |H|^2) |
| glColorFragmentOp2ATI(GL_DOT3_ATI, GL_REG_1_ATI, GL_GREEN_BIT_ATI, GL_NONE, |
| GL_REG_3_ATI, GL_NONE, GL_NONE, |
| GL_REG_3_ATI, GL_NONE, GL_NONE); |
| |
| // reg2 = |light to vertex|^2 |
| glColorFragmentOp2ATI(GL_DOT3_ATI, GL_REG_2_ATI, GL_NONE, GL_NONE, |
| GL_REG_2_ATI, GL_NONE, GL_NONE, |
| GL_REG_2_ATI, GL_NONE, GL_NONE); |
| |
| // Pass 2 |
| glSampleMapATI(GL_REG_0_ATI, GL_TEXTURE5_ARB, GL_SWIZZLE_STR_ATI); // sample enviroment map using eye vector |
| glSampleMapATI(GL_REG_2_ATI, GL_REG_2_ATI, GL_SWIZZLE_STR_ATI); // sample attenuation map |
| glSampleMapATI(GL_REG_3_ATI, GL_REG_1_ATI, GL_SWIZZLE_STR_ATI); // sample specular NHHH map = (N.H)^256 |
| glPassTexCoordATI(GL_REG_4_ATI, GL_REG_4_ATI, GL_SWIZZLE_STR_ATI); // pass N.L through |
| |
| // reg3 = (N.H)^256 * (N.L) |
| // this ensures a pixel is only lit if facing the light (since the specular exponent |
| // makes negative N.H positive we must do this) |
| glColorFragmentOp2ATI(GL_MUL_ATI, GL_REG_3_ATI, GL_NONE, GL_NONE, |
| GL_REG_3_ATI, GL_NONE, GL_NONE, |
| GL_REG_4_ATI, GL_NONE, GL_NONE); |
| |
| // reg3 = specular * environment map |
| glColorFragmentOp2ATI(GL_MUL_ATI, GL_REG_3_ATI, GL_NONE, GL_NONE, |
| GL_REG_0_ATI, GL_NONE, GL_NONE, |
| GL_REG_3_ATI, GL_NONE, GL_NONE); |
| |
| // reg4 = diffuse * environment map |
| glColorFragmentOp2ATI(GL_MUL_ATI, GL_REG_4_ATI, GL_NONE, GL_NONE, |
| GL_REG_0_ATI, GL_NONE, GL_NONE, |
| GL_REG_4_ATI, GL_NONE, GL_NONE); |
| |
| // reg0 = (specular * environment map) + (diffuse * environment map) |
| glColorFragmentOp2ATI(GL_ADD_ATI, GL_REG_0_ATI, GL_NONE, GL_NONE, |
| GL_REG_3_ATI, GL_NONE, GL_NONE, |
| GL_REG_4_ATI, GL_NONE, GL_NONE); |
| |
| // apply point light attenuation |
| glColorFragmentOp2ATI(GL_MUL_ATI, GL_REG_0_ATI, GL_NONE, GL_SATURATE_BIT_ATI, |
| GL_REG_0_ATI, GL_NONE, GL_NONE, |
| GL_REG_2_ATI, GL_RED, GL_NONE); |
| glEndFragmentShaderATI(); |
| |
| |
| Revision History |
| |
| Date: 11/4/2006 |
| Revision: 1.8 |
| - Updated contact info after ATI/AMD merger. |
| |
| Date: 8/21/2002 |
| Revision: 1.7 |
| - Fixed lack of comma typo in glAlphaFragmentOp2ATI prototypes. |
| |
| Date: 8/1/2002 |
| Revision: 1.6 |
| - Changed DeleteFragmentShaderATI behavior to silently ignore the |
| deletion of non-existent or default shaders. |
| |
| Date: 6/5/2002 |
| Revision: 1.5 |
| - Added interaction with ARB_shadow. |
| |
| Date: 5/30/2002 |
| Revision: 1.4 |
| - Specified that LERP's blend factor must be in the range [0,1]. |
| - Added error condition when trying to use secondary color in DOT4 |
| color instruction when replication is GL_NONE or GL_ALPHA. |
| |
| Date: 5/21/2002 |
| Revision: 1.3 |
| - Made number of registers (REG_x_ATI) explicit: 6. |
| - Changed CND0_ATI definition from >0 to >=0. |
| - Added wording to emphasize [0,1] range for constants. |
| - Added wording to reflect that EndFragmentShaderATI will close |
| Begin/End pair even if error is encountered. |
| - Added wording to reflect parallelism of color/alpha pairs. |
| - Added error condition when trying to use secondary color alpha. |
| - Added error condition when generating shader IDs with <range> 0. |
| - Added display list exclusion for everything except |
| BindFragmentShaderATI and SetFragmentShaderConstantATI. |
| - Cleaned up, fixed typos, and reformatted. |
| - Added New State section. |
| - Replaced sample code. |
| |
| Date: 4/19/2002 |
| Revision: 1.2 |
| - Updated swizzle table to indicate that projected texcoords are |
| undefined when used in conjunction with cubemaps or 3D textures. |
| |
| Date: 3/20/2002 |
| Revision: 1.1 |
| - Made resource availability explicit. |
| - Deprecated implementation-dependent constant queries. |
| - Added various error conditions described in prose of spec. |
| - Changed PRIMARY_COLOR_EXT to PRIMARY_COLOR_ARB. |
| - Cleaned up and fixed typos throughout. |
| |
| Date: 1/2/2002 |
| Revision: 1.02 |
| - Added note that PRIMARY_COLOR_EXT and SECONDARY_INTERPOLATOR_ATI can not |
| be used on the first pass of a two pass shader. Also added error |
| for this case to Errors section. |
| - Added note that in order to save the contents of a register from the |
| first pass to the second, there has to be a PassTexCoordATI() on that |
| register to itself on the next pass. |
| - Changed PRIMARY_COLOR to PRIMARY_COLOR_EXT. |
| |
| Date: 10/15/2001 |
| Revision: 1.01 |
| - Fixed typos in example program. |
| - Added language about the shader result being placed in REG_0_ATI. |
| - Specify range supported [-8..8]. |
| - Added notes on how to specify whether DOT4/DOT3/DOT2_ADD result |
| goes to alpha channel. |
| |
| Date: 8/21/2001 |
| Revision: 1.0 |
| - Added equation for source modifiers. |
| |
| Date: 8/6/2001 |
| Revision: 0.6 |
| - Added restraint that only SWIZZLE_STR_ATI and SWIZZLE_STR_DR_ATI |
| can be used on the second pass when the source is a register. |
| |
| Date: 6/29/2001 |
| Revision: 0.5 |
| - Removed glTexProjectATI and change glSampleMapATI/glPassTexCoordATI to |
| take a <swizzle> parameter instead of <project>. |
| - Changed MAD_ATI from (a + b * c) to (a * b + c). |
| |
| Date: 6/11/2001 |
| Revision: 0.4 |
| - Removed FRAC_ATI. |
| - Added <project> parameter to SampleMapATI and PassTexCoordATI to |
| match current implementation. |
| |
| Date: 5/01/2001 |
| Revision: 0.3 |
| - Added COLOR_ALPHA_PAIRING_ATI. |
| - Attempted to clarify definition of SampleMapATI in the documentation |
| section. Changed <map> to <interp>. |
| - Added TexProjectATI and documented texture projection modes to allow |
| implementations that only support 3-tuples to select between (s, t, r) |
| and (s, t, q) coordinates. |
| |
| Date: 4/19/2001 |
| Revision: 0.2 |
| - Removed <dstRot> from ColorFragmentOp[1..3]ATI. |
| - Changed SHADER_ATI to FRAGMENT_SHADER_ATI. |
| - Fixed the <op>'s in the New Tokens section to go to the proper |
| Color/AlphaOp functions. |
| - Added ZERO and ONE constants. |
| - Made number of passes queryable: removed NUM_PASSn_INSTRUCTIONS_ATI, |
| replaced with NUM_PASSES_ATI, NUM_INSTRUCTIONS_PER_PASS_ATI, and |
| NUM_INSTRUCTIONS_TOTAL_ATI. |
| - Documented when new pass starts (SampleMapATI/PassCoordATI). |
| - Added NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI/NUM_LOOPBACK_COMPONENTS_ATI. |
| - Fixed sample usage to not do a dependent read on the base map. |
| |
| Date: 4/16/2001 |
| Revision: 0.1 |
| - First draft |