blob: 1b80b166d9ce5049845e9e1f02065c617eb76736 [file] [log] [blame]
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.