| Name |
| |
| ARB_tessellation_shader |
| |
| Name Strings |
| |
| GL_ARB_tessellation_shader |
| |
| Contact |
| |
| Pat Brown, NVIDIA Corporation (pbrown 'at' nvidia.com) |
| |
| Contributors |
| |
| Barthold Lichtenbelt, NVIDIA |
| Bill Licea-Kane, AMD |
| Bruce Merry, ARM |
| Chris Dodd, NVIDIA |
| Eric Werness, NVIDIA |
| Graham Sellers, AMD |
| Greg Roth, NVIDIA |
| Ignacio Castano, NVIDIA |
| Jeff Bolz, NVIDIA |
| Nick Haemel, AMD |
| Pierre Boudier, AMD |
| Piers Daniell, NVIDIA |
| |
| Notice |
| |
| Copyright (c) 2010-2019 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 at the 2010/01/22 F2F meeting. |
| Approved by the Khronos Board of Promoters on March 10, 2010. |
| |
| Version |
| |
| Last Modified Date: September 17, 2019 |
| Revision: 23 |
| |
| Number |
| |
| ARB Extension #91 |
| |
| Dependencies |
| |
| This extension is written against the OpenGL 3.2 (Compatibility Profile) |
| Specification. |
| |
| This extension is written against Version 1.50 (Revision 09) of the OpenGL |
| Shading Language Specification. |
| |
| OpenGL 3.2 and GLSL 1.50 are required. |
| |
| This specification interacts with the core profile of OpenGL 3.2. |
| |
| This specification interacts with ARB_gpu_shader5. |
| |
| This specification interacts with ARB_gpu_shader_fp64. |
| |
| This specification interacts with NV_gpu_shader5. |
| |
| This specification interacts with NV_primitive_restart. |
| |
| Overview |
| |
| This extension introduces new tessellation stages and two new shader types |
| to the OpenGL primitive processing pipeline. These pipeline stages |
| operate on a new basic primitive type, called a patch. A patch consists |
| of a fixed-size collection of vertices, each with per-vertex attributes, |
| plus a number of associated per-patch attributes. Tessellation control |
| shaders transform an input patch specified by the application, computing |
| per-vertex and per-patch attributes for a new output patch. A |
| fixed-function tessellation primitive generator subdivides the patch, and |
| tessellation evaluation shaders are used to compute the position and |
| attributes of each vertex produced by the tessellator. |
| |
| When tessellation is active, it begins by running the optional |
| tessellation control shader. This shader consumes an input patch and |
| produces a new fixed-size output patch. The output patch consists of an |
| array of vertices, and a set of per-patch attributes. The per-patch |
| attributes include tessellation levels that control how finely the patch |
| will be tessellated. For each patch processed, multiple tessellation |
| control shader invocations are performed -- one per output patch vertex. |
| Each tessellation control shader invocation writes all the attributes of |
| its corresponding output patch vertex. A tessellation control shader may |
| also read the per-vertex outputs of other tessellation control shader |
| invocations, as well as read and write shared per-patch outputs. The |
| tessellation control shader invocations for a single patch effectively run |
| as a group. A built-in barrier() function is provided to allow |
| synchronization points where no shader invocation will continue until all |
| shader invocations have reached the barrier. |
| |
| The tessellation primitive generator then decomposes a patch into a new |
| set of primitives using the tessellation levels to determine how finely |
| tessellated the output should be. The primitive generator begins with |
| either a triangle or a quad, and splits each outer edge of the primitive |
| into a number of segments approximately equal to the corresponding element |
| of the outer tessellation level array. The interior of the primitive is |
| tessellated according to elements of the inner tessellation level array. |
| The primitive generator has three modes: "triangles" and "quads" split a |
| triangular or quad-shaped patch into a set of triangles that cover the |
| original patch; "isolines" splits a quad-shaped patch into a set of line |
| strips running across the patch horizontally. Each vertex generated by |
| the tessellation primitive generator is assigned a (u,v) or (u,v,w) |
| coordinate indicating its relative location in the subdivided triangle or |
| quad. |
| |
| For each vertex produced by the tessellation primitive generator, the |
| tessellation evaluation shader is run to compute its position and other |
| attributes of the vertex, using its (u,v) or (u,v,w) coordinate. When |
| computing final vertex attributes, the tessellation evaluation shader can |
| also read the attributes of any of the vertices of the patch written by |
| the tessellation control shader. Tessellation evaluation shader |
| invocations are completely independent, although all invocations for a |
| single patch share the same collection of input vertices and per-patch |
| attributes. |
| |
| The tessellator operates on vertices after they have been transformed by a |
| vertex shader. The primitives generated by the tessellator are passed |
| further down the OpenGL pipeline, where they can be used as inputs to |
| geometry shaders, transform feedback, and the rasterizer. |
| |
| The tessellation control and evaluation shaders are both optional. If |
| neither shader type is present, the tessellation stage has no effect. If |
| no tessellation control shader is present, the input patch provided by the |
| application is passed directly to the tessellation primitive generator, |
| and a set of default tessellation level parameters is used to control |
| primitive generation. In this extension, patches may not be passed beyond |
| the tessellation evaluation shader, and an error is generated if an |
| application provides patches and the current program object contains no |
| tessellation evaluation shader. |
| |
| IP Status |
| |
| No known IP claims. |
| |
| New Procedures and Functions |
| |
| void PatchParameteri(enum pname, int value); |
| void PatchParameterfv(enum pname, const float *values); |
| |
| New Tokens |
| |
| Accepted by the <mode> parameter of Begin and all vertex array functions |
| that implicitly call Begin: |
| |
| PATCHES 0xE |
| |
| Accepted by the <pname> parameter of PatchParameteri, GetBooleanv, |
| GetDoublev, GetFloatv, GetIntegerv, and GetInteger64v: |
| |
| PATCH_VERTICES 0x8E72 |
| |
| Accepted by the <pname> parameter of PatchParameterfv, GetBooleanv, |
| GetDoublev, GetFloatv, and GetIntegerv, and GetInteger64v: |
| |
| PATCH_DEFAULT_INNER_LEVEL 0x8E73 |
| PATCH_DEFAULT_OUTER_LEVEL 0x8E74 |
| |
| Accepted by the <pname> parameter of GetProgramiv: |
| |
| TESS_CONTROL_OUTPUT_VERTICES 0x8E75 |
| TESS_GEN_MODE 0x8E76 |
| TESS_GEN_SPACING 0x8E77 |
| TESS_GEN_VERTEX_ORDER 0x8E78 |
| TESS_GEN_POINT_MODE 0x8E79 |
| |
| Returned by GetProgramiv when <pname> is TESS_GEN_MODE: |
| |
| TRIANGLES |
| QUADS |
| ISOLINES 0x8E7A |
| |
| Returned by GetProgramiv when <pname> is TESS_GEN_SPACING: |
| |
| EQUAL |
| FRACTIONAL_ODD 0x8E7B |
| FRACTIONAL_EVEN 0x8E7C |
| |
| Returned by GetProgramiv when <pname> is TESS_GEN_VERTEX_ORDER: |
| |
| CCW |
| CW |
| |
| Returned by GetProgramiv when <pname> is TESS_GEN_POINT_MODE: |
| |
| FALSE |
| TRUE |
| |
| Accepted by the <pname> parameter of GetBooleanv, GetDoublev, GetFloatv, |
| GetIntegerv, and GetInteger64v: |
| |
| MAX_PATCH_VERTICES 0x8E7D |
| MAX_TESS_GEN_LEVEL 0x8E7E |
| MAX_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E7F |
| MAX_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E80 |
| MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS 0x8E81 |
| MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS 0x8E82 |
| MAX_TESS_CONTROL_OUTPUT_COMPONENTS 0x8E83 |
| MAX_TESS_PATCH_COMPONENTS 0x8E84 |
| MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS 0x8E85 |
| MAX_TESS_EVALUATION_OUTPUT_COMPONENTS 0x8E86 |
| MAX_TESS_CONTROL_UNIFORM_BLOCKS 0x8E89 |
| MAX_TESS_EVALUATION_UNIFORM_BLOCKS 0x8E8A |
| MAX_TESS_CONTROL_INPUT_COMPONENTS 0x886C |
| MAX_TESS_EVALUATION_INPUT_COMPONENTS 0x886D |
| MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E1E |
| MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E1F |
| |
| Accepted by the <pname> parameter of GetActiveUniformBlockiv: |
| |
| UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER 0x84F0 |
| UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER 0x84F1 |
| |
| Accepted by the <type> parameter of CreateShader and returned by the |
| <params> parameter of GetShaderiv: |
| |
| TESS_EVALUATION_SHADER 0x8E87 |
| TESS_CONTROL_SHADER 0x8E88 |
| |
| |
| Additions to Chapter 2 of the OpenGL 3.2 (Compatibility Profile) Specification (OpenGL |
| Operation) |
| |
| Modify Section 2.6.1, Begin and End, p. 22 |
| |
| (insert before the last paragraph, p. 27) |
| |
| Separate Patches |
| |
| Separate patches are specified with mode PATCHES. A patch is an ordered |
| collection of vertices used for primitive tessellation (section 2.X). The |
| vertices comprising a patch have no implied geometric ordering. The |
| vertices of a patch are used by tessellation shaders and a fixed-function |
| tessellator to generate new point, line, or triangle primitives. |
| |
| Each patch in the series has a fixed number of vertices, which is |
| specified by calling |
| |
| void PatchParameteri(enum pname, int value); |
| |
| with <pname> set to PATCH_VERTICES. The error INVALID_VALUE is generated |
| if <value> is less than or equal to zero or is greater than the |
| implementation-dependent maximum patch size, MAX_PATCH_VERTICES. The |
| patch size is initially three vertices. |
| |
| If the number of vertices in a patch is given by <v>, the <v>*<i>+1st |
| through <v>*<i>+<v>th vertices (in that order) determine a patch for each |
| i = 0, 1, ..., n-1, where there are <v>*<n>+<k> vertices. <k> is in the |
| range [0,<v>-1]; if <k> is not zero, the final <k> vertices are ignored. |
| |
| |
| (modify second paragraph, p. 29) The state required for Begin and End |
| consists of a sixteen-valued integer indicating either one of the fifteen |
| possible Begin/End modes, or that no Begin/End mode is being processed. |
| |
| |
| Modify Section 2.14, Vertex Shaders, p. 82 |
| |
| (modify fourth paragraph, p. 82) In addition to vertex shaders, |
| tessellation control shaders, tessellation evaluation shaders, geometry |
| shaders, and fragment shaders can be created, compiled, and linked into |
| program objects. Tessellation control and evaluation shaders are used to |
| control the operation of the tessellator, and are described in section |
| 2.X. Geometry shaders affect the processing of primitives assembled from |
| vertices (see section 2.15). Fragment shaders affect the processing of |
| fragments during rasterization (see section 3.12). A single program |
| object can contain vertex, tessellation control, tessellation evaluation, |
| geometry, and fragment shaders. |
| |
| |
| Modify Section 2.14.2, Program Objects, p. 84 |
| |
| (insert before third paragraph, p. 85) |
| |
| Linking will fail if the program object contains objects to form a |
| tessellation control shader (see section 2.X.1), and |
| |
| * the program contains no objects to form a vertex shader; |
| |
| * the output patch vertex count is not specified in any compiled |
| tessellation control shader object; or |
| |
| * the output patch vertex count is specified differently in multiple |
| tessellation control shader objects. |
| |
| Linking will fail if the program object contains objects to form a |
| tessellation evaluation shader (see section 2.X.3), and |
| |
| * the program contains no objects to form a vertex shader; |
| |
| * the tessellation primitive mode is not specified in any compiled |
| tessellation evaluation shader object; or |
| |
| * the tessellation primitive mode, spacing, vertex order, or point mode |
| is specified differently in multiple tessellation evaluation shader |
| objects. |
| |
| |
| Modify Section 2.14.4, Uniform Variables, p, 89 |
| |
| (modify sixth paragraph, p. 93) If <pname> is |
| UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER, |
| UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER, |
| UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER, |
| UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER, or |
| UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER, then a boolean value |
| indicating whether the uniform block identified by <uniformBlockIndex> is |
| referenced by the vertex, tessellation control, tessellation evaluation, |
| geometry, or fragment shaders of <program>, respectively, is returned. |
| |
| (modify next-to-last paragraph, p. 101) There is a set of |
| implementation-dependent maximums for the number of active uniform blocks |
| used by each shader. If the number of uniform blocks used by any shader |
| in the program exceeds its corresponding limit, the program will fail to |
| link. The limits for vertex, tessellation control, tessellation |
| evaluation, geometry, and fragment shaders can be obtained by calling |
| GetIntegerv with pname values of MAX_VERTEX_UNIFORM_BLOCKS, |
| MAX_TESS_CONTROL_UNIFORM_BLOCKS, MAX_TESS_EVALUATION_UNIFORM_BLOCKS, |
| MAX_GEOMETRY_UNIFORM_BLOCKS, and MAX_FRAGMENT_UNIFORM_BLOCKS, |
| respectively. |
| |
| |
| Modify Section 2.14.6, Varying Variables, p. 106 |
| |
| (modify three paragraphs starting with the last paragraph, p. 106, to |
| refer less specifically to geometry shaders) ... These varying variables |
| are used as the mechanism to communicate values to the next active stage |
| in the vertex processing pipeline: either the tessellation control |
| shader, the tessellation evaluation shader, the geometry shader, or the |
| fixed-function vertex processing stages leading to rasterization. |
| |
| If the varying variables are passed directly to the vertex processing |
| stages leading to rasterization, the values of all varying and special |
| variables are expected to be interpolated across the primitive being |
| rendered, unless flatshaded. Otherwise, the values of all varying and |
| special variables are collected by the primitive assembly stage and passed |
| on to the subsequent pipeline stage once enough data for one primitive has |
| been collected |
| |
| The number of components (individual scalar numeric values) of varying and |
| special variables that can be written by the vertex shader, whether or not |
| a tessellation control, tessellation evaluation, or geometry shader is |
| active, is given by the value of the implementation-dependent constant |
| MAX_VERTEX_OUTPUT_COMPONENTS. Outputs declared as vectors, matrices, and |
| arrays will all consume multiple components. |
| |
| (modify next-to-last paragraph, p. 107) Each program object can specify a |
| set of output variables from one shader to be recorded in transform |
| feedback mode (see section 2.19). If a geometry shader is active, its |
| output variables are the ones that can be recorded. Otherwise, |
| tessellation evaluation shader outputs will be recorded, if that shader is |
| active. Otherwise, tessellation control shader outputs will be recorded, |
| if that shader is active. Otherwise, vertex shader outputs will be |
| recorded. The values to record are specified with the command ... |
| |
| (modify bullet list, p. 108) |
| |
| * the count specified by TransformFeedbackVaryings is non-zero, but the |
| program object has no vertex, tessellation control, tessellation |
| evaluation, or geometry shader; |
| |
| * any variable name specified in the varyings array is not declared as |
| an output in the shader stage whose outputs can be recorded; |
| |
| ... |
| |
| |
| Modify Section 2.14.7, Shader Execution, p. 109 |
| |
| (Modify the part of the section describing what is and is not done for |
| processing vertices when vertex shaders are active, p. 109 and 110. This |
| rewrite is intended to apply to all programmable vertex processing |
| pipeline stages. Ideally, we should refactor the spec to first have a |
| general programmable shading section describing common shader |
| functionality and this pipeline, followed by sections containing |
| domain-specific items.) |
| |
| If a successfully linked program object that contains a vertex, |
| tessellation control, tessellation evaluation, or geometry shader is made |
| current by calling UseProgram, the executable version of these shaders are |
| used to process incoming vertex values, rather than the fixed-function |
| vertex processing described in sections 2.16 through 2.13. In particular, |
| |
| (keep list of fixed-function operations that are not performed) |
| |
| Instead, the following sequence of operations is performed: |
| |
| * Vertices are processed by the vertex shader (section 2.14) and |
| assembled into primitives as described in sections 2.6 through 2.10. |
| |
| * If the current program contains a tessellation control shader, each |
| individual patch primitive is processed by the tessellation control |
| shader (section 2.X.1). Otherwise, primitives are passed through |
| unmodified. If active, the tessellation control shader consumes its |
| input patch and produces a new patch primitive, which is passed to |
| subsequent pipeline stages. |
| |
| * If the current program contains a tessellation evaluation shader, each |
| individual patch primitive is processed by the tessellation primitive |
| generator (section 2.X.2) and tessellation evaluation shader (section |
| 2.X.3). Otherwise, primitives are passed through unmodified. When a |
| tessellation evaluation shader is active, the tessellation primitive |
| generator produces a new collection of point, line, or triangle |
| primitives to be passed to subsequent pipeline stages. The vertices |
| of these primitives are processed by the tessellation evaluation |
| shader. The patch primitive passed to the tessellation primitive |
| generator is consumed by this process. |
| |
| * If the current program contains a geometry shader, each individual |
| primitive is processed by the geometry shader (section 2.15). |
| Otherwise, primitives are passed through unmodified. If active, the |
| geometry shader consumes its input patch. However, each geometry |
| shader invocation may emit new vertices, which are arranged into |
| primitives and passed to subsequent pipeline stages. |
| |
| * The primitives reaching this stage in the pipeline are then processed |
| by the following fixed-function operations: |
| |
| (NOTE: This change rearranges the order of some of the operations, |
| and adds explicit references to transform feedback and rasterization. |
| The pipeline stages have been in the wrong order since OpenGL 2.0 -- |
| in particular, clipping logically happens before perspective division |
| and viewport transformations.) |
| |
| * Color clamping or masking (section 2.13.6). |
| |
| * Transform feedback (section 2.19). |
| |
| * Flatshading (section 2.21). |
| |
| * Clipping, including client-defined clip planes (section 2.22). |
| |
| * Perspective division on clip coordinates (section 2.16). |
| |
| * Viewport mapping, including depth range scaling (section 2.16.1). |
| |
| * Front face determination (section 2.13.1). |
| |
| * Color, texture coordinate, fog, point-size and generic attribute |
| clipping (section 2.22.1). |
| |
| * Final color processing (section 2.23). |
| |
| * Rasterization (chapter 3). |
| |
| |
| Modify Section 2.14.7, Shader Execution, p. 109 |
| |
| (modify last paragraph, p. 110) This section describes texture |
| functionality that is only accessible through vertex, tessellation |
| control, tessellation evaluation, geometry, or fragment shaders. ... |
| |
| (modify first paragraph under "Texture Access", p. 112) Shaders have the |
| ability to do a lookup into a texture map. The maximum number of texture |
| image units available to vertex, tessellation control, tessellation |
| evaluation, geometry, or fragment shaders are the values of |
| the implementation-dependent constants |
| |
| * MAX_VERTEX_TEXTURE_IMAGE_UNITS (vertex), |
| * MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS (tessellation control), |
| * MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS (tessellation evaluation), |
| * MAX_GEOMETRY_TEXTURE_IMAGE_UNITS (geometry), and |
| * MAX_TEXTURE_IMAGE_UNITS (fragment). |
| |
| The vertex shader, tessellation control and evaluation shader, geometry |
| shader, and fragment processing combined cannot use more than the value of |
| MAX_COMBINED_TEXTURE_IMAGE_UNITS texture image units. If more than one |
| pipeline stage accesses the same texture image unit, each such access |
| counts separately against the MAX_COMBINED_TEXTURE_IMAGE_UNITS limit. |
| |
| (modify next-to-last paragraph p. 112) When a texture lookup is performed |
| in a shader, the filtered ... |
| |
| (modify last paragraph p. 112) In shaders other than fragment shaders, it |
| is not possible... |
| |
| (modify last paragraph before "Shader Inputs", p. 113) If a shader uses a |
| sampler where the associated ... |
| |
| |
| Insert a new section immediately after Section 2.14, Vertex Shaders. |
| |
| Section 2.X, Tessellation |
| |
| Tessellation is a process that reads a patch primitive and generates new |
| primitives used by subsequent pipeline stages. The generated primitives |
| are formed by subdividing a single triangle or quad primitive according to |
| fixed or shader-computed levels of detail and transforming each of the |
| vertices produced during this subdivision. |
| |
| Tessellation functionality is controlled by two types of tessellation |
| shaders: tessellation control shaders and tessellation evaluation |
| shaders. Tessellation is considered active if and only if there is an |
| active program object, and that program object contains a tessellation |
| control or evaluation shader. |
| |
| The tessellation control shader is used to read an input patch provided by |
| the application, and emit an output patch. The tessellation control |
| shader is run once for each vertex in the output patch and computes the |
| attributes of that vertex. Additionally, the tessellation control shader |
| may compute additional per-patch attributes of the output patch. The most |
| important per-patch outputs are the tessellation levels, which are used to |
| control the number of subdivisions performed by the tessellation primitive |
| generator. The tessellation control shader may also write additional |
| per-patch attributes for use by the tessellation evaluation shader. If no |
| tessellation control shader is active, the patch provided is passed |
| through to the tessellation primitive generator stage unmodified. |
| |
| If a tessellation evaluation shader is active, the tessellation primitive |
| generator subdivides a triangle or quad primitive into a collection of |
| points, lines, or triangles according to the tessellation levels of the |
| patch and the set of layout declarations specified in the tessellation |
| evaluation shader text. The tessellation levels used to control |
| subdivision are normally written by the tessellation control shader. If |
| no tessellation control shader is active, default tessellation levels are |
| instead used. |
| |
| When a tessellation evaluation shader is active, it is run on each vertex |
| generated by the tessellation primitive generator to compute the final |
| position and other attributes of the vertex. The tessellation evaluation |
| shader can read the relative location of the vertex in the subdivided |
| output primitive, given by an (u,v) or (u,v,w) coordinate, as well as the |
| position and attributes of any or all of the vertices in the input patch. |
| |
| Tessellation operates only on patch primitives. If tessellation is |
| active, the error INVALID_OPERATION is generated by Begin (or vertex array |
| commands that implicitly call Begin) if the primitive mode is not |
| PATCHES. |
| |
| Patch primitives are not supported by pipeline stages below the |
| tessellation evaluation shader. If there is no active program object or |
| the active program object does not contain a tessellation evaluation |
| shader, the error INVALID_OPERATION is generated by Begin (or vertex array |
| commands that implicitly call Begin) if the primitive mode is PATCHES. |
| |
| A program object that includes a tessellation shader of any kind must also |
| include a vertex shader, and will fail to link if no vertex shader is |
| provided. |
| |
| |
| Section 2.X.1, Tessellation Control Shaders |
| |
| The tessellation control shader consumes an input patch provided by the |
| application and emits a new output patch. The input patch is an array of |
| vertices with attributes corresponding to output variables written by the |
| vertex shader. The output patch consists of an array of vertices with |
| attributes corresponding to per-vertex output variables written by the |
| tessellation control shader and a set of per-patch attributes |
| corresponding to per-patch output variables written by the tessellation |
| control shader. Tessellation control output variables are per-vertex by |
| default, but may be declared as per-patch using the "patch" qualifier. |
| |
| The number of vertices in the output patch is fixed when the program is |
| linked, and is specified in tessellation control shader source code using |
| the output layout qualifier "vertices", as described in the OpenGL Shading |
| Language Specification. A program will fail to link if the output patch |
| vertex count is not specified by any tessellation control shader object |
| attached to the program, if it is specified differently by multiple |
| tessellation control shader objects, if it is less than or equal to zero, |
| or if it is greater than the implementation-dependent maximum patch |
| size. The output patch vertex count may be queried by calling GetProgramiv |
| with the symbolic constant TESS_CONTROL_OUTPUT_VERTICES. |
| |
| Tessellation control shaders are created as described in section 2.14.1, |
| using a <type> of TESS_CONTROL_SHADER. When a new input patch is |
| received, the tessellation control shader is run once for each vertex in |
| the output patch. The tessellation control shader invocations |
| collectively specify the per-vertex and per-patch attributes of the output |
| patch. The per-vertex attributes are obtained from the per-vertex output |
| variables written by each invocation. Each tessellation control shader |
| invocation may only write to per-vertex output variables corresponding to |
| its own output patch vertex. The output patch vertex number corresponding |
| to a given tessellation control point shader invocation is given by the |
| built-in variable gl_InvocationID. Per-patch attributes are taken from |
| the per-patch output variables, which may be written by any tessellation |
| control shader invocation. While tessellation control shader invocations |
| may read any per-vertex and per-patch output variable and write any |
| per-patch output variable, reading or writing output variables also |
| written by other invocations has ordering hazards discussed below. |
| |
| |
| Section 2.X.1.1, Tessellation Control Shader Variables |
| |
| Tessellation control shaders can access uniforms belonging to the current |
| program object. The amount of storage available for uniform variables in |
| the default uniform block accessed by a tessellation control shader is |
| specified by the value of the implementation-dependent constant |
| MAX_TESS_CONTROL_UNIFORM_COMPONENTS. The total amount of combined storage |
| available for uniform variables in all uniform blocks accessed by a |
| tessellation control shader (including the default uniform block) is |
| specified by the value of the implementation-dependent constant |
| MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS. These values represent the |
| numbers of individual floating-point, integer, or boolean values that can |
| be held in uniform variable storage for a tessellation evaluation shader. |
| A link error is generated if an attempt is made to utilize more than the |
| space available for tessellation control shader uniform variables. |
| Uniforms are manipulated as described in section 2.14.4. Tessellation |
| control shaders also have access to samplers to perform texturing |
| operations, as described in sections 2.14.5. |
| |
| Tessellation control shaders can access the transformed attributes of all |
| vertices for their input primitive using input variables. A vertex shader |
| writing to output variables generates the values of these input varying |
| variables, including values for built-in as well as user-defined varying |
| variables. Values for any varying variables that are not written by a |
| vertex shader are undefined. |
| |
| Additionally, tessellation control shaders can write to one or more output |
| variables, including per-vertex attributes for the vertices of the output |
| patch and per-patch attributes of the patch. Tessellation control shaders |
| can also write to a set of built-in per-vertex and per-patch outputs |
| defined in the OpenGL Shading Language. The per-vertex and per-patch |
| attributes of the output patch are used by the tessellation primitive |
| generator (section 2.X.2) and may be read by tessellation evaluation |
| shader (section 2.X.3). |
| |
| |
| Section 2.X.1.2, Tessellation Control Shader Execution Environment |
| |
| If a successfully linked program object that contains a tessellation |
| control shader is made current by calling UseProgram, the executable |
| version of the tessellation control shader is used to process patches |
| resulting from the primitive assembly stage. When tessellation control |
| shader execution completes, the input patch is consumed. A new patch is |
| assembled from the per-vertex and per-patch output variables written by |
| the shader and is passed to subsequent pipeline stages. |
| |
| There are several special considerations for tessellation control shader |
| execution described in the following sections. |
| |
| Texture Access |
| |
| The Shader-Only Texturing subsection of section 2.14.7 describes texture |
| lookup functionality accessible to a vertex shader. The texel fetch and |
| texture size query functionality described there also applies to |
| tessellation control shaders. |
| |
| Tessellation Control Shader Inputs |
| |
| Section 7.1 of the OpenGL Shading Language Specification describes the |
| built-in variable array gl_in[] available as input to a tessellation |
| control shader. gl_in[] receives values from equivalent built-in output |
| variables written by the vertex shader (section 2.14.7). Each array |
| element of gl_in[] is a structure holding values for a specific vertex of |
| the input patch. The length of gl_in[] is equal to the |
| implementation-dependent maximum patch size (gl_MaxPatchVertices). |
| Behavior is undefined if gl_in[] is indexed with a vertex index greater |
| than or equal to the current patch size. The members of each element of |
| the gl_in[] array are gl_Position, gl_PointSize, gl_ClipDistance[], |
| gl_ClipVertex, gl_FrontColor, gl_BackColor, gl_FrontSecondaryColor, |
| gl_BackSecondaryColor, gl_TexCoord[], and gl_FogFragCoord[]. |
| |
| Tessellation control shaders have available several other special input |
| variables not replicated per-vertex and not contained in gl_in[], |
| including: |
| |
| * The variable gl_PatchVerticesIn holds the number of vertices in the |
| input patch being processed by the tessellation control shader. |
| |
| * The variable gl_PrimitiveID is filled with the number of primitives |
| processed 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 triangle primitive is |
| processed. Restarting a primitive topology using the primitive |
| restart index has no effect on the primitive ID counter. |
| |
| * The variable gl_InvocationID holds an invocation number for the |
| current tessellation control shader invocation. Tessellation control |
| shaders are invoked once per output patch vertex, and invocations are |
| numbered beginning with zero. |
| |
| Similarly to the built-in varying variables, each user-defined input |
| varying variable has a value for each vertex and thus needs to be declared |
| as arrays or inside input blocks declared as arrays. Declaring an array |
| size is optional. If no size is specified, it will be taken from the |
| implementation-dependent maximum patch size (gl_MaxPatchVertices). If a |
| size is specified, it must match the maximum patch size; otherwise, a |
| compile or link |
| error will occur. Since the array size may be larger than the number of |
| vertices found in the input patch, behavior is undefined if a per-vertex |
| input variable is accessed using an index greater than or equal to the |
| number of vertices in the input patch. The OpenGL Shading Language |
| doesn't support multi-dimensional arrays; therefore, user-defined |
| tessellation control shader inputs corresponding to vertex shader outputs |
| declared as arrays must be declared as array members of an input block |
| that is itself declared as an array. |
| |
| (Note: minor restructuring in the following paragraph relative to the |
| equivalent geometry shader language.) |
| |
| Similarly to the limit on vertex shader output components (see section |
| 2.14.6), there is a limit on the number of components of built-in and |
| user-defined input varying variables that can be read by the tessellation |
| control shader, given by the value of the implementation-dependent |
| constant MAX_TESS_CONTROL_INPUT_COMPONENTS. When a program is linked, all |
| components of any varying and special variable read by a tessellation |
| control shader will count against this limit. A program whose |
| tessellation control shader exceeds this limit may fail to link, unless |
| device-dependent optimizations are able to make the program fit within |
| available hardware resources. |
| |
| |
| Tessellation Control Shader Outputs |
| |
| Section 7.1 of the OpenGL Shading Language Specification describes the |
| built-in variable array gl_out[] available as an output for a tessellation |
| control shader. gl_out[] passes values to equivalent built-in input |
| variables read by subsequent shader stages or to subsequent fixed |
| functionality vertex processing pipeline stages. Each array element of |
| gl_out[] is a structure holding values for a specific vertex of the output |
| patch. The length of gl_out[] is equal to the output patch size specified |
| in the tessellation control shader output layout declaration |
| (gl_VerticesOut). The members of each element of the gl_out[] array are |
| gl_Position, gl_PointSize, gl_ClipDistance[], gl_ClipVertex, |
| gl_FrontColor, gl_BackColor, gl_FrontSecondaryColor, |
| gl_BackSecondaryColor, gl_TexCoord[], and gl_FogFragCoord[], and behave |
| identically to equivalently named vertex shader outputs (section 2.14.7). |
| |
| Tessellation shaders additionally have two built-in per-patch output |
| arrays, gl_TessLevelOuter[] and gl_TessLevelInner[]. These arrays are not |
| replicated for each output patch vertices and are not members of gl_out[]. |
| gl_TessLevelOuter[] is an array of four floating-point values specifying |
| the approximate number of segments that the tessellation primitive |
| generator should use when subdividing each outer edge of the primitive it |
| subdivides. gl_TessLevelInner[] is an array of two floating-point values |
| specifying the approximate number of segments used to produce a |
| regularly-subdivided primitive interior. The values written to |
| gl_TessLevelOuter and gl_TessLevelInner need not be integers, and their |
| interpretation depends on the type of primitive the tessellation primitive |
| generator will subdivide and other tessellation parameters, as discussed |
| in the following section. |
| |
| A tessellation control shader may also declare user-defined per-vertex |
| output variables. User-defined per-vertex output variables are declared |
| with the qualifier "out" and have a value for each vertex in the output |
| patch. Such variables must be declared as arrays or inside output blocks |
| declared as arrays. Declaring an array size is optional. If no size is |
| specified, it will be taken from the output patch size (gl_VerticesOut) |
| declared in the shader. If a size is specified, it must match the maximum |
| patch size; otherwise, a compile or link link error will occur. The OpenGL Shading |
| Language doesn't support multi-dimensional arrays; therefore, user-defined |
| per-vertex tessellation control shader outputs with multiple elements per |
| vertex must be declared as array members of an output block that is itself |
| declared as an array. |
| |
| While per-vertex output variables are declared as arrays indexed by vertex |
| number, each tessellation control shader invocation may write only to |
| those outputs corresponding to its output patch vertex. Tessellation |
| control shaders must use the special variable gl_InvocationID as the |
| vertex number index when writing to per-vertex output variables. |
| |
| Additionally, a tessellation control shader may declare per-patch output |
| variables using the qualifier "patch out". Unlike per-vertex outputs, |
| per-patch outputs do not correspond to any specific vertex in the patch, |
| and are not indexed by vertex number. Per-patch outputs declared as |
| arrays have multiple values for the output patch; similarly declared |
| per-vertex outputs would indicate a single value for each vertex in the |
| output patch. User-defined per-patch outputs are not used by the |
| tessellation primitive generator, but may be read by tessellation |
| evaluation shaders. |
| |
| There are several limits on the number of components of built-in and |
| user-defined output variables that can be written by the tessellation |
| control shader. The number of components of active per-vertex output |
| variables may not exceed the value of MAX_TESS_CONTROL_OUTPUT_COMPONENTS. |
| The number of components of active per-patch output variables may not |
| exceed the value of MAX_TESS_PATCH_COMPONENTS. The built-in outputs |
| gl_TessLevelOuter[] and gl_TessLevelInner[] are not counted against the |
| per-patch limit. The total number of components of active per-vertex and |
| per-patch outputs is derived by multiplying the per-vertex output |
| component count by the output patch size and then adding the per-patch |
| output component count. The total component count may not exceed |
| MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS. When a program is linked, all |
| components of any varying and special variables written by a tessellation |
| control shader will count against this limit. A program exceeding any of |
| these limits may fail to link, unless device-dependent optimizations are |
| able to make the program fit within available hardware resources. |
| |
| |
| Tessellation Control Shader Execution Order |
| |
| For tessellation control shaders with a declared output patch size greater |
| than one, the shader is invoked more than once for each input patch. The |
| order of execution of one tessellation control shader invocation relative |
| to the other invocations for the same input patch is largely undefined. |
| The built-in function barrier() provides some control over relative |
| execution order. When a tessellation control shader calls the barrier() |
| function, its execution pauses until all other invocations have also |
| called the same function. Output variable assignments performed by any |
| invocation executed prior to calling barrier() will be visible to any |
| other invocation after the call to barrier() returns. Shader output |
| values read in one invocation but written by another may be undefined |
| without proper use of barrier(); full rules are found in the OpenGL |
| Shading Language Specification. |
| |
| The barrier() function may only be called inside the main entry point of |
| the tessellation control shader and may not be called in potentially |
| divergent flow control. In particular, barrier() may not be called inside |
| a switch statement, in either sub-statement of an if statement, inside a |
| do, for, or while loop, or at any point after a return statement in the |
| function main(). |
| |
| |
| Section 2.X.2, Tessellation Primitive Generation |
| |
| If a tessellation evaluation shader is present, the tessellation primitive |
| generator consumes the input patch and produces a new set of basic |
| primitives (points, lines, or triangles). These primitives are produced |
| by subdividing a geometric primitive (rectangle or triangle) according to |
| the per-patch tessellation levels written by the tessellation control |
| shader, if present, or taken from default patch parameter values. This |
| subdivision is performed in an implementation-dependent manner. If no |
| tessellation evaluation shader is present, the tessellation primitive |
| generator passes incoming primitives through without modification. |
| |
| The type of subdivision performed by the tessellation primitive generator |
| is specified by an input layout declaration in the tessellation evaluation |
| shader using one of the identifiers "triangles", "quads", and "isolines". |
| For "triangles", the primitive generator subdivides a triangle primitive |
| into smaller triangles. For "quads", the primitive generator subdivides a |
| rectangle primitive into smaller triangles. For "isolines", the primitive |
| generator subdivides a rectangle primitive into a collection of line |
| segments arranged in strips stretching horizontally across the rectangle. |
| Each vertex produced by the primitive generator has an associated (u,v,w) |
| or (u,v) position in a normalized parameter space, with parameter values |
| in the range [0,1], as illustrated in Figure X.1. For "triangles", the |
| vertex position is a barycentric coordinate (u,v,w), where u+v+w==1, and |
| indicates the relative influence of the three vertices of the triangle on |
| the position of the vertex. For "quads" and "isolines", the position is a |
| (u,v) coordinate indicating the relative horizontal and vertical position |
| of the vertex relative to the subdivided rectangle. The subdivision |
| process is explained in more detail in subsequent sections. |
| |
| (0,1) OL3 (1,1) (0,1,0) (0,1) (1,1) |
| +--------------+ + ^ + <no edge> + |
| | | / \ | |
| | +--------+ | / \ | +--------------+ |
| | | IL0 | | OL0 / + \ OL2 | |
| OL0| |IL1 | |OL2 / / \ \ | +--------------+ |
| | | | | / /IL0\ \ OL0 |
| | +--------+ | / +-----+ \ | +--------------+ |
| | | / \ | |
| +--------------+ +---------------+ v +--------------+ |
| (0,0) OL1 (1,0) (0,0,1) OL1 (1,0,0) (0,0) OL1 (1,0) |
| |
| quads triangles isolines |
| |
| Figure X.1: Domain parameterization for tessellation generator |
| primitive modes (triangles, quads, or isolines). The coordinates |
| illustrate the value of gl_TessCoord at the corners of the domain. The |
| labels on the edges indicate the inner (IL0 and IL1) and outer (OL0 |
| through OL3) tessellation level values used to control the number of |
| subdivisions along each edge of the domain. |
| |
| When no tessellation control shader is present, the tessellation levels |
| are taken from default patch tessellation levels. These default levels |
| are set by calling |
| |
| void PatchParameterfv(enum pname, const float *values); |
| |
| If <pname> is PATCH_DEFAULT_OUTER_LEVEL, <values> specifies an array of |
| four floating-point values corresponding to the four outer tessellation |
| levels for each subsequent patch. If <pname> is |
| PATCH_DEFAULT_INNER_LEVEL, <values> specifies an array of two |
| floating-point values corresponding to the two inner tessellation levels. |
| |
| A patch is discarded by the tessellation primitive generator if any |
| relevant outer tessellation level is less than or equal to zero. Patches |
| will also be discarded if any outer tessellation level corresponds to a |
| floating-point NaN (not a number) in implementations supporting NaN. |
| When patches are discarded, no new primitives will be generated and the |
| tessellation evaluation program will not be run. For "quads", all four |
| outer levels are relevant. For "triangles" and "isolines", only the first |
| three or two outer levels, respectively, are relevant. Negative inner |
| levels will not cause a patch to be discarded; they will be clamped as |
| described below. |
| |
| Each of the tessellation levels is used to determine the number and |
| spacing of segments used to subdivide a corresponding edge. The method |
| used to derive the number and spacing of segments is specified by an input |
| layout declaration in the tessellation evaluation shader using one of the |
| identifiers "equal_spacing", "fractional_even_spacing", or |
| "fractional_odd_spacing". If no spacing is specified in the tessellation |
| evaluation shader, "equal_spacing" will be used. |
| |
| If "equal_spacing" is used, the floating-point tessellation level is first |
| clamped to the range [1,<max>], where <max> is implementation-dependent |
| maximum tessellation level (MAX_TESS_GEN_LEVEL). The result is rounded up |
| to the nearest integer <n>, and the corresponding edge is divided into <n> |
| segments of equal length in (u,v) space. |
| |
| If "fractional_even_spacing" is used, the tessellation level is first |
| clamped to the range [2,<max>] and then rounded up to the nearest even |
| integer <n>. If "fractional_odd_spacing" is used, the tessellation level |
| is clamped to the range [1,<max>-1] and then rounded up to the nearest odd |
| integer <n>. If <n> is one, the edge will not be subdivided. Otherwise, |
| the corresponding edge will be divided into <n>-2 segments of equal |
| length, and two additional segments of equal length that are typically |
| shorter than the other segments. The length of the two additional |
| segments relative to the others will decrease monotonically with the value |
| of <n>-<f>, where <f> is the clamped floating-point tessellation level. |
| When <n>-<f> is zero, the additional segments will have equal length to |
| the other segments. As <n>-<f> approaches 2.0, the relative length of the |
| additional segments approaches zero. The two additional segments should |
| be placed symmetrically on opposite sides of the subdivided edge. The |
| relative location of these two segments is undefined, but must be |
| identical for any pair of subdivided edges with identical values of <f>. |
| |
| When the tessellation primitive generator produces triangles (in the |
| "triangles" or "quads" modes), the orientation of all triangles can be |
| specified by an input layout declaration in the tessellation evaluation |
| shader using the identifiers "cw" and "ccw". If the order is "cw", the |
| vertices of all generated triangles will have a clockwise ordering in |
| (u,v) or (u,v,w) space, as illustrated in Figure X.1. If the order is |
| "ccw", the vertices will be specified in counter-clockwise order. If no |
| layout is specified, "ccw" will be used. |
| |
| For all primitive modes, the tessellation primitive generator is capable |
| of generating points instead of lines or triangles. If an input layout |
| declaration in the tessellation evaluation shader specifies the identifier |
| "point_mode", the primitive generator will generate one point for each |
| distinct vertex produced by tessellation. Otherwise, the primitive |
| generator will produce a collection of line segments or triangles |
| according to the primitive mode. When tessellating triangles or quads in |
| point mode with fractional odd spacing, the tessellation primitive |
| generator may produce "interior" vertices that are positioned on the edge |
| of the patch if an inner tessellation level is less than or equal to one. |
| Such vertices are considered distinct from vertices produced by |
| subdividing the outer edge of the patch, even if there are pairs of |
| vertices with identical coordinates. |
| |
| The points, lines, or triangles produced by the tessellation primitive |
| generator are passed to subsequent pipeline stages in an |
| implementation-dependent order. |
| |
| |
| Section 2.X.2.1, Triangle Tessellation |
| |
| If the tessellation primitive mode is "triangles", an equilateral triangle |
| is subdivided into a collection of triangles covering the area of the |
| original triangle. First, the original triangle is subdivided into a |
| collection of concentric equilateral triangles. The edges of each of |
| these triangles are subdivided, and the area between each triangle pair is |
| filled by triangles produced by joining the vertices on the subdivided |
| edges. The number of concentric triangles and the number of subdivisions |
| along each triangle except the outermost is derived from the first inner |
| tessellation level. The edges of the outermost triangle are subdivided |
| independently, using the first, second, and third outer tessellation |
| levels to control the number of subdivisions of the u==0 (left), v==0 |
| (bottom), and w==0 (right) edges, respectively. The second inner |
| tessellation level and the fourth outer tessellation level have no effect |
| in this mode. |
| |
| If the first inner tessellation level and all three outer tessellation |
| levels are exactly one after clamping and rounding, only a single triangle |
| with (u,v,w) coordinates of (0,0,1), (1,0,0), and (0,1,0) is generated. |
| If the inner tessellation level is one and any of the outer tessellation |
| levels is greater than one, the inner tessellation level is treated as |
| though it were originally specified as 1+epsilon and will result in a two- |
| or three-segment subdivision depending on the tessellation spacing. When |
| used with fractional odd spacing, the three-segment subdivision may |
| produce "inner" vertices positioned on the edge of the triangle. |
| |
| If any tessellation level is greater than one, tessellation begins by |
| producing a set of concentric inner triangles and subdividing their edges. |
| First, the three outer edges are temporarily subdivided using the clamped |
| and rounded first inner tessellation level and the specified tessellation |
| spacing, generating <n> segments. For the outermost inner triangle, the |
| inner triangle is degenerate -- a single point at the center of the |
| triangle -- if <n> is two. Otherwise, for each corner of the outer |
| triangle, an inner triangle corner is produced at the intersection of two |
| lines extended perpendicular to the corner's two adjacent edges running |
| through the vertex of the subdivided outer edge nearest that corner. If |
| <n> is three, the edges of the inner triangle are not subdivided and is |
| the final triangle in the set of concentric triangles. Otherwise, each |
| edge of the inner triangle is divided into <n>-2 segments, with the <n>-1 |
| vertices of this subdivision produced by intersecting the inner edge with |
| lines perpendicular to the edge running through the <n>-1 innermost |
| vertices of the subdivision of the outer edge. Once the outermost inner |
| triangle is subdivided, the previous subdivision process repeats itself, |
| using the generated triangle as an outer triangle. This subdivision |
| process is illustrated in Figure X.2. |
| |
| (0,1,0) |
| + |
| / \ |
| (0,1,0) O. .O |
| + / + \ |
| / \ O. / \ .O |
| O. .O / O. .O \ |
| / + \ / / + \ \ |
| O. / \ .O / / / \ \ \ |
| / O. .O \ O. / / \ \ .O |
| / / O \ \ / O. / \ .O \ |
| O. / . \ .O / / O-------O \ \ |
| / O----O----O \ O. / . . \ .O |
| / . . . \ / O----O-------O----O \ |
| O----O----O----O----O / . . . . \ |
| (0,0,1) (1,0,0) O----O----O-------O----O----O |
| (0,0,1) (1,0,0) |
| |
| Figure X.2, Inner Triangle Tessellation with inner tessellation levels |
| of four and five (not to scale). This figure depicts the vertices along |
| the bottom edge of the concentric triangles. The edges of inner |
| triangles are subdivided by intersecting the edge with segments |
| perpendicular to the edge passing through each inner vertex of the |
| subdivided outer edge. |
| |
| Once all the concentric triangles are produced and their edges are |
| subdivided, the area between each pair of adjacent inner triangles is |
| filled completely with a set of non-overlapping triangles. In this |
| subdivision, two of the three vertices of each triangle are taken from |
| adjacent vertices on a subdivided edge of one triangle; the third is one |
| of the vertices on the corresponding edge of the other triangle. If the |
| innermost triangle is degenerate (i.e., a point), the triangle containing |
| it is subdivided into six triangles by connecting each of the six vertices |
| on that triangle with the center point. If the innermost triangle is not |
| degenerate, that triangle is added to the set of generated triangles |
| as-is. |
| |
| After the area corresponding to any inner triangles is filled, the |
| primitive generator generates triangles to cover area between the |
| outermost triangle and the outermost inner triangle. To do this, the |
| temporary subdivision of the outer triangle edge above is discarded. |
| Instead, the u==0, v==0, and w==0 edges are subdivided according to the |
| first, second, and third outer tessellation levels, respectively, and the |
| tessellation spacing. The original subdivision of the first inner |
| triangle is retained. The area between the outer and first inner |
| triangles is completely filled by non-overlapping triangles as described |
| above. If the first (and only) inner triangle is degenerate, a set of |
| triangles is produced by connecting each vertex on the outer triangle |
| edges with the center point. |
| |
| After all triangles are generated, each vertex in the subdivided triangle |
| is assigned a barycentric (u,v,w) coordinate based on its location |
| relative to the three vertices of the outer triangle. |
| |
| The algorithm used to subdivide the triangular domain in (u,v,w) space |
| into individual triangles is implementation-dependent. However, the set |
| of triangles produced will completely cover the domain, and no portion of |
| the domain will be covered by multiple triangles. The order in which the |
| generated triangles passed to subsequent pipeline stages and the order of |
| the vertices in those triangles are both implementation-dependent. |
| However, when depicted in a manner similar to Figure X.2, the order of the |
| vertices in the generated triangles will be either all clockwise or all |
| counter-clockwise, according to the vertex order layout declaration. |
| |
| |
| Section 2.X.2.2, Quad Tessellation |
| |
| If the tessellation primitive mode is "quads", a rectangle is subdivided |
| into a collection of triangles covering the area of the original |
| rectangle. First, the original rectangle is subdivided into a regular |
| mesh of rectangles, where the number of rectangles along the u==0 and u==1 |
| (vertical) and v==0 and v==1 (horizontal) edges are derived from the first |
| and second inner tessellation levels, respectively. All rectangles, |
| except those adjacent to one of the outer rectangle edges, are decomposed |
| into triangle pairs. The outermost rectangle edges are subdivided |
| independently, using the first, second, third, and fourth outer |
| tessellation levels to control the number of subdivisions of the u==0 |
| (left), v==0 (bottom), u==1 (right), and v==1 (top) edges, respectively. |
| The area between the inner rectangles of the mesh and the outer rectangle |
| edges are filled by triangles produced by joining the vertices on the |
| subdivided outer edges to the vertices on the edge of the inner rectangle |
| mesh. |
| |
| If both clamped inner tessellation levels and all four clamped outer |
| tessellation levels are exactly one, only a single triangle pair covering |
| the outer rectangle is generated. Otherwise, if either clamped inner |
| tessellation level is one, that tessellation level is treated as though it |
| were originally specified as 1+epsilon and will result in a two- or |
| three-segment subdivision depending on the tessellation spacing. When |
| used with fractional odd spacing, the three-segment subdivision may |
| produce "inner" vertices positioned on the edge of the rectangle. |
| |
| If any tessellation level is greater than one, tessellation begins by |
| subdividing the u==0 and u==1 edges of the outer rectangle into <m> |
| segments using the clamped and rounded first inner tessellation level and |
| the tessellation spacing. The v==0 and v==1 edges are subdivided into <n> |
| segments using using the second inner tessellation level. Each vertex on |
| the u==0 and v==0 edges are joined with the corresponding vertex on the |
| u==1 and v==1 edges to produce a set of vertical and horizontal lines that |
| divide the rectangle into a grid of smaller rectangles. The primitive |
| generator emits a pair of non-overlapping triangles covering each such |
| rectangle not adjacent to an edge of the outer rectangle. The boundary of |
| the region covered by these triangles forms an inner rectangle, the edges |
| of which are subdivided by the grid vertices that lie on the edge. If |
| either <m> or <n> is two, the inner rectangle is degenerate, and one or |
| both of the rectangle's "edges" consist of a single point. This |
| subdivision is illustrated in Figure X.3. |
| |
| (0,1) (1,1) |
| +--+--+--+--+--+--+--+ |
| | . . . . . . | |
| (0,1) (1,1) | . . . . . . | |
| +--+--+--+--+ +..O--O--O--O--O--O..+ |
| | . . . | | |**|**|**|**|**| | |
| | . . . | | |**|**|**|**|**| | |
| +..O--O--O..+ +..O--+--+--+--+--O..+ |
| | . . . | | |**|**|**|**|**| | |
| | . . . | | |**|**|**|**|**| | |
| +--+--+--+--+ +..O--O--O--O--O--O..+ |
| (0,0) (1,0) | . . . . . . | |
| | . . . . . . | |
| +--+--+--+--+--+--+--+ |
| (0,0) (1,0) |
| |
| Figure X.3, Inner Quad Tessellation with inner tessellation levels of |
| (4,2) and (7,4). The areas labeled with "*" on the right depict the 10 |
| inner rectangles, each of which will be subdivided into two triangles. |
| The points labeled "O" depict vertices on the boundary of the inner |
| rectangle, where the inner rectangle on the left side is degenerate (a |
| single line segment). The dotted lines (".") depict the horizontal and |
| vertical edges connecting corresponding points on the outer rectangle |
| edge. |
| |
| After the area corresponding to the inner rectangle is filled, the |
| primitive generator must produce triangles to cover area between the inner |
| and outer rectangles. To do this, the subdivision of the outer rectangle |
| edge above is discarded. Instead, the u==0, v==0, u==1, and v==1 edges |
| are subdivided according to the first, second, third, and fourth outer |
| tessellation levels, respectively, and the tessellation spacing. The |
| original subdivision of the inner rectangle is retained. The area between |
| the outer and inner rectangles is completely filled by non-overlapping |
| triangles. Two of the three vertices of each triangle are adjacent |
| vertices on a subdivided edge of one rectangle; the third is one of the |
| vertices on the corresponding edge of the other rectangle. If either edge |
| of the innermost rectangle is degenerate, the area near the corresponding |
| outer edges is filled by connecting each vertex on the outer edge with the |
| single vertex making up the inner "edge". |
| |
| The algorithm used to subdivide the rectangular domain in (u,v) space into |
| individual triangles is implementation-dependent. However, the set of |
| triangles produced will completely cover the domain, and no portion of the |
| domain will be covered by multiple triangles. The order in which the |
| generated triangles passed to subsequent pipeline stages and the order of |
| the vertices in those triangles are both implementation-dependent. |
| However, when depicted in a manner similar to Figure X.3, the order of the |
| vertices in the generated triangles will be either all clockwise or all |
| counter-clockwise, according to the vertex order layout declaration. |
| |
| |
| Isoline Tessellation |
| |
| If the tessellation primitive mode is "isolines", a set of independent |
| horizontal line segments is drawn. The segments are arranged into |
| connected strips called "isolines", where the vertices of each isoline |
| have a constant v coordinate and u coordinates covering the full range |
| [0,1]. The number of isolines generated is derived from the first outer |
| tessellation level; the number of segments in each isoline is derived from |
| the second outer tessellation level. Both inner tessellation levels and |
| the third and fourth outer tessellation levels have no effect in this |
| mode. |
| |
| As with quad tessellation above, isoline tessellation begins with a |
| rectangle. The u==0 and u==1 edges of the rectangle are subdivided |
| according to the first outer tessellation level. For the purposes of this |
| subdivision, the tessellation spacing mode is ignored and treated as |
| equal_spacing. An isoline is drawn connecting each vertex on the u==0 |
| rectangle edge to the corresponding vertex on the u==1 rectangle edge, |
| except that no line is drawn between (0,1) and (1,1). If the number of |
| isolines on the subdivided u==0 and u==1 edges is <n>, this process will |
| result in <n> equally spaced lines with constant v coordinates of 0, |
| 1/<n>, 2/<n>, ..., and (<n>-1)/<n>. |
| |
| Each of the <n> isolines is then subdivided according to the second outer |
| tessellation level and the tessellation spacing, resulting in <m> line |
| segments. Each segment of each line is emitted by the tessellation |
| primitive generator, as illustrated in Figure X.4. |
| |
| (0,1) (1,1) |
| + + (0,1) (1,1) |
| + + |
| O---O---O---O---O---O---O |
| |
| O---O---O---O---O---O---O |
| |
| O---O---O---O---O---O---O |
| O-----O-----O-----O |
| O---O---O---O---O---O---O (0,0) (1,0) |
| (0,0) (1,0) |
| |
| Figure X.4, Isoline Tessellation with the first two outer tessellation |
| levels of (4,6) and (1,3), respectively. The lines connecting the |
| vertices labeled "O" are emitted by the primitive generator. The |
| vertices labeled "+" correspond to (u,v) coordinates of (0,1) and (1,1), |
| where no line segments are generated. |
| |
| The order in which the generated line segments are passed to subsequent |
| pipeline stages and the order of the vertices in each generated line |
| segment are both implementation-dependent. |
| |
| |
| Section 2.X.3, Tessellation Evaluation Shaders |
| |
| If active, the tessellation evaluation shader takes the (u,v) or (u,v,w) |
| location of each vertex in the primitive subdivided by the tessellation |
| primitive generator, and generates a vertex with a position and associated |
| attributes. The tessellation evaluation shader can read any of the |
| vertices of its input patch, which is the output patch produced by the |
| tessellation control shader (if present) or provided by the application |
| and transformed by the vertex shader (if no control shader is used). |
| Evaluating the bivariate polynomials described in Section 5.1 (Evaluators) |
| using the vertices of the provided patch as control points is one example |
| of the type of computations that a tessellation evaluation shader might be |
| expected to perform. Tessellation evaluation shaders are created as |
| described in section 2.14.1, using a <type> of TESS_EVALUATION_SHADER. |
| |
| Each invocation of the tessellation evaluation shader writes the |
| attributes of exactly one vertex. The number of vertices evaluated per |
| patch depends on the tessellation level values computed by the |
| tessellation control shaders (if present) or specified as patch |
| parameters. Tessellation evaluation shader invocations run independently, |
| and no invocation can access the variables belonging to another |
| invocation. All invocations are capable of accessing all the vertices of |
| their corresponding input patch. |
| |
| If a tessellation control shader is present, the number of the vertices in |
| the input patch is fixed and is equal to the tessellation control shader |
| output patch size parameter in effect when the program was last linked. |
| If no tessellation control shader is present, the input patch is provided |
| by the application can have a variable number of vertices, as specified by |
| the PatchParameteri function. |
| |
| |
| Section 2.X.3.1, Tessellation Evaluation Shader Variables |
| |
| Tessellation evaluation shaders can access uniforms belonging to the |
| current program object. The amount of storage available for uniform |
| variables in the default uniform block accessed by a tessellation |
| evaluation shader is specified by the value of the |
| implementation-dependent constant MAX_TESS_EVALUATION_UNIFORM_COMPONENTS. |
| The total amount of combined storage available for uniform variables in |
| all uniform blocks accessed by a tessellation evaluation shader (including |
| the default uniform block) is specified by the value of the |
| implementation-dependent constant |
| MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS. These values represent |
| the numbers of individual floating-point, integer, or boolean values that |
| can be held in uniform variable storage for a tessellation evaluation |
| shader. A link error is generated if an attempt is made to utilize more |
| than the space available for tessellation evaluation shader uniform |
| variables. Uniforms are manipulated as described in section 2.14.4. |
| Tessellation evaluation shaders also have access to samplers to perform |
| texturing operations, as described in sections 2.14.5. |
| |
| Tessellation evaluation shaders can access the transformed attributes of |
| all vertices for their input primitive using input variables. If active, |
| a tessellation control shader writing to output variables generates the |
| values of these input varying variables, including values for built-in as |
| well as user-defined varying variables. If no tessellation control shader |
| is active, input variables will be obtained from vertex shader outputs. |
| Values for any varying variables that are not written by a vertex or |
| tessellation control shader are undefined. |
| |
| Additionally, tessellation evaluation shaders can write to one or more |
| built-in or user-defined output variables that will be passed to |
| subsequent programmable shader stages or fixed functionality vertex |
| pipeline stages. |
| |
| |
| Section 2.X.3.2, Tessellation Evaluation Shader Execution Environment |
| |
| If a successfully linked program object that contains a tessellation |
| evaluation shader is made current by calling UseProgram, the executable |
| version of the tessellation evaluation shader is used to process vertices |
| produced by the tessellation primitive generator. During this processing, |
| the shader may access the input patch processed by the primitive |
| generator. When tessellation evaluation shader execution completes, a new |
| vertex is assembled from the output variables written by the shader and is |
| passed to subsequent pipeline stages. |
| |
| There are several special considerations for tessellation evaluation |
| shader execution described in the following sections. |
| |
| Texture Access |
| |
| The Shader-Only Texturing subsection of section 2.14.7 describes texture |
| lookup functionality accessible to a vertex shader. The texel fetch and |
| texture size query functionality described there also applies to |
| tessellation evaluation shaders. |
| |
| Tessellation Evaluation Shader Inputs |
| |
| Section 7.1 of the OpenGL Shading Language Specification describes the |
| built-in variable array gl_in[] available as input to a tessellation |
| evaluation shader. gl_in[] receives values from equivalent built-in |
| output variables written by a previous shader (section 2.14.7). If a |
| tessellation control shader active, the values of gl_in[] will be taken |
| from tessellation control shader outputs. Otherwise, they will be taken |
| from vertex shader outputs. Each array element of gl_in[] is a structure |
| holding values for a specific vertex of the input patch. The length of |
| gl_in[] is equal to the implementation-dependent maximum patch size |
| (gl_MaxPatchVertices). Behavior is undefined if gl_in[] is indexed with a |
| vertex index greater than or equal to the current patch size. The members |
| of each element of the gl_in[] array are gl_Position, gl_PointSize, |
| gl_ClipDistance[], gl_ClipVertex, gl_FrontColor, gl_BackColor, |
| gl_FrontSecondaryColor, gl_BackSecondaryColor, gl_TexCoord[], and |
| gl_FogFragCoord[]. |
| |
| Tessellation evaluation shaders have available several other special input |
| variables not replicated per-vertex and not contained in gl_in[], |
| including: |
| |
| * The variables gl_PatchVerticesIn and gl_PrimitiveID are filled with |
| the number of the vertices in the input patch and a primitive number, |
| respectively. They behave exactly as the identically named inputs for |
| tessellation control shaders. |
| |
| * The variable gl_TessCoord is a three-component floating-point vector |
| consisting of the (u,v,w) coordinate of the vertex being processed by |
| the tessellation evaluation shader. The values of u, v, and w are in |
| the range [0,1], and vary linearly across the primitive being |
| subdivided. For tessellation primitive modes of "quads" or |
| "isolines", the w value is always zero. The (u,v,w) coordinates are |
| generated by the tessellation primitive generator in a manner |
| dependent on the primitive mode, as described in section 2.X.2. |
| gl_TessCoord is not an array; it specifies the location of the vertex |
| being processed by the tessellation evaluation shader, not of any |
| vertex in the input patch. |
| |
| * The variables gl_TessLevelOuter[] and gl_TessLevelInner[] are arrays |
| holding outer and inner tessellation levels of the patch, as used by |
| the tessellation primitive generator. If a tessellation control |
| shader is active, the tessellation levels will be taken from the |
| corresponding outputs of the tessellation control shader. Otherwise, |
| the default levels provided as patch parameters are used. |
| Tessellation level values loaded in these variables will be prior to |
| the clamping and rounding operations performed by the primitive |
| generator as described in Section 2.X.2. For triangular tessellation, |
| gl_TessLevelOuter[3] and gl_TessLevelInner[1] will be undefined. For |
| isoline tessellation, gl_TessLevelOuter[2], gl_TessLevelOuter[3], and |
| both values in gl_TessLevelInner[] are undefined. |
| |
| A tessellation evaluation shader may also declare user-defined per-vertex |
| input variables. User-defined per-vertex input variables are declared |
| with the qualifier "in" and have a value for each vertex in the input |
| patch. User-defined per-vertex input varying variables have a value for |
| each vertex and thus need to be declared as arrays or inside input blocks |
| declared as arrays. Declaring an array size is optional. If no size is |
| specified, it will be taken from the implementation-dependent maximum |
| patch size (gl_MaxPatchVertices). If a size is specified, it must match |
| the maximum patch size; otherwise, a compile or link error will occur. Since the |
| array size may be larger than the number of vertices found in the input |
| patch, behavior is undefined if a per-vertex input variable is accessed |
| using an index greater than or equal to the number of vertices in the |
| input patch. The OpenGL Shading Language doesn't support |
| multi-dimensional arrays; therefore, user-defined tessellation evaluation |
| shader inputs corresponding to vertex shader outputs declared as arrays |
| must be declared as array members of an input block that is itself |
| declared as an array. |
| |
| Additionally, a tessellation evaluation shader may declare per-patch input |
| variables using the qualifier "patch in". Unlike per-vertex inputs, |
| per-patch inputs do not correspond to any specific vertex in the patch, |
| and are not indexed by vertex number. Per-patch inputs declared as arrays |
| have multiple values for the input patch; similarly declared per-vertex |
| inputs would indicate a single value for each vertex in the output patch. |
| User-defined per-patch input variables are filled with corresponding |
| per-patch output values written by the tessellation control shader. If no |
| tessellation control shader is active, all such variables are undefined. |
| |
| (Note: minor restructuring in the following paragraph relative to the |
| equivalent geometry shader language.) |
| |
| Similarly to the limit on vertex shader output components (see section |
| 2.14.6), there is a limit on the number of components of built-in and |
| user-defined per-vertex and per-patch input variables that can be read by |
| the tessellation evaluation shader, given by the values of the |
| implementation-dependent constants MAX_TESS_EVALUATION_INPUT_COMPONENTS |
| and MAX_TESS_PATCH_COMPONENTS, respectively. The built-in inputs |
| gl_TessLevelOuter[] and gl_TessLevelInner[] are not counted against the |
| per-patch limit. When a program is linked, all components of any varying |
| and special variable read by a tessellation evaluation shader will count |
| against this limit. A program whose tessellation evaluation shader |
| exceeds this limit may fail to link, unless device-dependent optimizations |
| are able to make the program fit within available hardware resources. |
| |
| |
| Tessellation Evaluation Shader Outputs |
| |
| Tessellation evaluation shaders have a number of built-in output variables |
| used to pass values to equivalent built-in input variables read by |
| subsequent shader stages or to subsequent fixed functionality vertex |
| processing pipeline stages. These variables are gl_Position, |
| gl_PointSize, gl_ClipDistance[], gl_ClipVertex, gl_FrontColor, |
| gl_BackColor, gl_FrontSecondaryColor, gl_BackSecondaryColor, |
| gl_TexCoord[], and gl_FogFragCoord[], and all behave identically to |
| equivalently named vertex shader outputs (section 2.14.7). A tessellation |
| evaluation shader may also declare user-defined per-vertex output |
| variables. |
| |
| (Note: minor restructuring in the following paragraph relative to the |
| equivalent geometry shader language.) |
| |
| Similarly to the limit on vertex shader output components (see section |
| 2.14.6), there is a limit on the number of components of built-in and |
| user-defined output variables that can be written by the tessellation |
| evaluation shader, given by the values of the implementation-dependent |
| constant MAX_TESS_EVALUATION_OUTPUT_COMPONENTS. When a program is linked, |
| all components of any varying and special variable written by a |
| tessellation evaluation shader will count against this limit. A program |
| whose tessellation evaluation shader exceeds this limit may fail to link, |
| unless device-dependent optimizations are able to make the program fit |
| within available hardware resources. |
| |
| |
| Modify Section 2.19, Transform Feedback, p. 130 |
| |
| (modify fourth paragraph, p. 131) When transform feedback is active, all |
| geometric primitives generated must be compatible with the value of |
| <primitiveMode> ... If a tessellation evaluation or geometry shader is |
| active, the type of primitive emitted by that shader is used instead of |
| the <mode> parameter passed to drawing commands. If tessellation |
| evaluation and geometry shaders are both active, the output primitive type |
| of the geometry shader will be used for the purposes of this error. |
| |
| |
| Additions to Chapter 3 of the OpenGL 3.2 (Compatibility Profile) Specification (Rasterization) |
| |
| None. |
| |
| |
| Additions to Chapter 4 of the OpenGL 3.2 (Compatibility Profile) Specification (Per-Fragment |
| Operations and the Frame Buffer) |
| |
| None. |
| |
| |
| Additions to Chapter 5 of the OpenGL 3.2 (Compatibility Profile) Specification (Special Functions) |
| |
| None. |
| |
| |
| Additions to Chapter 6 of the OpenGL 3.2 (Compatibility Profile) Specification (State and State |
| Requests) |
| |
| Modify Section 6.1.16, Shader and Program Queries, p. 384 |
| |
| (modify second paragraph, p. 385) If <pname> is SHADER TYPE, VERTEX |
| SHADER, TESS_CONTROL_SHADER, TESS_EVALUATION_SHADER, GEOMETRY_SHADER, or |
| FRAGMENT_SHADER is returned if <shader> is a vertex, tessellation control, |
| tessellation evaluation, geometry, or fragment shader, respectively. ... |
| |
| (modify the next-to-last paragraph, p. 385) The command |
| |
| void GetProgramiv(uint program, enum pname, int *params); |
| |
| returns integer-valued properties of the program object... |
| |
| (add two paragraphs after the first paragraph, p. 385) |
| |
| If <pname> is TESS_CONTROL_OUTPUT_VERTICES, the number of vertices in the |
| tessellation control shader output patch is returned. If |
| TESS_CONTROL_OUTPUT_VERTICES is queried for a program which has not been |
| linked successfully, or which does not contain objects to form a |
| tessellation control shader, then an INVALID_OPERATION error is generated. |
| |
| If <pname> is TESS_GEN_MODE, QUADS, TRIANGLES, or ISOLINES is returned, |
| depending on the primitive mode declaration in the tessellation evaluation |
| shader. If <pname> is TESS_GEN_SPACING, EQUAL, FRACTIONAL_EVEN, or |
| FRACTIONAL_ODD is returned, depending on the spacing declaration in the |
| tessellation evaluation shader. If <pname> is TESS_GEN_VERTEX_ORDER, CCW |
| or CW is returned, depending on the vertex order declaration in the |
| tessellation evaluation shader. If <pname> is TESS_GEN_POINT_MODE, TRUE |
| is returned if point mode is enabled in a tessellation evaluation shader |
| declaration; FALSE is returned otherwise. If any of the <pname> values in |
| this paragraph are queried for a program which has not been linked |
| successfully, or which does not contain objects to form a tessellation |
| evaluation shader, then an INVALID_OPERATION error is generated. |
| |
| |
| Additions to Appendix A of the OpenGL 3.2 (Compatibility Profile) Specification (Invariance) |
| |
| Insert new section before Section A.4, What this All Means (p. 457) |
| |
| Section A.X, Tessellation Invariance |
| |
| When using a program containing tessellation evaluation shaders, the |
| fixed-function tessellation primitive generator consumes the input patch |
| specified by an application and emits a new set of primitives. The |
| following invariance rules are intended to provide repeatability |
| guarantees. Additionally, they are intended to allow an application with |
| a carefully crafted tessellation evaluation shader to ensure that the sets |
| of triangles generated for two adjacent patches have identical vertices |
| along shared patch edges, avoiding "cracks" caused by minor differences in |
| the positions of vertices along shared edges. |
| |
| Rule 1: When processing two patches with identical outer and inner |
| tessellation levels, the tessellation primitive generator will emit an |
| identical set of point, line, or triangle primitives as long as the active |
| program used to process the patch primitives has tessellation evaluation |
| shaders specifying the same tessellation mode, spacing, vertex order, and |
| point mode input layout qualifiers. Two sets of primitives are considered |
| identical if and only if they contain the same number and type of |
| primitives and the generated tessellation coordinates for the vertex |
| numbered <m> of the primitive numbered <n> are identical for all values of |
| <m> and <n>. |
| |
| Rule 2: The set of vertices generated along the outer edge of the |
| subdivided primitive in triangle and quad tessellation, and the |
| tessellation coordinates of each, depends only on the corresponding outer |
| tessellation level and the spacing input layout qualifier in the |
| tessellation evaluation shader of the active program. |
| |
| Rule 3: The set of vertices generated when subdividing any outer |
| primitive edge is always symmetric. For triangle tessellation, if the |
| subdivision generates a vertex with tessellation coordinates of the form |
| (0,x,1-x), (x,0,1-x), or (x,1-x,0), it will also generate a vertex with |
| coordinates of exactly (0,1-x,x), (1-x,0,x), or (1-x,x,0), respectively. |
| For quad tessellation, if the subdivision generates a vertex with |
| coordinates of (x,0) or (0,x), it will also generate a vertex with |
| coordinates of exactly (1-x,0) or (0,1-x), respectively. For isoline |
| tessellation, if it generates vertices at (0,x) and (1,x) where <x> is |
| not zero, it will also generate vertices at exactly (0,1-x) and (1,1-x), |
| respectively. |
| |
| Rule 4: The set of vertices generated when subdividing outer edges in |
| triangular and quad tessellation must be independent of the specific edge |
| subdivided, given identical outer tessellation levels and spacing. For |
| example, if vertices at (x,1-x,0) and (1-x,x,0) are generated when |
| subdividing the w==0 edge in triangular tessellation, vertices must be |
| generated at (x,0,1-x) and (1-x,0,x) when subdividing an otherwise |
| identical v==0 edge. For quad tessellation, if vertices at (x,0) and |
| (1-x,0) are generated when subdividing the v==0 edge, vertices must be |
| generated at (0,x) and (0,1-x) when subdividing an otherwise identical |
| u==0 edge. |
| |
| Rule 5: When processing two patches that are identical in all respects |
| enumerated in rule 1 except for vertex order, the set of triangles |
| generated for triangle and quad tessellation must be identical except for |
| vertex and triangle order. For each triangle <n1> produced by processing |
| the first patch, there must be a triangle <n2> produced when processing |
| the second patch each of whose vertices has the same tessellation |
| coordinates as one of the vertices in <n1>. |
| |
| Rule 6: When processing two patches that are identical in all respects |
| enumerated in rule 1 other than matching outer tessellation levels and/or |
| vertex order, the set of interior triangles generated for triangle and |
| quad tessellation must be identical in all respects except for vertex and |
| triangle order. For each interior triangle <n1> produced by processing |
| the first patch, there must be a triangle <n2> produced when processing |
| the second patch each of whose vertices has the same tessellation |
| coordinates as one of the vertices in <n1>. A triangle produced by the |
| tessellator is considered an interior triangle if none of its vertices lie |
| on an outer edge of the subdivided primitive. |
| |
| Rule 7: For quad and triangle tessellation, the set of triangles |
| connecting an inner and outer edge depends only on the inner and outer |
| tessellation levels corresponding to that edge and the spacing input |
| layout qualifier. |
| |
| Rule 8: The value of all defined components of gl_TessCoord will be in |
| the range [0,1]. Additionally, for any defined component <x> of |
| gl_TessCoord, the results of computing (1.0-<x>) in a tessellation |
| evaluation shader will be exact. Some floating-point values in the range |
| [0,1] may fail to satisfy this property, but such values may never be used |
| as tessellation coordinate components. |
| |
| |
| Additions to the AGL/GLX/WGL Specifications |
| |
| None. |
| |
| |
| Additions to the OpenGL Shading Language Specification, version 1.50 (Revision |
| 09) |
| |
| Including the following line in a shader can be used to control the |
| language features described in this extension: |
| |
| #extension GL_ARB_tessellation_shader : <behavior> |
| |
| where <behavior> is as specified in section 3.3. |
| |
| A new preprocessor #define is added to the OpenGL Shading Language: |
| |
| #define GL_ARB_tessellation_shader 1 |
| |
| |
| Modify Chapter 2, Overview of OpenGL Shading, p. 5 |
| |
| (modify first two introductory paragraphs) |
| |
| The OpenGL Shading Language is actually several closely related languages. |
| These languages are used to create shaders for the programmable processors |
| contained in the OpenGL processing pipeline. Currently, these processors |
| are the vertex, tessellation control, tessellation evaluation, geometry, |
| and fragment processors. |
| |
| Unless otherwise noted in this paper, a language feature applies to all |
| languages, and common usage will refer to these languages as a single |
| language. The specific languages will be referred to by the name of the |
| processor they target: vertex, tessellation control, tessellation |
| evalution, geometry, or fragment. |
| |
| (Insert two new sections after Section 2.1, Vertex Processor, p. 5.) |
| |
| |
| Section 2.X, Tessellation Control Processor |
| |
| The tessellation control processor is a programmable unit that operates on |
| a patch of incoming vertices and their associated data, emitting a new |
| output patch. Compilation units written in the OpenGL Shading Language to |
| run on this processor are called tessellation control shaders. When a |
| complete set of tessellation control shaders are compiled and linked, they |
| result in a tessellation control shader executable that runs on the |
| tessellation control processor. |
| |
| The tessellation control processor spawns a separate shader invocation for |
| each vertex of the output patch. Each invocation can read the attributes |
| of any vertex in the input or output patches, but can only write |
| per-vertex attributes for the corresponding output patch vertex. The |
| shader invocations collectively produce a set of per-patch attributes for |
| the output patch. After all tessellation control shader invocations have |
| completed, the output vertices and per-patch attributes are assembled to |
| form a patch to be used by subsequent pipeline stages. |
| |
| Tessellation control shader invocations run mostly independently, with |
| undefined relative execution order. However, the built-in function |
| barrier() can be used to control execution order by synchronizing |
| invocations, effectively dividing tessellation control shader execution |
| into a set of phases. Tessellation control shaders will get undefined |
| results if one invocation reads a per-vertex or per-patch attribute |
| written by another invocation at any point during the same phase, or if |
| two invocations attempt to write different values to the same per-patch |
| output in a single phase. |
| |
| |
| Section 2.Y, Tessellation Evaluation Processor |
| |
| The tessellation evaluation processor is a programmable unit that |
| evaluates the position and other attributes of a vertex generated by the |
| tessellation primitive generator, using a patch of incoming vertices and |
| their associated data. Compilation units written in the OpenGL Shading |
| Language to run on this processor are called tessellation evaluation |
| shaders. When a complete set of tessellation evaluation shaders are |
| compiled and linked, they result in a tessellation evaluation shader |
| executable that runs on the tessellation evaluation processor. |
| |
| The tessellation evaluation processor operates to compute the position and |
| attributes of a single vertex generated by the tessellation primitive |
| generator. The executable can read the attributes of any vertex in the |
| input patch, plus the tessellation coordinate, which is the relative |
| location of the vertex in the primitive being tessellated. The executable |
| writes the position and other attributes of the vertex. |
| |
| |
| Modify Section 3.6, Keywords, p. 14 |
| |
| (add the following to the keyword list) |
| |
| patch |
| |
| |
| Modify Section 4.2, Scoping, p. 27 |
| |
| (remove "(vertex, geometry, or fragment)" from the last paragraph of p. 28) |
| |
| |
| Modify Section 4.3, Storage Qualifiers, p. 29 |
| |
| (add two new qualifiers to the first table, p. 29) |
| |
| Qualifier Meaning |
| --------- ------------------------------------------------------------- |
| patch in linkage of per-patch attributes into a shader from a previous |
| stage (tessellation evaluation shaders only) |
| |
| patch out linkage out of a shader to a subsequent stage (tessellation |
| control shaders only) |
| |
| |
| Modify Section 4.3.4, Inputs, p. 31 |
| |
| (modify second paragraph, p. 31) Shader input variables are declared with |
| the "in", "centroid in", or "patch in" storage qualifiers. They form the |
| input interface between previous stages of the OpenGL pipeline and the |
| declaring shader. ... |
| |
| (modify third paragraph, p. 31) Vertex shader input variables (or |
| attributes) ... It is an error to use "centroid in" or "patch in" in a |
| vertex shader. ... |
| |
| (modify next-to-last paragraph, p. 31, and subsequent paragraphs, making |
| geometry shader language apply to tessellation control and evaluation |
| shaders as well) |
| |
| Tessellation control, evaluation, and geometry shader input variables get |
| the per-vertex values written out to output variables of the same names in |
| the previous active shader stage. They are typically declared with the |
| "in" or "centroid in" storage qualifier. For these inputs, "centroid in" |
| and interpolation qualifiers are allowed, but have no effect. Since |
| tessellation control, tessellation evaluation, and geometry shaders |
| operate on a primitive comprising multiple vertices, each input varying |
| variable (or input block, see interface blocks below) needs to be declared |
| as an array. For example, |
| |
| in float foo[]; // input for previous-stage output "out float foo" |
| |
| Each element of such an array corresponds to one vertex of the primitive |
| being processed. Each array can optionally have a size declared. The array |
| size will be set by, (or if provided must be consistent with) the input |
| layout declaration(s) establishing the type of input primitive, as |
| described later in section 4.3.8.1 Input Layout Qualifiers. |
| |
| For the interface from a previous shader stage to a tessellation control, |
| tessellation evaluation, or geometry shader, output variables from the |
| previous stage must match input variables of the same name in type and |
| qualification, except perhaps that the inputs must be declared as an array |
| indexed by vertex number. If any variables fail to match, a link error |
| will occur. |
| |
| If the output of the previous shader is itself an array with multiple |
| values per vertex, it must appear in an output block (see interface blocks |
| below) in the previous shader and in an input block in the tessellation |
| control, evaluation, or geometry shader with a block instance name |
| declared as an array. Use of blocks are required because two-dimensional |
| arrays are not supported. |
| |
| Additionally, tessellation evaluation shaders support per-patch input |
| variables declared with the "patch in" qualifier. Per-patch input |
| variables are filled with the values of per-patch output variables written |
| by the tessellation control shader. Per-patch inputs may be declared as |
| one-dimensional arrays, but are not indexed by vertex number. Input |
| variables may not be declared using the "patch in" qualifier in |
| tessellation control or geometry shaders. As with other input variables, |
| per-patch inputs must be declared using the same type and qualifiers as |
| per-patch outputs from the previous (tessellation control) shader stage. |
| |
| (modify third paragraph, p. 32) Fragment shader ... deprecated "varying" |
| and "centroid varying" modifiers. It is an error to use "patch in" in a |
| fragment shader. ... |
| |
| (modify last paragraph of the section) The fragment shader inputs form an |
| interface with the last active shader in the vertex processing pipeline. |
| For this interface, the prior stage shader output variables and fragment |
| shader input variables of the same name must match in type and |
| qualification (other than out matching to in). |
| |
| |
| Modify Section 4.3.6, Outputs, p. 33 |
| |
| (modify first paragraph of the section, p. 33) Shader output variables are |
| declared with the "out", "centroid out", or "patch out" storage |
| qualifiers. ... |
| |
| (modify third paragraph of the section, p. 33) Vertex, tessellation |
| evaluation, and geometry shader output variables output per-vertex data |
| ... deprecated varying storage qualifier. It is an error to use "patch |
| out" in a vertex, tessellation evaluation, or geometry shader. ... |
| |
| (modify the fourth paragraph of the section, p. 33) Individual vertex, |
| tessellation evaluation, and geometry outputs are ... |
| |
| (insert prior to the last paragraph, p. 33) |
| |
| Tessellation control shader output variables may be used to output |
| per-vertex and per-patch data. Per-vertex output variables are declared |
| using the "out" or "centroid out" storage qualifiers; per-patch output |
| variables are declared using the "patch out" storage qualifier. |
| Per-vertex and per-patch output variables can only be float, |
| floating-point vectors, matrices, signed or unsigned integers or integer |
| vectors, or arrays or structures of any these. Since tessellation control |
| shaders produce a primitive comprising multiple vertices, each per-vertex |
| output variable (or output block, see interface blocks below) needs to be |
| declared as an array. For example, |
| |
| out float foo[]; // feeds next-stage input "in float foo[]" |
| |
| Each element of such an array corresponds to one vertex of the primitive |
| being produced. Each array can optionally have a size declared. The |
| array size will be set by (or if provided must be consistent with) the |
| output layout declaration(s) establishing the number of vertices in the |
| output patch, as described later in section 4.3.8.2, Output Layout |
| Qualifiers. |
| |
| If a per-vertex output of the tessellation control shader is itself an |
| array with multiple values per vertex, it must appear in an output block |
| (see interface blocks below) in the tessellation control shader with a |
| block instance name declared as an array. Use of blocks are required |
| because two-dimensional arrays are not supported. |
| |
| Each tessellation control shader invocation has a corresponding output |
| patch vertex, and may assign values to per-vertex outputs only if they |
| belong to that corresponding vertex. If a per-vertex output variable is |
| used as an l-value, it is an error if the expression indicating the vertex |
| number is not the identifier "gl_InvocationID". |
| |
| The order of execution of a tessellation control shader invocation |
| relative to the other invocations for the same input patch is undefined |
| unless the built-in function barrier() is used. This provides some |
| control over relative execution order. When a shader invocation calls the |
| barrier() function, its execution pauses until all other invocations have |
| called the same function. Output variable assignments performed by any |
| invocation executed prior to calling barrier() will be visible to any |
| other invocation after the call to barrier() returns. |
| |
| Because tessellation control shader invocations may execute in undefined |
| order between barriers, the values of per-vertex or per-patch output |
| variables will sometimes be undefined. If the beginning and end of shader |
| execution and each call to barrier() are considered synchronization |
| points, the value of an output variable will be undefined in any of the |
| three following cases: |
| |
| (1) at the beginning of execution; |
| |
| (2) at each synchronization point, unless: |
| |
| * the value was well-defined after the previous synchronization |
| point and was not written by any invocation since; |
| |
| * the value was written by exactly one shader invocation since the |
| previous synchronization point; or |
| |
| * the value was written by multiple shader invocations since the |
| previous synchronization point, and the last write performed by |
| all such invocations wrote the same value; or |
| |
| (3) when read by a shader invocation, if: |
| |
| * the value was undefined at the previous synchronization point and |
| has not been writen by the same shader invocation since; or |
| |
| * the output variable is written to by any other shader invocation |
| between the previous and next synchronization points, even if that |
| assignment occurs in code following the read. |
| |
| If the value of an output variable is undefined at the end of shader |
| execution, the value passed to subsequent pipeline stages will be likewise |
| undefined. |
| |
| |
| (modify last paragraph, p. 33) Fragment outputs ... "out" storage |
| qualifier. It is an error to use "centroid out" or "patch out" in a |
| fragment shader. ... |
| |
| |
| Modify Section 4.3.8.1, Input Layout Qualifiers, p. 37 |
| |
| (modify first paragraph of the section) Vertex and tessellation control |
| shaders do not have any input layout qualifiers. |
| |
| (insert after first paragraph of the section) |
| |
| Tessellation evaluation shaders allow input layout qualifiers only on the |
| interface qualifier in, not on an input block, block member, or variable |
| declarations. The input layout qualifier identifiers allowed for |
| tessellation evaluation shaders are: |
| |
| layout-qualifier-id |
| triangles |
| quads |
| isolines |
| equal_spacing |
| fractional_even_spacing |
| fractional_odd_spacing |
| cw |
| ccw |
| point_mode |
| |
| One group of identifiers is used to specify a tessellation primitive mode |
| to be used by the tessellation primitive generator. To specify a |
| primitive mode, the identifier must be one of "triangles", "quads", or |
| "isolines", which specify that the tessellation primitive generator should |
| subdivide a triangle into smaller triangles, a quad into triangles, or a |
| quad into a collection of lines, respectively. |
| |
| A second group of identifiers is used to specify the vertex spacing used |
| by the tessellation primitive generator when subdividing an edge. To |
| specify vertex spacing, the identifier must be one of: |
| |
| * "equal_spacing", signifying that edges should be divided into a |
| collection of <N> equal-sized segments; |
| |
| * "fractional_even_spacing", signifying that edges should be divided |
| into an even number of equal-length segments plus two additional |
| shorter "fractional" segments; or |
| |
| * "fractional_odd_spacing", signifying that edges should be divided into |
| an odd number of equal-length segments plus two additional shorter |
| "fractional" segments. |
| |
| A third group of identifiers specifies whether the tessellation primitive |
| generator produces triangles in clockwise or counter-clockwise order, |
| according to the coordinate system depicted in the OpenGL specification. |
| The identifiers "cw" and "ccw" indicate clockwise and counter-clockwise |
| triangles, respectively. If the tessellation primitive generator does not |
| produce triangles, the order is ignored. |
| |
| The identifier "point_mode" specifies that the tessellation primitive |
| generator should produce one point for each distinct vertex in the |
| subdivided primitive, rather than generating lines or triangles. |
| |
| Any or all of these identifiers may be specified one or more times in a |
| single input layout declaration. |
| |
| At least one tessellation evaluation shader (compilation unit) in a |
| program must declare a primitive mode in its input layout; declarations |
| spacing, vertex order, and point mode qualifiers are optional. It is not |
| required that all tessellation evaluation shaders in a program declare a |
| primitive mode. If spacing or vertex order declarations are omitted, the |
| tessellation primitive generator will use equal spacing or |
| counter-clockwise vertex ordering, respectively. If a point mode |
| declaration is omitted, the tessellation primitive generator will produce |
| lines or triangles according to the primitive mode. If primitive mode, |
| spacing, or vertex order is declared more than once in the tessellation |
| evaluation shaders of a program, all such declarations must use the same |
| identifier. |
| |
| (modify third paragraph, p. 38) All unsized tessellation control and |
| evaluation shader input array declations will be sized to match the |
| implementation-dependent maximum patch size (gl_MaxPatchVertices). All |
| unsized geometry shader input declarations ... |
| |
| (modify fourth paragraph, p. 38) The intrinsically declared input array |
| gl_in[] will also be sized according to the maximum patch size or a |
| geometry shader input layout declaration. Hence, the expression |
| |
| gl_in.length() |
| |
| will return the maximum patch size or a value from the table above. |
| |
| |
| Modify Section 4.3.8.2, Output Layout Qualifiers, p. 40 |
| |
| (modify first paragraph, p. 40) Vertex, tessellation evaluation, and |
| fragment shaders cannot have output layout qualifiers. |
| |
| (insert after first paragraph of the section) |
| |
| Tessellation control shaders allow output layout qualifiers only on the |
| interface qualifier out, not on an output block, block member, or variable |
| declarations. The output layout qualifier identifiers allowed for |
| tessellation control shaders are: |
| |
| layout-qualifier-id |
| vertices = integer-constant |
| |
| The identifier "vertices" specifies the number of vertices in the output |
| patch produced by the tessellation control shader, which also specifies |
| the number of times the tessellation control shader is invoked. It is an |
| error for the output vertex count to be less than or equal to zero, or |
| greater than the implementation-dependent maximum patch size. |
| |
| The intrinsically declared tessellation control output array gl_out[] will |
| also be sized by any output layout declaration. Hence, the expression |
| |
| gl_out.length() |
| |
| will return the output patch vertex count specified in a previous output |
| layout qualifier. For outputs declared without an array size, including |
| intrinsically declared outputs (i.e., gl_out), a layout must be declared |
| before any use of the method length() or other array use that requires its |
| size to be known. |
| |
| It is a compile-time error if the output patch vertex count specified in |
| an output layout qualifier does not match the array size specified in any |
| output variable declaration in the same shader. |
| |
| All tessellation control shader layout declarations in a program must |
| specify the same output patch vertex count. There must be at least one |
| layout qualifier specifying an output patch vertex count in any program |
| containing tessellation control shaders; however, such a declaration is |
| not required in all tessellation control shader compilation units. |
| |
| |
| (Coalesce Sections 7.1., 7.2, and 7.6 into a single section, as described |
| below.) |
| |
| Section 7.1, Built-In Shader Special Inputs and Outputs |
| |
| 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 |
| shaders, through the use of built-in input and output variables. |
| |
| |
| In the vertex language, built-in input and output variables are |
| intrinsically declared as: |
| |
| in int gl_VertexID; |
| in int gl_InstanceID; |
| |
| out gl_PerVertex { |
| vec4 gl_Position; |
| float gl_PointSize; |
| float gl_ClipDistance[]; |
| }; |
| |
| The variable gl_VertexID is a vertex shader input variable that holds an |
| integer index for the vertex, as defined under Shader Inputs in section |
| 2.11.7 in the OpenGL Graphics System Specification. While the variable |
| gl_VertexID is always present, its value is not always defined. |
| |
| The variable gl_InstanceID is a vertex shader input variable that holds |
| the integer index of the current primitive in an instanced draw call (see |
| Shader Inputs in section 2.11.7 in the OpenGL Graphics System |
| Specification). If the current primitive does not come from an instanced |
| draw call, the value of gl_InstanceID is zero. |
| |
| 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 primitive assembly, clipping, culling, and other |
| fixed functionality operations, if present, that operate on primitives |
| after vertex processing has occurred. Its value is undefined after the |
| vertex processing stage if the vertex shader executable does not write |
| gl_Position, and it is undefined after geometry processing if the geometry |
| executable calls EmitVertex() without having written gl_Position since the |
| last EmitVertex() (or hasn't written it at all). |
| |
| The variable gl_PointSize is intended for a shader to write the size of |
| the point to be rasterized. It is measured in pixels. If gl_PointSize is |
| not written to, its value is undefined in subsequent pipe stages. |
| |
| (note: Changed the wording of this a bit from 1.50, to remove the mention |
| of maintaining clip planes and computing distances, which isn't required |
| to use the feature. Also tweaked a reference to gl_MaxVaryingComponents |
| in the following paragraph.) |
| |
| The variable gl_ClipDistance provides the forward compatible mechanism for |
| controlling user clipping. gl_ClipDistance[i] specifies a clip distance |
| for each plane i. A distance of 0 means the vertex is on the plane, a |
| positive distance means the vertex is inside the clip plane, and a |
| negative distance means the point is outside the clip plane. The clip |
| distances will be linearly interpolated across the primitive and the |
| portion of the primitive with interpolated distances less than 0 will be |
| clipped. |
| |
| The gl_ClipDistance array is predeclared as unsized and must be sized by |
| the shader either redeclaring it with a size or indexing it only with |
| integral constant expressions. This needs to size the array to include all |
| the clip planes that are enabled via the OpenGL API; if the size does not |
| include all enabled planes, results are undefined. The size can be at most |
| gl_MaxClipDistances. The number of input or output components consumed by |
| gl_ClipDistance will match the size of the array, no matter how many |
| planes are enabled. The shader must also set all values in gl_ClipDistance |
| that have been enabled via the OpenGL API, or results are |
| undefined. Values written into gl_ClipDistance for planes that are not |
| enabled have no effect. |
| |
| |
| In the tessellation control language, built-in input and output variables |
| are intrinsically declared as: |
| |
| in gl_PerVertex { |
| vec4 gl_Position; |
| float gl_PointSize; |
| float gl_ClipDistance[]; |
| } gl_in[gl_MaxPatchVertices]; |
| in int gl_PatchVerticesIn; |
| in int gl_PrimitiveID; |
| in int gl_InvocationID; |
| |
| out gl_PerVertex { |
| vec4 gl_Position; |
| float gl_PointSize; |
| float gl_ClipDistance[]; |
| } gl_out[gl_VerticesOut]; |
| |
| patch out float gl_TessLevelOuter[4]; |
| patch out float gl_TessLevelInner[2]; |
| |
| The input variables gl_Position, gl_PointSize, and gl_ClipDistance read |
| corresponding outputs written by the vertex shader. The output variables |
| of the same names behave as described for the identical vertex shader |
| outputs. |
| |
| The variable gl_PatchVerticesIn is available only in the tessellation |
| control and evaluation languages. It is an integer specifying the number |
| of vertices in the input patch being processed by the shader. A single |
| tessellation control or evaluation shader can read patches of differening |
| sizes, so the value of gl_PatchVerticesIn may differ between patches. |
| |
| The input variable gl_PrimitiveID is available only in the tessellation |
| control, tessellation evaluation, and fragment languages. For |
| tessellation control and evaluation shaders, it is filled with the number |
| of primitives processed by the shader since the current set of rendering |
| primitives was started. For fragment shaders, it is filled with the value |
| written to the gl_PrimitiveID geometry shader output if a geometry shader |
| is present. Otherwise, it is assigned in the same manner as with |
| tessellation control and evaluation shaders. |
| |
| The input variable gl_InvocationID is available only in the tessellation |
| control and geometry language. In the tessellation control shader, it |
| identifies the number of the output patch vertex assigned to the |
| tessellation control shader invocation. In the geometry shader, it |
| identifies the invocation number assigned to the geometry shader |
| invocation. In both cases, gl_InvocationID is assigned integer values in |
| the range [0, <N>-1], where <N> is the number of output patch vertices or |
| geometry shader invocations per primitive. |
| |
| The output variables gl_TessLevelOuter[] and gl_TessLevelInner[] are |
| available only in the tessellation control language. The values written |
| to these variables are assigned to the corresponding outer and inner |
| tessellation levels of the output patch. They are used by the |
| tessellation primitive generator to control primitive tessellation and may |
| be read by tessellation evaluation shaders. |
| |
| |
| In the tessellation evaluation language, built-in input and output |
| variables are intrinsically declared as: |
| |
| in gl_PerVertex { |
| vec4 gl_Position; |
| float gl_PointSize; |
| float gl_ClipDistance[]; |
| } gl_in[gl_MaxPatchVertices]; |
| in int gl_PatchVerticesIn; |
| in int gl_PrimitiveID; |
| in vec3 gl_TessCoord; |
| patch in float gl_TessLevelOuter[4]; |
| patch in float gl_TessLevelInner[2]; |
| |
| out gl_PerVertex { |
| vec4 gl_Position; |
| float gl_PointSize; |
| float gl_ClipDistance[]; |
| }; |
| |
| The input variables gl_Position, gl_PointSize, gl_ClipDistance read |
| corresponding outputs written by the previous shader (vertex or |
| tessellation control). The output variables of the same names behave as |
| described for the identical vertex shader outputs. |
| |
| The input variables gl_PatchVerticesIn and gl_PrimitiveID behave as in the |
| identically-named tessellation control shader inputs. |
| |
| The variable gl_TessCoord is available only in the tessellation evaluation |
| language. It specifies a three-component (u,v,w) vector identifying the |
| position of the vertex being processed by the shader relative to the |
| primitive being tessellated. |
| |
| The input variables gl_TessLevelOuter[] and gl_TessLevelInner[] are |
| available only in the tessellation evaluation shader. If a tessellation |
| control shader is active, these variables are filled with corresponding |
| outputs written by the tessellation control shader. Otherwise, they are |
| assigned with default tessellation levels specified in the OpenGL API. |
| |
| |
| In the geometry language, built-in input and output variables are |
| intrinsically declared as: |
| |
| in gl_PerVertex { |
| vec4 gl_Position; |
| float gl_PointSize; |
| float gl_ClipDistance[]; |
| } gl_in[]; |
| in int gl_PrimitiveIDIn; |
| |
| out gl_PerVertex { |
| vec4 gl_Position; |
| float gl_PointSize; |
| float gl_ClipDistance[]; |
| }; |
| out int gl_PrimitiveID; |
| out int gl_Layer; |
| |
| The input variables gl_Position, gl_PointSize, gl_ClipDistance read |
| corresponding outputs written by the previous shader (vertex or |
| tessellation control). The output variables of the same names behave as |
| described for the identical vertex shader outputs. |
| |
| The input variable gl_PrimitiveIDIn behaves identically to the |
| tessellation control and evaluation shader input variable gl_PrimitiveID. |
| |
| The output variable gl_PrimitiveID is available only in the geometry |
| language and provides a single integer that serves as a primitive |
| identifier. This is then available to fragment shaders as the fragment |
| input gl_PrimitiveID, which will select the written primitive ID from the |
| provoking vertex in the primitive being shaded. If a fragment shader using |
| gl_PrimitiveID is active and a geometry shader is also active, the |
| geometry shader must write to gl_PrimitiveID or the fragment shader input |
| gl_PrimitiveID is undefined. See section 2.12.4 (under Geometry Shader |
| Outputs) and section 3.9.2 (under Shader Inputs) of the OpenGL Graphics |
| System Specification for more information. |
| |
| The output variable gl_Layer is available only in the geometry language, |
| and is used to select a specific layer of a multi-layer framebuffer |
| attachment. The actual layer used will come from one of vertices in the |
| primitive being shaded. Which vertex the layer comes from is undefined, so |
| it is best to write the same layer value for all vertices of a |
| primitive. If a shader statically assigns a value to gl_Layer, layered |
| rendering mode is enabled. See section 2.12.4 (under Geometry Shader |
| Outputs) and section 4.4.7 Layered Framebuffers of the OpenGL Graphics |
| System Specification for more information. If a shader statically assigns |
| a value to gl_Layer, and there is an execution path through the shader |
| that does not set gl_Layer, then the value of gl_Layer is undefined for |
| executions of the shader that take that path. |
| |
| |
| In the fragment language, built-in input and output variables are |
| intrinsically declared as: |
| |
| in vec4 gl_FragCoord; |
| in bool gl_FrontFacing; |
| in float gl_ClipDistance[]; |
| in vec2 gl_PointCoord; |
| in int gl_PrimitiveID; |
| |
| out vec4 gl_FragColor; // deprecated |
| out vec4 gl_FragData[gl_MaxDrawBuffers]; // deprecated |
| out float gl_FragDepth; |
| |
| (copy the variable descriptions verbatim from Section 7.2) |
| |
| |
| Section 7.1.1, Compatibility Profile Built-In Shader Special Variables |
| |
| When using the compatibility profile, the GL can provide fixed |
| functionality behavior for the vertex and fragment programmable pipeline |
| stages. For example, mixing a fixed functionality vertex stage with a |
| programmable fragment stage. |
| |
| The following built-in vertex, tessellation control, tessellation |
| evaluation, and geometry output variables are available to specify inputs |
| for the subsequent programmable shader stage or the fixed functionality |
| fragment stage. A particular one should be written to if any |
| functionality in a corresponding shader or fixed pipeline uses it or state |
| derived from it. Otherwise, behavior is undefined. The following members |
| are added to the output gl_PerVertex block in these languages: |
| |
| out gl_PerVertex { |
| // in addition to other gl_PerVertex members... |
| vec4 gl_ClipVertex; |
| vec4 gl_FrontColor; |
| vec4 gl_BackColor; |
| vec4 gl_FrontSecondaryColor; |
| vec4 gl_BackSecondaryColor; |
| vec4 gl_TexCoord[]; |
| float gl_FogFragCoord; |
| }; |
| |
| The variable gl_ClipVertex provides a place for vertex and geometry |
| shaders to write the coordinate to be used with the user clipping planes. |
| |
| The user must ensure the clip vertex and user clipping planes are defined |
| in the same coordinate space. User clip planes work properly only under |
| linear transform. It is undefined what happens under nonlinear transform. |
| |
| If a linked set of shaders forming a program contains no static write to |
| gl_ClipVertex or gl_ClipDistance, but the application has requested |
| clipping against user clip planes through the API, then the coordinate |
| written to gl_Position is used for comparison against the user clip |
| planes. Writing to gl_ClipDistance is the preferred method for user |
| clipping. It is an error for the set of shaders forming a program to |
| statically read or write both gl_ClipVertex and gl_ClipDistance. |
| |
| gl_FrontColor, glFrontSecondaryColor, gl_BackColor, and |
| glBackSecondaryColor assigns primary and secondary colors for front and |
| back faces of primitives containing the vertex being processed. |
| gl_TexCoord assigns texture coordinates for the vertex being processed. |
| |
| For gl_FogFragCoord, the value written will be used as the "c" value in |
| section 3.11 of the OpenGL Graphics System Specification, by the fixed |
| functionality pipeline. For example, if the z-coordinate of the fragment |
| in eye space is desired as "c", then that's what the vertex shader |
| executable should write into gl_FogFragCoord. |
| |
| As with all arrays, indices used to subscript gl_TexCoord must either be |
| an integral constant expressions, or this array must be re-declared by the |
| shader with a size. The size can be at most gl_MaxTextureCoords. Using |
| indexes close to 0 may aid the implementation in preserving varying |
| resources. |
| |
| In the tessellation control, evaluation, and geometry shaders, the outputs |
| of the previous stage described above are also available in the input |
| gl_PerVertex block in these languages. |
| |
| in gl_PerVertex { |
| // in addition to other gl_PerVertex members... |
| vec4 gl_ClipVertex; |
| vec4 gl_FrontColor; |
| vec4 gl_BackColor; |
| vec4 gl_FrontSecondaryColor; |
| vec4 gl_BackSecondaryColor; |
| vec4 gl_TexCoord[]; |
| float gl_FogFragCoord; |
| } gl_in[]; |
| |
| The following fragment inputs are also available in a fragment shader when |
| using the compatibility profile: |
| |
| in vec4 gl_Color; |
| in vec4 gl_SecondaryColor; |
| in vec4 gl_TexCoord[]; |
| in float gl_FogFragCoord; |
| |
| The values in gl_Color and gl_SecondaryColor will be derived automatically |
| by the system from gl_FrontColor, gl_BackColor, gl_FrontSecondaryColor, |
| and gl_BackSecondaryColor based on which face is visible in the primitive |
| producing the fragment. If fixed functionality is used for vertex |
| processing, then gl_FogFragCoord will either be the z-coordinate of the |
| fragment in eye space, or the interpolation of the fog coordinate, as |
| described in section 3.11 of the OpenGL Graphics System Specification. The |
| gl_TexCoord[] values are the interpolated gl_TexCoord[] values from a |
| vertex shader or the texture coordinates of any fixed pipeline based |
| vertex functionality. |
| |
| Indices to the fragment shader gl_TexCoord array are as described above in |
| the vertex shader text. |
| |
| |
| Modify Section 7.4, Built-In Constants, p. 74 |
| |
| (add to the list of constants at the bottom of p. 74) |
| |
| const int gl_MaxTessControlInputComponents = 128; |
| const int gl_MaxTessControlOutputComponents = 128; |
| const int gl_MaxTessControlTextureImageUnits = 16; |
| const int gl_MaxTessControlUniformComponents = 1024; |
| const int gl_MaxTessControlTotalOutputComponents = 4096; |
| |
| const int gl_MaxTessEvaluationInputComponents = 128; |
| const int gl_MaxTessEvaluationOutputComponents = 128; |
| const int gl_MaxTessEvaluationTextureImageUnits = 16; |
| const int gl_MaxTessEvaluationUniformComponents = 1024; |
| |
| const int gl_MaxTessPatchComponents = 120; |
| |
| const int gl_MaxPatchVertices = 32; |
| const int gl_MaxTessGenLevel = 64; |
| |
| (modify the minimum value for one other constant) |
| |
| const int gl_MaxCombinedTextureImageUnits = 80; |
| |
| |
| Modify Section 8.7, Texture Lookup Functions, p. 90 |
| |
| (modify first paragraph, accounting for all the new shader types) Texture |
| lookup functions are available to all shaders. However, automatic level |
| of detail computations are only performed for fragment shaders; other |
| shaders operate as though the base level of detail were computed as zero. |
| The functions in the table below ... |
| |
| (modify first paragraph, p. 91) In all functions below, the bias parameter |
| is optional for fragment shaders. The bias parameter is not accepted in |
| any other shader type. For ... |
| |
| (Also, make miscellaneous modifications elsewhere in the spec to account |
| for the fact that vertex and fragment shaders are not the only two |
| supported shader types.) |
| |
| |
| Insert a new section after Section 8.10, Geometry Shader Functions, |
| p. 103. |
| |
| Section 8.X, Shader Invocation Control Functions |
| |
| Shader invocation control functions are available only in tessellation |
| control shaders. These functions are used to control the relative |
| execution order of the multiple shader invocations used to process a |
| patch, which are otherwise executed with an undefined relative order. |
| |
| The function barrier() provides a partially defined order of execution |
| between shader invocations. This ensures that values written by one |
| invocation prior to the call to barrier() can be safely read by other |
| invocations after the call to barrier(). Because invocations may execute |
| in undefined order between barriers, the values of a per-vertex or |
| per-patch output variable will be undefined in a number of cases |
| enumerated in Section 4.3.6. |
| |
| The barrier() function may only be called inside the main entry point of |
| the tessellation control shader and may not be called within any control |
| flow. Barriers are also disallowed after a return statement in function |
| main(). |
| |
| Syntax Description |
| ------------- -------------------------------------------------- |
| void barrier(void) For any given static instance of barrier(), all |
| tessellation control shader invocations for a single |
| input patch must enter it before any will be allowed |
| to continue beyond it. |
| |
| Modify Section 9, Shading Language Grammar, p. 105 |
| |
| !!! TBD |
| |
| |
| GLX Protocol |
| |
| None. |
| |
| |
| Errors |
| |
| The error INVALID_VALUE is generated by PatchParameteri if <pname> is |
| PATCH_VERTICES and <value> is less than or equal to zero or is greater |
| than the implementation-dependent maximum patch size. |
| |
| The error INVALID_OPERATION is generated by Begin (or vertex array |
| commands that implicitly call Begin) if the active program contains a |
| tessellation control or evaluation shader and the primitive mode is not |
| PATCHES. |
| |
| The error INVALID_OPERATION is generated by Begin (or vertex array |
| commands that implicitly call Begin) if the primitive mode is PATCHES if |
| either: |
| |
| * the active program contains no tessellation evaluation shader, or |
| * no program is active. |
| |
| The error INVALID_OPERATION is generated by GetProgramiv if <pname> |
| identifies a tessellation control or evaluation shader-specific property |
| and <program> has not been linked successfully, or does not contain |
| objects to form a shader whose type corresponds to <pname>. |
| |
| |
| Dependencies on OpenGL 3.2 (Core Profile) |
| |
| If only the core profile of OpenGL 3.2 is supported, references to |
| functionality deprecated by OpenGL 3.0 (built-in input/output variables |
| corresponding to fixed-function vertex attributes, glBegin, fixed-function |
| vertex processing) should be removed and/or replaced with functionality |
| supported in the core profile. In such an environment, the PATCHES |
| primitive type is not supported by the deleted Begin() function but will |
| still be supported by vertex array draw calls such as DrawArrays() and |
| DrawElements(). |
| |
| Dependencies on ARB_gpu_shader5 |
| |
| If ARB_gpu_shader5 is not supported, references to the input variable |
| gl_InvocationID in the geometry shader language should be deleted. This |
| spec references gl_InvocationID in order to provide a complete set of |
| language for implementations supporting GLSL 1.50 and both extensions. |
| |
| Dependencies on ARB_gpu_shader_fp64 |
| |
| If ARB_gpu_shader_fp64 is supported, discussion of the maximum number of |
| input, output, and uniform components supported by the implementation for |
| tessellation control and evaluation shaders should note each |
| double-precision floating-point value is counted as two components. |
| |
| Dependencies on NV_gpu_shader5 |
| |
| If NV_gpu_shader5 is supported, discussion of the maximum number of input, |
| output, and uniform components supported by the implementation for |
| tessellation control and evaluation shaders should note each 64-bit |
| integer value is counted as two components. |
| |
| Dependencies on NV_primitive_restart |
| |
| If primitive restart is enabled, sending a vertex with the restart index |
| will start a new patch at the beginning. Any vertices specified prior to |
| the restart index that form a partial patch will be discarded. |
| |
| New State |
| |
| Add the following state to Table 6.5, Current Values and Associated Data, |
| p. 343 |
| |
| Default |
| Get Value Type Get Command Value Description Sec. Attr. |
| ------------------------ ---- -------------- --------- ------------------------ ------ ------- |
| PATCH_VERTICES Z+ GetIntegerv 3 Number of vertices in 2.6.1 current |
| input patch |
| PATCH_DEFAULT_OUTER_ 4xR GetFloatv 4 x 1.0 Default outer tessellation 2.X.2 - |
| LEVEL level w/o control shader |
| PATCH_DEFAULT_INNER_ 2xR GetFloatv 2 x 1.0 Default outer tessellation 2.X.2 - |
| LEVEL level w/o control shader |
| |
| Add the following state to Table 6.40, Program Object State, p. 378 |
| |
| Default |
| Get Value Type Get Command Value Description Sec. Attr. |
| ------------------------ ---- -------------- --------- ------------------------ ------ ----- |
| TESS_CONTROL_OUTPUT_ Z+ GetProgramiv 0 Output patch size 2.X.1 - |
| VERTICES for tess. control shader |
| TESS_GEN_MODE Z+ GetProgramiv QUADS Base primitive type for 2.X.2 - |
| tess. prim. generator |
| TESS_GEN_SPACING Z+ GetProgramiv EQUAL Spacing of tess. prim. 2.X.2 - |
| generator edge subdivision |
| TESS_GEN_VERTEX_ORDER Z+ GetProgramiv CCW Order of vertices in 2.X.2 - |
| primitives generated by |
| tess. prim generator |
| TESS_GEN_POINT_MODE Z+ GetProgramiv FALSE Tess prim. generator 2.X.2 - |
| emits points? |
| UNIFORM_BLOCK_REF- B GetActive- 0 True if uniform block is |
| ERENCED_BY_TESS_ UniformBlockiv actively referenced by 2.14.4 - |
| CONTROL_SHADER tess. control stage |
| UNIFORM_BLOCK_REF- B GetActive- 0 True if uniform block is 2.14.4 - |
| ERENCED_BY_TESS_ UniformBlockiv actively referenced by |
| EVALUTION_SHADER tess evaluation stage |
| |
| New Implementation Dependent State |
| |
| Minimum |
| Get Value Type Get Command Value Description Sec. |
| ------------------------- ---- ----------- ------- -------------------------- ------ |
| MAX_TESS_GEN_LEVEL Z+ GetIntegerv 64 maximum tessellation level 2.X.2 |
| supported by tessellation |
| primitive generator |
| MAX_PATCH_VERTICES Z+ GetIntegerv 32 maximum patch size 2.6.1 |
| MAX_TESS_CONTROL_ Z+ GetIntegerv 1024 number of words for tess. 2.X.1.1 |
| UNIFORM_COMPONENTS control shader uniforms |
| MAX_TESS_EVALUATION_ Z+ GetIntegerv 1024 number of words for tess. 2.X.3.1 |
| UNIFORM_COMPONENTS evaluation shader uniforms |
| MAX_TESS_CONTROL_TEXTURE_ Z+ GetIntegerv 16 number of tex. image units 2.14.7 |
| IMAGE_UNITS for tess. control shaders |
| MAX_TESS_EVALUATION_ Z+ GetIntegerv 16 number of tex. image units 2.14.7 |
| TEXTURE_IMAGE_UNITS for tess. eval. shaders |
| MAX_TESS_CONTROL_ Z+ GetIntegerv 128 num. components for per- 2.X.1.2 |
| OUTPUT_COMPONENTS vertex outputs in tess. |
| control shaders |
| MAX_TESS_PATCH_ Z+ GetIntegerv 120 num. components for per- 2.X.1.2 |
| COMPONENTS patch output varyings |
| for tess. control shaders |
| MAX_TESS_CONTROL_TOTAL_ Z+ GetIntegerv 4096 Total num components for 2.X.1.2 |
| OUTPUT_COMPONENTS tess. control shader |
| outputs |
| MAX_TESS_EVALUATION_ Z+ GetIntegerv 128 num. components for per- 2.X.3.2 |
| OUTPUT_COMPONENTS vertex outputs in tess. |
| evaluation shaders |
| MAX_TESS_CONTROL_ Z+ GetIntegerv 128 num. components for per- 2.X.1.2 |
| INPUT_COMPONENTS vertex inputs in tess. |
| control shaders |
| MAX_TESS_EVALUATION_ Z+ GetIntegerv 128 num. components for per- 2.X.3.2 |
| INPUT_COMPONENTS vertex inputs in tess. |
| evaluation shaders |
| MAX_TESS_CONTROL_ Z+ GetIntegerv 12 num. of supported uniform 2.14.4 |
| UNIFORM_BLOCKS blocks for tess. control |
| shaders |
| MAX_TESS_EVALUATION_ Z+ GetIntegerv 12 num. of supported uniform 2.14.4 |
| UNIFORM_BLOCKS blocks for tess. evaluation |
| shaders |
| MAX_COMBINED_TESS_ Z+ GetIntegerv * number of words for tess. 2.X.1.1 |
| CONTROL_UNIFORM_ control uniform variables |
| COMPONENTS in all uniform blocks |
| (including default) |
| MAX_COMBINED_TESS_ Z+ GetIntegerv * number of words for tess. 2.X.3.1 |
| EVALUATION_UNIFORM_ evaluation uniform vari- |
| COMPONENTS ables in all uniform |
| blocks (including default) |
| |
| The minimum values for MAX_COMBINED_*_UNIFORM_COMPONENTS by computing the |
| value of: |
| |
| MAX_*_UNIFORM_COMPONENTS + MAX_*_UNIFORM_BLOCKS * (MAX_UNIFORM_BLOCK_SIZE/4) |
| |
| using the minimum values of the corresponding terms. |
| |
| Also, increase the minimum for MAX_COMBINED_UNIFORM_BLOCKS to 60 (12 |
| blocks per stage, five stages) and MAX_COMBINED_TEXTURE_IMAGE_UNITS to 80 |
| (16 image units per stage, five stages). |
| |
| |
| Issues |
| |
| (1) How does tessellation fit into the existing GL pipeline? |
| |
| RESOLVED: The following diagram illustrates how tessellation shaders |
| fit into the "vertex processing" portion of the GL (Chapter 2 of the |
| OpenGL 3.2 Specification). |
| |
| First, vertex attributes are specified via immediate-mode commands or |
| through vertex arrays. They can be conventional attributes (e.g., |
| glVertex, glColor, glTexCoord) or generic (numbered) attributes. |
| |
| Vertices are then transformed, either using a vertex shader or |
| fixed-function vertex processing. Fixed-function vertex processing |
| includes position transformation (modelview and projection matrices), |
| lighting, texture coordinate generation, and other calculations. The |
| results of either method are a "transformed vertex", which has a |
| position (in clip coordinates), front and back colors, texture |
| coordinates, generic attributes (vertex shader only), and so on. Note |
| that on many current GL implementations, vertex processing is performed |
| by executing a "fixed function vertex shader" generated by the driver. |
| |
| After vertex transformation, vertices are assembled into primitives, |
| according to the topology (e.g., TRIANGLES, QUAD_STRIP) provided by the |
| call to glBegin(). Primitives are points, lines, triangles, quads, |
| polygons, lines or triangles with adjacency, or patches. Many GL |
| implementations do not directly support quads or polygons, but instead |
| decompose them into triangles as permitted by the spec. |
| |
| After initial primitive assembly, patch primitives are processed by the |
| tessellation control shader, if present. The tessellation control |
| shader reads the vertices of the incoming patch and generates a new |
| patch, consisting of a set of vertices and per-patch data. The |
| tessellation control shader runs with multiple invocations, one per |
| vertex in the output patch. Each invocation computes the properties of |
| its own vertex; the invocations collectively compute any per-patch data. |
| The vertices and per-patch data are then assembled into a new patch |
| primitive. |
| |
| If a tessellation evaluation shader is present, the tessellation |
| primitive generator and the tessellation evaluation shader will convert |
| an incoming patch into a new set of point, line, or triangle primitives. |
| The tessellation primitive generator uses the per-patch tessellation |
| levels and output layout qualifiers to appropriately subdivide a |
| triangle or quadrilateral into point, line, or triangle primitives. For |
| each vertex in the subdivided surface, the tessellation evaluation |
| shader is run to compute its position and other attributes, given a |
| (u,v) or (u,v,w) location within the subdivided primitive, the vertices |
| of the patch, and any per-patch data produced by the tessellation |
| control shader. The results are assembled into primitives for |
| processing by subsequent stages. |
| |
| After vertex transformation and tessellation, a geometry shader is |
| executed on each individual point, line, triangle, or patch primitive, |
| if one is active. It can read the attributes of each transformed vertex |
| in the primitive, perform arbitrary computations, and emit new |
| transformed vertices. These emitted vertices are themselves assembled |
| into primitives according to the output primitive type of the geometry |
| shader. |
| |
| Then, the colors of the vertices of each primitive are clamped to [0,1] |
| (if color clamping is enabled), and flat shading may be performed by |
| taking the color from the provoking vertex of the primitive. |
| |
| Each primitive is clipped to the view volume, and to any enabled |
| user-defined clip planes. Color, texture coordinate, and other |
| attribute values are computed for each new vertex introduced by |
| clipping. |
| |
| After clipping, the position of each vertex (in clip coordinates) is |
| converted to normalized device coordinates in the perspective division |
| (divide by w) step, and to window coordinates in the viewport |
| transformation step. |
| |
| At the same time, color values may be converted to normalized |
| fixed-point values according to the "Final Color Processing" portion of |
| the specification. |
| |
| After the vertices of the primitive are transformed to window |
| coordinate, the GL determines if the primitive is front- or back-facing. |
| That information is used for two-sided color selection, where a single |
| set of colors is selected from either the front or back colors |
| associated with each transformed vertex. |
| |
| When all this is done, the final transformed position, colors (primary |
| and secondary), and other attributes are used for rasterization (Chapter |
| 3 in the OpenGL 2.0 Specification). |
| |
| When the raster position is specified (via glRasterPos), it goes through |
| the entire vertex processing pipeline as though it were a point. |
| However, tessellation and geometry shaders are never run on the raster |
| position. |
| |
| |
| |generic |conventional |
| |vertex |vertex |
| |attributes |attributes |
| | | |
| | +-------------------+ |
| | | | |
| V V V |
| vertex fixed-function |
| shader vertex |
| | processing |
| | | |
| | | |
| +<-------------------+ |
| | |
| |position, color, |
| |other vertex data |
| | |
| V |
| Begin/ primitive patch tessellation (control point, |
| End -----> assembly -----------> control parallel patch, |
| State | shaders final patch) |
| | | | |
| | vertices| |per-patch |
| | | |data |
| | | | |
| | | | |
| V patch V V |
| +<------------- primitive |
| | assembly |
| | |
| | patch |
| +-------+-+---------------+ output |
| | | | |tess layout |
| | vert-| |per-patch |levels qualifiers |
| | ices | |data | | |
| | | | V | |
| | | | (u,v,w) tessellation | |
| | | | +------ primitive <--------+ |
| | | | | generator |
| | V V V | |
| | tessellation | |
| | evaluation |connectivity |
| | shader | |
| | | V |
| | +--------> primitive |
| | vertex assembly |
| V | |
| +<-------------------------+ |
| | Output |
| |position, color, Primitive |
| |other vertex data Type |
| | | |
| | geometry primitive | |
| +----------> shader ------> assembly <-+ |
| | | |
| V | |
| +<------------------------------+ |
| | |
| | |
| | color flat |
| +----------> clamping -----> shading |
| | | |
| V | |
| +<------------------------------+ |
| | |
| clipping |
| | perspective viewport |
| +------> divide ----> transform |
| | | |
| | +---+-----+ |
| | V | |
| | final facing | |
| +------> color determination | |
| | processing | | |
| | | | | |
| | | | | |
| | +-----+ +----+ | |
| | | | | |
| | V V | |
| | two-sided | |
| | coloring | |
| | | | |
| | | | |
| +------------------+ | +-------------+ |
| | | | |
| V V V |
| rasterization |
| | |
| | |
| V |
| |
| (2) Should we introduce new "patch" primitive types, or should |
| tessellation be allowed to operate on patches assembled from a point |
| list or other primitive types? |
| |
| RESOLVED: Provide new patch primitives. |
| |
| (3) Unlike other primitive types, patches don't have a definite number of |
| vertices. How should the number of vertices in a patch be specified? |
| |
| RESOLVED: Use a piece of "patch parameter" context state specified by |
| the PatchParameteri entry point to indicate a patch size. |
| |
| Several other options were considered, including creating a new set of |
| APIs to draw patches, having the input patch size be a (GLSL) program |
| parameter, or providing a separate "patch" enum for each supported patch |
| size (e.g., "PATCH16" for a 16-vertex patch). The new API was rejected |
| because the new calls may need to interact with a wide variety of vertex |
| APIs (e.g., multi-draw array calls, instancing, ranged element arrays); |
| a patch size parameter is orthogonal to all of these. Having a fixed |
| input patch size in a GLSL program may be fine in some cases. We expect |
| that some tessellation control shaders may want handle input patches |
| with a variable number of extraordinary vertices, which would be |
| incompatible with a fixed patch size in the program. Handling many |
| different "patch" enums in a frequently invoked draw calls didn't seem |
| to make sense, either. |
| |
| (4) Should we support "overlap" of patches -- strips where some points in |
| one patch are reused in neighboring ones? If so, how should the |
| overlap be specified? Using a separate GL call? Using a parameter in |
| the program specifying a strip? Using an overlap parameter that says |
| how many vertices from one patch are carried over to the next one? |
| Something else? |
| |
| RESOLVED: We will not support patch strips in this extension. Regular |
| strips of patches can be drawn efficiently using DrawElements and an |
| index buffer. |
| |
| (5) May patches be specified in immediate mode, and if so, how? |
| |
| RESOLVED: Yes; this support falls out of the API definition. Immediate |
| mode may be useful in the compatibility profile to allow Begin/End-based |
| applications to use tessellation without changing the way they specify |
| vertices. |
| |
| For the core profile, immediate mode is not supported for any primitive |
| type, including patches. |
| |
| (6) How are the vertices of patch primitives interpreted when compiled |
| into display lists (compatibility profile)? |
| |
| RESOLVED: During compilation, the vertices are simply stored into the |
| display list as-is. During execution, they are interpreted according to |
| the current patch size values specified by PatchParameteri. To |
| interpret patches according to values determined at display list compile |
| time, compile PatchParameteri calls to set the size and stride into the |
| display list. |
| |
| One downside of this choice is that making the interpretation of patch |
| vertices dependent on run-time state means that the display list |
| compiler may not be able to determine the number of vertices in a patch |
| primitive, and would be unable to perform any operations that require |
| knowing the patch structure. |
| |
| (7) What should these shaders be called? |
| |
| RESOLVED: The shader that converts an input patch to an output patch is |
| called a "tessellation control shader" (TCS). The use of "control" has |
| several connotations -- the vertices of the input and output patches are |
| often called "control points" and the tessellation levels computed are |
| used to control the tessellation primitive generator. The shader that |
| takes the (u,v,w) or (u,v) points generated by the tessellation |
| primitive generator are called tessellation evaluation shaders (TES), as |
| they evaluate the position and other attributes of all the vertices of |
| the tessellated primitive. |
| |
| Other options considered for TCS include "patch shaders" or "primitive |
| shaders". These choices seemed too general; the existing geometry |
| shaders are arguably already primitive shaders. The term "tessellation |
| shader" was also considered for TES, but that choice also seemed too |
| general -- TCS is strongly related to tessellation as well. |
| |
| Other APIs may refer to the tessellation control and evaluation shaders |
| as "hull shaders" and "domain shaders", respectively. |
| |
| (8) Should coupling of tessellation control and evaluation shaders be |
| required? |
| |
| RESOLVED: No. A tessellation control shader without an evaluation |
| shader might be used in conjunction with transform feedback to generate |
| regular transformed patches. Also, if the set of patches provided by |
| the application is already in a form usable by the tessellator, the |
| tessellation control shader may be bypassed. In this use case, the |
| application would be required to provide default tessellation levels via |
| the PatchParameterfv API, since no shader would be available to compute |
| them. |
| |
| It may be useful to have a patch produced by a tessellation control |
| shader to be fed directly to a geometry shader that performs some |
| operation on full patches, rather than individual triangles of a |
| tessellated patch. However, such capability is not provided in this |
| extension. |
| |
| (9) What measures are provided to ensure crack-free tessellation, where |
| the results of tessellating multiple adjacent meshes produce the same |
| vertices along the edges? |
| |
| RESOLVED: The most likely cause of cracking is due to shared patch |
| edges being subdivided differently. In order to get consistent |
| tessellation along shared edges, the tessellation control shaders (or |
| default levels) must be constructed so that outer tessellation level |
| corresponding to the shared edge must be exactly the same in both |
| patches. |
| |
| Hardware implementations should guarantee that the same set of vertices |
| is produced when subdividing a shared patch edge where the corresponding |
| outer tessellation level matches. Hardware implementations of this |
| extension should also guarantee that the (u,v,w) parameters generated |
| are complementary. Walking along a shared patch edge may take you from |
| a u/v/w coordinate of 0.0 to 1.0 in one patch, and from 1.0 to 0.0. In |
| this case, the u/v/w coordinates generated for any given vertex along |
| this edge should sum to *exactly* 1.0. |
| |
| Even with proper hardware support, tessellation evaluation shaders need |
| to be crafted carefully to avoid arithmetic errors caused by the order |
| of operations. For example, errors in floating-point math mean that |
| it's not always the case that: |
| |
| ((A + B) + C) + D = A + (B + (C + D)) |
| |
| An evaluation shader walking a shared edge in opposite directions |
| could easily run into errors such as this. |
| |
| The "precise" qualifier provided by the ARB_gpu_shader5 extension can be |
| used to reduce the risk of cracking due to compiler optimizations. |
| |
| The full details of how to guarantee crack-free tessellation are beyond |
| the scope of this specification. |
| |
| (10) Should we provide special built-ins or other mechanisms to assist in |
| crack-free tessellation or other common tessellation shader usages? |
| If so, what should be provided? |
| |
| RESOLVED: Options considered include: |
| |
| * a test if a vertex is at the edge of a patch (for some common patch |
| topologies); |
| |
| * a special directive to ensure that certain math operations requiring |
| precise results are not adversely affected by compiler optimizations |
| (e.g, reordering of operations, using asymmetric floating-point |
| multiply-add operations); |
| |
| * special "lerp" intrinsics to ensure exact results for |
| "complementary" weights; and |
| |
| * special built-ins for commonly used attribute evaluations (e.g., |
| linear, bicubic, and other polynomial evaluations) |
| |
| This extension doesn't provide any such mechanisms; however, the |
| "precise" qualifier in ARB_gpu_shader5 addresses the second issue. |
| |
| (11) Should we provide specific invariance guarantees to ensure crack-free |
| tessellation? If so, what would they be? |
| |
| RESOLVED: Formulating guarantees of this sort is difficult. The |
| "precise" qualifier can be used to guarantee that expressions are |
| evaluated in the manner specified in the shader code. |
| |
| (12) In what domain should position parameters for tessellation shaders be |
| provided? |
| |
| RESOLVED: We will provide tessellation coordinates in a standard [0,1] |
| parameterization. Two-dimensional (u,v) coordinates with components in |
| [0,1] is a standard parameterization; for example, it is what is used |
| for OpenGL evaluators. |
| |
| A [-1,+1] parameterization has some advantages; in particular, the |
| equivalent of "1-u" in this scheme is simply "-u". Floating-point |
| calculations involving these terms would result in values of identical |
| magnitude, but opposite sign. This advantage is not particularly |
| important if the [0,1] parameterization is computed in a way that |
| ensures that u+(1-u) == 1.0, with no floating-point rounding error. |
| |
| Three-dimensional barycentric coordinates are provided for triangular |
| patches, where each coordinate is a linear weight for one of the corners |
| of the subdivided primitive. Four-dimensional barycentric coordinates |
| may be useful quad patches, but can be computed easily enough by a |
| tessellation evaluation shader if required. |
| |
| (13) What type of patches are supported by the tessellation primitive |
| generator? |
| |
| RESOLVED: The primitive generator will subdivide triangular and |
| rectangular patches into triangles, and will also subdivide a |
| rectangular patch into line strips (called "isolines"). Triangular and |
| rectangular patches are useful for direct rendering of higher-order |
| surfaces; isolines are useful for a number of things, including |
| realistic hair rendering. |
| |
| Note that the notion of a patch in the tessellation API is simply an |
| ordered collection of vertices of a fixed size. There is no requirement |
| that the vertices of the patch be arranged in a triangular or |
| rectangular pattern at all. Even for "normal" patches, there is no |
| required vertex ordering. Applications should be careful that the |
| vertices of the patches they provide are ordered in the manner expected |
| by the tessellation shaders they use. |
| |
| (14) Should the tessellation control and evaluation shaders be provided in |
| a single compliation unit, or in multiple units? |
| |
| RESOLVED: Separate units. While tessellation control and evaluation |
| shaders might often be tightly coupled, they can exist separately. With |
| the current GLSL program object API, all shader types are linked |
| together into a single "program" unit, regardless. A future API may |
| allow decoupled shaders, in which case the tessellation control and |
| evaluation shaders may want to be packaged separately. |
| |
| (15) Should the tessellation control shader be provided in a single |
| compilation unit with a single entry point, a single compilation unit |
| with multiple entry points, or in multiple compilation units? |
| |
| RESOLVED: The extension packages the tessellation control shader into a |
| single entry point that is run once per output vertex. The barrier() |
| function is provided to divide the tessellation control shader into |
| execution phases that allow the separate threads to communicate via |
| shared output variables. |
| |
| We considered an approach that explicitly packages the different phases |
| of execution into separate functions. Such a shader might have a |
| "control point entrypoint" run independently in parallel and would be |
| responsible for computing per-vertex attributes for each control point |
| of the output patch. The shader might also have one or more "patch |
| entrypoints" run independently that would be responsible for per-patch |
| attributes. Restrictions on the capabilities might also be provided to |
| limit the communication between threads and entrypoints to specific |
| well-defined points. For example, the control point entrypoint might be |
| allowed to write per-vertex outputs, but could be forbidden to read |
| outputs written by other threads. Patch entrypoints could be guaranteed |
| to run after control point entrypoints, forbidden from writing |
| per-vertex outputs, and restricted to reading and writing disjoint |
| per-patch outputs. Because shader outputs are defined at global scope |
| in GLSL, enforcing such restrictions in a single shader executable would |
| be difficult. For example, the compiler might be required to forbid |
| calls to utility functions reading/writing global outputs in a specific |
| manner. Such a restriction might need to apply to a lengthy call chain |
| (i.e., an entrypoint calls function A, which calls function B, which |
| calls function C, which performs specific operations on an output). |
| |
| We also considered an approach with completely separate shader types in |
| separate compilation units. For example, we might provide separate |
| "tessellation control point shaders" and one or more types of |
| "tessellation control patch shaders". The linker would build a single |
| tessellation control executable from one or more of these shaders. The |
| languages for these different shader types could be constrained to |
| enforce restrictions. For example, tessellation control point shaders |
| could be forbidden from declaring per-patch outputs, and per-vertex |
| outputs would be non-arrays to prevent threads from reading the outputs |
| of other control point shaders. Per-vertex attributes of the output |
| patch could be declared as inputs to the tessellation control patch |
| shaders to forbid writes. |
| |
| Another option considered provided a single shader entry point called |
| once per patch and have an optimizing compiler extract the same sort of |
| parallel execution units provided by the explicitly parallel shader |
| model. However, we didn't want to depend on "compiler magic" to get |
| acceptable performance. |
| |
| (17) Tessellation control shaders have a shared output patch, where |
| individual threads can read and write these shared outputs. Should |
| we do anything to prevent multiple theads from reading and writing |
| the same output? If not, what should happen if they do? |
| |
| RESOLVED: We are currently enforcing no compile-time restrictions on |
| these cases. The built-in function barrier() can be used by the shader |
| writer to segregate shader execution into phases. No problems should |
| arise as long as no two threads access the same shared output in the |
| same phase. Reading outputs written by other threads would not be a |
| problem as long as the output was written in a previous phase. |
| |
| The relative execution order of the shader threads within a single phase |
| is undefined; a single phase may be run fully in parallel or fully |
| serially. If multiple threads write different values to the same output |
| in the same phase, the thread that "wins" is undefined -- and for |
| vectors, different components may have a different "winning thread". If |
| one thread reads an output written by another thread in the same phase, |
| the newly written value may or may not be available at the time the read |
| is executed. |
| |
| In some of the alternate programming models considered in the discussion |
| of the previous issue, it might be possible for the compiler to avoid |
| read/write and write/write hazards. For example, the compiler might |
| allow an output variable to be written by only a single entrypoint, and |
| could allow only those entrypoints logically "after" the entry point to |
| read it. Such enforcement would prevent undefined behavior, but would |
| have some drawbacks of its own. In particular, it doesn't solve the |
| problem of multiple threads computing a single per-patch attribute. One |
| very natural use would be to use a patch entrypoint to compute the four |
| outer tessellation levels in parallel. If all threads only write to |
| gl_TessLevelOuter[gl_InvocationID], there are no hazards. However, |
| detecting and preventing hazards are problematic if more complicated |
| array indexing is used. Also, there would be a problem if a parallel |
| shader was structured in such a way that one output might be written by |
| exactly one thread, but it wasn't obvious to the compiler which thread |
| actually would write it. |
| |
| (19) How should we name the parameters that control the degree of |
| tessellation along edges of a given patch and the (u,v) or (u,v,w) |
| parameter driving the tessellation shader evaluation? |
| |
| RESOLVED: The parameters controlling subdivision are called |
| "tessellation levels". The ones controlling subdivision of the outer |
| edges of the patch are called "outer tessellation levels"; the ones |
| controlling the interior are called "inner tessellation levels". The |
| built-in variables are called "gl_TessLevelOuter[]" and |
| "gl_TessLevelInner[]". Both are declared as arrays of floating-point |
| scalars, rather than vectors, so they can be accessed with indexing. |
| The (u,v) or (u,v,w) coordinate used by the tessellation evaluation |
| shader is referred to as the "tessellation coordinate", giving the |
| relative coordinates of the vertex in the primitive being tessellated. |
| The built-in input variable holding this value is called "gl_TessCoord". |
| |
| (20) How would applications handle attributes that may want to be sampled |
| with different frequency? For example, OpenGL evaluators can specify |
| evaluator maps of different order for different attributes? For |
| example, evaluating (u,v) with a cubic 2D map (order == 4) requires |
| 16 control points, while a linear map (order == 2) only requires 4. |
| |
| RESOLVED: Tessellation evaluation shaders can read from any vertex or |
| per-patch attribute, so they can read whatever the tessellation control |
| shader throws at them. Tessellation control shaders may choose to |
| compute attributes sampled at a different frequency than per-control |
| point in one of several ways: |
| |
| * Compute and output the attribute in only a subset of the |
| tessellation control shader threads; for example, only compute the |
| "linear" attributes in threads 0-3. |
| |
| * Encode the attribute across multiple control points. For example, |
| four vec4 values could be passed out as a float for each vertex if |
| 16 control point shader threads were used. Doing this may be tricky |
| in some cases. |
| |
| * Compute the "linear" attributes as four-element per-patch outputs. |
| If using this technique, it would be desirable to compute these |
| independently in the tessellation control shader, if possible. |
| |
| (21) To what level should we enforce that different shader types in a |
| program match exactly, and to what level does the current program |
| need to match the topology enums (e.g., GL_POINTS) provided by the |
| application? |
| |
| RESOLVED: If the tessellator is being used, we will require a patch |
| primitive as input and throw an INVALID_OPERATION error if any other |
| primitive type is provided. This is consistent with geometry shaders |
| requiring primitives consistent with their input topology. |
| |
| If no tessellation evaluation shader is present, a patch primitive would |
| need to be passed through to the geometry shader, or potentially |
| transform feedback and rasterization. That capability will not be |
| provided by this extension, but may be provided in the future or in a |
| vendor-specific extension. |
| |
| (22) If we have a notion of a "patch" as a random (though possibly |
| fixed-size) blob of vertices, should we extend this concept to |
| encompass geometry shaders as well? |
| |
| RESOLVED: No, we will not allow geometry shaders to receive patches in |
| this extension. That limitation may be relaxed in a future extension. |
| |
| Such a mechanism would allow patches to be used by geometry shaders in |
| settings other than tessellation. For example, QUADS primitives are |
| subdivided into two triangles when passed to geometry shaders. However, |
| this mechanism allows applications to pass 4-vertex PATCHES primitives |
| to geometry shaders, which can treat the four vertices as a quad. Note |
| also that the only way one could get patches to geometry shaders is if |
| no tessellation evaluation shader is present, because the tessellation |
| primitive generator will consume an input patch. |
| |
| (23) Should we support a programming model where the tessellation control |
| shader can be written serially rather than explicitly requiring |
| parallel execution? |
| |
| RESOLVED: Not in this extension. The parallel programming model allows |
| for improved efficiency. While an optimizing compiler could refactor |
| the code to execute in parallel, depending on this refactoring would run |
| the risk of major performance pitfalls. |
| |
| (24) Should the use of tessellation shaders be allowed with fixed-function |
| vertex processing, or should we require the use of a vertex shader? |
| |
| RESOLVED: When using tessellation control or evaluation shaders, |
| programmable vertex shaders will be required. This follows the |
| precedent established by EXT_geometry_shader4 that requires that if you |
| use a programmable shader for any stage prior to rasterization, you |
| can't mix that with fixed-function vertex processing. |
| |
| (25) Should we support variable-size input patches in the tessellation |
| control or evaluation shaders? If so, how can one get at the number |
| of vertices in the input patch? |
| |
| RESOLVED: Yes, variable-size input patches are supported, though the |
| input size can not be changed within a single draw call or Begin/End |
| pair. The vertex count for a specific input patch can be obtained in a |
| shader using the input variable "gl_PatchVerticesIn". Additionally, the |
| maximum patch size supported by the implementation, used for sizing |
| unsigned per-vertex input arrays, is given by the constant |
| "gl_MaxPatchVertices". |
| |
| The EXT_geometry_shader4 provided a constant "gl_VerticesIn" |
| corresponding to the fixed input primitive size set by the input |
| primitive type. This variable was dropped when geometry shaders were |
| included in GLSL 1.50 because the value of this constant couldn't be |
| known at CompileShader() time. Using GLSL 1.50, a shader could extract |
| the same value using "gl_in.length()" as long as the input primitive |
| type was declared prior to the use of "length()". |
| |
| This spec initially repurposed "gl_VerticesIn" for tessellation shaders |
| to refer to the input "gl_PatchVerticesIn", but having a variable that |
| was a constant in some shaders/#extension configurations and an input in |
| others was confusing. |
| |
| (26) Must per-vertex input variables be declared as arrays indexed by |
| vertex number? What syntax should be used in the declaration? |
| |
| RESOLVED: Yes, they must be declared as arrays or members of blocks |
| declared as arrays. We strongly recommend that shaders simply omit the |
| vertex size; a default size will be injected automatically by the |
| compiler. For example, if each input patch vertex a vec3 named position |
| an array of four vec2 values called "texcoords" and the implementation's |
| maximum patch size is 32, any of the following declarations are legal. |
| |
| in vec3 position[]; |
| in vec3 position[gl_MaxPatchVertices]; |
| in vec3 position[32]; |
| in TexCoords { |
| vec2 coords[4]; |
| } tex[]; |
| in TexCoords { |
| vec2 coords[4]; |
| } tex[gl_MaxPatchVertices]; |
| in TexCoords { |
| vec2 coords[4]; |
| } tex[32]; |
| |
| Shaders using the "32" form won't be portable; they will break when run |
| on any implementation that has a different patch size limit. Shaders |
| using "gl_MaxPatchVertices" will be portable, but there's no point in |
| specifying a vertex count. Just say no. |
| |
| (27) Can tessellation shaders be run on primitives such as triangles or |
| triangle strips? |
| |
| RESOLVED: Not directly. However, if an application is drawing |
| independent triangles using DrawElements, it can pass the same set of |
| indices using PATCHES and a patch size of 3 vertices and use the |
| tessellator normally. |
| |
| (29) How does tessellation interact with PolygonMode? Edge flags? |
| |
| RESOLVED: When the tessellation primitive generator decomposes a patch |
| and emits triangles, each triangle will be drawn with all edge flags set |
| to TRUE (as with regular TRIANGLE_STRIP primitives). If the polygon |
| mode is not FILL, each triangle will be drawn using points or lines, as |
| with any other primitive. PolygonMode and edge flags have no effect on |
| point or line primitives, and will thus have no effect if a patch is |
| used to generate points or isolines, or if the patch makes it to the |
| rasterizer. |
| |
| (30) Are any of the clamped/filtered gl_TessLevel values computed by the |
| tessellation primitive generator available to tessellation evaluation |
| shaders? |
| |
| RESOLVED: No, the only tessellation levels directly available to the |
| tessellation evaluation shaders will be the raw values written by the |
| tessellation control shaders or taken from default tessellation |
| levels. |
| |
| If a tessellation evaluation shader requires clamped or rounded levels, |
| it can perform the clamping itself. Alternately, the clamped levels can |
| be computed in the tessellation control patch shaders and passed to the |
| evaluation shader using a per-patch output declared as "patch out". |
| |
| (31) Should any of the patch parameters or the maximum input patch size |
| parameter have a "TESS_" prefix? |
| |
| RESOLVED: No. These are properties of patches, not any tessellation |
| units. While patches may be commonly used for tessellation, they might |
| also be used in the future by geometry shaders or transform feedback |
| with no tessellation shaders present. |
| |
| (32) How are primitives generated by the tessellator wound in (u,v) space? |
| Can we wind in either direction, or is only one way supported? At |
| the very least, we should guarantee that the winding is internally |
| consistent. |
| |
| RESOLVED: We will support both clockwise and counter-clockwise winding |
| in the normalized (u,v) space, where the winding can be specified using |
| a layout qualifier. Note that the final position of the vertices are |
| computed in the tessellation evaluation shader, and a triangle that is |
| counter-clockwise in (u,v) space may end up clockwise in screen space. |
| |
| (35) Tessellation evaluation shaders have a fixed input patch size if a |
| tessellation control shader is present, but a variable input patch |
| size otherwise. Is that a problem? |
| |
| RESOLVED: No, we don't think so. |
| |
| (36) How do patches interact with primitive restart indices? |
| |
| RESOLVED: Primitive restart terminates the existing patch and start a |
| new one, just like any other primitive. Since we only support |
| independent patch primitives, primtive restart with patches is every bit |
| as pointless as it is with independent point, line, triangle, and quad |
| primitives. |
| |
| (37) Should the default tessellation levels be used automatically if they |
| are not written by the tessellation control shader? |
| |
| RESOLVED: No. If you don't write tessellation levels in a tessellation |
| control patch shader, they will be undefined. If an application really |
| want a "default" tessellation level in conjunction with the tessellation |
| control shader, it can simply copy one from a uniform. |
| |
| (40) How does tessellation interact with rasterization features such as |
| flat shading and stippled lines? How are the vertices produced by |
| the tessellator presented to the geometry shader, if one is present? |
| |
| RESOLVED: For quad and triangle tessellation, a set of independent |
| triangles is generated by the tessellation primitive generator. For |
| isoline tessellation, a set of independent lines is generated. In both |
| cases, the order in which the triangles or lines are drawn is undefined. |
| Additionally, the order of vertices in the triangles or lines are also |
| undefined. The only thing that is defined is that when triangles are |
| generated, their winding will be consistent with the "cw" or "ccw" |
| layout qualifer. |
| |
| As a result, using flat shading and line stipple with tessellation |
| shaders may not produce regular results given that the first vertex |
| (resetting stipple) and last vertex (provoking vertex for flat shading) |
| of each primitive are undefined. Additionally, the order of vertices |
| presented to a geometry shader will not be predictable. All of these |
| features will work with tessellation; they just won't produce results |
| that are as regular as what you'd get decomposing a patch into a set of |
| triangle strips. |
| |
| Note that for the isoline tessellation, while the line segments appear |
| to be arranged in strips, they are rendered as independent segments and |
| have their stipple reset at the beginning of each segment. |
| |
| (41) Tessellation control shaders declare per-vertex outputs as arrays or |
| members of block arrays indexed by vertex number. However, we only |
| allow each thread to write per-vertex outputs for its own vertex. |
| How should we impose this restriction? |
| |
| RESOLVED: The current specification requires that the value of the |
| expression used as a vertex input must be the identifier |
| "gl_InvocationID". This does mean that even trivially equivalent |
| expressions such as "(gl_InvocationID)" or "glInvocationID + 0" should |
| not be accepted by the compiler. |
| |
| We considered allowing compilers to accept equivalent expressions like |
| "(gl_InvocationID)", "(gl_InvocationID + 0)", or a temporary variable |
| assigned the value of "gl_InvocationID". We also considered allowing |
| any expression, with undefined behavior if the value of the index |
| turned out to not be equal to "gl_InvocationID". We chose to have a |
| stronger restriction to avoid undefined behavior and errors that |
| depending on specific compiler behavior. |
| |
| Applications not wishing to use the string "gl_InvocationID" can use |
| the #define preprocessor feature to define an alternate name. |
| |
| (42) What restrictions should apply to the barrier() built-in? |
| |
| RESOLVED: Given that the barrier() function must be reached by all |
| threads before any thread continues, it would be possible for shader |
| thread groups to hang if any thread in the group never reaches the |
| barrier because of conditional flow control. |
| |
| We would prefer not to provide a mechanism allowing improperly-coded |
| shaders to hang, so it would be necessary to rely on compiler analysis |
| to prevent the use of barrier() in places where it isn't safe, which |
| would include: |
| |
| * calls within "if" or "else" substatements of an if statement, |
| |
| * calls within "do", "for", or "while" loops if the number of loop |
| iterations is not known to be uniform, or if any thread may execute |
| a "continue" or "break" statement, |
| |
| * calls within functions called directly or indirectly by main() in |
| cases any call in the chain is in conditional code, and |
| |
| * calls within the main() entrypoint issued after one or more threads |
| have executed a "return" statement. |
| |
| Relying on such analysis on fully general shader code may be fragile and |
| difficult to replicate uniformly across all compiler implementations. |
| As a result, we choose a heavy-handed approach in which we only allow |
| calls to barrier() inside main(). Even within main, barrier() calls are |
| forbidden inside loops (even those that turn out to have constant loop |
| counts and don't execute "break" or "continue" statements), if |
| statements, or after a return statement. |
| |
| (43) Why provide a limit on the maximum number of components (both |
| per-vertex and per-patch) emitted by a tessellation control shader, |
| i.e. MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS? |
| |
| RESOLVED: We expect that some implementations of this extension might |
| have a fixed limit on output buffering that may not not allow the |
| combined use of a maximum number of per-patch and per-vertex attributes. |
| |
| (44) What is the meaning of a "vertex shader" inside a pipeline with |
| tessellation enabled? |
| |
| RESOLVED: There are two different types of "vertex" when tessellation |
| is involved. We have the vertices of the input patch, and we have the |
| vertices generated by the tessellation primitive generator. If one |
| considers "vertices" to be points used to control rasterized primitives, |
| the former may be more reasonably considered "control points", since |
| they typically won't be used as-in in primitives sent to the rasterizer. |
| Additionally, operations typically performed in a vertex shader |
| (lighting, texture coordinate generation) may instead be performed by a |
| after evaluating the position and normal in the tessellation evaluation |
| shader. In such a world view, one might rename the pipeline stage |
| typically called "vertex shader" when tessellation is disabled to be a |
| "control point shader" stage. A logically separate pipeline stage with |
| a lot in common with existing vertex shaders would be run after the |
| tessellation evaluation shader. |
| |
| This extension chooses not to adopt the above approach, however. While |
| a post-tessellation vertex shader may have a lot in common with the |
| vertex shader used without tessellation, it's not likely that the shader |
| code used in these two cases will be completely identical. In |
| particular, the vertex positions and normals computed by the |
| tessellation coordinate shader will likely be in a different coordinate |
| system than the "object space" positions and normals used for vanilla |
| vertex shaders. The linkage between the two types of vertex shader and |
| the previous stage are also very different -- post-tessellation vertex |
| shaders would get their inputs from the outputs of the tessellation |
| evaluation shader; "normal" vertex shaders get their inputs from vertex |
| attribute arrays specified with the OpenGL API. Additionally, allowing |
| a vertex shader to live at the beginning or middle of the pipeline would |
| have problems if/when OpenGL releases the monolithic single program |
| model in the current GLSL API. In such an API, it would be necessary to |
| generate code for a vertex shader without knowledge of whether it would |
| be run with or without tessellation. |
| |
| In the model we do expose, developers need to keep in mind that with |
| tessellation: |
| |
| * vertex shaders are run on control points, not post-tessellation |
| vertices, and |
| |
| * many of the vertex processing operations typically performed by the |
| vertex shader will be performed by the tessellation evaluation |
| shader. |
| |
| It may be possible to share some or all portions of existing vertex |
| shader code verbatim with the tessellation evaluation shaders via clever |
| use of #ifdefs or multiple shader objects. Additionally, higher-level |
| shader or effects libraries may be able to expose a different pipeline |
| configuration as long as they generate code and shader/program objects |
| that fit the existing pipeline. |
| |
| (45) Should we provide the ability for the implementation to automatically |
| generate a "pass-through" vertex shader, effectively making vertex |
| shaders optional when tessellating. In some tessellation algorithms, |
| the bulk of the work will be done in the tessellation control and |
| evaluation shaders, and the vertex shader will have little or no |
| interesting work to do. |
| |
| RESOLVED: Not in this extension. This functionality might be useful, |
| but making such a change would have significant impact. First, there |
| would be quite a bit of text to rewrite regarding vertex attributes, all |
| of which is now in the "vertex shader" section but might want to be done |
| more neutrally. Additionally, the input variables for |
| tessellation/geometry shaders would presumably now receive vertex |
| attributes. However, TCS/TES/GS can have inputs that are not supported |
| as equivalent vertex shader inputs. In particular, structures are |
| allowed as inputs in TCS/TES/GS, but not in VS. This probably has |
| further impact on the vertex attribute language. We chose to leave out |
| this functionality for simplicity. |
| |
| (46) Should we reserve "patch" as a keyword for per-patch input |
| qualifiers, or use something more obscure, such as "per_patch"? |
| Whatever keyword we choose, should it be reserved in all languages or |
| just tessellation control and evaluation? |
| |
| RESOLVED: This extension uses "patch". |
| |
| (47) Should we allow tessellation control or evaluation inputs and outputs |
| to be declared as "centroid in" or "centroid out", or with |
| interpolation modifiers, even if those variables aren't being |
| interpolated? |
| |
| RESOLVED: Yes. This allows for mix-and-match linkage where you can |
| feed an output from a single vertex shader to a fragment shader in one |
| program and a tessellation/geometry shader in another. The shading |
| language requires that variables on each interface match in type and |
| qualification. Therefore, if a fragment shader input is declared as |
| "centroid in", the vertex shader output must be declared similarly. |
| When used on inputs in tessellation control, tessellation evaluation, |
| and geometry shaders, "centroid" and any other interpolation modifiers |
| have no effect. |
| |
| (48) Should we provide a tessellation spacing mode where the tessellation |
| levels are snapped to powers of two? |
| |
| RESOLVED: No. Such a mode would be useful to avoid motion of generated |
| vertices as the tessellation levels change. When using a power of two, |
| an increasing tessellation level snaps from 2 to 4 to 8 to 16. In each |
| transition, the <n> existing points generated by the tessellator on each |
| edge don't move -- new vertices are introduced at the midpoint of each |
| old edge in the subdivision. |
| |
| Applications can implement this behavior themselves by manually snapping |
| the levels of detail they compute in the tessellation control shader. |
| |
| (49) Should we make clockwise/counter-clockwise winding of tessellation |
| output program state or context state? |
| |
| RESOLVED: Program state, for simplicity. Making it program state means |
| that if an application wants to use the same tessellation evaluation |
| shader with different winding orders, it would need to generate two |
| separate programs/tessellation evaluation shaders. This doesn't seem to |
| be a significant enough usage case to justify the overhead of having to |
| program a separate piece of tessellation state. |
| |
| Note that applications that want to use the same program with different |
| windings can work around this limitation by toggling the FrontFace API |
| state as required. Counter-clockwise primitives with FrontFace set to |
| CCW will generally be indistinguishable from clockwise primitives with |
| FrontFace set to CW. The only limitation of this approach is that it |
| doesn't affect the winding of primitives captured by transform feedback. |
| |
| (50) Tessellation using "point_mode" is supposed to emit each distinct |
| vertex produced by the tessellation primitive generator exactly once. |
| Are there cases where this can produce multiple vertices with the same |
| position? |
| |
| RESOLVED: Yes. If fractional odd spacing is used, we have outer |
| tessellation levels that are greater than 1.0, and inner tessellation |
| levels less than or equal to 1.0, this can occur. If any outer level is |
| greater than 1.0, we will subdivide the outer edges of the patch, and |
| will need a subdivided patch interior to connect to. We handle this by |
| treating inner levels less than or equal to 1.0 as though they were |
| slightly greater than 1.0 ("1+epsilon"). |
| |
| With fractional odd spacing, inner levels between 1.0 and 3.0 will |
| produce a three-segment subdivision, with one full-size interior segment |
| and two smaller ones on the outside. The following figure illustrates |
| what happens to quad tessellation if the horizontal inner LOD (IL0) goes |
| from 3.0 toward 1.0 in fractional odd mode: |
| |
| IL0==3 IL0==2 IL0=1.5 IL0=1.2 |
| +-----------+ +-----------+ +-----------+ +-----------+ |
| | | | | | | | | |
| | +---+ | | +-----+ | | +-------+ | |+---------+| |
| | | | | | | | | | | | | || || |
| | | | | | | | | | | | | || || |
| | +---+ | | +-----+ | | +-------+ | |+---------+| |
| | | | | | | | | |
| +-----------+ +-----------+ +-----------+ +-----------+ |
| |
| As the inner level approaches 1.0, the vertical inner edges in this |
| example get closer and closer to the outer edge. The distance between |
| the inner and outer vertical edges approaches zero for an inner level of |
| 1+epsilon, and the positions of vertices produced by subdividing such |
| edges may be numerically indistinguishable. |
| |
| Revision History |
| |
| Rev. Date Author Changes |
| ---- -------- --------- ----------------------------------------- |
| 23 09/17/19 Jon Leech Fix typo in quad tessellation language |
| (internal API issue 113). |
| 22 04/21/15 Jon Leech Allow user-defined TCS input and output, |
| and TES input variable array size mismatches |
| to be detected at compile as well as link time |
| (Bug 12185). |
| |
| 21 04/20/15 Jon Leech Remove "per-patch" part of description of |
| MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS |
| (Bug 13765). |
| |
| 20 04/25/14 pbrown Clarify that the tessellation primitive |
| generator may produce multiple vertices with |
| the same gl_TessCoord values in point mode when |
| fractional odd spacing is used with an inner |
| tessellation level less than or equal to 1.0 |
| (bug 11979). |
| |
| 19 10/25/12 pbrown Update spec language describing tessellation of |
| isolines. Fix the inconsistent/incorrect |
| language describing the handling of tessellation |
| levels -- outer level 0 controls the number of |
| isolines generated and outer level 1 controls |
| the number of segements in each isoline (bug |
| 9195/9607). Minor isoline tessellation wording |
| fixes for improved clarity. |
| |
| 18 03/29/10 pbrown Update issues (42), (46), and (47). |
| |
| 17 03/22/10 pbrown Minor corrections to the Dependencies section. |
| |
| 16 01/29/10 pbrown Updates from ARB review (bug 5905). In |
| particular, we again allow only the token |
| "gl_Invocation" for indexing TCS outputs, |
| reversing changes in version 7. Added some |
| clarifications to barrier(). Increased minimum |
| value of gl_MaxCombinedTextureImageUnits. |
| |
| 15 01/26/10 pbrown Reflow some ragged paragraphs. |
| |
| 14 01/20/10 Jon Leech Make behavior, not just results undefined |
| when reading gl_in beyond the number of |
| vertices in the input patch (Bug 5880). |
| |
| 13 01/20/10 pbrown Clarify the required minimum values for |
| MAX_COMBINED_*_UNIFORM_COMPONENTS (bug 5919). |
| |
| 12 01/14/10 Jon Leech Remove erroneous reference to triangles from |
| tesselation control shader input language |
| (Bug 5881). |
| |
| 11 01/14/10 pbrown Minor clarifications from spec reviews. Add |
| missing edits for gl_InvocationID changes from |
| version 7. |
| |
| 10 12/14/09 pbrown Rename "gl_VerticesIn" to "gl_PatchVerticesIn" |
| to avoid collision with the EXT_geometry_shader4 |
| variable of the same name. Add language |
| clarifying the size applied to unsized input |
| arrays for tessellation control and evaluation |
| shaders. |
| |
| 9 12/10/09 pbrown Rename the layout qualifiers for vertex order to |
| "cw" and "ccw". Minor changes to invariance |
| rules, including addition of a rule guaranteeing |
| that <x> + (1-<x>) is exactly 1.0 for |
| gl_TessCoord components. |
| |
| 8 12/10/09 pbrown Convert from EXT to ARB. |
| |
| 7 12/09/09 pbrown Miscellaneous fixes from spec review: Added a |
| new invariance section describing a set of |
| hopefully useful rules for tessellation. |
| Slightly relaxed the rules requiring |
| gl_InvocationID for TCS per-vertex outputs. |
| Cleaned up language on primitive generation and |
| when outputs are defined in TCS w.r.t. barrier. |
| General typo fixes and language clarifications. |
| |
| 6 11/02/09 pbrown Fix cut-and-paste error in the definition of |
| gl_PrimitiveID. |
| |
| 5 10/23/09 pbrown Change the name of one GLSL constant to |
| gl_MaxTessPatchComponents (was "TessControl") |
| to match the API constant name. This limit |
| also applies to evaluation shaders. |
| |
| 4 10/13/09 pbrown Minor typo fixes. |
| |
| 3 10/01/09 pbrown Renamed some of the tessellation evaluation |
| shader input layout qualifiers to more closely |
| match geometry shader conventions. Renamed |
| gl_ThreadID to gl_InvocationID. Fixed one |
| reference to an old layout qualifier name. |
| |
| 2 09/28/09 pbrown Typo fix. |
| |
| 1 pbrown Internal revisions. |
| |