| Name |
| |
| OES_shader_io_blocks |
| |
| Name String |
| |
| GL_OES_shader_io_blocks |
| |
| Contact |
| |
| Jon Leech (oddhack 'at' sonic.net) |
| Daniel Koch, NVIDIA (dkoch 'at' nvidia.com) |
| |
| Contributors |
| |
| Daniel Koch, NVIDIA (dkoch 'at' nvidia.com) |
| Pat Brown, NVIDIA (pbrown 'at' nvidia.com) |
| Slawomir Grajewski, Intel |
| Graham Connor, Imagination |
| Ben Bowman, Imagination |
| Jonathan Putsman, Imagination |
| |
| Notice |
| |
| Copyright (c) 2008-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 ES 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 |
| |
| Portions Copyright (c) 2013-2014 NVIDIA Corporation. |
| |
| Status |
| |
| Approved by the OpenGL ES Working Group |
| Ratified by the Khronos Board of Promoters on November 7, 2014 |
| |
| Version |
| |
| Last Modified Date: October 8, 2014 |
| Revision: 2 |
| |
| Number |
| |
| OpenGL ES Extension #213 |
| |
| Dependencies |
| |
| OpenGL ES 3.1 and OpenGL ES Shading Language 3.10 are required. |
| |
| This specification is written against the OpenGL ES 3.1 (March 17, |
| 2014) and OpenGL ES 3.10 Shading Language (March 17, 2014) |
| Specifications. |
| |
| OES_shader_multisample_interpolation trivially affects the definition of |
| this extension. |
| |
| OES_geometry_shader and EXT_geometry_shader interact with this extension. |
| |
| OES_tessellation_shader and EXT_tessellation_shader interact with this |
| extension. |
| |
| Overview |
| |
| This extension extends the functionality of interface blocks to |
| support input and output interfaces in the OpenGL ES Shading Language. |
| |
| Input and output interface blocks are used for forming the |
| interfaces between vertex, tessellation control, tessellation |
| evaluation, geometry and fragment shaders. This accommodates passing |
| arrays between stages, which otherwise would require multi-dimensional |
| array support for tessellation control outputs and for tessellation |
| control, tessellation evaluation, and geometry shader inputs. |
| |
| This extension provides support for application defined |
| interface blocks which are used for passing application-specific |
| information between shader stages. |
| |
| This extension moves the built-in "per-vertex" in/out variables |
| to a new built-in gl_PerVertex block. This is necessary for |
| tessellation and geometry shaders which require a separate |
| instance for each vertex, but it can also be useful for vertex |
| shaders. |
| |
| Finally, this extension allows the redeclaration of the |
| gl_PerVertex block in order to reduce the set of variables that must |
| be passed between shaders. |
| |
| New Procedures and Functions |
| |
| None |
| |
| New Tokens |
| |
| None |
| |
| Additions to Chapter 7 of the OpenGL ES 3.1 Specification (Programs and Shaders) |
| |
| Modify section 7.4.1 "Shader Interface Matching": |
| |
| When multiple shader stages are active, the outputs of one stage form an |
| interface with the inputs of the next stage. At each such interface, |
| shader inputs are matched up against outputs from the previous stage: |
| |
| * An output block is considered to match an input block in the |
| subsequent shader if the two blocks have the same block name, and |
| the members of the block match exactly in name, type, qualification, |
| and declaration order. |
| |
| * An output variable is considered to match an input variable in the |
| subsequent shader if: |
| |
| - the two variables match in name, type, and qualification; or |
| |
| - the two variables are declared with the same location layout |
| qualifier and match in type and qualification. |
| |
| Variables or block members declared as structures are considered to |
| match in type if and only if structure members match in name, type, |
| qualification, and declaration order. Variables or block members |
| declared as arrays are considered to match in type only if both |
| declarations specify the same element type and array size. The rules for |
| determining if variables or block members match in qualification are |
| found in the OpenGL ES Shading Language Specification. |
| |
| For program objects containing multiple shaders, LinkProgram will check |
| for mismatches on interfaces between shader stages in the program being |
| linked and generate a link error if a mismatch is detected. A link error |
| will be generated if any statically referenced input variable or block |
| does not have a matching output. |
| |
| With separable program objects ... |
| |
| At an interface between program objects, the set of inputs and outputs |
| are considered to match exactly if and only if: |
| |
| * Every declared input block or variable has a matching output, |
| as described above. |
| |
| * There are no output blocks or user-defined output variables declared |
| without a matching input block or variable declaration. |
| |
| * All matched input and output variables (in a block or otherwise) have |
| identical precision qualification. |
| |
| When the set of inputs and outputs ... |
| |
| When using any built-in input or output in the gl_PerVertex block in |
| separable program objects, shader code may redeclare that block prior |
| to use. If the shader does not redeclare the block, the intrinsically |
| declared definition of that block will be used. |
| |
| A separable program will fail to link if: |
| |
| * the shader uses a built-in block member not found in the |
| (re)declaration of that block. |
| |
| There is one exception to this rule described below. |
| |
| As described above, an exact interface match requires matching built-in |
| input and output blocks. At an interface between two non-fragment shader |
| stages, the gl_PerVertex input and output blocks are considered to match |
| if and only if the block members match exactly in name, type, |
| qualification, and declaration order. At an interface involving the |
| fragment shader stage, the presence or absence of any built-in output |
| does not affect interface matching. At an interface involving the |
| vertex shader stage, built-in outputs not found in a block in the |
| vertex shader are considered to match the corresponding inputs found |
| in the gl_PerVertex input block of the subsequent non-fragment stage, |
| provided they match in precision qualification. |
| |
| Built-in inputs or outputs not found in blocks do not affect interface |
| matching. Any such built-in inputs are well-defined unless they are |
| derived from built-in outputs not written by the previous shader stage. |
| |
| New State |
| |
| None |
| |
| New Implementation Dependent State |
| |
| None |
| |
| Additions to the OpenGL ES Shading Language 3.10 Specification |
| |
| Including the following line in a shader can be used to control the |
| language features described in this extension: |
| |
| #extension GL_OES_shader_io_blocks : <behavior> |
| |
| where <behavior> is as specified in section 3.4. |
| |
| A new preprocessor #define is added to the OpenGL ES Shading Language: |
| |
| #define GL_OES_shader_io_blocks 1 |
| |
| If the OES_geometry_shader extension is enabled, the |
| OES_shader_io_blocks extension is also implicitly enabled. |
| |
| If the OES_tessellation_shader extension is enabled, the |
| OES_shader_io_blocks extension is also implicitly enabled. |
| |
| |
| Modify section 3.8 "Identifiers:" |
| |
| Replace the second paragraph with the following: |
| |
| Identifiers starting with "gl_" are reserved for use by OpenGL ES, and |
| may not be declared in a shader as either a variable or a function; this |
| results in a compile-time error. However, as noted in the specification, |
| there are some cases where previously declared variables can be redeclared, |
| and predeclared "gl_" names are allowed to be redeclared in a shader only |
| for these specific purposes. More generally, it is a compile-time error to |
| redeclare a variable, including those starting "gl_". |
| |
| |
| Modify section 4.3.4 "Input Variables": |
| |
| Add following the first paragraph on p. 39: |
| |
| ... superfluous declarations of input variables. |
| |
| Only the input variables that are statically read need to be written by |
| the previous stage; it is allowed to have superfluous declarations of |
| input variables. This is shown in the following table. |
| |
| [?? clarify this is for internal interfaces only] |
| ----------------------------------------------------------------------------------- |
| | | Consuming Shader (input variables) | |
| | Treatment of Mismatched +---------------------------------------------------+ |
| | Input Variables | No | Declared but | Declared and | |
| | | Declaration | no Static Use | Static Use | |
| +-----------------------------+-------------+---------------+---------------------| |
| | | No Declaration | Allowed | Allowed | Link-Time Error | |
| | Generating |----------------+-------------+---------------+---------------------| |
| | Shader | Declared but | Allowed | Allowed | Allowed (values | |
| | (output | no Static Use | | | are undefined) | |
| | variables) |----------------+-------------+---------------+---------------------| |
| | | Declared and | | | Allowed (values are | |
| | | Static Use | Allowed | Allowed | potentially undef.) | |
| | | | | | | |
| ----------------------------------------------------------------------------------- |
| |
| Consumption errors are based on static use only. Compilation may |
| generate a warning, but not an error, for any dynamic use the compiler |
| can deduce that might cause consumption of undefined values. |
| |
| See section 7 "Built-in Variables" ... |
| |
| |
| (Modify the first paragraph, starting "The output of the vertex shader", |
| on p. 41): |
| |
| The fragment shader inputs form an interface with the last active shader |
| in the vertex processing pipeline. For this interface, the last active |
| shader stage output variables and fragment shader input variables of the |
| same name must match in type and qualification, with a few exceptions... |
| |
| |
| (Modify the third paragraph on p. 41): |
| |
| Shaders can ensure matches across such interfaces either by using input |
| and output layout qualifiers (sections 4.4.1 "Input Layout Qualifiers" |
| and 4.4.2 "Output Layout Qualifiers") or by using identical input and |
| output declarations of blocks or variables. Complete rules for interface |
| matching are found ... |
| |
| |
| Modify section 4.3.9 "Interface Blocks": |
| |
| Input, output, uniform, and buffer variable declarations can be grouped |
| into named interface blocks to provide coarser granularity backing than |
| is achievable with individual declarations. They can have an optional |
| instance name, used in the shader to reference their members. An output |
| block of one programmable stage is backed by a corresponding input block |
| in the subsequent programmable stage. A uniform block is backed by the |
| application with a buffer object. A block of buffer variables, called a |
| shader storage block, is also backed by the application with a buffer |
| object. It is a compile-time error to have an input block in a vertex |
| shader or an output block in a fragment shader; these uses are reserved |
| for future use. |
| |
| An interface block is started by an "in", "out", "uniform", or "buffer" |
| keyword, followed by a block name, followed by an open curly brace ( { ) |
| as follows: |
| |
| (modify the grammar rules after the third paragraph) |
| |
| interface-block: |
| layout-qualifier_opt interface-storage-qualifier block-name |
| { member-list } instance-name_opt ; |
| |
| interface-storage-qualifier: |
| in |
| out |
| uniform |
| buffer |
| |
| ... |
| |
| Each of the above elements ... |
| |
| ... with four uniforms grouped inside it. |
| |
| Types and declarators are the same as for other input, output, uniform, |
| and buffer variable declarations outside blocks, with these exceptions: |
| |
| * opaque types are not allowed |
| * structure definitions cannot be nested inside a block |
| |
| Any of these would result in a compile-time error. Otherwise, built-in |
| types, previously declared structures, and arrays of these are allowed |
| as the type of a declarator in the same manner they are allowed outside |
| a block. |
| |
| If no optional qualifier is used in a member-declaration, the |
| qualification of the variable is just in, out, uniform, or buffer as |
| determined by interface-storage-qualifier. If optional qualifiers are |
| used, they can include interpolation qualifiers and storage qualifiers, |
| and they must declare an input, output, or uniform variable consistent |
| with the interface qualifier of the block: input, output, uniform, and |
| buffer variables can only be declared in in, out, uniform, and shader |
| storage blocks, respectively. |
| |
| Repeating the "in", "out", "uniform", or "buffer" interface qualifier |
| for a member's storage qualifier is optional. "centroid in" and "sample |
| in" variables are consistent with "in" blocks, and "centroid out" and |
| "sample out" variables are consistent with "out" blocks. |
| |
| A <shader interface> is defined to be one of these: |
| |
| * All the uniform variables of a program. This spans all compilation |
| units linked together within one program. |
| * All the buffer blocks declared in a program. |
| * The boundary between adjacent programmable pipeline stages: This |
| spans all the outputs declared in all compilation units of the |
| first stage and all the inputs declared in all compilation units |
| of the second stage. Note that the fragment shader is considered |
| to have a shared boundary with the previous adjacent stage even |
| though in practice, all values passed from prior stages to the |
| fragment shader first pass through the rasterizer and |
| interpolator. |
| |
| The block name (block-name) is used to match interfaces: an output block |
| of one pipeline stage will be matched to an input block with the same |
| name in the subsequent pipeline stage. For uniform or shader storage |
| blocks, the application uses the block name to identify the block. Block |
| names have no other use within a shader beyond interface matching; it is |
| a compile-time error to use a block name at global scope for anything |
| other than as a block name (e.g., use of a block name for a global |
| variable name or function name is currently reserved). It is a |
| compile-time error to use the same block name for more than one block |
| declaration in the same shader interface (as defined above) within one |
| shader, even if the block contents are identical. |
| |
| Matched block names within a shader interface (as defined above) must |
| match in terms of having the same number of declarations with the same |
| sequence of types, precisions, and the same sequence of member names, as |
| well as having the same member-wise layout qualification (see next |
| section). Matched uniform block names (but not input or output block |
| names) must also either all be lacking an instance name or all having an |
| instance name, putting their members at the same scoping level. When |
| instance names are present on matched block names, it is allowed for the |
| instance names to differ; they need not match for the blocks to match. |
| Furthermore, if a matching block is declared as an array, then the array |
| sizes must also match (or follow array matching rules for the interface |
| between a vertex and a geometry shader). Any mismatch will generate a |
| link-time error. A block name is allowed to have different definitions |
| in different interfaces within the same shader, allowing, for example, |
| an input block and output block to have the same name. |
| |
| If an instance name (instance-name) is not used, the names declared |
| inside the block are scoped at the global level and accessed as if they |
| were declared outside the block. If an instance name is used, then it |
| puts all the members inside a scope within its own name space, accessed |
| with the field selector ( . ) operator (analogously to structures). For |
| example, |
| |
| uniform Transform_1 |
| { |
| mat4 modelview; // API will use "modelview" |
| } |
| uniform Transform_2 |
| { |
| mat4 projection; // API will use "Transform_2.projection" |
| } transform_2; // instance name |
| mat4 projection; // different than transform_2.projection |
| mat4 modelview; // illegal, already defined |
| |
| Outside the shading language (i.e., in the API), members are similarly |
| identified except the block name is always used in place of the instance |
| name (API accesses are to interfaces, not to shaders). If there is no |
| instance name, then the API does not use the block name to access a |
| member, just the member name. |
| |
| Within an interface, all declarations of the same global name must be |
| for the same object and must match in type and in whether they declare a |
| variable or member of a block with no instance name. The API also needs |
| this name to uniquely identify an object in the interface. It is a |
| link-time error if any particular interface contains |
| |
| * two different blocks, each having no instance name, and each |
| having a member of the same name, or |
| * a variable outside a block, and a block with no instance name, |
| where the variable has the same name as a member in the block. |
| |
| out Vertex { |
| vec4 Position; // API transform/feedback will use "Vertex.Position" |
| vec2 Texture; |
| } Coords; // shader will use "Coords.Position" |
| out Vertex2 { |
| vec4 Color; // API will use "Color" |
| float Color2; |
| }; |
| // in same program as Vertex2 above: |
| out Vertex3 { |
| float Intensity; |
| vec4 Color; // ERROR, name collision with Color in Vertex2 |
| }; |
| float Color2; // ERROR, collides with Color2 in Vertex2 |
| |
| For blocks declared as arrays, the array index must also be included |
| when accessing members, as in this example |
| |
| uniform Transform { // API uses "Transform[2]" to refer to instance 2 |
| mat4 ModelViewMatrix; |
| mat4 ModelViewProjectionMatrix; |
| float Deformation; |
| } transforms[4]; |
| ... |
| ... = transforms[2].ModelViewMatrix; // shader access of instance 2 |
| // API uses "Transform.ModelViewMatrix" to query an offset or other query |
| |
| For uniform or shader storage blocks declared as an array, each |
| individual array element corresponds to a separate buffer object, |
| backing one instance of the block. As the array size indicates the |
| number of buffer objects needed, uniform and shader storage block array |
| declarations must specify an array size. All indices used to index a |
| uniform or shader storage block array must be constant integral |
| expressions. |
| |
| When using OpenGL ES API entry points to identify the name of an |
| individual block in an array of blocks, the name string must include an |
| array index (e.g., Transform[2]). When using OpenGL ES API entry points |
| to refer to offsets or other characteristics of a block member, an array |
| index must not be specified (e.g., Transform.ModelViewMatrix). |
| |
| There are implementation dependent limits on the number of uniform |
| blocks and the number of shader storage blocks that can be used per |
| stage. If either limit is exceeded, it will cause a link-time error. |
| |
| |
| Modify section 4.4 "Layout Qualifiers": |
| |
| Layout qualifiers can appear in several forms of declaration. They can |
| appear as part of an interface block definition or block member, as |
| shown in the grammar in the previous section. They can also appear with |
| just an interface qualifier (a storage qualifier that is "in", "out", or |
| "uniform") to establish layouts of other declarations made with that |
| interface qualifier: |
| |
| layout-qualifier interface-qualifier ; |
| |
| ... |
| |
| The layout-qualifier expands to |
| |
| layout-qualifier : |
| layout ( layout-qualifier-id-list ) |
| |
| layout-qualifier-id-list : |
| layout-qualifier-id |
| layout-qualifier-id , layout-qualifier-id-list |
| |
| layout-qualifier-id |
| layout-qualifier-name |
| layout-qualifier-name = layout-qualifier-value |
| |
| The tokens used for layout-qualifier-name are identifiers, not keywords. |
| Generally, they can be listed in any order. Order-dependent meanings |
| exist only if explicitly called out below. Similarly, these identifiers |
| are not case sensitive, unless explicitly noted otherwise. |
| |
| More than one layout qualifier may appear in a single declaration. |
| Additionally, the same layout-qualifier-name can occur multiple times |
| within a layout qualifier or across multiple layout qualifiers in the |
| same declaration. When the same layout-qualifier-name occurs multiple |
| times, in a single declaration, the last occurrence overrides the former |
| occurrence(s). Further, if such a layout-qualifier-name will effect |
| subsequent declarations or other observable behavior, it is only the |
| last occurrence that will have any effect, behaving as if the earlier |
| occurrence(s) within the declaration are not present. This is also true |
| for overriding layout-qualifier-names, where one overrides the other |
| (e.g., row_major vs. column_major); only the last occurrence has any |
| effect. |
| |
| [[ The last paragraph of this section in GLSL 4.40 and the really nice |
| table of layout qualifiers from different stages could be inserted |
| at this point, but aren't necessary. ]] |
| |
| 4.4.1 Input Layout Qualifiers |
| |
| Some input layout qualifiers apply to all shader languages and some |
| apply only to specific languages. The latter are discussed in separate |
| sections below. |
| |
| All shaders, except compute shaders, allow "location" layout qualifiers |
| on input variable declarations, input block declarations, and input |
| block member declarations. |
| |
| The layout qualifier identifier for inputs is: |
| |
| layout-qualifier-id |
| location = integer-constant |
| |
| Only one argument is accepted. For example, |
| |
| layout(location = 3) in vec4 normal; |
| |
| will establish that the shader input <normal> is assigned to vector |
| location number 3. For vertex shader inputs, the location specifies the |
| number of the vertex attribute from which input values are taken. For |
| inputs of all other shader types, the location specifies a vector number |
| that can be used to match against outputs from a previous shader stage, |
| even if that shader is in a different program object. |
| |
| The following language describes how many locations are consumed by a |
| given type. However, geometry shader inputs, tessellation control shader |
| inputs and outputs, and tessellation evaluation inputs all have an |
| additional level of arrayness relative to other shader inputs and outputs. |
| This outer array level is removed from the type before considering how |
| many locations the type consumes. |
| |
| If a shader input is any scalar or vector type, it will consume a single |
| location. |
| |
| If the declared input (after potentially removing an outer array level as |
| just described above) is an array of size <n> and each of the elements |
| takes <m> locations, it will be assigned <m> * <n> consecutive locations |
| starting with the location specified. For example, |
| |
| layout (location = 6) in vec4 colors[3]; |
| |
| will establish that the shader input <colors> is assigned to vector |
| location numbers 6, 7, and 8. |
| |
| If the declared input is an <n> x <m> matrix, it will be assigned multiple |
| locations starting with the location specified. The number of locations |
| assigned for each matrix will be the same as for an <n>-element array of |
| <m>-component vectors. For example, |
| |
| layout (location = 9) in mat4 transforms[2]; |
| |
| will establish that shader input <transforms> is assigned to vector |
| locations 9-16, with <transforms[0]> being assigned to locations 9-12, |
| and <transforms[1]> being assigned to locations 13-16. |
| |
| If the declared input is a structure or block, its members will be |
| assigned consecutive locations in their order of declaration, with the |
| first member assigned the location provided in the layout qualifier. For |
| a structure, this process applies to the entire structure. It is a |
| compile-time error to use a location qualifier on a member of a |
| structure. For a block, this process applies to the entire block, or |
| until the first member is reached that has a location layout qualifier. |
| When a block member is declared with a location qualifier, its location |
| comes from that qualifier: The member's location qualifier overrides the |
| block-level declaration. Subsequent members are again assigned |
| consecutive locations, based on the newest location, until the next |
| member declared with a location qualifier. The values used for locations |
| do not have to be declared in increasing order. |
| |
| If a block has no block-level location layout qualifier, it is required |
| that either all or none of its members have a location layout qualifier, |
| or a compile-time error results. |
| |
| The locations consumed by block and structure members are determined by |
| applying the rules above recursively as though the structure member were |
| declared as an input variable of the same type. For example: |
| |
| layout(location = 3) in struct S { |
| vec3 a; // gets location 3 |
| mat2 b; // gets locations 4 and 5 |
| vec4 c[2]; // gets locations 6 and 7 |
| layout (location = 8) vec2 A; // ERROR, can't use on struct member |
| } s; |
| |
| layout(location = 4) in block { |
| vec4 d; // gets location 4 |
| vec4 e; // gets location 5 |
| layout(location = 7) vec4 f; // gets location 7 |
| vec4 g; // gets location 8 |
| layout (location = 1) vec4 h; // gets location 1 |
| vec4 i; // gets location 2 |
| vec4 j; // gets location 3 |
| vec4 k; // ERROR, location 4 already used |
| }; |
| |
| The number of input locations available to a shader is limited. For |
| vertex shaders, the limit is the advertised number of vertex attributes. |
| For all other shaders, the limit is implementation-dependent and must be |
| no less than one fourth of the advertised maximum input component count. |
| A program will fail to link if any attached shader uses a location |
| greater than or equal to the number of supported locations, unless |
| device-dependent optimizations are able to make the program fit within |
| available hardware resources. |
| |
| A program will fail to link if explicit location assignments leave the |
| linker unable to find space for other variables without explicit |
| assignments. |
| |
| For the purposes of determining if a non-vertex input matches an output |
| from a previous shader stage, the location layout qualifier (if any) |
| must match. |
| |
| If a vertex shader input variable with no location assigned in the |
| shader text has a location specified through the OpenGL ES API, the |
| API-assigned location will be used. Otherwise, such variables will |
| be assigned a location by the linker. See section 2.11.5 "Vertex |
| Attributes" of the OpenGL ES 3.1 Graphics System Specification for |
| more details. |
| |
| It is an error if more than one input or element of a matrix input is |
| bound to the same location. |
| |
| |
| Add new subsection 4.4.1.fs: |
| |
| 4.4.1.fs Fragment Shader Inputs |
| |
| Fragment shaders can have an input layout for redeclaring the built-in |
| variable gl_FragCoord: |
| |
| in vec4 gl_FragCoord; // redeclaration that changes nothing is allowed |
| |
| The built-in gl_FragCoord is only predeclared in fragment shaders, so |
| redeclaring it in any other shader language results in a compile-time |
| error. |
| |
| Fragment shaders also allow the following layout qualifier on "in" only |
| (not with variable declarations) |
| |
| layout-qualifier-id |
| early_fragment_tests |
| |
| to request that fragment tests be performed before fragment shader |
| execution, as described in section 3.9.2 "Early Fragment Tests" of the |
| OpenGL ES Specification. |
| |
| For example, specifying |
| |
| layout(early_fragment_tests) in; |
| |
| will make per-fragment tests be performed before fragment shader |
| execution. In addition, it is an error to statically write to |
| gl_FragDepth in the fragment shader. |
| |
| If this is not declared, per-fragment tests will be performed after |
| fragment shader execution. |
| |
| 4.4.1.1 Compute Shader Inputs ... |
| |
| |
| Replace section 4.4.2 |
| |
| 4.4.2 Output Layout Qualifiers |
| |
| Some output layout qualifiers apply to all shader languages and some |
| apply only to specific languages. The latter are discussed in separate |
| sections below. |
| |
| As with input layout qualifiers, all shaders except compute shaders |
| allow location layout qualifiers on output variable declarations, output |
| block declarations, and output block member declarations. |
| |
| The layout qualifier identifier for outputs is: |
| |
| layout-qualifier-id |
| location = integer-constant |
| |
| The usage and rules for applying the location qualifier to blocks and |
| structures are exactly as described in section 4.4.1 "Input Layout |
| Qualifiers". |
| |
| |
| This qualifier may appear at most once with a declaration. For example, |
| |
| layout(location = 3) out vec4 color; |
| |
| will establish that the fragment shader output color is assigned to |
| fragment color 3. |
| |
| For fragment shader outputs, the location specifies the color output |
| number receiving the values of the output. For outputs of all other |
| shader stages, the location specifies a vector number that can be used |
| to match against inputs in a subsequent shader stage, even if that |
| shader is in a different program object. |
| |
| Declared outputs of scalar or vector type consume a single location. |
| |
| If the declared output is an array, it will be assigned consecutive |
| locations starting with the location specified. For example, |
| |
| layout(location = 2) out vec4 colors[3]; |
| |
| will establish that <colors> is assigned to vector location numbers 2, |
| 3, and 4. |
| |
| If the declared output is an n x m matrix, it will be assigned multiple |
| locations starting with the location specified. The number of locations |
| assigned will be the same as for an n-element array of m-component |
| vectors. |
| |
| If the declared output is a structure, its members will be assigned |
| consecutive locations in the order of declaration, with the first member |
| assigned the location specified for the structure. The number of |
| locations consumed by a structure member is determined by applying the |
| rules above recursively as though the structure member were declared as |
| an output variable of the same type. |
| |
| Location layout qualifiers may be used on output variables declared as |
| structures, but it is a compile-time error to use them on individual |
| members. Location layout qualifiers may be used on output blocks and |
| output block members. |
| |
| The number of output locations available to a shader is limited. For |
| fragment shaders, the limit is the advertised number of draw buffers. |
| For all other shaders, the limit is implementation-dependent and must be |
| no less than one fourth of the advertised maximum output component |
| count (compute shaders have no outputs.) A program will fail to link if |
| any attached shader uses a location greater than or equal to the number |
| of supported locations, unless device-dependent optimizations are able |
| to make the program fit within available hardware resources. |
| Compile-time errors may also be given if at compile time it is known the |
| link will fail. A negative output location will result in a compile-time |
| error. |
| |
| A program will fail to link if any of the following occur: |
| |
| * any two fragment shader output variables are assigned to the same |
| location |
| * if any two output variables from the same vertex stage are assigned |
| to the same location. |
| |
| For all shader types, a program will fail to link if explicit location |
| assignments leave the linker unable to find space for other variables |
| without explicit assignments. |
| |
| If an output variable has no location assigned in the shader text, it |
| will be assigned a location by the linker. See section 3.9.2 "Shader |
| Execution" of the OpenGL ES Specification for more details. |
| |
| For the purposes of determining if a non-fragment output matches an |
| input from a subsequent shader stage, the location layout qualifier (if |
| any) must match. |
| |
| |
| (Add new subsection 4.4.2.fs): |
| |
| 4.4.2.fs Fragment Outputs |
| |
| Fragment shaders can have an output layout for redeclaring the built-in |
| variable gl_FragDepth: |
| |
| out float gl_FragDepth; // redeclaration that changes nothing is allowed |
| |
| The built-in gl_FragDepth is only predeclared in fragment shaders, so |
| redeclaring it in any other shader language results in a compile-time |
| error. |
| |
| |
| (Remove subsection 4.5.1 "Linking of Vertex Outputs and Fragment |
| Inputs". Note that the table from this section is moved to section |
| 4.3.4, while most of the interface matching language is now dealt with |
| in "Shader Interface Matching" in the OpenGL ES Specification as |
| modified by this extension.) |
| |
| |
| (Modify the first two paragraphs of section 7.1 "Vertex Shader Special |
| Variables", moving one paragraph up one level to the introduction of |
| chapter 7): |
| |
| 7 Built-in Variables |
| |
| Some OpenGL operations occur in fixed functionality and need to provide |
| values to or receive values from shader executables. Shaders communicate |
| with fixed-function OpenGL pipeline stages, and optionally with other |
| shader executables, through the use of built-in input and output |
| variables. |
| |
| 7.1 Vertex Shader Special Variables |
| |
| In the vertex language, the built-ins are intrinsically declared as |
| follows: |
| |
| in highp int gl_VertexID; |
| in highp int gl_InstanceID; |
| |
| out gl_PerVertex { |
| highp vec4 gl_Position; |
| highp float gl_PointSize; |
| }; |
| |
| The variable gl_Position is intended for writing the homogeneous vertex |
| position. It can be written at any time during shader execution. This |
| value will be used by the following shader stage, or if there are no |
| other shaders prior to the fragment shader, by primitive assembly, |
| clipping, culling, and other fixed functionality operations that operate |
| on primitives after vertex processing has occurred. Its value is |
| undefined after vertex processing if the vertex shader does not write |
| gl_Position. |
| |
| The variable gl_PointSize ... |
| |
| Add a new section 7.io following section 7.3 "Built-In Uniform State": |
| |
| 7.io Redeclaring Built-in Blocks |
| |
| The gl_PerVertex block can be redeclared in a shader to explicitly |
| indicate what subset of the members will be used. This is necessary to |
| establish the interface between multiple programs. If the gl_PerVertex |
| block is not redefined in a given program, the intrinsically declared |
| definition of that block is used for the program interface. |
| |
| For example: |
| |
| out gl_PerVertex { |
| highp vec4 gl_Position; // will use gl_Position |
| highp float gl_PointSize; // will use gl_PointSize |
| highp vec4 t; // error, only gl_PerVertex members allowed |
| }; // no other members of gl_PerVertex will be used |
| |
| This establishes the output interface the shader will use with the |
| subsequent pipeline stage. It must be a subset of the built-in members |
| of gl_PerVertex. Such a redeclaration can also add the invariant |
| qualifier and interpolation qualifiers. |
| |
| Other layout qualifiers, like location, cannot be added to such a |
| redeclaration, unless specifically stated. |
| |
| If a built-in interface block is redeclared, it must appear in the |
| shader before any use of any member included in the built-in |
| declaration, or a compile-time error will result. It is also a |
| compile-time error to redeclare the block more than once or to redeclare |
| a built-in block and then use a member from that built-in block that was |
| not included in the redeclaration. Also, if a built-in interface block |
| is redeclared, no member of the built-in declaration can be redeclared |
| outside the block redeclaration. If multiple shaders using members of a |
| built-in block belonging to the same interface are linked together in |
| the same program, they must all redeclare the built-in block in the same |
| way, as described in section 4.3.7 "Interface Blocks" for interface |
| block matching, or a link-time error will result. It will also be a |
| link-time error if some shaders in a program redeclare a specific |
| built-in interface block while another shader in that program does not |
| redeclare that interface block yet still uses a member of that interface |
| block. If a built-in block interface is formed across shaders in |
| different programs, the shaders must all redeclare the built-in block in |
| the same way (as described for a single program), or the values passed |
| along the interface are undefined. |
| |
| Dependencies on OES_shader_multisample_interpolation |
| |
| If OES_shader_multisample_interpolation is not supported, references to |
| "sample in", "sample out" and the extension should be ignored. |
| |
| Dependencies on OES_geometry_shader and EXT_geometry_shader |
| |
| If OES_geometry_shader or EXT_geometry_shader is enabled, this extension |
| is implicitly enabled for geometry shaders. |
| |
| If OES_geometry_shader or EXT_geometry_shader is not supported, ignore all |
| references to geometry shaders. |
| |
| Dependencies on OES_tessellation_shader and EXT_tessellation_shader |
| |
| If OES_tessellation_shader or EXT_tessellation_shader is enabled, this |
| extension is implicitly enabled for tessellation control and evaluation |
| shaders. |
| |
| If OES_tessellation_shader or EXT_tessellation_shaders is not supported, |
| ignore all references to tessellation shaders. |
| |
| Issues |
| |
| (1) What functionality was removed from interface blocks relative to |
| GL 4.4? |
| |
| - Interactions with features not supported by the underlying |
| ES 3.1 API and Shading Language, including: |
| * gl_ClipDistance shader inputs and outputs. |
| * "component" layout |
| * location aliasing |
| * fragment shader output "index" layout |
| * fragment shader gl_FragDepth layout "depth*" qualifiers |
| * double-precision scalars and vectors |
| * matching across shader stages with different qualifiers (other |
| than precision and "in"/"out"). |
| * References allowing or assuming more than one shader object per |
| pipeline stage. |
| * gl_PerFragment is not added (only exists in compatibility profile). |
| |
| (2) What functionality was changed and added relative to interface blocks |
| in GL 4.4? |
| |
| - separable shaders are not required to redeclare the gl_PerVertex block. |
| - clarifications on types allowed for vertex and fragment shader inputs |
| from ES 3.0. |
| |
| (3) Are any grammar additions required in chapter 9? |
| |
| There may be something needed for supporting interface blocks on in/out |
| declarations, but I believe not, since the existing GLSL-ES 3.10 grammar |
| already has these as storage_qualifier tokens. |
| |
| (4) Shader Interface Matching rules have been updated to relax precision |
| matching on shader outputs and inputs, as previously required in ES |
| 3.0. This was changed during 3.1 development but is now proposed to |
| return to 3.0 behavior, matching this extension. |
| |
| RESOLVED. Per Bug 11189, when using a program that contains both sides |
| of an interface, the precision qualifier on inputs/outputs does not need |
| to match. However for two separable programs, the precision qualifiers |
| on inputs/outputs are required to match on the external interfaces. |
| Failing to do so results in a validation error. |
| |
| (5) In section 4.3.7 "Interface Matching", the corresponding part of |
| desktop GLSL 4.40 (pp. 49-50) has some material that's very |
| different than GLSL-ES language. Still need to review its |
| applicability here. |
| |
| UNRESOLVED. This should be addressed by rebasing on the ES 3.1 specs. |
| |
| (6) Should we allow re-declaring the gl_PerVertex block? |
| |
| DISCUSSION: If we do, we need to update Section 3.8 with language from |
| Section 3.7 in the GLSL 4.4 spec about redeclaring 'gl_' variables. |
| If we don't, applications will always pay the space for gl_PointSize, |
| and would never be able to have 'invariant' or different interpolation |
| or precision qualifiers on vertex, tessellation, or geometry shader |
| built-in outputs. This seems undesirable. |
| |
| RESOLVED: Yes. Section 3.8 updated. |
| |
| (7) What is the behavior of LinkProgram with respect to gl_PerVertex |
| blocks? |
| |
| DISCUSSION: |
| a) When using monolithic programs, gl_PerVertex does not need to be |
| redeclared in any shader stage. |
| |
| b) When using separable programs with only OpenGL ES 3.1-level |
| functionality (vertex and fragment only), gl_PerVertex does not need to |
| be redeclared. In fact, gl_PerVertex can't be redeclared, since no |
| language mechanism exists in unextended ES 3.1 to do so. Adding such a |
| requirement merely due to the presence of this extension would break |
| valid OpenGL ES 3.1-level applications. The lack of a redeclaration |
| requirement in OpenGL ES 3.1 is a difference relative to OpenGL 4.1, |
| but the reasons why we added this requirement in OpenGL 4.1 (many |
| shader stages, a larger set of built-ins, and the desire to be able to |
| treat gl_PerVertex members like other "regular" varyings) don't exist |
| in unextended ES 3.1. |
| |
| c) When using separable programs, any shader with the ability to redeclare |
| gl_PerVertex could require redeclaration when any of its members are |
| used. This would be mostly compatible with OpenGL 4.1, which requires |
| all stages to redeclare and provides the ability to do so in all |
| stages. However, since the intrinsically declared gl_PerVertex blocks |
| are actually fairly small in ES, redeclaring gl_PerVertex is optional |
| in ES. The basic rules here are: |
| |
| - gl_PerVertex exists iff OES_shader_io_blocks is enabled. |
| - OES_shader_io_blocks is always enabled if OES_geometry_shader |
| or OES_tesselation_shader is enabled. |
| - OES_shader_io_blocks can be optionally enabled for VS and FS. |
| |
| (8) What happens when you use the following together in a program |
| pipeline? |
| - a separable vertex-only program A which doesn't enable |
| OES_shader_io_blocks, and |
| - a separable program B containing a tessellation or geometry shader |
| |
| DISCUSSION: This was not an issue in OpenGL because separable shaders |
| were added (in GL 4.1) after geometry shaders and input blocks were |
| added (in GL 3.2), so any separable program with a vertex shader could |
| redeclare gl_PerVertex. There are basically 3 options: |
| |
| a) Driver has to make any combination of VS outputs in A and redeclared |
| input gl_PerVertex block in B work correctly. |
| b) Lack of redeclaring gl_PerVertex in A implies interface mismatch with |
| redeclared gl_PerVertex in B. Per the standard rules, if there is no |
| complete interface match, all inputs are undefined except for |
| individual variables that match by location, just as with user- |
| defined variables. Built-ins can't be assigned numeric locations, so |
| would be considered not to match. |
| c) It is an error. The vertex shader must be modified to support |
| being used in combination with geometry and tessellation shaders. |
| |
| RESOLVED: (a) There will only be one or at most two (if |
| OES_geometry_point_size is enabled) outputs from the vertex shader |
| that would need to be matched up with the gl_PerVertex block in the |
| next shader. It doesn't seem onerous to just make it work, and it is |
| desirable to be able to just drop a geometry shader into an otherwise |
| valid ES 3.1 application without modifying the vertex shader. |
| |
| (9) Why are there so many edits to section 4.4.1 and 4.4.2 and what |
| really changed? |
| |
| Some of this is due to restructuring to create subsections specific to |
| different shader stages, some appears to be correct (but potentially |
| redundant) language from GLSL 4.40, and some is useful block-related |
| language. |
| |
| (10) One of the new matching requirements for ES 3.1 is that |
| interpolation qualifies don't need to match. Is that true for block |
| members as well, or just loose variables? |
| |
| RESOLVED. This is true for block members as well. |
| In general, we'll allow the same rules for matching variables and |
| block members. Then a block matches iff the block members match. |
| |
| [?? still need to apply/verify edits for this]. |
| |
| Revision History |
| |
| Rev. Date Author Changes |
| ---- -------- --------- ------------------------------------------------- |
| |
| 2 08/10/2014 olson Removed contradictory language forbidding |
| location layout qualifiers on output blocks |
| or output block members (Bug 12831) |
| 1 06/18/2014 dkoch Initial OES version based on EXT. |
| No functional changes. |