| Name |
| |
| ARB_shading_language_420pack |
| |
| Name Strings |
| |
| GL_ARB_shading_language_420pack |
| |
| Contact |
| |
| John Kessenich (cepheus 'at' frii.com) |
| |
| Contributors |
| |
| Pat Brown, NVIDIA |
| Jeff Bolz, NVIDIA |
| Pierre Boudier, AMD |
| Piers Daniell, NVIDIA |
| Patrick Doane, Blizzard |
| John Kessenich |
| Daniel Koch, Transgaming |
| Bill Licea-Kane, AMD |
| Barthold Lichtenbelt, NVIDIA |
| Ian Romanick, Intel |
| Bruce Merry, ARM |
| Graham Sellers, AMD |
| Robert Simpson, Qualcomm |
| |
| Notice |
| |
| Copyright (c) 2011-2013 The Khronos Group Inc. Copyright terms at |
| http://www.khronos.org/registry/speccopyright.html |
| |
| Specification Update Policy |
| |
| Khronos-approved extension specifications are updated in response to |
| issues and bugs prioritized by the Khronos OpenGL Working Group. For |
| extensions which have been promoted to a core Specification, fixes will |
| first appear in the latest version of that core Specification, and will |
| eventually be backported to the extension document. This policy is |
| described in more detail at |
| https://www.khronos.org/registry/OpenGL/docs/update_policy.php |
| |
| Status |
| |
| Complete. |
| Approved by the ARB 25-Jul-2011. |
| Approved by the Khronos Promoters on 2011/07/29. |
| |
| Version |
| |
| Last Modified Date: 11-Sep-2014 |
| Revision: 4 |
| |
| Number |
| |
| ARB Extension #108 |
| |
| Dependencies |
| |
| GLSL 1.3 is required for all features. GLSL 1.4 is required |
| declaring a binding for a uniform block, as uniform blocks were not |
| present until version 1.4. |
| |
| This extension interacts with the ARB_shader_image_load_store |
| extension, for assigning locations to image variables. |
| |
| References to *patch* are not valid unless tessellation stages are |
| present and enabled. |
| |
| While this document is self-contained, clarifying context for how to |
| add the following changes can be seen by looking at version 4.20 of |
| the GLSL specification. |
| |
| Overview |
| |
| This is a language feature only extension formed from changes made |
| to version 4.20 of GLSL. It includes: |
| |
| * Add line-continuation using '\', as in C++. |
| |
| * Change from ASCII to UTF-8 for the language character set and also |
| allow any characters inside comments. |
| |
| * Allow implicit conversions of return values to the declared type of |
| the function. |
| |
| * The *const* keyword can be used to declare variables within a function |
| body with initializer expressions that are not constant expressions. |
| |
| * Qualifiers on variable declarations no longer have to follow a strict |
| order. The layout qualifier can be used multiple times, and multiple |
| parameter qualifiers can be used. However, this is not as |
| straightforward as saying declarations have arbitrary lists of |
| initializers. Typically, one qualifier from each class of qualifiers |
| is allowed, so care is now taken to classify them and say so. Then, |
| of these, order restrictions are removed. |
| |
| * Add layout qualifier identifier "binding" to bind the location of a |
| uniform block. This requires version 1.4 of GLSL. If this extension |
| is used with an earlier version than 1.4, this feature is not present. |
| |
| * Add layout qualifier identifier "binding" to bind units to sampler |
| and image variable declarations. |
| |
| * Add C-style curly brace initializer lists syntax for initializers. |
| Full initialization of aggregates is required when these are used. |
| |
| * Allow ".length()" to be applied to vectors and matrices, returning |
| the number of components or columns. |
| |
| * Allow swizzle operations on scalars. |
| |
| * Built-in constants for gl_MinProgramTexelOffset and |
| gl_MaxProgramTexelOffset. |
| |
| IP Status |
| |
| No known IP claims. |
| |
| Additions to Chapter 3 of the OpenGL Shading Language |
| |
| Change the opening of 3.1 Character Set to |
| |
| "The source character set used for the OpenGL shading languages, outside of |
| comments, is a subset of UTF-8. It includes the following characters: |
| |
| "The backslash ( \ ) as the line-continuation character when used as |
| the last character of a line, just before a new line." |
| |
| and after the list, referring to all the characters: |
| |
| "An error will be given if any other character is used outside a comment. |
| |
| "There are no trigraphs. There are no escape sequences or other uses of the |
| backslash beyond use as the line-continuation character." |
| |
| At the end of section 3.2, add |
| |
| "Line numbers are one more than the number of new lines that have been |
| processed, including counting the new lines that will be removed by the |
| line-continuation character ( \ ). |
| |
| "Lines separated by the line-continuation character preceding a new line |
| are concatenated together before either comment processing or preprocessing. |
| No white space is substituted for the line-continuation character. That is, |
| a single token could be formed by the concatenation by taking the characters |
| at the end of one line concatenating them with the characters at the |
| beginning of the next line." |
| |
| float f\ |
| oo; |
| // forms a single line equivalent to "float foo;" |
| // (assuming '\' is the last character before the new line and "oo" are |
| // the first two characters of the next line) |
| |
| Add to the preprocessor: |
| |
| "Preprocessing takes places after new lines have been removed by the |
| line-continuation character." |
| |
| "Including the following line in a shader will enable module import and |
| related extended language features described in this extension: |
| |
| #extension GL_ARB_shading_language_420pack : <behavior> |
| |
| where <behavior> is as specified in section 3.3 for the #extension |
| directive." |
| |
| A new preprocessor macro is added to the OpenGL Shading Language: |
| |
| #define GL_ARB_shading_language_420pack 1 |
| |
| Add to the section on comments |
| |
| "Inside comments, any byte values may be used, except a byte whose value |
| is 0. No errors will be given for the content of comments and no validation |
| on the content of comments need be done. |
| |
| "Removal of new lines by the line-continuation character ( \ ) logically |
| occurs before comments are processed. That is, a single-line comment ending |
| in the line-continuation character ( \ ) includes the next line in the |
| comment." |
| |
| // a single-line comment containing the next line \ |
| a = b; // this is still in the first comment |
| |
| Additions to Chapter 4 of the OpenGL Shading Language |
| |
| Add to the syntax description of integer literals: |
| |
| "When tokenizing, the maximal token matching the above will be recognized |
| before a new token is started." |
| |
| Add to the syntax description of floating-point literals: |
| |
| "When tokenizing, the maximal token matching the above will be recognized |
| before a new token is started." |
| |
| Add to the description of .length(): |
| |
| "This returns a type int." |
| |
| Add a new section for initializers |
| |
| "Initializers |
| |
| "At declaration, an initial value for an aggregate variable may be provided, |
| specified as an equals (=) followed by an initializer. The initializer is |
| either an assignment-expression or a list of initializers enclosed in curly |
| braces. The grammar for the initializer is: |
| |
| initializer : |
| assignment-expression |
| { initializer-list } |
| { initializer-list , } |
| |
| initializer-list : |
| initializer |
| initializer-list , initializer |
| |
| "The assignment-expression is a normal expression except that a comma ( , ) |
| outside parentheses is interpreted as the end of the initializer, not as the |
| sequence operator. As explained in more detail below, this allows creation |
| of nested initializers: The aggregate and its initializer must exactly match |
| in terms of nesting, number of components/elements/members present at each |
| level, and types of components/elements/members. |
| |
| "An assignment-expression in an initializer must be either the same type as |
| the object it initializes or be a type that can be converted to the object's |
| type according to section 4.1.10 "Implicit Conversions". Since these include |
| constructors, an aggregate can be initialized by either a constructor or an |
| initializer list; an element in an initializer list can be a constructor. |
| |
| "If an initializer is a list of initializers enclosed in curly braces, the |
| variable being declared must be a vector, a matrix, an array, or a |
| structure. |
| |
| int i = { 1 }; // illegal, i is not an aggregate |
| |
| "A list of initializers enclosed in a matching set of curly braces is |
| applied to one aggregate. This may be the variable being declared or an |
| aggregate contained in the variable being declared. Individual |
| initializers from the initializer list are applied to the elements/members |
| of the aggregate, in order. |
| |
| "If the aggregate has a vector type, initializers from the list are applied |
| to the components of the vector, in order, starting with component 0. The |
| number of initializers must match the number of components. |
| |
| "If the aggregate has a matrix type, initializers from the list must be |
| vector initializers and are applied to the columns of the matrix, in order, |
| starting with column 0. The number of initializers must match the number of |
| columns. |
| |
| "If the aggregate has a structure type, initializers from the list are |
| applied to the members of the structure, in the order declared in the |
| structure, starting with the first member. The number of initializers must |
| match the number of members. |
| |
| "Applying these rules, the following matrix declarations are equivalent: |
| |
| mat2x2 a = mat2( vec2( 1.0, 0.0 ), vec2( 0.0, 1.0 ) ); |
| mat2x2 b = { vec2( 1.0, 0.0 ), vec2( 0.0, 1.0 ) }; |
| mat2x2 c = { { 1.0, 0.0 }, { 0.0, 1.0 } }; |
| |
| "All of the following declarations are illegal. |
| |
| float a[2] = { 3.4, 4.2, 5.0 }; // illegal |
| vec2 b = { 1.0, 2.0, 3.0 }; // illegal |
| mat3x3 c = { vec3(0.0), vec3(1.0), vec3(2.0), vec3(3.0) }; // illegal |
| mat2x2 d = { 1.0, 0.0, 0.0, 1.0 }; // illegal, can't flatten nesting |
| struct { |
| float a; |
| int b; |
| } e = { 1.2, 2, 3 }; // illegal |
| |
| "In all cases, the innermost initializer (i.e., not a list of initializers |
| enclosed in curly braces) applied to an object must have the same type as |
| the object being initialized or be a type that can be converted to the |
| object's type according to section 4.1.10 "Implicit Conversions". In the |
| latter case, an implicit conversion will be done on the initializer before |
| the assignment is done. All of the following declarations are illegal. |
| |
| int a = true; // illegal |
| vec4 b[2] = { vec4(0.0), 1.0 }; // illegal |
| mat4x2 c = { vec3(0.0), vec3(1.0) }; // illegal |
| |
| struct S1 { |
| vec4 a; |
| vec4 b; |
| }; |
| |
| struct { |
| float s; |
| float t; |
| } d[] = { S1(vec4(0.0), vec4(1.1)) }; // illegal |
| |
| "If an initializer (of either form) is provided for an unsized array, the |
| size of the array is determined by the number of top-level (non-nested) |
| initializers within the initializer. All of the following declarations |
| create arrays explicitly sized with five elements: |
| |
| float a[] = float[](3.4, 4.2, 5.0, 5.2, 1.1); |
| float b[] = { 3.4, 4.2, 5.0, 5.2, 1.1 }; |
| float c[] = a; // c is explicitly size 5 |
| float d[5] = b; // means the same thing |
| |
| "It is an error to have too few or too many initializers in an initializer |
| list for the aggregate being initialized. That is, all elements of an array, |
| all members of a structure, all columns of a matrix, and all components of a |
| vector must have exactly one initializer expression present, with no |
| unconsumed initializers. |
| |
| Change the definition of the storage qualifier *const* in the table: |
| |
| const | a variable whose value cannot be changed |
| |
| Change the definition of storage qualifiers to only include the following |
| rows |
| |
| const |
| in |
| out |
| attribute |
| uniform |
| varying |
| |
| (Removing "centroid in", "sample in", "centroid out", "sample out", |
| "centroid varying", "patch in", and "patch out".) |
| |
| and with this introduction: |
| |
| "Variable declarations may have at most one storage qualifier specified in |
| front of the type." |
| |
| and make a new class "Auxiliary Storage Qualifier" to contain |
| |
| Auxiliary Storage | Meaning |
| Qualifier | |
| ----------------- ------- |
| centroid | centroid-based interpolation |
| sample | per-sample interpolation |
| patch | per-tessellation-patch attributes |
| |
| add that |
| |
| "Some input and output qualified variables can be qualified with at most one |
| additional auxiliary storage qualifier. |
| |
| "Not all combinations of qualification are allowed. Which variable types can |
| have which qualifiers are specifically defined in upcoming sections." |
| |
| Removing |
| |
| "These interpolation qualifiers may only precede the qualifiers in, |
| centroid in, sample in, out, centroid out, or sample out in a |
| declaration." |
| |
| Change the last paragraph in this section to say |
| |
| "Initializers in global declarations may only be used in declarations of |
| global variables with no storage qualifier, with a *const* qualifier or |
| with a uniform qualifier...." |
| |
| Change the Constant Qualifier section to instead say |
| |
| "Named compile-time constants or read-only variables can be declared using |
| the const qualifier. The const qualifier can be used with any of the |
| non-void transparent basic data types, as well as with structures and arrays |
| of these. It is an error to write to a const variable outside of its |
| declaration, so they must be initialized when declared. For example, |
| |
| const vec3 zAxis = vec3 (0.0, 0.0, 1.0); |
| const float ceiling = a + b; // a and b not necessarily constants |
| |
| "Structure members may not be qualified with *const*. Structure variables |
| can be declared as *const*, and initialized with a structure constructor or |
| initializer. |
| |
| "Initializers for *const* declarations at global scope must be |
| constant expressions..." |
| |
| In the Constant Expressions section, change the *const* bullet to say |
| |
| * a variable declared with the const qualifier and an initializer, |
| where the initializer is a constant expression |
| |
| and add the bullet |
| |
| * valid use of the length() method on a sized object, whether or not the |
| object itself is constant |
| |
| Add to "Inputs" section |
| |
| "It is an error to use any auxiliary or interpolation qualifiers on a vertex |
| shader input." |
| |
| "Applying the *patch* qualifier to inputs can only be done in tessellation |
| evaluation shaders." |
| |
| "The auxiliary storage qualifiers *centroid* and *sample* can also be |
| applied, as well as the interpolation qualifiers *flat*, *noperspective*, |
| and *smooth*." |
| |
| Change all occurances of "patch in qualifier" to "patch qualifier" or |
| "patch in qualifiers". Similarly for any occurances of "patch out", |
| "centroid in", "sample in", "centroid out", and "sample out", through-out |
| the specification. |
| |
| Also change |
| |
| "Fragment shader inputs get per-fragment values, typically interpolated |
| from a previous stage's outputs. They are declared in fragment shaders |
| with the in storage qualifier, the centroid in storage qualifier, ..." |
| |
| to |
| |
| "Fragment shader inputs get per-fragment values, typically interpolated |
| from a previous stage's outputs. They are declared in fragment shaders |
| with the in storage qualifier. The auxiliary storage qualifiers centroid |
| and sample can also be applied, as well as the interpolation qualifiers |
| flat, noperspective, and smooth..." |
| |
| Change |
| |
| "They are declared in fragment shaders with the in storage qualifier, the |
| centroid in storage qualifier, or the deprecated varying and centroid |
| varying storage qualifiers." |
| |
| to |
| |
| "They are declared in fragment shaders with the in storage qualifier or the |
| deprecated varying storage qualifier." |
| |
| Add to the "Outputs" section |
| |
| "A variable also cannot be declared with both the *in* and the *out* |
| qualifiers." |
| |
| Change |
| |
| "Vertex, tessellation evaluation, and geometry output variables output |
| per-vertex data and are declared using the out, centroid out, or sample out |
| storage qualifiers" |
| |
| to |
| |
| "Vertex, tessellation evaluation, and geometry output variables output |
| per-vertex data and are declared using the out storage qualifier" |
| |
| Change |
| |
| "It is an error to use patch out in a vertex, tessellation evaluation, |
| or geometry shader." |
| |
| to |
| |
| "Applying *patch* to an output can only be done in a tessellation control |
| shader." |
| |
| Change |
| |
| "Per vertex output variables are arrayed (see arrayed under 4.3.4 Inputs) |
| and declared using out or centroid out storage qualifiers." |
| |
| to |
| |
| "Per-vertex output variables are arrayed and declared using the *out* |
| qualifier without the *patch* qualifier. Per-patch output variables are |
| declared using the *patch* and *out* storage qualifiers." |
| |
| Add |
| |
| "It is an error to use auxiliary storage qualifiers or interpolation |
| qualifiers on an output in a fragment shader." |
| |
| Modify Interface Blocks with new relaxed qualifier rules: |
| |
| "If optional qualifiers are used, they can include interpolation qualifiers, |
| auxiliary storage qualifiers, and storage qualifiers..." |
| |
| Add to Layout Qualifiers: |
| |
| "More than one layout qualifier may appear in a single declaration. If the |
| same layout-qualifier-name occurs in multiple layout qualifiers for the same |
| declaration, the last one overrides the former ones." |
| |
| Add to Uniform Block Layout Qualifiers, if the base language version is 1.4 |
| or above: |
| |
| layout-qualifier-id |
| binding = integer-constant |
| |
| "The binding identifier specifies the uniform buffer binding point |
| corresponding to the uniform block, which will be used to obtain the |
| values of the member variables of the block. It is an error to specify the |
| binding identifier for the global scope or for block member declarations. |
| Any uniform block declared without a binding identifier is initially |
| assigned to block binding point zero. After a program is linked, the |
| binding points used for uniform blocks declared with or without a binding |
| identifier can be updated by the OpenGL API. |
| |
| "If the binding identifier is used with a uniform block instanced as an |
| array then the first element of the array takes the specified block binding |
| and each subsequent element takes the next consecutive uniform block |
| binding point. |
| |
| "If the binding point for any uniform block instance is less than zero, or |
| greater than or equal to the implementation-dependent maximum number of |
| uniform buffer bindings, a compilation error will occur. When the binding |
| identifier is used with a uniform block instanced as an array of size N, |
| all elements of the array from binding through binding + N - 1 must be |
| within this range." |
| |
| Add for sampler and image layout qualifiers: |
| |
| Note: The "image" variable aspect of this interacts with |
| ARB_shader_image_load_store and only applies if the extension |
| ARB_shader_image_load_store is enabled. |
| |
| "Uniform layout qualifiers can be used to bind opaque uniform variables to |
| specific buffers or units. Texture image units can be bound to samplers |
| and image units can be bound to images. |
| |
| layout-qualifier-id |
| binding = integer-constant |
| |
| "The identifier binding specifies which unit will be bound. Any uniform |
| sampler or image variable declared without a binding qualifier is |
| initially bound to unit zero. After a program is linked, the unit |
| referenced by a sampler or image uniform variable declared with or |
| without a binding identifier can be updated by the OpenGL API. |
| |
| "If the binding identifier is used with an array, the first element of the |
| array takes the specified unit and each subsequent element takes the next |
| consecutive unit. |
| |
| If the binding is less than zero, or greater than or equal to the |
| implementation-dependent maximum supported number of units, a compilation |
| error will occur. When the binding identifier is used with an array of size |
| N, all elements of the array from binding through binding + N - 1 must be |
| within this range." |
| |
| Change the "Interpolation" section to be the "Interplotation Qualifiers" |
| section and change the first paragraph to now be the following. |
| |
| "Inputs and outputs that could be interpolated can be further qualified by |
| at most one of the following interpolation qualifiers: |
| |
| Qualifier Meaning |
| --------- ------- |
| smooth perspective correct interpolation |
| flat no interpolation |
| noperspective linear interpolation |
| |
| "The presence of and type of interpolation is controlled by the above |
| interpolation qualifiers as well as the auxiliary storage qualifiers |
| *centroid* and *sample*. The auxiliary storage qualifier *patch* is not |
| used for interpolation; it is an error to use interpolation qualifiers with |
| *patch*. |
| |
| Add the following parameter qualifier |
| |
| Qualifier Meaning |
| --------- ------- |
| const for function parameters that cannot be written to |
| |
| and note that precision qualifiers are also allowed on parameters. |
| |
| Delete the following sentence in the "Invariant Qualifier" section: |
| |
| "The invariant qualifier must appear before any interpolation qualifiers |
| or storage qualifiers when combined with a declaration." |
| |
| Replace the "Order of Qualification" section with the following |
| |
| 4.11 "Order and Repetition of Qualification" |
| |
| "When multiple qualifiers are present in a variable or parameter |
| declaration, they may appear in any order, but they must all appear before |
| the type. The layout qualifier is the only qualifier that can appear more |
| than once. Further, a declaration can have at most one storage qualifier, |
| at most one auxiliary storage qualifier, and at most one interpolation |
| qualifier. If inout is used, neither in nor out may be used. Multiple |
| memory qualifiers can be used. Any violation of these rules will cause a |
| compile-time error." |
| |
| Additions to Chapter 5 of the OpenGL Shading Language |
| |
| Change the section title "Vector Components" to be "Vector and Scalar |
| Components and Length". In that section do the following. |
| |
| Change first sentence to "The names of the components of a vector or |
| scalar are denoted by a single letter." |
| |
| Add the following last sentence to its paragraph: |
| |
| "The component names x, r, and s are, for example, synonyms for the same |
| (first) component in a vector. They are also the names of the only |
| component in a scalar." |
| |
| Add to the example |
| |
| float height; |
| height.x // is legal |
| height.y // is illegal |
| |
| and to the third example |
| |
| float f = 1.2; |
| vec4 dup = f.xxxx; // dup = (1.2, 1.2, 1.2, 1.2) |
| |
| "This notation is more concise than the constructor syntax. To form an |
| r-value, it can be applied to any expression that results in a vector or |
| scalar r-value. Any resulting vector of any operation must be a valid |
| vector in the language; hence the following is illegal:" |
| |
| vec4 f; |
| vec4 g = pos.xyzwxy.xyzw; // illegal; pos.xyzwxy is non-existent "vec6" |
| |
| Add to the end of this section: |
| |
| "The *length* method may be applied to vectors (but not scalars). The |
| result is the number of components in the vector. For example, |
| |
| vec3 v; |
| const int L = v.length(); |
| |
| "sets the constant L to 3. The type returned by .length() on a vector is |
| *int*." |
| |
| Add to the Matrix Components section: |
| |
| "The length method may be applied to matrices. The result is the number |
| of columns of the matrix. For example, |
| |
| mat3x4 v; |
| const int L = v.length(); |
| |
| "sets the constant L to 3. The type returned by .length() on a matrix |
| is *int*." |
| |
| Additions to Chapter 6 of the OpenGL Shading Language |
| |
| Add to the "Function Definitions" section the following functionality |
| regarding function return values: |
| |
| "If the type of returnValue does not match returnType, there must be an |
| implicit conversion in section 4.1.10 "Implicit Conversions" that |
| converts the type of returnValue to returnType, or a compile error will |
| result." |
| |
| and the clarifations: |
| |
| "A void function can only use return without a return argument, even if |
| the return argument has void type. Return statements only accept values: |
| |
| void func1() { } |
| void func2() { return func1(); } // illegal return statement |
| |
| "Only a precision qualifier is allowed on the return type of a function. |
| Formal parameters can have parameter, precision, and memory qualifiers, |
| but no other qualifiers." |
| |
| Under the section "Function Calling Conventions" change to the *inout* |
| bullet: |
| |
| * "The keyword *inout* is used as a qualifier to denote the parameter |
| is to be both copied in and copied out. It means the same thing as |
| specifying both in and out." |
| |
| and the following grammar changes: Delete the const-qualifier parts of |
| the existing grammar and instead use |
| |
| parameter-qualifiers : |
| empty |
| list of parameter-qualifier |
| |
| parameter-qualifier : |
| empty |
| const |
| in |
| out |
| inout |
| memory qualifier |
| precision qualifier |
| |
| Additions to Chapter 7 of the OpenGL Shading Language |
| |
| Add to the built-in constants |
| |
| const int gl_MinProgramTexelOffset = -7; |
| const int gl_MaxProgramTexelOffset = 8; |
| |
| Additions to Chapter 9 of the OpenGL Shading Language |
| |
| TBD. |
| |
| Conformance Tests |
| |
| Verify that the following two vectors are identical: |
| |
| vec4 a = vec4(1.0); |
| vec4 b = (1.0).xxxx; |
| |
| Verify that the following generates a compilation error: |
| |
| vec2 a = 1.xx; |
| |
| Verify that the following two vectors are identical: |
| |
| vec2 a = (1).xx; |
| vec2 b = vec2(1.0); |
| |
| Verify that the following two arrays are identical: |
| |
| vec4 a[] = vec4 [] (vec4(1.2), vec4(0.0), vec4(0.0), vec4(0.0), |
| vec4(0.0), vec4(0.0), vec4(0.0), vec4(2.4), |
| vec4(0.0), vec4(0.0), vec4(0.0), vec4(0.0), |
| vec4(0.0), vec4(0.0), vec4(0.0), vec4(3.6)); |
| vec4 b[] = { vec4(1.2), vec4(0.0), vec4(0.0), vec4(0.0), |
| vec4(0.0), vec4(0.0), vec4(0.0), vec4(2.4), |
| vec4(0.0), vec4(0.0), vec4(0.0), vec4(0.0), |
| vec4(0.0), vec4(0.0), vec4(0.0), vec4(3.6) }; |
| |
| Verify that the following two arrays are identical: |
| |
| vec4 a[12] = vec4 [] (vec4(1.2), vec4(0.0), vec4(0.0), vec4(0.0), |
| vec4(0.0), vec4(0.0), vec4(0.0), vec4(2.4), |
| vec4(0.0), vec4(0.0), vec4(0.0), vec4(0.0)); |
| vec4 b[12] = { vec4(1.2), vec4(0.0), vec4(0.0), vec4(0.0), |
| vec4(0.0), vec4(0.0), vec4(0.0), vec4(2.4) }; |
| |
| Verify that the following three matrices are identical: |
| |
| mat2x2 a = mat2( vec2( 1.0, 0.0 ), vec2( 0.0, 1.0 ) ); |
| mat2x2 b = { vec2( 1.0, 0.0 ), vec2( 0.0, 1.0 ) }; |
| mat2x2 c = { { 1.0, 0.0 }, { 0.0, 1.0 } }; |
| |
| Verify that the following generates a compliation error: |
| |
| float a[2] = { 1.0, 2.0, 3.0 }; |
| |
| Verify that the following generates a compliation error: |
| |
| mat2x2 d = { 1.0, 0.0, 0.0, 1.0 }; |
| |
| |
| Verify that the output of the following fragment shader is (0, 1, 0, 1): |
| |
| #version 410 |
| #extension GL_ARB_shading_language_420pack: require |
| out vec4 color; |
| void main() |
| { |
| color = (vec2(0).length() == 2) ? vec4(0, 1, 0, 1) : vec4(1, 0, 0, 1); |
| } |
| |
| Repeat the above test with vec2(0).length() replaced by ivec2(0).length(). |
| |
| Repeat the above test with vec2(0).length() replaced by uvec2(0).length(). |
| |
| Repeat the above test with vec2(0).length() replaced by bvec2(0).length(). |
| |
| Repeat the above test with vec2(0).length() replaced by dvec2(0).length(). |
| |
| |
| Verify that the output of the following fragment shader is (0, 1, 0, 1): |
| |
| #version 410 |
| #extension GL_ARB_shading_language_420pack: require |
| out vec4 color; |
| void main() |
| { |
| color = (vec3(0).length() == 3) ? vec4(0, 1, 0, 1) : vec4(1, 0, 0, 1); |
| } |
| |
| Repeat the above test with vec3(0).length() replaced by ivec3(0).length(). |
| |
| Repeat the above test with vec3(0).length() replaced by uvec3(0).length(). |
| |
| Repeat the above test with vec3(0).length() replaced by bvec3(0).length(). |
| |
| Repeat the above test with vec3(0).length() replaced by dvec3(0).length(). |
| |
| |
| Verify that the output of the following fragment shader is (0, 1, 0, 1): |
| |
| #version 410 |
| #extension GL_ARB_shading_language_420pack: require |
| out vec4 color; |
| void main() |
| { |
| color = (vec4(0).length() == 4) ? vec4(0, 1, 0, 1) : vec4(1, 0, 0, 1); |
| } |
| |
| Repeat the above test with vec4(0).length() replaced by ivec4(0).length(). |
| |
| Repeat the above test with vec4(0).length() replaced by uvec4(0).length(). |
| |
| Repeat the above test with vec4(0).length() replaced by bvec4(0).length(). |
| |
| Repeat the above test with vec4(0).length() replaced by dvec4(0).length(). |
| |
| |
| Verify that the output of the following fragment shader is (0, 1, 0, 1): |
| |
| #version 410 |
| #extension GL_ARB_shading_language_420pack: require |
| out vec4 color; |
| void main() |
| { |
| color = (mat2(0).length() == 2) ? vec4(0, 1, 0, 1) : vec4(1, 0, 0, 1); |
| } |
| |
| Repeat the above test with mat2(0).length() replaced by mat2x2(0).length(). |
| |
| Repeat the above test with mat2(0).length() replaced by dmat2x2(0).length(). |
| |
| Repeat the above test with mat2(0).length() replaced by mat2x3(0).length(). |
| |
| Repeat the above test with mat2(0).length() replaced by dmat2x3(0).length(). |
| |
| Repeat the above test with mat2(0).length() replaced by mat2x4(0).length(). |
| |
| Repeat the above test with mat2(0).length() replaced by dmat2x4(0).length(). |
| |
| |
| Verify that the output of the following fragment shader is (0, 1, 0, 1): |
| |
| #version 410 |
| #extension GL_ARB_shading_language_420pack: require |
| out vec4 color; |
| void main() |
| { |
| color = (mat3(0).length() == 3) ? vec4(0, 1, 0, 1) : vec4(1, 0, 0, 1); |
| } |
| |
| Repeat the above test with mat3(0).length() replaced by mat3x2(0).length(). |
| |
| Repeat the above test with mat3(0).length() replaced by dmat3x2(0).length(). |
| |
| Repeat the above test with mat3(0).length() replaced by mat3x3(0).length(). |
| |
| Repeat the above test with mat3(0).length() replaced by dmat3x3(0).length(). |
| |
| Repeat the above test with mat3(0).length() replaced by mat3x4(0).length(). |
| |
| Repeat the above test with mat3(0).length() replaced by dmat3x4(0).length(). |
| |
| |
| Verify that the output of the following fragment shader is (0, 1, 0, 1): |
| |
| #version 410 |
| #extension GL_ARB_shading_language_420pack: require |
| out vec4 color; |
| void main() |
| { |
| color = (mat4(0).length() == 4) ? vec4(0, 1, 0, 1) : vec4(1, 0, 0, 1); |
| } |
| |
| Repeat the above test with mat4(0).length() replaced by mat4x2(0).length(). |
| |
| Repeat the above test with mat4(0).length() replaced by dmat4x2(0).length(). |
| |
| Repeat the above test with mat4(0).length() replaced by mat4x3(0).length(). |
| |
| Repeat the above test with mat4(0).length() replaced by dmat4x3(0).length(). |
| |
| Repeat the above test with mat4(0).length() replaced by mat4x4(0).length(). |
| |
| Repeat the above test with mat4(0).length() replaced by dmat4x4(0).length(). |
| |
| |
| Verify that the output of the following fragment shader is (0, 1, 0, 1): |
| |
| #version 410 |
| #extension GL_ARB_shading_language_420pack: require |
| out vec4 color; |
| void main() |
| { |
| color = (mat2(0)[0].length() == 2) |
| ? vec4(0, 1, 0, 1) : vec4(1, 0, 0, 1); |
| } |
| |
| Repeat the above test with mat2(0)[0].length() replaced by |
| mat2x2(0)[0].length(). |
| |
| Repeat the above test with mat2(0)[0].length() replaced by |
| dmat2x2(0)[0].length(). |
| |
| Repeat the above test with mat2(0)[0].length() replaced by |
| mat3x2(0)[0].length(). |
| |
| Repeat the above test with mat2(0)[0].length() replaced by |
| dmat3x2(0)[0].length(). |
| |
| Repeat the above test with mat2(0)[0].length() replaced by |
| mat4x2(0)[0].length(). |
| |
| Repeat the above test with mat2(0)[0].length() replaced by |
| dmat4x2(0)[0].length(). |
| |
| |
| Verify that the output of the following fragment shader is (0, 1, 0, 1): |
| |
| #version 410 |
| #extension GL_ARB_shading_language_420pack: require |
| out vec4 color; |
| void main() |
| { |
| color = (mat3(0)[0].length() == 3) |
| ? vec4(0, 1, 0, 1) : vec4(1, 0, 0, 1); |
| } |
| |
| Repeat the above test with mat3(0)[0].length() replaced by |
| mat2x3(0)[0].length(). |
| |
| Repeat the above test with mat3(0)[0].length() replaced by |
| dmat2x3(0)[0].length(). |
| |
| Repeat the above test with mat3(0)[0].length() replaced by |
| mat3x3(0)[0].length(). |
| |
| Repeat the above test with mat3(0)[0].length() replaced by |
| dmat3x3(0)[0].length(). |
| |
| Repeat the above test with mat3(0)[0].length() replaced by |
| mat4x3(0)[0].length(). |
| |
| Repeat the above test with mat3(0)[0].length() replaced by |
| dmat4x3(0)[0].length(). |
| |
| |
| Verify that the output of the following fragment shader is (0, 1, 0, 1): |
| |
| #version 410 |
| #extension GL_ARB_shading_language_420pack: require |
| out vec4 color; |
| void main() |
| { |
| color = (mat4(0)[0].length() == 4) |
| ? vec4(0, 1, 0, 1) : vec4(1, 0, 0, 1); |
| } |
| |
| Repeat the above test with mat4(0)[0].length() replaced by |
| mat2x4(0)[0].length(). |
| |
| Repeat the above test with mat4(0)[0].length() replaced by |
| dmat2x4(0)[0].length(). |
| |
| Repeat the above test with mat4(0)[0].length() replaced by |
| mat3x4(0)[0].length(). |
| |
| Repeat the above test with mat4(0)[0].length() replaced by |
| dmat3x4(0)[0].length(). |
| |
| Repeat the above test with mat4(0)[0].length() replaced by |
| mat4x4(0)[0].length(). |
| |
| Repeat the above test with mat4(0)[0].length() replaced by |
| dmat4x4(0)[0].length(). |
| |
| |
| Verify that the following shader generates a compilation error: |
| |
| #version 410 |
| #extension GL_ARB_shading_language_420pack: require |
| out vec4 color; |
| void main() |
| { |
| float v; |
| int l = v.length(); |
| color = vec4(1, 0, 0, 1); |
| } |
| |
| Repeat the above test with "float v" replaced by "int v". |
| |
| Repeat the above test with "float v" replaced by "uint v". |
| |
| Repeat the above test with "float v" replaced by "bool v". |
| |
| Repeat the above test with "float v" replaced by "double v". |
| |
| |
| Verify that the following shader compiles without error: |
| |
| #version 410 |
| #extension GL_ARB_shading_language_420pack: require |
| void main() |
| { |
| float b[vec2(0).length()]; |
| } |
| |
| Repeat the above test with vec2(0).length() replaced by ivec2(0).length(). |
| |
| Repeat the above test with vec2(0).length() replaced by uvec2(0).length(). |
| |
| Repeat the above test with vec2(0).length() replaced by bvec2(0).length(). |
| |
| Repeat the above test with vec2(0).length() replaced by dvec2(0).length(). |
| |
| Repeat the above test with vec2(0).length() replaced by ivec3(0).length(). |
| |
| Repeat the above test with vec2(0).length() replaced by uvec3(0).length(). |
| |
| Repeat the above test with vec2(0).length() replaced by bvec3(0).length(). |
| |
| Repeat the above test with vec2(0).length() replaced by dvec3(0).length(). |
| |
| Repeat the above test with vec2(0).length() replaced by ivec4(0).length(). |
| |
| Repeat the above test with vec2(0).length() replaced by uvec4(0).length(). |
| |
| Repeat the above test with vec2(0).length() replaced by bvec4(0).length(). |
| |
| Repeat the above test with vec2(0).length() replaced by dvec4(0).length(). |
| |
| Repeat the above test with vec2(0).length() replaced by mat2(0).length(). |
| |
| Repeat the above test with vec2(0).length() replaced by mat2x2(0).length(). |
| |
| Repeat the above test with vec2(0).length() replaced by mat2x3(0).length(). |
| |
| Repeat the above test with vec2(0).length() replaced by mat2x4(0).length(). |
| |
| Repeat the above test with vec2(0).length() replaced by mat3(0).length(). |
| |
| Repeat the above test with vec2(0).length() replaced by mat3x2(0).length(). |
| |
| Repeat the above test with vec2(0).length() replaced by mat3x3(0).length(). |
| |
| Repeat the above test with vec2(0).length() replaced by mat3x4(0).length(). |
| |
| Repeat the above test with vec2(0).length() replaced by mat4(0).length(). |
| |
| Repeat the above test with vec2(0).length() replaced by mat4x2(0).length(). |
| |
| Repeat the above test with vec2(0).length() replaced by mat4x3(0).length(). |
| |
| Repeat the above test with vec2(0).length() replaced by mat4x4(0).length(). |
| |
| Repeat the above test with vec2(0).length() replaced by dmat2(0).length(). |
| |
| Repeat the above test with vec2(0).length() replaced by dmat2x2(0).length(). |
| |
| Repeat the above test with vec2(0).length() replaced by dmat2x3(0).length(). |
| |
| Repeat the above test with vec2(0).length() replaced by dmat2x4(0).length(). |
| |
| Repeat the above test with vec2(0).length() replaced by dmat3(0).length(). |
| |
| Repeat the above test with vec2(0).length() replaced by dmat3x2(0).length(). |
| |
| Repeat the above test with vec2(0).length() replaced by dmat3x3(0).length(). |
| |
| Repeat the above test with vec2(0).length() replaced by dmat3x4(0).length(). |
| |
| Repeat the above test with vec2(0).length() replaced by dmat4(0).length(). |
| |
| Repeat the above test with vec2(0).length() replaced by dmat4x2(0).length(). |
| |
| Repeat the above test with vec2(0).length() replaced by dmat4x3(0).length(). |
| |
| Repeat the above test with vec2(0).length() replaced by dmat4x4(0).length(). |
| |
| More TBD. |
| |
| Issues |
| |
| 1) How is the ambiguity of swizzling an integer literal resolved? |
| |
| RESOLVED: Greedy lexing. The sequence "5.x" will be interpreted |
| as the floating-point literal 5.0 followed by the identifier "x". |
| |
| 2) Should the array subscript operator be applicable to scalars as it is |
| to vectors? |
| |
| RESOLVED: NO. In conduction with the rest of the features of this |
| extension, this would allow writing generic code such as: |
| |
| #define SUM_COMPONENTS(value, result) \ |
| do { |
| for (int i = 0; i < (value).length(); i++) |
| result += (value)[i]; |
| } while (0) |
| |
| However, using macros in this fashion is a poor approximation |
| of generic functions. Until a better mechanism is added to |
| GLSL, there is little utility in array accesses to scalars or |
| single component vectors. |
| |
| 3) Should vectors and matrices also be able to use initializer lists? |
| |
| RESOLVED: YES. Many places in the language treat vectors as 2, 3, or |
| 4 element arrays of a scalar type. Matrices are often treated as |
| arrays of vector types. Continuing that treatment here is logical. |
| |
| 4) What happens when an explicitly sized array is initialized with too few |
| elements? Is it allowed? |
| |
| RESOLVED: DISALLOWED. In C/C++ this is allowed. The uninitialized |
| elements are implicitly initialized to the appropriate reprensentation |
| of zero. However, the belief is that this enables a variety of |
| programming errors that are difficult to debug on a GPU. |
| |
| 5) Can scalars be initialized using an initializer list? |
| |
| RESOLVED: NO. In C/C++ this is allowed. The ISO C99 specification |
| specifically say, "The initializer for a scalar shall be a single |
| expression, optionally enclosed in braces." However, this may |
| pose problems if / when a vec1 type is added. |
| |
| 6) Are initializer lists for vectors flexible in the same way that vector |
| constructors are? Specifically, is the initialzier list for 'c', |
| below, legal? |
| |
| vec2 a = vec2(2, 3); |
| vec4 b = vec4(1, a, 4); // b = { 1, 2, 3, 4 } |
| vec4 c = { 1, a, 4 }; // Legal? |
| |
| RESOLVED: NO. In C++ there is a distinction between a constructor |
| and an initializer list. If you had vec2 and vec4 classes in C++, a |
| constructor 'vec4(float, vec2, float)' might exist, but the |
| initializer list for 'c' would not be legal. |
| |
| 7) Does adding *const* for read-only variables effect array sizing? |
| |
| RESOLVED. No. Array sizing changes are not part of this proposal. Array |
| sizing rules stay the same, where sizes must be compile-time constants, |
| whether or not the keyword 'const' was involved, just like it always has |
| been. The following was and still is disallowed: |
| |
| "void foo(const s) { int a[s]; }", |
| |
| as will be |
| |
| "void foo() { const s = exp; int a[s]; }". |
| |
| 8) Should we allow non-compile-time constant initializers for const at |
| global scope as well? |
| |
| RESOLVED. No. Would make linking more difficult. |
| |
| 9) Do we want to add the new C++ constexpr for declaring constant |
| functions? |
| |
| RESOLVED. No, not yet, could be a potential performance benefit in the |
| future, but treat as a separate extension. Note that most built-in |
| functions are already understood to be "constexpr". This has been |
| submitted into bugzilla. |
| |
| 10) What combinations of interpolation qualifiers are allowed? Before, |
| you could take one of smooth, flat, and noperspective and combine that with |
| one of centroid, sample, or patch. What do combinations do we actually |
| want? Do we want multiple intances of a single qualifier allowed? |
| (E.g. two layout qualifiers, or "in out"?) |
| |
| RESOLVED. Allow multiple "layout". Not anything else. |
| |
| 11) Should we allow multiple block declarations to use the same |
| binding point? For example: |
| layout(binding = 3) uniform Block1 { ... }; |
| layout(binding = 3) uniform Block2 { ... }; |
| |
| RESOLVED: There is no reason to disallow this usage; in particular, |
| existing UBO shaders effectively declare all blocks with |
| "layout(block = 0)". |
| |
| 12) Should the qualifier be called "location", "block" or "binding"? |
| |
| RESOLVED: The qualifier is called "binding" because it makes it more |
| clear what parameter of UniformBlockBinding that this qualifier |
| affects. "block" could be confused with either the |
| <uniformBlockIndex> or <uniformBlockBinding> and "location" might be |
| confused with the current uses of the qualifier "location" for |
| attribute locations or it could be confused with uses of "location" |
| for uniform variable location, which blocks don't have. |
| |
| 13) Should sampler initialization use a layout(binding) qualifier |
| instead of specifying a uniform initializer? |
| |
| RESOLVED: Revision #4 of the sampler initialization spec uses a |
| layout(binding) qualifier for sampler uniforms. This is more |
| forward looking and makes the spec more consistent with |
| ARB_uniform_block_binding_initialization and |
| ARB_shader_atomic_counters. |
| |
| Revision History |
| |
| Revision 4, 11-Sep-2014 (pbrown) |
| - Fix minor typo. |
| Revision 3, 13-May-2014 (John Kessenich) |
| - Resolve bug 10593. |
| Revision 2, 25-Jul-2011 (John Kessenich) |
| - Mark as complete and approved. |
| - Tidy up some formating and non-raw-text quote marks. |
| - Pull in the initializers for images, to completely subsume |
| GL_ARB_uniform_sampler_initialization. |
| - Point out image and patch dependencies. |
| Revision 1, 5-Jul-2011 (John Kessenich) |
| - Initial version. Formed by combing the content of the |
| 4.20 draft specification and the content of draft |
| extensions: |
| * ARB_shading_language_vec1 |
| * ARB_shading_language_relaxed_qualifiers |
| * ARB_shading_language_length |
| * ARB_shading_language_initializer_list |
| * GL_ARB_uniform_block_binding_initialization |
| * GL_ARB_uniform_sampler_initialization (just sampler binding) |
| Issues were carried across and renumbered. |
| Conformance tests were carried over. |
| |