Name EXT_gpu_shader4 Name Strings GL_EXT_gpu_shader4 Contact Barthold Lichtenbelt, NVIDIA (blichtenbelt 'at' nvidia.com) Pat Brown, NVIDIA (pbrown 'at' nvidia.com) Status Multi vendor extension Shipping for GeForce 8 Series (November 2006) Version Last Modified Date: 12/14/2009 Author revision: 16 Number 326 Dependencies OpenGL 2.0 is required. This extension is written against the OpenGL 2.0 specification and version 1.10.59 of the OpenGL Shading Language specification. This extension trivially interacts with ARB_texture_rectangle. This extension trivially interacts with GL_EXT_texture_array. This extension trivially interacts with GL_EXT_texture_integer. This extension trivially interacts with GL_EXT_geometry_shader4 This extension trivially interacts with GL_EXT_texture_buffer_object. NV_primitive_restart trivially affects the definition of this extension. ARB_color_buffer_float affects the definition of this extension. EXT_draw_instanced affects the definition of this extension. Overview This extension provides a set of new features to the OpenGL Shading Language and related APIs to support capabilities of new hardware. In particular, this extension provides the following functionality: * New texture lookup functions are provided that allow shaders to access individual texels using integer coordinates referring to the texel location and level of detail. No filtering is performed. These functions allow applications to use textures as one-, two-, and three-dimensional arrays. * New texture lookup functions are provided that allow shaders to query the dimensions of a specific level-of-detail image of a texture object. * New texture lookup functions variants are provided that allow shaders to pass a constant integer vector used to offset the texel locations used during the lookup to assist in custom texture filtering operations. * New texture lookup functions are provided that allow shaders to access one- and two-dimensional array textures. The second, or third, coordinate is used to select the layer of the array to access. * New "Grad" texture lookup functions are provided that allow shaders to explicitely pass in derivative values which are used by the GL to compute the level-of-detail when performing a texture lookup. * A new texture lookup function is provided to access a buffer texture. * The existing absolute LOD texture lookup functions are no longer restricted to the vertex shader only. * The ability to specify and use cubemap textures with a DEPTH_COMPONENT internal format. This also enables shadow mapping on cubemaps. The 'q' coordinate is used as the reference value for comparisons. A set of new texture lookup functions is provided to lookup into shadow cubemaps. * The ability to specify if varying variables are interpolated in a non-perspective correct manner, if they are flat shaded or, if multi-sampling, if centroid sampling should be performed. * Full signed integer and unsigned integer support in the OpenGL Shading Language: - Integers are defined as 32 bit values using two's complement. - Unsigned integers and vectors thereof are added. - New texture lookup functions are provided that return integer values. These functions are to be used in conjunction with new texture formats whose components are actual integers, rather than integers that encode a floating-point value. To support these lookup functions, new integer and unsigned-integer sampler types are introduced. - Integer bitwise operators are now enabled. - Several built-in functions and operators now operate on integers or vectors of integers. - New vertex attribute functions are added that load integer attribute data and can be referenced in a vertex shader as integer data. - New uniform loading commands are added to load unsigned integer data. - Varying variables can now be (unsigned) integers. If declared as such, they have to be flat shaded. - Fragment shaders can define their own output variables, and declare them to be of type floating-point, integer or unsigned integer. These variables are bound to a fragment color index with the new API command BindFragDataLocationEXT(), and directed to buffers using the existing DrawBuffer or DrawBuffers API commands. * Added new built-in functions truncate() and round() to the shading language. * A new built-in variable accessible from within vertex shaders that holds the index implicitly passed to ArrayElement to specify the vertex. This is called the vertex ID. * A new built-in variable accessible from within fragment and geometry shaders that hold the index of the currently processed primitive. This is called the primitive ID. This extension also briefly mentions a new shader type, called a geometry shader. A geometry shader is run after vertices are transformed, but before clipping. A geometry shader begins with a single primitive (point, line, triangle. It can read the attributes of any of the vertices in the primitive and use them to generate new primitives. A geometry shader has a fixed output primitive type (point, line strip, or triangle strip) and emits vertices to define a new primitive. Geometry shaders are discussed in detail in the GL_EXT_geometry_shader4 specification. New Procedures and Functions void VertexAttribI1iEXT(uint index, int x); void VertexAttribI2iEXT(uint index, int x, int y); void VertexAttribI3iEXT(uint index, int x, int y, int z); void VertexAttribI4iEXT(uint index, int x, int y, int z, int w); void VertexAttribI1uiEXT(uint index, uint x); void VertexAttribI2uiEXT(uint index, uint x, uint y); void VertexAttribI3uiEXT(uint index, uint x, uint y, uint z); void VertexAttribI4uiEXT(uint index, uint x, uint y, uint z, uint w); void VertexAttribI1ivEXT(uint index, const int *v); void VertexAttribI2ivEXT(uint index, const int *v); void VertexAttribI3ivEXT(uint index, const int *v); void VertexAttribI4ivEXT(uint index, const int *v); void VertexAttribI1uivEXT(uint index, const uint *v); void VertexAttribI2uivEXT(uint index, const uint *v); void VertexAttribI3uivEXT(uint index, const uint *v); void VertexAttribI4uivEXT(uint index, const uint *v); void VertexAttribI4bvEXT(uint index, const byte *v); void VertexAttribI4svEXT(uint index, const short *v); void VertexAttribI4ubvEXT(uint index, const ubyte *v); void VertexAttribI4usvEXT(uint index, const ushort *v); void VertexAttribIPointerEXT(uint index, int size, enum type, sizei stride, const void *pointer); void GetVertexAttribIivEXT(uint index, enum pname, int *params); void GetVertexAttribIuivEXT(uint index, enum pname, uint *params); void Uniform1uiEXT(int location, uint v0); void Uniform2uiEXT(int location, uint v0, uint v1); void Uniform3uiEXT(int location, uint v0, uint v1, uint v2); void Uniform4uiEXT(int location, uint v0, uint v1, uint v2, uint v3); void Uniform1uivEXT(int location, sizei count, const uint *value); void Uniform2uivEXT(int location, sizei count, const uint *value); void Uniform3uivEXT(int location, sizei count, const uint *value); void Uniform4uivEXT(int location, sizei count, const uint *value); void GetUniformuivEXT(uint program, int location, uint *params); void BindFragDataLocationEXT(uint program, uint colorNumber, const char *name); int GetFragDataLocationEXT(uint program, const char *name); New Tokens Accepted by the parameters of GetVertexAttribdv, GetVertexAttribfv, GetVertexAttribiv, GetVertexAttribIuivEXT and GetVertexAttribIivEXT: VERTEX_ATTRIB_ARRAY_INTEGER_EXT 0x88FD Returned by the parameter of GetActiveUniform: SAMPLER_1D_ARRAY_EXT 0x8DC0 SAMPLER_2D_ARRAY_EXT 0x8DC1 SAMPLER_BUFFER_EXT 0x8DC2 SAMPLER_1D_ARRAY_SHADOW_EXT 0x8DC3 SAMPLER_2D_ARRAY_SHADOW_EXT 0x8DC4 SAMPLER_CUBE_SHADOW_EXT 0x8DC5 UNSIGNED_INT 0x1405 UNSIGNED_INT_VEC2_EXT 0x8DC6 UNSIGNED_INT_VEC3_EXT 0x8DC7 UNSIGNED_INT_VEC4_EXT 0x8DC8 INT_SAMPLER_1D_EXT 0x8DC9 INT_SAMPLER_2D_EXT 0x8DCA INT_SAMPLER_3D_EXT 0x8DCB INT_SAMPLER_CUBE_EXT 0x8DCC INT_SAMPLER_2D_RECT_EXT 0x8DCD INT_SAMPLER_1D_ARRAY_EXT 0x8DCE INT_SAMPLER_2D_ARRAY_EXT 0x8DCF INT_SAMPLER_BUFFER_EXT 0x8DD0 UNSIGNED_INT_SAMPLER_1D_EXT 0x8DD1 UNSIGNED_INT_SAMPLER_2D_EXT 0x8DD2 UNSIGNED_INT_SAMPLER_3D_EXT 0x8DD3 UNSIGNED_INT_SAMPLER_CUBE_EXT 0x8DD4 UNSIGNED_INT_SAMPLER_2D_RECT_EXT 0x8DD5 UNSIGNED_INT_SAMPLER_1D_ARRAY_EXT 0x8DD6 UNSIGNED_INT_SAMPLER_2D_ARRAY_EXT 0x8DD7 UNSIGNED_INT_SAMPLER_BUFFER_EXT 0x8DD8 Accepted by the parameter of GetBooleanv, GetIntegerv, GetFloatv, and GetDoublev: MIN_PROGRAM_TEXEL_OFFSET_EXT 0x8904 MAX_PROGRAM_TEXEL_OFFSET_EXT 0x8905 Additions to Chapter 2 of the OpenGL 2.0 Specification (OpenGL Operation) Modify Section 2.7 "Vertex Specification", p.20 Insert before last paragraph, p.22: The VertexAttrib* commands described so far should not be used to load data for vertex attributes declared as signed or unsigned integers or vectors thereof in a vertex shader. If they are used to load signed or unsigned integer vertex attributes, the value in those attributes are undefined. Instead use the commands void VertexAttribI[1234]{i,ui}EXT(uint index, T values); void VertexAttribI[1234]{i,ui}vEXT(uint index, T values); void VertexAttribI4{b,s,ub,us}vEXT(uint index, T values); to specify fixed-point attributes that are not converted to floating-point. These attributes can be accessed in vertex shaders that declare attributes as signed or unsigned integers or vectors. The VertexAttribI4* commands extend the data passed in to a full signed or unsigned integer. If a VertexAttribI* command is used that does not match the type of the attribute declared in a vertex shader, the values in the attributes are undefined. This means that the unsigned versions of the VertexAttribI* commands need to be used to load data for unsigned integer vertex attributes or vectors, and the signed versions of the VertexAttribI* commands for signed integer vertex attributes or vectors. Note that this also means that the VertexAttribI* commands should not be used to load data for a vertex attribute declared as a float, float vector or matrix, otherwise their values are undefined. Insert at end of function list, p.24: void VertexAttribIPointerEXT(uint index, int size, enum type, sizei stride, const void *pointer); (modify last paragraph, p.24) The parameter in the VertexAttribPointer and VertexAttribIPointerEXT commands identify the generic vertex attribute array being described. The error INVALID_VALUE is generated if is greater than or equal to MAX_VERTEX_ATTRIBS. Generic attribute arrays with integer arguments can be handled in one of three ways: converted to float by normalizing to [0,1] or [-1,1] as specified in table 2.9, converted directly to float, or left as integers. Data for an array specified by VertexAttribPointer will be converted to floating-point by normalizing if the parameter is TRUE, and converted directly to floating-point otherwise. Data for an array specified by VertexAttribIPointerEXT will always be left as integer values. (modify Table 2.4, p. 25) Integer Command Sizes Handling Types ---------------------- ------- --------- ----------------- VertexPointer 2,3,4 cast ... NormalPointer 3 normalize ... ColorPointer 3,4 normalize ... SecondaryColorPointer 3 normalize ... IndexPointer 1 cast ... FogCoordPointer 1 n/a ... TexCoordPointer 1,2,3,4 cast ... EdgeFlagPointer 1 integer ... VertexAttribPointer 1,2,3,4 flag ... VertexAttribIPointerEXT 1,2,3,4 integer byte, ubyte, short, ushort, int, uint Table 2.4: Vertex array sizes (values per vertex) and data types. The "integer handling" column indicates how fixed-point data types are handled: "cast" means that they converted to floating-point directly, "normalize" means that they are converted to floating-point by normalizing to [0,1] (for unsigned types) or [-1,1] (for signed types), "integer" means that they remain as integer values, and "flag" means that either "cast" or "normalized" applies, depending on the setting of the flag in VertexAttribPointer. (modify end of pseudo-code, pp. 27-28) for (j = 1; j < genericAttributes; j++) { if (generic vertex attribute j array enabled) { if (generic vertex attribute j array is a pure integer array) { VertexAttribI[size][type]vEXT(j, generic vertex attribute j array element i); } else if (generic vertex attribute j array normalization flag is set and is not FLOAT or DOUBLE) { VertexAttrib[size]N[type]v(j, generic verex attribute j array element i); } else { VertexAttrib[size][type]v(j, generic verex attribute j array element i); } } } if (generic vertex attribute 0 array enabled) { if (generic vertex attribute 0 array is a pure integer array) { VertexAttribI[size][type]vEXT(0, generic verex attribute 0 array element i); } else if (generic vertex attribute 0 array normalization flag is set and is not FLOAT or DOUBLE) { VertexAttrib[size]N[type]v(0, generic verex attribute 0 array element i); } else { VertexAttrib[size][type]v(0, generic verex attribute 0 array element i); } } Modify section 2.14.7, "Flatshading", p. 69 Add a new paragraph at the end of the section on p. 70 as follows: If a vertex or geometry shader is active, the flat shading control described so far applies to the built-in varying variables gl_FrontColor, gl_BackColor, gl_FrontSecondaryColor and gl_BackSecondaryColor. Through the OpenGL Shading Language varying qualifier flat any vertex attribute can be flagged to be flat-shaded. See the OpenGL Shading Language Specification section 4.3.6 for more information. Modify section 2.14.8, "Color and Associated Data Clipping", p. 71 Add to the end of this section: For vertex shader varying variables specified to be interpolated without perspective correction (using the noperspective keyword), the value of t used to obtain the varying value associated with P will be adjusted to produce results that vary linearly in screen space. Modify section 2.15.3, "Shader Variables", page 75 Add the following new return types to the description of GetActiveUniform on p. 81. SAMPLER_1D_ARRAY_EXT, SAMPLER_2D_ARRAY_EXT, SAMPLER_1D_ARRAY_SHADOW_EXT, SAMPLER_2D_ARRAY_SHADOW_EXT, SAMPLER_CUBE_SHADOW_EXT, SAMPLER_BUFFER_EXT, INT_SAMPLER_1D_EXT, INT_SAMPLER_2D_EXT, INT_SAMPLER_3D_EXT, INT_SAMPLER_CUBE_EXT, INT_SAMPLER_2D_RECT_EXT, INT_SAMPLER_1D_ARRAY_EXT, INT_SAMPLER_2D_ARRAY_EXT, INT_SAMPLER_BUFFER_EXT, UNSIGNED_INT, UNSIGNED_INT_VEC2_EXT, UNSIGNED_INT_VEC3_EXT, UNSIGNED_INT_VEC4_EXT, UNSIGNED_INT_SAMPLER_1D_EXT, UNSIGNED_INT_SAMPLER_2D_EXT, UNSIGNED_INT_SAMPLER_3D_EXT, UNSIGNED_INT_SAMPLER_CUBE_EXT, UNSIGNED_INT_SAMPLER_2D_RECT_EXT, UNSIGNED_INT_SAMPLER_1D_ARRAY_EXT, UNSIGNED_INT_SAMPLER_2D_ARRAY_EXT, UNSIGNED_INT_SAMPLER_BUFFER_EXT. Add the following uniform loading command prototypes on p. 81 as follows: void Uniform{1234}uiEXT(int location, T value); void Uniform{1234}uivEXT(int location, sizei count, T value); (add the following paragraph to the description of the above commands) The Uniform*ui{v} commands will load count sets of one to four unsigned integer values into a uniform location defined as a unsigned integer, an unsigned integer vector, an array of unsigned integers or an array of unsigned integer vectors. (change the first sentence of the last paragraph as follows) When loading values for a uniform declared as a Boolean, the Uniform*i{v}, Uniform*ui{v} and Uniform*f{v} set of commands can be used to load boolean values. Modify section 2.15.4 Shader execution, p. 84. Add a new section "2.15.4.1 Shader Only Texturing" before the sub- section "Texture Access" on p. 85 This section describes texture functionality that is only accessible through vertex, geometry or fragment shaders. Also refer to the OpenGL Shading Language Specification, section 8.7 and Section 3.8 of the OpenGL 2.0 specification. Note: For unextended OpenGL 2.0 and the OpenGL Shading Language version 1.20, all supported texture internal formats store unsigned integer values but return floating-point results in the range [0, 1] and are considered unsigned "normalized" integers. The ARB_texture_float extension introduces floating-point internal format where components are both stored and returned as floating-point values, and are not clamped. The EXT_texture_integer extension introduces formats that store either signed or unsigned integer values. This extension defines additional OpenGL Shading Language texture lookup functions, see section 8.7 of the OpenGL Shading Language, that return either signed or unsigned integer values if the internal format of the texture is signed or unsigned, respectively. Texel Fetches The OpenGL Shading Language texel fetch functions provide the ability to extract a single texel from a specified texture image. The integer coordinates passed to the texel fetch functions are used directly as the texel coordinates (i, j, k) into the texture image. This in turn means the texture image is point-sampled (no filtering is performed). The level of detail accessed is computed by adding the specified level-of-detail parameter to the base level of the texture, level_base. The texel fetch functions can not perform depth comparisons or access cube maps. Unlike filtered texel accesses, texel fetches do not support LOD clamping or any texture wrap mode, and require a mipmapped minification filter to access any level of detail other than the base level. The results of the texel fetch are undefined: * if the computed LOD is less than the texture's base level (level_base) or greater than the maximum level (level_max), * if the computed LOD is not the texture's base level and the texture's minification filter is NEAREST or LINEAR, * if the layer specified for array textures is negative or greater than the number of layers in the array texture, * if the texel at (i,j,k) coordinates refer to a border texel outside the defined extents of the specified LOD, where i < -b_s, j < -b_s, k < -b_s, i >= w_s - b_s, j >= h_s - b_s, or k >= d_s - b_s, where the size parameters (w_s, h_s, d_s, and b_s) refer to the width, height, depth, and border size of the image, as in equations 3.15, 3.16, and 3.17, or . if the texture being accessed is not complete (or cube complete for cubemaps). Texture Size Query The OpenGL Shading Language texture size functions provide the ability to query the size of a texture image. The LOD value passed in as an argument to the texture size functions is added to the level_base of the texture to determine a texture image level. The dimensions of that image level, excluding a possible border, are then returned. If the computed texture image level is outside the range [level_base, level_max], the results are undefined. When querying the size of an array texture, both the dimensions and the layer count are returned. Note that buffer textures do not support mipmapping, therefore the previous lod discussion does not apply to buffer textures Make the section "Texture Access" a subsection of 2.15.4.1 Modify the first paragraph on p. 86 as follows: Texture lookups involving textures with depth component data can either return the depth data directly or return the results of a comparison with the R value (see section 3.8.14) used to perform the lookup. The comparison operation is requested in the shader by using any of the shadow sampler and in the texture using the TEXTURE COMPARE MODE parameter. These requests must be consistent; the results of a texture lookup are undefined if: * The sampler used in a texture lookup function is not one of the shadow sampler types, and the texture object's internal format is DEPTH COMPONENT, and the TEXTURE COMPARE MODE is not NONE. * The sampler used in a texture lookup function is one of the shadow sampler types, and the texture object's internal format is DEPTH COMPONENT, and the TEXTURE COMPARE MODE is NONE. * The sampler used in a texture lookup function is one of the shadow sampler types, and the texture object's internal format is not DEPTH COMPONENT. Add a new section "2.15.4.2 Shader Inputs" before "Position Invariance" on p. 86 Besides having access to vertex attributes and uniform variables, vertex shaders can access the read-only built-in variables gl_VertexID and gl_InstanceID. The gl_VertexID variable holds the integer index implicitly passed to ArrayElement() to specify the vertex. The variable gl_InstanceID holds the integer index of the current primitive in an instanced draw call. See also section 7.1 of the OpenGL Shading Language Specification. Add a new section "2.15.4.3 Shader Outputs" A vertex shader can write to built-in as well as user-defined varying variables. These values are expected to be interpolated across the primitive it outputs, unless they are specified to be flat shaded. Refer to section 2.15.3 and the OpenGL Shading Language specification sections 4.3.6, 7.1 and 7.6 for more detail. The built-in output variables gl_FrontColor, gl_BackColor, gl_FrontSecondaryColor, and gl_BackSecondaryColor hold the front and back colors for the primary and secondary colors for the current vertex. The built-in output variable gl_TexCoord[] is an array and holds the set of texture coordinates for the current vertex. The built-in output variable gl_FogFragCoord is used as the "c" value, as described in section 3.10 "Fog" of the OpenGL 2.0 specification. The built-in special variable gl_Position is intended to hold the homogeneous vertex position. Writing gl_Position is optional. The built-in special variable gl_ClipVertex holds the vertex coordinate used in the clipping stage, as described in section 2.12 "Clipping" of the OpenGL 2.0 specification. The built in special variable gl_PointSize, if written, holds the size of the point to be rasterized, measured in pixels. Number section "Position Invariance", "Validation" and "Undefined Behavior" as sections 2.15.4.4, 2.15.4.5, and 2.15.4.6 respectively. Additions to Chapter 3 of the OpenGL 2.0 Specification (Rasterization) Modify Section 3.8.1, Texture Image Specification, p. 150 (modify 4th paragraph, p. 151 -- add cubemaps to the list of texture targets that can be used with DEPTH_COMPONENT textures) Textures with a base internal format of DEPTH_COMPONENT are supported by texture image specification commands only if is TEXTURE_1D, TEXTURE_2D, TEXTURE_CUBE_MAP, TEXTURE_RECTANGLE_ARB, PROXY_TEXTURE_1D, PROXY_TEXTURE_2D, PROXY_TEXTURE_CUBE_MAP, or PROXY_TEXTURE_RECTANGLE_ARB. Using this format in conjunction with any other target will result in an INVALID_OPERATION error. Delete Section 3.8.7, Texture Wrap Modes. (The language in this section is folded into updates to the following section, and is no longer needed here.) Modify Section 3.8.8, Texture Minification: (replace the last paragraph, p. 171): Let s(x,y) be the function that associates an s texture coordinate with each set of window coordinates (x,y) that lie within a primitive; define t(x,y) and r(x,y) analogously. Let u(x,y) = w_t * s(x,y) + offsetu_shader, v(x,y) = h_t * t(x,y) + offsetv_shader, w(x,y) = d_t * r(x,y) + offsetw_shader, and where w_t, h_t, and d_t are as defined by equations 3.15, 3.16, and 3.17 with w_s, h_s, and d_s equal to the width, height, and depth of the image array whose level is level_base. (offsetu_shader, offsetv_shader, offsetw_shader) is the texel offset specified in the OpenGL Shading Language texture lookup functions that support offsets. If the texture function used does not support offsets, or for fixed-function texture accesses, all three shader offsets are taken to be zero. For fixed-function texture accesses, all three shader offsets are taken to be zero. For a one-dimensional texture, define v(x,y) == 0 and w(x,y) === 0; for two-dimensional textures, define w(x,y) == 0. After u(x,y), v(x,y), and w(x,y) are generated, they are clamped if the corresponding texture wrap modes are CLAMP or MIRROR_CLAMP_EXT. Let u'(x,y) = clamp(u(x,y), 0, w_t), if TEXTURE_WRAP_S is CLAMP clamp(u(x,y), -w_t, w_t), if TEXTURE_WRAP_S is MIRROR_CLAMP_EXT, or u(x,y), otherwise v'(x,y) = clamp(v(x,y), 0, w_t), if TEXTURE_WRAP_T is CLAMP clamp(v(x,y), -w_t, w_t), if TEXTURE_WRAP_T is MIRROR_CLAMP_EXT, or v(x,y), otherwise w'(x,y) = clamp(w(x,y), 0, w_t), if TEXTURE_WRAP_R is CLAMP clamp(w(x,y), -w_t, w_t), if TEXTURE_WRAP_R is MIRROR_CLAMP_EXT, or w(x,y), otherwise, where clamp(,,) returns if is less than , if a is greater than , and otherwise. (start a new paragraph with "For a polygon, rho is given at a fragment with window coordinates...", and then continue with the original spec text.) (replace text starting with the last paragraph on p. 172, continuing to the end of p. 174) When lambda indicates minification, the value assigned to TEXTURE_MIN_FILTER is used to determine how the texture value for a fragment is selected. When TEXTURE_MIN_FILTER is NEAREST, the texel in the image array of level level_base that is nearest (in Manhattan distance) to that specified by (s,t,r) is obtained. Let i, j, and k be integers such that: i = apply_wrap(floor(u'(x,y))), j = apply_wrap(floor(v'(x,y))), and k = apply_wrap(floor(w'(x,y))), where the coordinate returned by apply_wrap() is as defined by Table X.19. The values of i, j, and k are then modified according to the texture wrap modes, as described in Table 3.19, to produce new values (i', j', and k'). For a three-dimensional texture, the texel at location (i,j,k) becomes the texture value. For a two-dimensional texture, k is irrelevant, and the texel at location (i,j) becomes the texture value. For a one-dimensional texture, j and k are irrelevant, and the texel at location i becomes the texture value. Wrap mode Result -------------------------- ------------------------------------------ CLAMP_TO_EDGE clamp(coord, 0, size-1) CLAMP_TO_BORDER clamp(coord, -1, size) CLAMP { clamp(coord, 0, size-1), { for NEAREST filtering { clamp(coord, -1, size), { for LINEAR filtering REPEAT mod(coord, size) MIRROR_CLAMP_TO_EDGE_EXT clamp(mirror(coord), 0, size-1) MIRROR_CLAMP_TO_BORDER_EXT clamp(mirror(size), 0, size) MIRROR_CLAMP_EXT { clamp(mirror(coord), 0, size-1), { for NEAREST filtering { clamp(mirror(size), 0, size), { for LINEAR filtering MIRRORED_REPEAT (size-1) - mirror(mod(coord, 2*size)-size) Table X.19: Texel location wrap mode application. mod(,) is defined to return -*floor(/), and mirror() is defined to return if is greater than or equal to zero or -(1+) otherwise. The values of "wrap mode" and size are TEXTURE_WRAP_S and w_t, TEXTURE_WRAP_T and h_t, and TEXTURE_WRAP_R and d_t, for i, j, and k coordinates, respectively. The coordinate clamp and MIRROR_CLAMP_EXT depends on the filtering mode (NEAREST or LINEAR). If the selected (i,j,k), (i,j), or i location refers to a border texel that satisfies any of the following conditions: i < -b_s, j < -b_s, k < -b_s, i >= w_t + b_s, j >= h_t + b_s, or j >= d_t + b_s, then the border values defined by TEXTURE_BORDER_COLOR are used in place of the non-existent texel. If the texture contains color components, the values of TEXTURE_BORDER_COLOR are interpreted as an RGBA color to match the texture's internal format in a manner consistent with table 3.15. If the texture contains depth components, the first component of TEXTURE_BORDER_COLOR is interpreted as a depth value. When TEXTURE_MIN_FILTER is LINEAR, a 2x2x2 cube of texels in the image array of level level_base is selected. Let: i_0 = apply_wrap(floor(u' - 0.5)), j_0 = apply_wrap(floor(v' - 0.5)), k_0 = apply_wrap(floor(w' - 0.5)), i_1 = apply_wrap(floor(u' - 0.5) + 1), j_1 = apply_wrap(floor(v' - 0.5) + 1), k_1 = apply_wrap(floor(w' - 0.5) + 1), alpha = frac(u' - 0.5), beta = frac(v' - 0.5), gamma = frac(w' - 0.5), where frac() denotes the fractional part of . For a three-dimensional texture, the texture value tau is found as... (replace last paragraph, p.174) For any texel in the equation above that refers to a border texel outside the defined range of the image, the texel value is taken from the texture border color as with NEAREST filtering. modify the last paragraph of section 3.8.8, p. 175, as follows: The rules for NEAREST or LINEAR filtering are then applied to the selected array. Specifically, the coordinate (u,v,w) is computed as in equation 3.20a, with w_s, h_s, and d_s equal to the width, height, and depth of the image array whose level is 'd'. Modify the second paragraph on p. 176 The rules for NEAREST or LINEAR filtering are then applied to each of the selected arrays, yielding two corresponding texture valutes Tau1 and Tau2. Specifically, for level d1, the coordinate (u,v,w) is computed as in equation 3.20a, with w_s, h_s, and d_s equal to the width, height, and depth of the image array whose level is 'd1'. For level d2 the coordinate (u', v', w') is computed as in equation 3.20a, with w_s, h_s, and d_s equal to the width, height, and depth of the image array whose level is 'd2'. Modify the first paragraph of section 3.8.9 "Texture Magnification" as follows: When lambda indicates magnification, the value assigned to TEXTURE_MAG_FILTER determines how the texture value is obtained. There are two possible values for TEXTURE_MAG_FILTER: NEAREST and LINEAR. NEAREST behaves exactly as NEAREST for TEXTURE_MIN_FILTER and LINEAR behaves exactly as LINEAR for TEXTURE_MIN_FILTER, as described in the previous section, including the wrapping calculations. The level-of-detail level_base texture array is always used for magnification. Modify Section 3.8.14, Texture Comparison Modes (p. 185) (modify 2nd paragraph, p. 188, indicating that the Q texture coordinate is used for depth comparisons on cubemap textures) Let D_t be the depth texture value, in the range [0, 1]. For fixed-function texture lookups, let R be the interpolated texture coordinate, clamped to the range [0, 1]. For texture lookups generated by an OpenGL Shading Language lookup function, let R be the reference value for depth comparisons provided in the lookup function, also clamped to [0, 1]. Then the effective texture value L_t, I_t, or A_t is computed as follows: Modify section 3.11, Fragment Shaders, p. 193 Modify the third paragraph on p. 194 as follows: Additionally, when a vertex shader is active, it may define one or more varying variables (see section 2.15.3 and the OpenGL Shading Language Specification). These values are, if not flat shaded, interpolated across the primitive being rendered. The results of these interpolations are available when varying variables of the same name are defined in the fragment shader. Add the following paragraph to the end of section 3.11.1, p. 194 A fragment shader can also write to varying out variables. Values written to these variables are used in the subsequent per-fragment operations. Varying out variables can be used to write floating-point, integer or unsigned integer values destined for buffers attached to a framebuffer object, or destined for color buffers attached to the default framebuffer. The subsection 'Shader Outputs' of the next section describes API how to direct these values to buffers. Add a new paragraph at the beginning of the section "Texture Access", p. 194 Section 2.15.4.1 describes texture lookup functionality accessible to a vertex shader. The texel fetch and texture size query functionality described there also applies to fragment shaders. Modify the second paragraph on p. 195 as follows: Texture lookups involving textures with depth component data can either return the depth data directly or return the results of a comparison with the R value (see section 3.8.14) used to perform the lookup. The comparison operation is requested in the shader by using any of the shadow sampler and in the texture using the TEXTURE COMPARE MODE parameter. These requests must be consistent; the results of a texture lookup are undefined if: * The sampler used in a texture lookup function is not one of the shadow sampler types, and the texture object's internal format is DEPTH COMPONENT, and the TEXTURE COMPARE MODE is not NONE. * The sampler used in a texture lookup function is one of the shadow sampler types, and the texture object's internal format is DEPTH COMPONENT, and the TEXTURE COMPARE MODE is NONE. * The sampler used in a texture lookup function is one of the shadow sampler types, and the texture object's internal format is not DEPTH COMPONENT. Add the following paragraph to the section Shader Inputs, p. 196 If a geometry shader is active, the built-in variable gl_PrimitiveID contains the ID value emitted by the geometry shader for the provoking vertex. If no geometry shader is active, gl_PrimitiveID is filled with the number of primitives processed by the rasterizer since the last time Begin was called (directly or indirectly via vertex array functions). The first primitive generated after a Begin is numbered zero, and the primitive ID counter is incremented after every individual point, line, or polygon primitive is processed. For polygons drawn in point or line mode, the primitive ID counter is incremented only once, even though multiple points or lines may be drawn. For QUADS and QUAD_STRIP primitives that are decomposed into triangles, the primitive ID is incremented after each complete quad is processed. For POLYGON primitives, the primitive ID counter is undefined. The primitive ID is undefined for fragments generated by DrawPixels or Bitmap. Restarting a primitive topology using the primitive restart index has no effect on the primitive ID counter. Modify the first paragraph of the section Shader Outputs, p. 196 as follows The OpenGL Shading Language specification describes the values that may be output by a fragment shader. These outputs are split into two categories. User-defined varying out variables and built-in variables. The built-in variables are gl_FragColor, gl_FragData[n], and gl_FragDepth. If fragment clamping is enabled, the final fragment color values or the final fragment data values or the final varying out variable values written by a fragment shader are clamped to the range [0,1] and then may be converted to fixed-point as described in section 2.14.9. Only user-defined varying out variables declared as a floating-point type are clamped and may be converted. If fragment clamping is disabled, the final fragment color values or the final fragment data values or the final varying output variable values are not modified. The final fragment depth written... Modify the second paragraph of the section Shader Outputs, p. 196 as follows ...A fragment shader may not statically assign values to more than one of gl_FragColor, gl_FragData or any user-defined varying output variable. In this case, a compile or link error will result. A shader statically... Add the following to the end of the section Shader Outputs, p. 197 The values of user-defined varying out variables are directed to a color buffer in a two step process. First the varying out variable is bound to a fragment color by using its number. The GL will assign a number to each varying out variable, unless overridden by the command BindFragDataLocationEXT(). The number of the fragment color assigned for each user-defined varying out variable can be queried with GetFragDataLocationEXT(). Next, the DrawBuffer or DrawBuffers commands (see section 4.2.1) direct each fragment color to a particular buffer. The binding of a user-defined varying out variable to a fragment color number can be specified explicitly. The command void BindFragDataLocationEXT(uint program, uint colorNumber, const char *name); specifies that the varying out variable name in program should be bound to fragment color colorNumber when the program is next linked. If name was bound previously, its assigned binding is replaced with colorNumber. name must be a null terminated string. The error INVALID_VALUE is generated if colorNumber is equal or greater than MAX_DRAW_BUFFERS. BindFragDataLocationEXT has no effect until the program is linked. In particular, it doesn't modify the bindings of varying out variables in a program that has already been linked. The error INVALID OPERATION is generated if name starts with the reserved "gl_" prefix. When a program is linked, any varying out variables without a binding specified through BindFragDataLocationEXT will automatically be bound to fragment colors by the GL. Such bindings can be queried using the command GetFragDataLocationEXT. LinkProgram will fail if the assigned binding of a varying out variable would cause the GL to reference a non-existant fragment color number (one greater than or equal to MAX DRAW_BUFFERS). LinkProgram will also fail if more than one varying out variable is bound to the same number. This type of aliasing is not allowed. BindFragDataLocationEXT may be issued before any shader objects are attached to a program object. Hence it is allowed to bind any name (except a name starting with "gl_") to a color number, including a name that is never used as a varying out variable in any fragment shader object. Assigned bindings for variables that do not exist are ignored. After a program object has been linked successfully, the bindings of varying out variable names to color numbers can be queried. The command int GetFragDataLocationEXT(uint program, const char *name); returns the number of the fragment color that the varying out variable name was bound to when the program object program was last linked. name must be a null terminated string. If program has not been successfully linked, the error INVALID OPERATION is generated. If name is not a varying out variable, or if an error occurs, -1 will be returned. Additions to Chapter 4 of the OpenGL 2.0 Specification (Per-Fragment Operations and the Frame Buffer) Modify Section 4.2.1, Selecting a Buffer for Writing (p. 212) (modify next-to-last paragraph, p. 213) If a fragment shader writes to gl_FragColor, DrawBuffers specifies a set of draw buffers into which the single fragment color defined by gl_FragColor is written. If a fragment shader writes to gl_FragData or a user-defined varying out variable, DrawBuffers specifies a set of draw buffers into which each of the multiple output colors defined by these variables are separately written. If a fragment shader writes to neither gl_FragColor, nor gl FragData, nor any user-defined varying out variables, the values of the fragment colors following shader execution are undefined, and may differ for each fragment color. Additions to Chapter 5 of the OpenGL 2.0 Specification (Special Functions) Change section 5.4 Display Lists, p. 237 Add the commands VertexAttribIPointerEXT and BindFragDataLocationEXT to the list of commands that are not compiled into a display list, but executed immediately, under "Program and Shader Objects", p. 241 Additions to Chapter 6 of the OpenGL 2.0 Specification (State and State Requests) Modify section 6.1.14 "Shader and Program Queries", p. 256 Modify 2nd paragraph, p.259: Add the following to the list of GetVertexAttrib* commands: void GetVertexAttribIivEXT(uint index, enum pname, int *params); void GetVertexAttribIuivEXT(uint index, enum pname, uint *params); obtain the... must be one of VERTEX_ATTRIB_ARRAY_ENABLED ,., VERTEX_ATTRIB_ARRAY_NORMALIZED, VERTEX_ATTRIB_ARRAY_INTEGER_EXT, or CURRENT_VERTEX_ATTRIB. ... Split 3rd paragraph, p.259 ... The size, stride, type, normalized flag, and unconverted integer flag are set by the commands VertexAttribPointer and VertexAttribIPointerEXT. The normalized flag is always set to FALSE by by VertexAttribIPointerEXT. The unconverted integer flag is always set to FALSE by VertexAttribPointer and TRUE by VertexAttribIPointerEXT. The query CURRENT_VERTEX_ATTRIB returns the current value for the generic attribute . GetVertexAttribdv and GetVertexAttribfv read and return the current attribute values as floating-point values; GetVertexAttribiv reads them as floating-point values and converts them to integer values; GetVertexAttribIivEXT reads and returns them as integers; GetVertexAttribIuivEXT reads and returns them as unsigned integers. The results of the query are undefined if the current attribute values are read using one data type but were specified using a different one. The error INVALID_OPERATION is generated if is zero. Change the prototypes in the first paragraph on page 260 as follows: void GetUniformfv(uint program, int location, float *params); void GetUniformiv(uint program, int location, int *params); void GetUniformuivEXT(uint program, int location, uint *params); Additions to Appendix A of the OpenGL 2.0 Specification (Invariance) None. Additions to the AGL/GLX/WGL Specifications None. Interactions with GL_ARB_color_buffer_float If the GL_ARB_color_buffer_float extension is not supported then any reference to fragment clamping in section 3.11.2 "Shader Execution" needs to be deleted. Interactions with GL_ARB_texture_rectangle If the GL_ARB_texture_rectangle extension is not supported then all references to texture lookup functions with 'Rect' in the name need to be deleted. Interactions with GL_EXT_texture_array If the GL_EXT_texture_array extension is not supported, all references to one- and two-dimensional array texture sampler types (e.g., sampler1DArray, sampler2DArray) and the texture lookup functions that use them need to be deleted. Interactions with GL_EXT_geometry_shader4 If the GL_EXT_geometry_shader4 extension is not supported, all references to a geometry shader need to be deleted. Interactions with GL_NV_primitive_restart The spec describes the behavior that primitive restart does not affect the primitive ID counter, including for POLYGON primitives (where one could argue that the restart index starts a new primitive without a new Begin to reset the count). If NV_primitive_restart is not supported, references to that extension in the discussion of the primitive ID counter should be removed. If NV_primitive_restart is supported, index values causing a primitive restart are not considered as specifying an End command, followed by another Begin. Primitive restart is therefore not guaranteed to immediately update material properties when a vertex shader is active. The spec language on p.64 of the OpenGL 2.0 specification says "changes are not guaranteed to update material parameters, defined in table 2.11, until the following End command." Interactions with EXT_texture_integer If the EXT_texture_integer spec is not supported, the discussion about this spec in section 2.15.4.1 needs to be removed. All texture lookup functions that return integers or unsigned integers, as discussed in section 8.7 of the OpenGL Shading Language specification, also need to be removed. Interactions with EXT_texture_buffer_object If EXT_texture_buffer_object is not supported, references to buffer textures, as well as the texelFetchBuffer and texelSizeBuffer lookup functions and samplerBuffer types, need to be removed. Interactions with EXT_draw_instanced If EXT_draw_instanced is not supported, the value of gl_InstanceID is always zero. GLX Protocol The following rendering commands are sent to the server as part of a glXRender request: Uniform1uiEXT 2 12 rendering command length 2 269 rendering command opcode 4 INT32 location 4 CARD32 v0 Uniform2uiEXT 2 16 rendering command length 2 270 rendering command opcode 4 INT32 location 4 CARD32 v0 4 CARD32 v1 Uniform3uiEXT 2 20 rendering command length 2 271 rendering command opcode 4 INT32 location 4 CARD32 v0 4 CARD32 v1 4 CARD32 v2 Uniform4uiEXT 2 24 rendering command length 2 272 rendering command opcode 4 INT32 location 4 CARD32 v0 4 CARD32 v1 4 CARD32 v2 4 CARD32 v3 BindFragDataLocationEXT 2 12+n+p rendering command length 2 273 rendering command opcode 4 CARD32 program 4 CARD32 color n LISTofBYTE name, n = strlen(name) + 1 p padding, p=pad(n) The following rendering commands are sent sent to the server as part of a glXRender request or as a glXRenderLarge request. Uniform1uivEXT 2 12+count*4 rendering command length 2 274 rendering command opcode 4 INT32 location 4 CARD32 count 4*count LISTofCARD32 value If the command is encoded in a glXRenderLarge request, the command opcode and command length fields above are expanded to 4 bytes each: 4 16+count*4 rendering command length 4 274 rendering command opcode Uniform2uivEXT 2 12+count*4*2 rendering command length 2 275 rendering command opcode 4 INT32 location 4 CARD32 count 2*4*count LISTofCARD32 value If the command is encoded in a glXRenderLarge request, the command opcode and command length fields above are expanded to 4 bytes each: 4 16+count*4*2 rendering command length 4 275 rendering command opcode Uniform3uivEXT 2 12+count*4*3 rendering command length 2 276 rendering command opcode 4 INT32 location 4 CARD32 count 3*4*count LISTofCARD32 value If the command is encoded in a glXRenderLarge request, the command opcode and command length fields above are expanded to 4 bytes each: 4 16+count*4 rendering command length 4 276 rendering command opcode Uniform4uivEXT 2 12+count*4*4 rendering command length 2 277 rendering command opcode 4 INT32 location 4 CARD32 count 4*4*count LISTofCARD32 value If the command is encoded in a glXRenderLarge request, the command opcode and command length fields above are expanded to 4 bytes each: 4 16+count*4*4 rendering command length 4 277 rendering command opcode The following non-rendering commands are added. GetUniformuivEXT 1 CARD8 opcode (X assigned) 1 182 GLX opcode 2 4 request length 4 GLX_CONTEXT_TAG context tag 4 CARD32 program 4 INT32 location => 1 1 reply 1 unused 2 CARD16 sequence number 4 m reply length, m = (n == 1 ? 0 : n) 4 CARD32 unused 4 CARD32 n if (n = 1) this follows: 4 CARD32 params 12 unused otherwise this follows: 16 CARD32 unused 4*n CARD32 params Note that n may be zero, indicating that a GL error occured. GetFragDataLocationEXT 1 CARD8 opcode (X assigned) 1 183 GLX opcode 2 3+(n+p)/4 request length 4 GLX_CONTEXT_TAG context tag 4 CARD32 program n LISTofBYTE name, n = strlen(name) + 1 p padding, p=pad(n) => 1 1 reply 1 unused 2 CARD16 sequence number 4 0 reply length 4 CARD32 retval 20 unused GLX protocol for following commands is defined in the NV_vertex_program4 extension: VertexAttribI1iEXT, VertexAttribI2iEXT, VertexAttribI3iEXT, VertexAttribI4iEXT, VertexAttribI1uiEXT, VertexAttribI2uiEXT, VertexAttribI3uiEXT, VertexAttribI4uiEXT, VertexAttribI1ivEXT, VertexAttribI2ivEXT, VertexAttribI3ivEXT, VertexAttribI4ivEXT, VertexAttribI1uivEXT, VertexAttribI2uivEXT, VertexAttribI3uivEXT, VertexAttribI4uivEXT, VertexAttribI4bvEXT, VertexAttribI4svEXT, VertexAttribI4ubvEXT, VertexAttribI4usvEXT, GetVertexAttribIivEXT, GetVertexAttribIuivEXT VertexAttribIPointerEXT is an entirely client-side command. Errors The error INVALID_VALUE is generated by BindFragDataLocationEXT() if colorNumber is equal or greater than MAX_DRAW_BUFFERS. The error INVALID OPERATION is generated by BindFragDataLocationEXT() if name starts with the reserved "gl_" prefix. The error INVALID_OPERATION is generated by BindFragDataLocationEXT() or GetFragDataLocationEXT if program is not the name of a program object. The error INVALID_OPERATION is generated by GetFragDataLocationEXT() if program has not been successfully linked. New State (add to table 6.7, p. 268) Initial Get Value Type Get Command Value Description Sec. Attribute --------- ---- --------------- ------- -------------------- ---- --------- VERTEX_ATTRIB_ARRAY 16+xB GetVertexAttrib FALSE vertex attrib array 2.8 vertex-array INTEGER_EXT has unconverted ints New Implementation Dependent State Minimum Get Value Type Get Command Value Description Sec. Attrib -------------------------------- ---- --------------- ------- --------------------- ------ ------ MIN_PROGRAM_TEXEL_OFFSET_EXT Z GetIntegerv -8 minimum texel offset 2.x.4.4 - allowed in lookup MAX_PROGRAM_TEXEL_OFFSET_EXT Z GetIntegerv +7 maximum texel offset 2.x.4.4 - allowed in lookup Modifications to The OpenGL Shading Language Specification, Version 1.10.59 Including the following line in a shader can be used to control the language features described in this extension: #extension GL_EXT_gpu_shader4 : where is as specified in section 3.3. A new preprocessor #define is added to the OpenGL Shading Language: #define GL_EXT_gpu_shader4 1 Add to section 3.6 "Keywords" Add the following keywords: noperspective, flat, centroid Remove the unsigned keyword from the list of keywords reserved for future use, and add it to the list of keywords. The following new vector types are added: uvec2, uvec3, uvec4 The following new sampler types are added: sampler1DArray, sampler2DArray, sampler1DArrayShadow, sampler2DArrayShadow, samplerCubeShadow isampler1D, isampler2D, isampler3D, isamplerCube, isampler2DRect, isampler1DArray, isampler2DArray usampler1D, usampler2D, usampler3D, usamplerCube, usampler2DRect, usampler1DArray, usampler2DArray samplerBuffer, isamplerBuffer, usamplerBuffer Add to section 4.1 "Basic Types" Break the table in this section up in several tables. The first table 4.1.1 is named "scalar, vector and matrix data types". It includes the first row through the 'mat4" row. Add the following to the first section of this table: unsigned int An unsigned integer uvec2 A two-component unsigned integer vector uvec3 A three-component unsigned integer vector uvec4 A four-component unsigned integer vector Break out the sampler types in a separate table, and name that table 4.1.2 "default sampler types". Add the following sampler types to this new table: sampler1DArray handle for accessing a 1D array texture sampler2DArray handle for accessing a 2D array texture sampler1DArrayShadow handle for accessing a 1D array depth texture with comparison sampler2DArrayShadow handle for accessing a 2D array depth texture with comparison samplerBuffer handle for accessing a buffer texture Add a table 4.1.3 called "integer sampler types": isampler1D handle for accessing an integer 1D texture isampler2D handle for accessing an integer 2D texture isampler3D handle for accessing an integer 3D texture isamplerCube handle for accessing an integer cube map texture isampler2DRect handle for accessing an integer rectangle texture isampler1DArray handle for accessing an integer 1D array texture isampler2DArray handle for accessing an integer 2D array texture isamplerBuffer handle for accessing an integer buffer texture Add a table 4.1.4 called "unsigned integer sampler types": usampler1D handle for accessing an unsigned integer 1D texture usampler2D handle for accessing an unsigned integer 2D texture usampler3D handle for accessing an unsigned integer 3D texture usamplerCube handle for accessing an unsigned integer cube map texture usampler2DRect handle for accessing an unsigned integer rectangle texture usampler1DArray handle for accessing an unsigned integer 1D array texture usampler2DArray handle for accessing an unsigned integer 2D array texture usamplerBuffer handle for accessing an unsigned integer buffer texture Change section 4.1.3 "Integers" Remove the first two paragraphs and replace with the following: Signed, as well as unsigned integers, are fully supported. Integers hold whole numbers. Integers have at least 32 bits of precision, including a sign bit. Signed integers are stored using a two's complement representation. Integers are declared and optionally initialized with integer expressions as in the following example: int i, j = 42; unsigned int k = 3u; Literal integer constants can be expressed in decimal (base 10), octal (base 8), or hexadecimal (base 16) as follows. integer-constant: decimal-constant integer-suffix_opt octal-constant integer-suffix_opt hexadecimal-constant integer-suffix_opt integer-suffix: one of u U Change section 4.3 "Type Qualifiers" Change the "varying" and "out" qualifier as follows: varying - linkage between a vertex shader and fragment shader, or between a fragment shader and the back end of the OpenGL pipeline. out - for function parameters passed back out of a function, but not initialized for use when passed in. Also for output varying variables (fragment only). In the qualifier table, add the following sub-qualifiers under the varying qualifier: flat varying noperspective varying centroid varying Change section 4.3.4 "Attribute" Change the sentence: The attribute qualifier can be used only with the data types float, vec2, vec3, vec4, mat2, mat3, and mat4. To: The attribute qualifier can be used only with the data types int, ivec2, ivec3, ivec4, unsigned int, uvec2, uvec3, uvec4, float, vec2, vec3, vec4, mat2, mat3, and mat4. Change the fourth paragraph to: It is expected that graphics hardware will have a small number of fixed locations for passing vertex attributes. Therefore, the OpenGL Shading language defines each non-matrix attribute variable as having space for up to four integer or floating-point values (i.e., a vec4, ivec4 or uvec4). There is an implementation dependent limit on the number of attribute variables that can be used and if this is exceeded it will cause a link error. (Declared attribute variables that are not used do not count against this limit.) A scalar attribute counts the same amount against this limit as a vector of size four, so applications may want to consider packing groups of four unrelated scalar attributes together into a vector to better utilize the capabilities of the underlying hardware. A mat4 attribute will... Change section 4.3.6 "Varying" Change the first paragraph to: Varying variables provide the interface between the vertex shader, the fragment shader, and the fixed functionality between the vertex and fragment shader, as well as the interface from the fragment shader to the back-end of the OpenGL pipeline. The vertex shader will compute values per vertex (such as color, texture coordinates, etc.) and write them to variables declared with the varying qualifier. A vertex shader may also read varying variables, getting back the same values it has written. Reading a varying variable in a vertex shader returns undefined values if it is read before being written. The fragment shader will compute values per fragment and write them to variables declared with the varying out qualifier. A fragment shader may also read varying variables, getting back the same result it has written. Reading a varying variable in a fragment shader returns undefined values if it is read before being written. Varying variables may be written more than once. If so, the last value assigned is the one used. Change the second paragraph to: Varying variables that are set per vertex are interpolated by default in a perspective-correct manner over the primitive being rendered, unless the varying is further qualified with noperspective. Interpolation in a perspective correct manner is specified in equations 3.6 and 3.8 in the OpenGL 2.0 specification. When noperspective is specified, interpolation must be linear in screen space, as described in equation 3.7 and the approximation that follows equation 3.8. If single-sampling, the value is interpolated to the pixel's center, and the centroid qualifier, if present, is ignored. If multi-sampling, and the varying is not qualified with centroid, then the value must be interpolated to the pixel's center, or anywhere within the pixel, or to one of the pixel's samples. If multi-sampling and the varying is qualified with centroid, then the value must be interpolated to a point that lies in both the pixel and in the primitive being rendered, or to one of the pixel's samples that falls within the primitive. [NOTE: Language for centroid sampling taken from the GLSL 1.20.4 specification] Varying variables, set per vertex, can be computed on a per-primitive basis (flat shading), or interpolated over a line or polygon primitive (smooth shading). By default, a varying variable is smooth shaded, unless the varying is further qualified with flat. When smooth shading, the varying is interpolated over the primitive. When flat shading, the varying is constant over the primitive, and is taken from the single provoking vertex of the primitive, as described in Section 2.14.7 of the OpenGL 2.0 specification. Change the fourth paragraph to: The type and any qualifications (flat, noperspective, centroid) of varying variables with the same name declared in both the vertex and fragment shaders must match, otherwise the link command will fail. Note that built-in varying variables, which have names starting with "gl_", can not be further qualified with flat, noperspective or centroid. The flat keyword cannot be used together with either the noperspective or centroid keywords to further qualify a single varying variable, otherwise a compile error will occur. When using the keywords centroid, flat or noperspective, it must immediately precede the varying keyword. When using both centroid and noperspective keywords, either one can be specified first. Only those varying variables used (i.e. read) in the fragment shader must be written to by the vertex shader; declaring superfluous varying variables in the vertex shader is permissible. Varying out variables, set per fragment, can not be further qualified with flat, noperspective or centroid. Fragment shaders output values to the back-end of the OpenGL pipeline using either user-defined varying out variables or built-in variables, as described in section 7.2, unless the discard keyword is executed. If the back-end of the OpenGL pipeline consumes a user-defined varying out variable and an execution of a fragment shader does not write a value to that variable, then the value consumed is undefined. If the back-end of the OpenGL pipeline consumes a varying out variable and a fragment shader either writes values into less components of the variable, or if the variable is declared to have less components, than needed, the values of the missing component(s) are undefined. The OpenGL specification, section 3.x.x, describes API to route varying output variables to color buffers. Add the following examples: noperspective varying float temperature; flat varying vec3 myColor; centroid varying vec2 myTexCoord; centroid noperspective varying vec2 myTexCoord; varying out ivec3 foo; Change the third paragraph on p. 25 as follows: The "varying" qualifier can be used only with the data types float, vec2, vec3, vec4, mat2, mat3, and mat4, int, ivec2, ivec3, ivec4, unsigned int, uvec2, uvec3, uvec4 or arrays of these. Structures cannot be varying. If the varying is declared as one of the integer or unsigned integer data type variants, then it has to also be qualified as being flat shaded, otherwise a compile error will occur. The "varying out" qualifier can be used only with the data types float, vec2, vec3, vec4, int, ivec2, ivec3, ivec4, unsigned int, uvec2, uvec3 or uvec4. Structures or arrays cannot be declared as varying out. Change section 5.1 "Operators" Remove the "reserved" qualifications from the following operator precedence table entries: Precedence Operator class ---------- ----------------------------------- 3 (tilde is reserved) 4 (modulus reserved) 6 bit-wise shift (reserved) 9 bit-wise and (reserved) 10 bit-wise exclusive or (reserved) 11 bit-wise inclusive or (reserved) 16 (modulus, shift, and bit-wise are reserved) Change section 5.8 "Assignments" Change the first bullet from: * The arithmetic assignments add into (+=).. To: * The arithmetic assignments add into (+=), subtract from (- =), multiply into (*=), and divide into (/=) as well as the assignments modulus into (%=), left shift by (<<=), right shift by (>>=), and into (&=), inclusive or into (|=), exclusive or into (^=). The expression Delete the last bullet in this paragraph. Remove the second bullet in the section starting with: The assignments modulus into.. Change section 5.9 "Expressions" Change the bullet: The operator modulus (%) is reserved for future use to: * The arithmetic operator % that operates on signed or unsigned integer typed expressions (including vectors). The two operands must be of the same type, or one can be a signed or unsigned integer scalar and the other a signed or unsigned integer vector. If the second operand is zero, results are undefined. If one operand is scalar and the other is a vector, the scalar is applied component-wise to the vector, resulting in the same type as the vector. If both operands are non-negative, then the remainder is non-negative. Results are undefined if one, or both, operands are negative. Change the last bullet: "Operators and (&), or (|), exclusive or (^), not (~), right-shift (>>), left shift (<<). These operators are reserved for future use." To the following bullets: * The one's complement operator ~. The operand must be of type signed or unsigned integer (including vectors), and the result is the one's complement of its operand. If the operand is a vector, the operator is applied component-wise to the vector. If the operand is unsigned, the result is computed by subtracting the value from the largest unsigned integer value. If the operand is signed, the result is computed by converting the operand to an unsigned integer, applying ~, and converting back to a signed integer. * The shift operators << and >>. For both operators, the operands must be of type signed or unsigned integer (including vectors). If the first operand is a scalar, the second operand has to be a scalar as well. The result is undefined if the right operand is negative, or greater than or equal to the number of bits in the left expression's type. The value of E1 << E2 is E1 (interpreted as a bit pattern) left-shifted by E2 bits. The value of E1 >> E2 is E1 right-shifted by E2 bit positions. If E1 is a signed integer, the right-shift will extend the sign bit. If E1 is an unsigned integer, the right-shift will zero-extend. * The bitwise AND operator &. The operands must be of type signed or unsigned integer (including vectors). The two operands must be of the same type, or one can be a signed or unsigned integer scalar and the other a signed or unsigned integer vector. If one operand is a scalar and the other a vector, the scalar is applied component-wise to the vector, resulting in the same type as the vector. The result is the bitwise AND function of the operands. * The bitwise exclusive OR operator ^. The operands must be of type signed or unsigned integer (including vectors). The two operands must be of the same type, or one can be a signed or unsigned integer scalar and the other a signed or unsigned integer vector. If one operand is a scalar and the other a vector, the scalar is applied component-wise to the vector, resulting in the same type as the vector. The result is the bitwise exclusive OR function of the operands. * The bitwise inclusive OR operator |. The operands must be of type signed or unsigned integer (including vectors). The two operands must be of the same type, or one can be a signed or unsigned integer scalar and the other a signed or unsigned integer vector. If one operand is a scalar and the other a vector, the scalar is applied component-wise to the vector, resulting in the same type as the vector. The result is the bitwise inclusive OR function of the operands. Change Section 7.1 "Vertex Shader Special Variables" Add the following definition to the list of built-in variable definitions: int gl_VertexID // read-only int gl_InstanceID // read-only Add the following paragraph at the end of the section: The variable gl_VertexID is available as a read-only variable from within vertex shaders and holds the integer index implicitly passed to ArrayElement() to specify the vertex. The value of gl_VertexID is defined if and only if: * the vertex comes from a vertex array command that specifies a complete primitive (e.g. DrawArrays, DrawElements), * all enabled vertex arrays have non-zero buffer object bindings, and * the vertex does not come from a display list, even if the display list was compiled using DrawArrays / DrawElements with data sourced from buffer objects. The variable gl_InstanceID is availale as a read-only variable from within vertex shaders and holds holds the integer index of the current primitive in an instanced draw call (DrawArraysInstancedEXT, DrawElementsInstancedEXT). If the current primitive does not come from an instanced draw call, the value of gl_InstanceID is zero. Change Section 7.2 "Fragment Shader Special Variables" Change the 8th and 9th paragraphs on p. 43 as follows: If a shader statically assigns a value to gl_FragColor, it may not assign a value to any element of gl_FragData nor to any user-defined varying output variable (section 4.3.6). If a shader statically writes a value to any element of gl_FragData, it may not assign a value to gl_FragColor nor to any user-defined varying output variable. That is, a shader may assign values to either gl_FragColor, gl_FragData, or any user-defined varying output variable, but not to a combination of the three options. If a shader executes the discard keyword, the fragment is discarded, and the values of gl_FragDepth, gl_FragColor, gl_FragData and any user-defined varying output variables become irrelevant. Add the following paragraph to the top of p. 44: The variable gl_PrimitiveID is available as a read-only variable from within fragment shaders and holds the id of the currently processed primitive. Section 3.11, subsection "Shader Inputs" of the OpenGL 2.0 specification describes what value it holds based on the primitive type. Add the following prototype to the list of built-in variables accessible from a fragment shader: int gl_PrimitiveID; Change Chapter 8, sixth paragraph on page 50: Change the sentence: When the built-in functions are specified below, where the input arguments (and corresponding output)can be float, vec2, vec3, or vec4, genType is used as the argument. To: When the built-in functions are specified below, where the input arguments (and corresponding output) can be float, vec2, vec3, or vec4, genType is used as the argument. Where the input arguments (and corresponding output) can be int, ivec2, ivec3 or ivec4, genIType is used as the argument. Where the input arguments (and corresponding output) can be unsigned int, uvec2, uvec3, or uvec4, genUType is used as the argument. Add to section 8.3 "Common functions" Add integer versions of the abs, sign, min, max and clamp functions, as follows: Syntax: genIType abs(genIType x) genIType sign(genIType x) genIType min(genIType x, genIType y) genIType min(genIType x, int y) genUType min(genUType x, genUType y) genUType min(genUType x, unsigned int y) genIType max(genIType x, genIType y) genIType max(genIType x, int y) genUType max(genUType x, genUType y) genUType max(genUType x, unsigned int y) genIType clamp(genIType x, genIType minval, genIType maxval) genIType clamp(genIType x, int minval, int maxval) genUType clamp(genUType x, genUType minval, genUType maxval) genUType clamp(genUType x, unsigned int minval, unsigned int maxval) Add the following new functions: Syntax: genType truncate(genType x) Description: Returns a value equal to the integer closest to x whose absolute value is not larger than the absolute value of x. Syntax: genType round(genType x) Description: Returns a value equal to the closest integer to x. If the fractional portion of the operand is 0.5, the nearest even integer is returned. For example, round (1.0) returns 1.0. round(-1.5) returns -2.0. round(3.5) and round (4.5) both return 4.0. Add to section 8.6 "Vector Relational Functions" Change the sentence: Below, "bvec" is a placeholder for one of bvec2, bvec3, or bvec4, "ivec" is a placeholder for one of ivec2, ivec3, or ivec4, and "vec" is a placeholder for vec2, vec3, or vec4. To: Below, "bvec" is a placeholder for one of bvec2, bvec3, or bvec4, "ivec" is a placeholder for one of ivec2, ivec3, or ivec4, "uvec" is a placeholder for one of uvec2, uvec3 or uvec4 and "vec" is a placeholder for vec2, vec3, or vec4. Add uvec versions of all but the any, all and not functions to the table in this section, as follows: bvec lessThan(uvec x, uvec y) bvec lessThanEqual(uvec x, uvec y) bvec greaterThan(uvec x, uvec y) bvec greaterThanEqual(uvec x, uvec y) bvec equal(uvec x, uvec y) bvec notEqual(uvec x, uvec y) Add to section 8.7 "Texture Lookup Functions" Remove the first sentence in the last paragraph: "The built-ins suffixed with "Lod" are allowed only in a vertex shader.". Add to this section: Texture data can be stored by the GL as floating point, unsigned normalized integer, unsigned integer or signed integer data. This is determined by the type of the internal format of the texture. Texture lookups on unsigned normalized integer and floating point data return floating point values in the range [0, 1]. See also section 2.15.4.1 of the OpenGL specification. Texture lookup functions are provided that can return their result as floating point, unsigned integer or signed integer, depending on the sampler type passed to the lookup function. Care must be taken to use the right sampler type for texture access. Table 8.xxx lists the supported combinations of sampler types and texture internal formats. texture internal default (float) integer unsigned integer format sampler sampler sampler float vec4 n/a n/a normalized vec4 n/a n/a signed int n/a ivec4 n/a unsigned int n/a n/a uvec4 Table 8.xxx Valid combinations of the type of the internal format of a texture and the type of the sampler used to access the texture. Each cell in the table indicates the type of the return value of a texture lookup. N/a means this combination is not supported. A texture lookup using a n/a combination will return undefined values. The exceptions to this table are the "textureSize" lookup functions, which will return an integer or integer vector, regardless of the sampler type. If a texture with a signed integer internal format is accessed, one of the signed integer sampler types must be used. If a texture with an unsigned integer internal format is accessed, one of the unsigned integer sampler types must be used. Otherwise, one of the default (float) sampler types must be used. If the types of a sampler and the corresponding texture internal format do not match, the result of a texture lookup is undefined. If an integer sampler type is used, the result of a texture lookup is an ivec4. If an unsigned integer sampler type is used, the result of a texture lookup is a uvec4. If a default sampler type is used, the result of a texture lookup is a vec4, where each component is in the range [0, 1]. Integer and unsigned integer functions of all the texture lookup functions described in this section are also provided, except for the "shadow" versions, using function overloading. Their prototypes, however, are not listed separately. These overloaded functions use the integer or unsigned-integer versions of the sampler types and will return an ivec4 or an uvec4 respectively, except for the "textureSize" functions, which will always return an integer, or integer vector. Refer also to table 8.xxxx for valid combinations of texture internal formats and sampler types. For example, for the texture1D function, the complete set of prototypes is: vec4 texture1D(sampler1D sampler, float coord [, float bias]) ivec4 texture1D(isampler1D sampler, float coord [, float bias]) uvec4 texture1D(usampler1D sampler, float coord [, float bias]) Add the following new texture lookup functions: Syntax: vec4 texelFetch1D(sampler1D sampler, int coord, int lod) vec4 texelFetch2D(sampler2D sampler, ivec2 coord, int lod) vec4 texelFetch3D(sampler3D sampler, ivec3 coord, int lod) vec4 texelFetch2DRect(sampler2DRect sampler, ivec2 coord) vec4 texelFetch1DArray(sampler1DArray sampler, ivec2 coord, int lod) vec4 texelFetch2DArray(sampler2DArray sampler, ivec3 coord, int lod) Description: Use integer texture coordinate to lookup a single texel from the level-of-detail on the texture bound to as described in section 2.15.4.1 of the OpenGL specification "Texel Fetches". For the "array" versions, the layer of the texture array to access is either coord.t or coord.p, depending on the use of the 1D or 2D texel fetch lookup, respectively. Note that texelFetch2DRect does not take a level-of-detail input. Syntax: vec4 texelFetchBuffer(samplerBuffer sampler, int coord) Description: Use integer texture coordinate to lookup into the buffer texture bound to . Syntax: int textureSizeBuffer(samplerBuffer sampler) int textureSize1D(sampler1D sampler, int lod) ivec2 textureSize2D(sampler2D sampler, int lod) ivec3 textureSize3D(sampler3D sampler, int lod) ivec2 textureSizeCube(samplerCube sampler, int lod) ivec2 textureSize2DRect(sampler2DRect sampler, int lod) ivec2 textureSize1DArray(sampler1DArray sampler, int lod) ivec3 textureSize2DArray(sampler2DArray sampler, int lod) Description: Returns the dimensions, width, height, depth, and number of layers, of level for the texture bound to , as described in section 2.15.4.1 of the OpenGL specification section "Texture Size Query". For the textureSize1DArray function, the first (".x") component of the returned vector is filled with the width of the texture image and the second component with the number of layers in the texture array. For the textureSize2DArray function, the first two components (".x" and ".y") of the returned vector are filled with the width and height of the texture image respectively. The third component (".z") is filled with the number of layers in the texture array. Syntax: vec4 texture1DArray(sampler1DArray sampler, vec2 coord [, float bias]) vec4 texture1DArrayLod(sampler1DArray sampler, vec2 coord, float lod) Description: Use the first element (coord.s) of texture coordinate coord to do a texture lookup in the layer indicated by the second coordinate coord.t of the 1D texture array currently bound to sampler. The layer to access is computed by layer = max (0, min(d - 1, floor (coord.t + 0.5)) where 'd' is the depth of the texture array. Syntax: vec4 texture2DArray(sampler2DArray sampler, vec3 coord [, float bias]) vec4 texture2DArrayLod(sampler2DArray sampler, vec3 coord, float lod) Description: Use the first two elements (coord.s, coord.t) of texture coordinate coord to do a texture lookup in the layer indicated by the third coordinate coord.p of the 2D texture array currently bound to sampler. The layer to access is computed by layer = max (0, min(d - 1, floor (coord.p + 0.5)) where 'd' is the depth of the texture array. Syntax: vec4 shadow1DArray(sampler1DArrayShadow sampler, vec3 coord, [float bias]) vec4 shadow1DArrayLod(sampler1DArrayShadow sampler, vec3 coord, float lod) Description: Use texture coordinate coord.s to do a depth comparison lookup on an array layer of the depth texture bound to sampler, as described in section 3.8.14 of version 2.0 of the OpenGL specification. The layer to access is indicated by the second coordinate coord.t and is computed by layer = max (0, min(d - 1, floor (coord.t + 0.5)) where 'd' is the depth of the texture array. The third component of coord (coord.p) is used as the R value. The texture bound to sampler must be a depth texture, or results are undefined. Syntax: vec4 shadow2DArray(sampler2DArrayShadow sampler, vec4 coord) Description: Use texture coordinate (coord.s, coord.t) to do a depth comparison lookup on an array layer of the depth texture bound to sampler, as described in section 3.8.14 of version 2.0 of the OpenGL specification. The layer to access is indicated by the third coordinate coord.p and is computed by layer = max (0, min(d - 1, floor (coord.p + 0.5)) where 'd' is the depth of the texture array. The fourth component of coord (coord.q) is used as the R value. The texture bound to sampler must be a depth texture, or results are undefined. Syntax: vec4 shadowCube(samplerCubeShadow sampler, vec4 coord) Description: Use texture coordinate (coord.s, coord.t, coord.p) to do a depth comparison lookup on the depth cubemap bound to sampler, as described in section 3.8.14. The direction of the vector (coord.s, coord.t, coord.p) is used to select which face to do a two-dimensional texture lookup in, as described in section 3.8.6 of the OpenGL 2.0 specification. The fourth component of coord (coord.q) is used as the R value. The texture bound to sampler must be a depth cubemap, otherwise results are undefined. Syntax: vec4 texture1DGrad(sampler1D sampler, float coord, float ddx, float ddy); vec4 texture1DProjGrad(sampler1D sampler, vec2 coord, float ddx, float ddy); vec4 texture1DProjGrad(sampler1D sampler, vec4 coord, float ddx, float ddy); vec4 texture1DArrayGrad(sampler1DArray sampler, vec2 coord, float ddx, float ddy); vec4 texture2DGrad(sampler2D sampler, vec2 coord, vec2 ddx, vec2 ddy); vec4 texture2DProjGrad(sampler2D sampler, vec3 coord, vec2 ddx, vec2 ddy); vec4 texture2DProjGrad(sampler2D sampler, vec4 coord, vec2 ddx, vec2 ddy); vec4 texture2DArrayGrad(sampler2DArray sampler, vec3 coord, vec2 ddx, vec2 ddy); vec4 texture3DGrad(sampler3D sampler, vec3 coord, vec3 ddx, vec3 ddy); vec4 texture3DProjGrad(sampler3D sampler, vec4 coord, vec3 ddx, vec3 ddy); vec4 textureCubeGrad(samplerCube sampler, vec3 coord, vec3 ddx, vec3 ddy); vec4 shadow1DGrad(sampler1DShadow sampler, vec3 coord, float ddx, float ddy); vec4 shadow1DProjGrad(sampler1DShadow sampler, vec4 coord, float ddx, float ddy); vec4 shadow1DArrayGrad(sampler1DArrayShadow sampler, vec3 coord, float ddx, float ddy); vec4 shadow2DGrad(sampler2DShadow sampler, vec3 coord, vec2 ddx, vec2 ddy); vec4 shadow2DProjGrad(sampler2DShadow sampler, vec4 coord, vec2 ddx, vec2 ddy); vec4 shadow2DArrayGrad(sampler2DArrayShadow sampler, vec4 coord, vec2 ddx, vec2 ddy); vec4 texture2DRectGrad(sampler2DRect sampler, vec2 coord, vec2 ddx, vec2 ddy); vec4 texture2DRectProjGrad(sampler2DRect sampler, vec3 coord, vec2 ddx, vec2 ddy); vec4 texture2DRectProjGrad(sampler2DRect sampler, vec4 coord, vec2 ddx, vec2 ddy); vec4 shadow2DRectGrad(sampler2DRectShadow sampler, vec3 coord, vec2 ddx, vec2 ddy); vec4 shadow2DRectProjGrad(sampler2DRectShadow sampler, vec4 coord, vec2 ddx, vec2 ddy); vec4 shadowCubeGrad(samplerCubeShadow sampler, vec4 coord, vec3 ddx, vec3 ddy); Description: The "Grad" functions map the partial derivatives ddx and ddy to ds/dx, dt/dx, dr/dx, and ds/dy, dt/dy, dr/dy respectively and use texture coordinate "coord" to do a texture lookup as described for their non "Grad" counterparts. The derivatives ddx and ddy are used as the explicit derivate of "coord" with respect to window x and window y respectively and are used to compute lambda_base(x,y) as in equation 3.18 in the OpenGL 2.0 specification. For the "Proj" versions, it is assumed that the partial derivatives ddx and ddy are already projected. I.e. the GL assumes that ddx and ddy represent d(s/q)/dx, d(t/q)/dx, d(r/q)/dx and d(s/q)/dy, d(t/q)/dy, d(r/q)/dy respectively. For the "Cube" versions, the partial derivatives ddx and ddy are assumed to be in the coordinate system used before texture coordinates are projected onto the appropriate cube face. The partial derivatives of the post-projection texture coordinates, which are used for level-of-detail and anisotropic filtering calculations, are derived from coord, ddx and ddy in an implementation-dependent manner. NOTE: Except for the "array" and shadowCubeGrad() functions, these functions are taken from the ARB_shader_texture_lod spec and are functionally equivalent. Syntax: vec4 texture1DOffset(sampler1D sampler, float coord, int offset [,float bias]) vec4 texture1DProjOffset(sampler1D sampler, vec2 coord, int offset [,float bias]) vec4 texture1DProjOffset(sampler1D sampler, vec4 coord, int offset [,float bias]) vec4 texture1DLodOffset(sampler1D sampler, float coord, float lod, int offset) vec4 texture1DProjLodOffset(sampler1D sampler, vec2 coord, float lod, int offset) vec4 texture1DProjLodOffset(sampler1D sampler, vec4 coord, float lod, int offset) vec4 texture2DOffset(sampler2D sampler, vec2 coord, ivec2 offset [,float bias]) vec4 texture2DProjOffset(sampler2D sampler, vec3 coord, ivec2 offset [,float bias]) vec4 texture2DProjOffset(sampler2D sampler, vec4 coord, ivec2 offset [,float bias]) vec4 texture2DLodOffset(sampler2D sampler, vec2 coord, float lod, ivec2 offset) vec4 texture2DProjLodOffset(sampler2D sampler, vec3 coord, float lod, ivec2 offset) vec4 texture2DProjLodOffset(sampler2D sampler, vec4 coord, float lod, ivec2 offset) vec4 texture3DOffset(sampler3D sampler, vec3 coord, ivec3 offset [,float bias]) vec4 texture3DProjOffset(sampler3D sampler, vec4 coord, ivec3 offset [,float bias]) vec4 texture3DLodOffset(sampler3D sampler, vec3 coord, float lod, ivec3 offset) vec4 texture3DProjLodOffset(sampler3D sampler, vec4 coord, float lod, ivec3 offset) vec4 shadow1DOffset(sampler1DShadow sampler, vec3 coord, int offset [,float bias]) vec4 shadow2DOffset(sampler2DShadow sampler, vec3 coord, ivec2 offset [,float bias]) vec4 shadow1DProjOffset(sampler1DShadow sampler, vec4 coord, int offset [,float bias]) vec4 shadow2DProjOffset(sampler2DShadow sampler, vec4 coord, ivec2 offset [,float bias]) vec4 shadow1DLodOffset(sampler1DShadow sampler, vec3 coord, float lod, int offset) vec4 shadow2DLodOffset(sampler2DShadow sampler, vec3 coord, float lod, ivec2 offset) vec4 shadow1DProjLodOffset(sampler1DShadow sampler, vec4 coord, float lod, int offset) vec4 shadow2DProjLodOffset(sampler2DShadow sampler, vec4 coord, float lod, ivec2 offset) vec4 texture2DRectOffset(sampler2DRect sampler, vec2 coord, ivec2 offset) vec4 texture2DRectProjOffset(sampler2DRect sampler, vec3 coord, ivec2 offset) vec4 texture2DRectProjOffset(sampler2DRect sampler, vec4 coord, ivec2 offset) vec4 shadow2DRectOffset(sampler2DRectShadow sampler, vec3 coord, ivec2 offset) vec4 shadow2DRectProjOffset(sampler2DRectShadow sampler, vec4 coord, ivec2 offset) vec4 texelFetch1DOffset(sampler1D sampler, int coord, int lod, int offset) vec4 texelFetch2DOffset(sampler2D sampler, ivec2 coord, int lod, ivec2 offset) vec4 texelFetch3DOffset(sampler3D sampler, ivec3 coord, int lod, ivec3 offset) vec4 texelFetch2DRectOffset(sampler2DRect sampler, ivec2 coord, ivec2 offset) vec4 texelFetch1DArrayOffset(sampler1DArray sampler, ivec2 coord, int lod, int offset) vec4 texelFetch2DArrayOffset(sampler2DArray sampler, ivec3 coord, int lod, ivec2 offset) vec4 texture1DArrayOffset(sampler1DArray sampler, vec2 coord, int offset [, float bias]) vec4 texture1DArrayLodOffset(sampler1DArray sampler, vec2 coord, float lod, int offset) vec4 texture2DArrayOffset(sampler2DArray sampler, vec3 coord, ivec2 offset [, float bias]) vec4 texture2DArrayLodOffset(sampler2DArray sampler, vec3 coord, float lod, ivec2 offset) vec4 shadow1DArrayOffset(sampler1DArrayShadow sampler, vec3 coord, int offset, [float bias]) vec4 shadow1DArrayLodOffset(sampler1DArrayShadow sampler, vec3 coord, float lod, int offset) vec4 shadow2DArrayOffset(sampler2DArrayShadow sampler, vec4 coord, ivec2 offset) vec4 texture1DGradOffset(sampler1D sampler, float coord, float ddx, float ddy, int offset); vec4 texture1DProjGradOffset(sampler1D sampler, vec2 coord, float ddx, float ddy, int offset); vec4 texture1DProjGradOffset(sampler1D sampler, vec4 coord, float ddx, float ddy, int offset); vec4 texture1DArrayGradOffset(sampler1DArray sampler, vec2 coord, float ddx, float ddy, int offset); vec4 texture2DGradOffset(sampler2D sampler, vec2 coord, vec2 ddx, vec2 ddy, ivec2 offset); vec4 texture2DProjGradOffset(sampler2D sampler, vec3 coord, vec2 ddx, vec2 ddy, ivec2 offset); vec4 texture2DProjGradOffset(sampler2D sampler, vec4 coord, vec2 ddx, vec2 ddy, ivec2 offset); vec4 texture2DArrayGradOffset(sampler2DArray sampler, vec3 coord, vec2 ddx, vec2 ddy, ivec2 offset); vec4 texture3DGradOffset(sampler3D sampler, vec3 coord, vec3 ddx, vec3 ddy, ivec3 offset); vec4 texture3DProjGradOffset(sampler3D sampler, vec4 coord, vec3 ddx, vec3 ddy, ivec3 offset); vec4 shadow1DGradOffset(sampler1DShadow sampler, vec3 coord, float ddx, float ddy, int offset); vec4 shadow1DProjGradOffset(sampler1DShadow sampler, vec4 coord, float ddx, float ddy, int offset); vec4 shadow1DArrayGradOffset(sampler1DArrayShadow sampler, vec3 coord, float ddx, float ddy, int offset); vec4 shadow2DGradOffset(sampler2DShadow sampler, vec3 coord, vec2 ddx, vec2 ddy, ivec2 offset); vec4 shadow2DProjGradOffset(sampler2DShadow sampler, vec4 coord, vec2 ddx, vec2 ddy, ivec2 offset); vec4 shadow2DArrayGradOffset(sampler2DArrayShadow sampler, vec4 coord, vec2 ddx, vec2 ddy, ivec2 offset); vec4 texture2DRectGradOffset(sampler2DRect sampler, vec2 coord, vec2 ddx, vec2 ddy, ivec2 offset); vec4 texture2DRectProjGradOffset(sampler2DRect sampler, vec3 coord, vec2 ddx, vec2 ddy, ivec2 offset); vec4 texture2DRectProjGradOffset(sampler2DRect sampler, vec4 coord, vec2 ddx, vec2 ddy, ivec2 offset); vec4 shadow2DRectGradOffset(sampler2DRectShadow sampler, vec3 coord, vec2 ddx, vec2 ddy, ivec2 offset); vec4 shadow2DRectProjGradOffset(sampler2DRectShadow sampler, vec4 coord, vec2 ddx, vec2 ddy, ivec2 offset); Description: The "offset" version of each function provides an extra parameter which is added to the (u,v,w) texel coordinates before looking up each texel. The offset value must be a constant expression. A limited range of offset values are supported; the minimum and maximum offset values are implementation-dependent and given by MIN_PROGRAM_TEXEL_OFFSET_EXT and MAX_PROGRAM_TEXEL_OFFSET_EXT, respectively. Note that does not apply to the layer coordinate for texture arrays. This is explained in detail in section 3.8.7 of the OpenGL Specification. Note that texel offsets are also not supported for cubemaps or buffer textures. Add to section 9 "Grammar" type_qualifer: CONST ATTRIBUTE // Vertex only varying-modifier_opt VARYING UNIFORM varying-modifier: FLAT CENTROID NOPERSPECTIVE type_specifier: VOID FLOAT INT UNSIGNED_INT BOOL Issues 1. Should we support shorts in GLSL? DISCUSSION: RESOLUTION: UNRESOLVED 2. Do bitwise shifts, AND, exclusive OR and inclusive OR support all combinations of scalars and vectors for each operand? DISCUSSION: It seems sense to support scalar OP scalar, vector OP scalar and vector OP vector. But what about scalar OP vector? Should the scalar be promoted to a vector first? RESOLUTION: RESOLVED. Yes, this should work essentially as the '+' operator. The scalar is applied to each component of the vector. 3. Which built-in functions should also operate on integers? DISCUSSION: There are several that don't make sense to define to operate on integers at all, but the following can be debated: pow, sqrt, dot (and the functions that use dot), cross. RESOLUTION: RESOLVED. Integer versions of the abs, sign, min, max and clamp functions are defined. Note that the modulus operator % has been defined for integer operands. 4. Do we need to support integer matrices? DISCUSSION: RESOLUTION: RESOLVED No, not at the moment. 5. Which texture array lookup functions do we need to support? DISCUSSION: We don't want to support lookup functions that need more than four components passed as parameters. Components can be used for texture coordinates, layer selection, 'R' depth compare and the 'q' coordinate for projection. However, texture projection might be relatively easy to support through code-generation, thus we might be able to support functions that need five components, as long as one of them is 'q' for projective texturing. Specifically, should we support: vec4 texture2DArrayProjLod(sampler2DArray sampler, vec4 coord, float lod) vec4 shadow1DArray(sampler1DArrayShadow sampler, vec3 coord, [float bias]) vec4 shadow1DArrayProj(sampler1DArrayShadow sampler, vec4 coord, [float bias]) vec4 shadow1DArrayLod(sampler1DArrayShadow sampler, vec3 coord, float lod) vec4 shadow1DArrayProjLod(sampler1DArrayShadow sampler, vec4 coord, float lod) vec4 shadow2DArray(sampler2DArrayShadow sampler, vec4 coord) vec4 shadow2DArrayProj(sampler2DArrayShadow sampler, vec4 coord, float refValue) RESOLUTION: RESOLVED, We'll support all but the "Proj" versions. The assembly spec (NV_gpu_program4) doesn't support the equivalent functionality, either. 6. How do we handle conversions between integer and unsigned integers? DISCUSSION: Do we allow automatic type conversions between signed and unsigned integers? RESOLUTION: RESOLVED. We will not add this until GLSL version 1.20 has been defined, and the implicit conversion rules have been established there. If we do this, we would likely only support implicit conversion from int to unsigned int, just like C does. 7. Should varying modifiers (flat, noperspective) apply to built-in varying variables also? DISCUSSION: There is API to control flat vs smooth shading for colors through glShadeModel(). There is also API to hint if colors should be interpolated perspective correct, or not, through glHint(). These API commands apply to the built-in color varying variables (gl_FrontColor etc). If the varying modifiers in a shader also apply to the color built-ins, which has precedence? RESOLUTION: RESOLVED. It is simplest and cleanest to only allow the varying modifiers to apply to user-defined varying variables. The behavior of the built-in color varying variables can still be controlled through the API. 8. How should perspective-incorrect interpolation (linear in screen space) and clipping interact? RESOLVED: Primitives with attributes specified to be perspective- incorrect should be clipped so that the vertices introduced by clipping should have attribute values consistent with the interpolation mode. We do not want to have large color shifts introduced by clipping a perspective-incorrect attribute. For example, a primitive that approaches, but doesn't cross, a frustum clip plane should look pretty much identical to a similar primitive that just barely crosses the clip plane. Clipping perspective-incorrect interpolants that cross the W==0 plane is very challenging. The attribute clipping equation provided in the spec effectively projects all the original vertices to screen space while ignoring the X and Y frustum clip plane. As W approaches zero, the projected X/Y window coordinates become extremely large. When clipping an edge with one vertex inside the frustum and the other out near infinity (after projection, due to W approaching zero), the interpolated attribute for the entire visible portion of the edge should almost exactly match the attribute value of the visible vertex. If an outlying vertex approaches and then goes past W==0, it can be said to go "to infinity and beyond" in screen space. The correct answer for screen-linear interpolation is no longer obvious, at least to the author of this specification. Rather than trying to figure out what the "right" answer is or if one even exists, the results of clipping such edges is specified as undefined. 9. Do we need to support a non-MRT fragment shader writing to (unsigned) integer outputs? DISCUSSION: Fragment shaders with only one fragment output are considered non-MRT shaders. This means that the output of the shader gets smeared across all color buffers attached to the framebuffer. Fragment shaders with multiple fragment outputs are MRT shaders. Each output is directed to a color buffer using the DrawBuffers API (for gl_FragData) and a combination of the BindFragDataLocationEXT and DrawBuffers API (for varying out variables). Before this extension, a non-MRT shader would write to gl_Color only. A shader writing to gl_FragData[] is a MRT shader. With the addition of varying out variables in this extension, any shader writing to a variable out variable is a MRT shader. It is not possible to construct a non-MRT shader writing to varying out variables. Varying out variables can be declared to be of type integer or unsigned integer. In order to support a non-MRT shader that can write to (unsigned) integer outputs, we could define two new built-in variables: ivec4 gl_FragColorInt; uvec4 gl_FragColorUInt; Or we could add a special rule stating that if the program object writes to exactly one varying out variable, it is considered to be non-MRT. RESOLUTION: NO. We don't care enough to support this. 10. Is section 2.14.8, "Color and Associated Data Clipping" in the core specification still correct? DISCUSSION: This section is in need of some updating, now that varying variables can be interpolated without perspective correction. Some (not so precise) language has been added in the spec body, suggesting that the interpolation needs to be performed in such a way as to produce results that vary linearly in screen space. However, we could define the exact interpolation method required to achieve this. A suggested updated paragraph follows, but we'll leave updating section 2.14.8 to a future edit of the core specification, not this extension. Replace Section 2.14.8, and rename it to "Vertex Attribute Clipping" After lighting, clamping or masking and possible flatshading, vertex attributes, including colors, texture and fog coordinates, shader varying variables, and point sizes computed on a per vertex basis, are clipped. Those attributes associated with a vertex that lies within the clip volume are unaffected by clipping. If a primitive is clipped, however, the attributes assigned to vertices produced by clipping are produced by interpolating attributes along the clipped edge. Let the attributes assigned to the two vertices P_1 and P_2 of an unclipped edge be a_1 and a_2. The value of t (section 2.12) for a clipped point P is used to obtain the attribute associated with P as a = t * a_1 + (1-t) * a_2 unless the attribute is specified to be interpolated without perspective correction in a shader (using the noperspective keyword). In that case, the attribute associated with P is a = t' * a_1 + (1-t') * a_2 where t' = (t * w_1) / (t * w_1 + (1-t) * w_2) and w_1 and w_2 are the w clip coordinates of P_1 and P_2, respectively. If w_1 or w_2 is either zero or negative, the value of the associated attribute is undefined. For a color index color, multiplying a color by a scalar means multiplying the index by the scalar. For a vector attribute, it means multiplying each vector component by the scalar. Polygon clipping may create a clipped vertex along an edge of the clip volume's boundary. This situation is handled by noting that polygon clipping proceeds by clipping against one plane of the clip volume's boundary at a time. Attribute clipping is done in the same way, so that clipped points always occur at the intersection of polygon edges (possibly already clipped) with the clip volume's boundary. 11. When and where in the texture filtering process are texel offsets applied? DISCUSSION: Texel offsets are applied to the (u,v,w) coordinates of the base level of the texture if the texture filter mode does not indicate mipmapping. Otherwise, texel offsets are applied to the (u,v,w) coordinates of the mipmap level 'd', as found by equation 3.27 or to mipmap levels 'd1' and 'd2' as found by equation 3.28 in the OpenGL 2.0 specification. In other words, texel offsets are applied to the (u,v,w) coordinate of whatever mipmap level is accessed. 12. Why is writing to the built-in output variable "gl_Position" in a vertex shader now optional? DISCUSSION: Before this specification, writing to gl_Position in a vertex shader was mandatory. The GL pipeline required a vertex position to be written in order to produce well-defined output. This is still the case if the GL pipeline indeed needs a vertex position. However, with fourth-generation programmable hardware there are now cases where the GL pipeline no longer requires a vertex position in order to produce well-defined results. If a geometry shader is present, the vertex shader does not need to write to gl_Position anymore. Instead, the geometry shader can compute a vertex position and write to its gl_Position output. In case of transform-feedback, where the output of a vertex or geometry shader is streamed to one or more buffer objects, perfectly valid results can be obtained without either the vertex shader nor geometry shader writing to gl_Position. The transform-feedback specification adds a new enable to discard primitives right before rasterization, making it potentially unnecessary to write to gl_Position. 13. How does this extension interact with ARB_shader_texture_lod? DISCUSSION: This extension adds "Grad" functions which are functionally equivalent to those defined by ARB_shader_texture_lod, but do not have an ARB suffix. RESOLUTION: There is no interaction. If both extensions are supported, both sets of functions are available and can be controlled independently via the #extension mechanism. Revision History Rev. Date Author Changes ---- -------- -------- ----------------------------------------- 16 12/14/09 mgodse Added GLX protocol. 15 04/09/09 pbrown Fixed a typo in the texture size query spec language - returns a layer count, not "index". 14 07/29/08 pbrown Discovered additional issues with texture wrap handling, replaced with logic that applies wrap modes per sample. 13 04/04/08 pbrown Added issue 13, concerning the (non-)interaction with ARB_shader_texture_lod. 12 02/04/08 pbrown Fix errors in texture wrap mode handling. Added a missing clamp to avoid sampling border in REPEAT mode. Fixed incorrectly specified weights for LINEAR filtering. 11 05/08/07 pbrown Add VertexAttribIPointerEXT to the list of commands that can't go in display lists. 10 01/23/07 pbrown Fix prototypes for a variety of functions that were specified with an incorrect sampler type. 9 12/15/06 pbrown Documented that the '#extension' token for this extension should begin with "GL_", as apparently called for per convention. 8 -- Pre-release revisions.