| Name |
| |
| OES_tessellation_shader |
| |
| Name Strings |
| |
| GL_OES_tessellation_shader |
| GL_OES_tessellation_point_size |
| |
| Contact |
| |
| Jon Leech (oddhack 'at' sonic.net) |
| Daniel Koch, NVIDIA (dkoch 'at' nvidia.com) |
| |
| Contributors |
| |
| Daniel Koch, NVIDIA (dkoch 'at' nvidia.com) |
| Pat Brown, NVIDIA (pbrown 'at' nvidia.com) |
| Bill Licea-Kane, Qualcomm (billl 'at' qti.qualcomm.com) |
| Jesse Hall, Google (jessehall 'at' google.com) |
| Dominik Witczak, Mobica |
| Jan-Harald Fredriksen, ARM |
| Maurice Ribble, Qualcomm |
| Vineet Goel, Qualcomm |
| Alex Chalfin, ARM |
| Graham Connor, Imagination |
| Ben Bowman, Imagination |
| Jonathan Putsman, Imagination |
| Slawomir Grajewski, Intel |
| Contributors to ARB_tessellation_shader |
| |
| Notice |
| |
| Copyright (c) 2010-2016 The Khronos Group Inc. Copyright terms at |
| http://www.khronos.org/registry/speccopyright.html |
| |
| Specification Update Policy |
| |
| Khronos-approved extension specifications are updated in response to |
| issues and bugs prioritized by the Khronos OpenGL ES Working Group. For |
| extensions which have been promoted to a core Specification, fixes will |
| first appear in the latest version of that core Specification, and will |
| eventually be backported to the extension document. This policy is |
| described in more detail at |
| https://www.khronos.org/registry/OpenGL/docs/update_policy.php |
| |
| Portions Copyright (c) 2013-2014 NVIDIA Corporation. |
| |
| Status |
| |
| Approved by the OpenGL ES Working Group |
| Ratified by the Khronos Board of Promoters on November 7, 2014 |
| |
| Version |
| |
| Last Modified Date: December 10, 2018 |
| Revision: 7 |
| |
| Number |
| |
| OpenGL ES Extension #214 |
| |
| Dependencies |
| |
| OpenGL ES 3.1 and OpenGL ES Shading Language 3.10 are required. |
| |
| This specification is written against the OpenGL ES 3.1 (March 17, 2014) |
| and OpenGL ES 3.10 Shading Language (March 17, 2014) Specifications. |
| |
| OES_geometry_shader is required in order to share language modifying the |
| OpenGL ES 3.1 specifications, which would otherwise have to be repeated |
| here. |
| |
| OES_shader_io_blocks or EXT_shader_io_blocks is required. |
| |
| OES_gpu_shader5 or EXT_gpu_shader5 is required. |
| |
| This extension interacts with OES_shader_multisample_interpolation. |
| |
| Overview |
| |
| This extension introduces new tessellation stages and two new shader types |
| to the OpenGL ES 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 ES 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. |
| However, if either a tessellation control or a tessellation evaluation |
| shader is present, the other must also be present. |
| |
| Not all tessellation shader implementations have the ability to write the |
| point size from a tessellation shader. Thus a second extension string and |
| shading language enable are provided for implementations which do |
| support tessellation shader point size. |
| |
| This extension relies on the OES_shader_io_blocks or EXT_shader_io_blocks |
| extension to provide the required functionality for declaring input and |
| output blocks and interfacing between shaders. |
| |
| This extension relies on the OES_gpu_shader5 or EXT_gpu_shader5 extension |
| to provide the 'precise' and 'fma' functionality which are necessary to |
| ensure crack-free tessellation. |
| |
| IP Status |
| |
| No known IP claims. |
| |
| New Procedures and Functions |
| |
| void PatchParameteriOES(enum pname, int value); |
| |
| New Tokens |
| |
| Accepted by the <mode> parameter of DrawArrays, DrawElements, |
| and other commands which draw primitives: |
| |
| PATCHES_OES 0xE |
| |
| Accepted by the <pname> parameter of PatchParameteriOES, GetBooleanv, |
| GetFloatv, GetIntegerv, and GetInteger64v: |
| |
| PATCH_VERTICES_OES 0x8E72 |
| |
| Accepted by the <pname> parameter of GetProgramiv: |
| |
| TESS_CONTROL_OUTPUT_VERTICES_OES 0x8E75 |
| TESS_GEN_MODE_OES 0x8E76 |
| TESS_GEN_SPACING_OES 0x8E77 |
| TESS_GEN_VERTEX_ORDER_OES 0x8E78 |
| TESS_GEN_POINT_MODE_OES 0x8E79 |
| |
| Returned by GetProgramiv when <pname> is TESS_GEN_MODE_OES: |
| |
| TRIANGLES |
| ISOLINES_OES 0x8E7A |
| QUADS_OES 0x0007 |
| |
| Returned by GetProgramiv when <pname> is TESS_GEN_SPACING_OES: |
| |
| EQUAL |
| FRACTIONAL_ODD_OES 0x8E7B |
| FRACTIONAL_EVEN_OES 0x8E7C |
| |
| Returned by GetProgramiv when <pname> is TESS_GEN_VERTEX_ORDER_OES: |
| |
| CCW |
| CW |
| |
| Returned by GetProgramiv when <pname> is TESS_GEN_POINT_MODE_OES: |
| |
| FALSE |
| TRUE |
| |
| Accepted by the <pname> parameter of GetBooleanv, GetFloatv, |
| GetIntegerv, and GetInteger64v: |
| |
| MAX_PATCH_VERTICES_OES 0x8E7D |
| MAX_TESS_GEN_LEVEL_OES 0x8E7E |
| MAX_TESS_CONTROL_UNIFORM_COMPONENTS_OES 0x8E7F |
| MAX_TESS_EVALUATION_UNIFORM_COMPONENTS_OES 0x8E80 |
| MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS_OES 0x8E81 |
| MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS_OES 0x8E82 |
| MAX_TESS_CONTROL_OUTPUT_COMPONENTS_OES 0x8E83 |
| MAX_TESS_PATCH_COMPONENTS_OES 0x8E84 |
| MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS_OES 0x8E85 |
| MAX_TESS_EVALUATION_OUTPUT_COMPONENTS_OES 0x8E86 |
| MAX_TESS_CONTROL_UNIFORM_BLOCKS_OES 0x8E89 |
| MAX_TESS_EVALUATION_UNIFORM_BLOCKS_OES 0x8E8A |
| MAX_TESS_CONTROL_INPUT_COMPONENTS_OES 0x886C |
| MAX_TESS_EVALUATION_INPUT_COMPONENTS_OES 0x886D |
| MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS_OES 0x8E1E |
| MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS_OES 0x8E1F |
| MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS_OES 0x92CD |
| MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS_OES 0x92CE |
| MAX_TESS_CONTROL_ATOMIC_COUNTERS_OES 0x92D3 |
| MAX_TESS_EVALUATION_ATOMIC_COUNTERS_OES 0x92D4 |
| MAX_TESS_CONTROL_IMAGE_UNIFORMS_OES 0x90CB |
| MAX_TESS_EVALUATION_IMAGE_UNIFORMS_OES 0x90CC |
| MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS_OES 0x90D8 |
| MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS_OES 0x90D9 |
| PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED_OES 0x8221 |
| |
| Accepted by the <props> parameter of |
| GetProgramResourceiv: |
| |
| IS_PER_PATCH_OES 0x92E7 |
| REFERENCED_BY_TESS_CONTROL_SHADER_OES 0x9307 |
| REFERENCED_BY_TESS_EVALUATION_SHADER_OES 0x9308 |
| |
| Accepted by the <type> parameter of CreateShader, by the <pname> |
| parameter of GetProgramPipelineiv, and returned by the |
| <params> parameter of GetShaderiv: |
| |
| TESS_EVALUATION_SHADER_OES 0x8E87 |
| TESS_CONTROL_SHADER_OES 0x8E88 |
| |
| Accepted by the <stages> parameter of UseProgramStages: |
| |
| TESS_CONTROL_SHADER_BIT_OES 0x00000008 |
| TESS_EVALUATION_SHADER_BIT_OES 0x00000010 |
| |
| Additions to the OpenGL ES 3.1 Specification |
| |
| Modify chapter 3 "Dataflow Model" |
| |
| Change the second paragraph, on p. 28: |
| |
| ... In the next stage vertices may be transformed, followed by assembly |
| into geometric primitives. Tessellation and geometry shaders may then |
| optionally generate multiple new primitives from single input |
| primitives. Optionally, the results ... |
| |
| |
| Modify figure 3.1 "Block diagram of the OpenGL ES pipeline" as modified |
| by OES_geometry_shader to insert new boxes "Tessellation Control |
| Shader", "Tessellation Primitive Generation", and "Tessellation |
| Evaluation Shader" in sequence following "Vertex Shader" and preceding |
| "Geometry Shader". Extend the arrows from the boxes "Image Load/Store" |
| .. "Uniform Block" to the right of "Vertex Shader" to connect to the new |
| "Control" and "Evaluation" boxes. |
| |
| |
| Replace the two paragraphs of chapter 7, "Programs and Shaders" on p. 64 |
| starting "Shader stages including ..." with: |
| |
| Shader stages including vertex, tessellation control, tessellation |
| evaluation, geometry, fragment, and compute shaders can be created, |
| compiled, and linked into program objects. |
| |
| Vertex shaders describe the operations that occur on vertex attributes. |
| Tessellation control and evaluation shaders are used to control |
| the operation of the tessellator (see section 11.1ts). Geometry shaders |
| affect the processing of primitives assembled from vertices (see section |
| 11.1gs). Fragment shaders affect the processing of fragments during |
| rasterization (see chapter 14). A single program object can contain all |
| of these shaders, or any subset thereof. |
| |
| Compute shaders ... |
| |
| |
| Add to table 7.1 "CreateShader <type> values" on p. 65: |
| |
| <type> Shader Stage |
| -------------------------- ------------------------------ |
| TESS_CONTROL_SHADER_OES Tessellation control shader |
| TESS_EVALUATION_SHADER_OES Tessellation evaluation shader |
| |
| |
| Add to the bullet list describing reasons for link failure below the |
| LinkProgram command on p. 70, as modified by OES_geometry_shader: |
| |
| * The program object contains an object to form a tessellation control |
| shader (see section 11.1ts.1), and |
| - the program is not separable and contains no object to form a |
| vertex shader; or |
| - the program is not separable and contains no object to form a |
| tessellation evaluation shader; or |
| - the output patch vertex count is not specified in the compiled |
| tessellation control shader object. |
| * The program object contains an object to form a tessellation |
| evaluation shader (see section 11.1ts.3), and |
| - the program is not separable and contains no object to form a |
| vertex shader; or |
| - the program is not separable and contains no object to form a |
| tessellation control shader; or |
| - the tessellation primitive mode is not specified in the compiled |
| tessellation evaluation shader object. |
| |
| |
| Modify section 7.3, "Program Objects", as modified by |
| OES_geometry_shader: |
| |
| Add to the second paragraph after UseProgram on p. 71: |
| |
| The executable code ... the results of vertex and/or fragment processing |
| will be undefined. However, this is not an error. If there is no active |
| program for the tessellation control, tessellation evaluation, or |
| geometry shader stages, those stages are ignored. If there is no active |
| program for the compute shader stage ... |
| |
| |
| Modify section 7.3.1, Program Interfaces: |
| |
| Modify table 7.2 "GetProgramResourceiv properties and supported |
| interfaces" on p. 81 to add "REFERENCED_BY_TESS_CONTROL_SHADER_OES" and |
| "REFERENCED_BY_TESS_EVALUATION_SHADER_OES" to the "Property" cell |
| already containing REFERENCED_BY_<stage>_SHADER for VERTEX, GEOMETRY, |
| FRAGMENT, and COMPUTE stages, with the same supported interfaces. |
| |
| Add to table 7.2: |
| |
| Property Supported Interfaces |
| ---------------------------------------- ----------------------------- |
| IS_PER_PATCH_OES PROGRAM_INPUT, PROGRAM_OUTPUT |
| |
| Add a new paragraph preceding the paragraph "For property IS_ROW_MAJOR" |
| on p. 83: |
| |
| For the property IS_PER_PATCH_OES, a single integer identifying whether |
| the input or output is a per-patch attribute is written to <params>. If |
| the active variable is a per-patch attribute (declared with the "patch" |
| qualifier), the value one is written to <params>; otherwise the value |
| zero is written to <params>. |
| |
| |
| Add tessellation shaders to the paragraph describing the REFERENCED_BY |
| properties, on p. 83: |
| |
| For the properties REFERENCED_BY_VERTEX_SHADER, |
| REFERENCED_BY_TESS_CONTROL_SHADER_OES, |
| REFERENCED_BY_TESS_EVALUATION_SHADER_OES, |
| REFERENCED_BY_GEOMETRY_SHADER_OES, REFERENCED_BY_FRAGMENT_SHADER, and |
| REFERENCED_BY_COMPUTE_SHADER, a single integer is written to <params>, |
| identifying whether the active resource is referenced by the vertex, |
| tessellation control, tessellation evaluation, geometry, fragment, or |
| compute shaders, respectively, in the program object. ... |
| |
| |
| Modify section 7.4, "Program Pipeline Objects" in the first |
| paragraph after UseProgramStages on p. 89: |
| |
| ... These stages may include vertex, tessellation control, tessellation |
| evaluation, geometry, fragment, or compute, indicated respectively by |
| VERTEX_SHADER_BIT, TESS_CONTROL_SHADER_BIT_OES, TESS_EVALUATION_BIT_OES, |
| GEOMETRY_SHADER_BIT_OES, FRAGMENT_SHADER_BIT, or COMPUTE_SHADER_BIT. ... |
| |
| |
| Modify section 7.4.1, "Shader Interface Matching" on p. 91, changing the |
| new paragraph starting "Geometry shader per-vertex ...": |
| |
| Tessellation control shader per-vertex output variables and blocks and |
| tessellation control, tessellation evaluation, and geometry shader |
| per-vertex input variables are required to be declared as arrays... |
| |
| |
| Modify section 7.4.2 "Program Pipeline Object State" on p. 92, |
| replacing the first bullet point: |
| |
| * Unsigned integers are required to hold the names of the active program |
| and each of the current vertex, tessellation control, tessellation |
| evaluation, geometry, fragment, and compute stage programs. Each |
| integer is initially zero. |
| |
| |
| Modify section 7.6, "Uniform Variables" |
| |
| Add to table 7.4 "Query targets for default uniform block storage ..." |
| on p. 96: |
| |
| Shader Stage <pname> for querying default uniform block |
| storage, in components |
| ---------------------------------- ------------------------------------------- |
| Tess. control (see sec. 11.1ts.1.1) MAX_TESS_CONTROL_UNIFORM_COMPONENTS_OES |
| Tess. eval (see sec. 11.1ts.3.1) MAX_TESS_EVALUATION_UNIFORM_COMPONENTS_OES |
| |
| |
| Add to table 7.5 "Query targets for combined uniform block storage ..." |
| on p. 96: |
| |
| |
| Shader Stage <pname> for querying combined uniform block |
| storage, in components |
| ---------------------------------- --------------------------------------------------- |
| Tess. control MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS_OES |
| Tess. eval MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS_OES |
| |
| |
| Modify section 7.6.2, "Uniform Blocks" on p. 104, changing the second |
| paragraph of the section: |
| |
| 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, fragment, and |
| compute shaders can be obtained by calling GetIntegerv with <pname> |
| values of MAX_VERTEX_UNIFORM_BLOCKS, |
| MAX_TESS_CONTROL_UNIFORM_BLOCKS_OES, |
| MAX_TESS_EVALUATION_UNIFORM_BLOCKS_OES, MAX_GEOMETRY_UNIFORM_BLOCKS_OES, |
| MAX_FRAGMENT_UNIFORM_BLOCKS, and MAX_COMPUTE_UNIFORM_BLOCKS, |
| respectively. |
| |
| |
| Modify section 7.7, "Atomic Counter Buffers" on p. 108, changing the |
| second paragraph of the section: |
| |
| There is a set of implementation-dependent maximums for the number of |
| active atomic counter buffers referenced by each shader. If the number |
| of atomic counter buffers referenced 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, fragment, and compute shaders can be obtained by calling |
| GetIntegerv with <pname> values of MAX_VERTEX_ATOMIC_COUNTER_BUFFERS, |
| MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS_OES, |
| MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS_OES, |
| MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_OES, |
| MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS, or |
| MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS, respectively. |
| |
| |
| Modify section 7.8, "Shader Buffer Variables and Shader Storage Blocks" |
| on p. 110, changing the fourth paragraph: |
| |
| If the number of active shader storage blocks referenced by the shaders |
| in a program exceeds implementation-dependent limits, the program will |
| fail to link. The limits for vertex, tessellation control, tessellation |
| evaluation, geometry, fragment, and compute shaders can be obtained by |
| calling GetIntegerv with pname values of |
| MAX_VERTEX_SHADER_STORAGE_BLOCKS, |
| MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS_OES, |
| MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS_OES, |
| MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_OES, |
| MAX_FRAGMENT_SHADER_STORAGE_BLOCKS, and |
| MAX_COMPUTE_SHADER_STORAGE_BLOCKS, respectively. ... |
| |
| |
| Modify Section 7.11.1, "Shader Memory Access Ordering": |
| |
| The order in which texture or buffer object memory is read or written by |
| shaders is largely undefined. For some shader types (vertex, |
| tessellation evaluation, and in some cases, fragment), even the number |
| of shader invocations that might perform loads and stores is undefined. |
| |
| In particular, the following rules apply: |
| |
| * While a vertex or tessellation evaluation shader will be executed at |
| least once for each unique vertex specified by the application (vertex |
| shaders) or generated by the tessellation primitive genertor |
| (tessellation evaluation shaders), it may be executed more than once |
| for implementation-dependent reasons. Additionally, ... |
| |
| |
| Modify section 7.12, "Shader, Program, and Program Pipeline Queries" |
| to add to the list of valid <pname>s for GetProgramiv on p. 120: |
| |
| If <pname> is TESS_CONTROL_OUTPUT_VERTICES_OES, the number of vertices |
| in the tessellation control shader output patch is returned. |
| |
| If <pname> is TESS_GEN_MODE_OES, QUADS_OES, TRIANGLES, or ISOLINES_OES |
| is returned, depending on the primitive mode declaration in the |
| tessellation evaluation shader. If <pname> is TESS_GEN_SPACING_OES, |
| EQUAL, FRACTIONAL_EVEN_OES, or FRACTIONAL_ODD_OES is returned, depending |
| on the spacing declaration in the tessellation evaluation shader. If |
| <pname> is TESS_GEN_VERTEX_ORDER_OES, CCW or CW is returned, depending |
| on the vertex order declaration in the tessellation evaluation shader. |
| If <pname> is TESS_GEN_POINT_MODE_OES, TRUE is returned if point mode is |
| enabled in a tessellation evaluation shader declaration; FALSE is |
| returned otherwise. |
| |
| |
| Add to the Errors for GetProgramiv on p. 121: |
| |
| An INVALID_OPERATION error is generated 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. |
| |
| An INVALID_OPERATION error is generated if TESS_GEN_MODE, |
| TESS_GEN_SPACING, TESS_GEN_VERTEX_ORDER, or TESS_GEN_POINT_MODE are |
| queried for a program which has not been linked successfully, or which |
| does not contain objects to form a tessellation evaluation shader, |
| |
| |
| Add new section 10.1.7sp following section 10.1.7, "Separate Triangles", |
| on p. 234: |
| |
| Section 10.1.7sp, Separate Patches |
| |
| Separate patches are specified with mode PATCHES_OES. A patch is an |
| ordered collection of vertices used for primitive tessellation (see |
| section 11.1ts). The vertices comprising a patch have no implied |
| geometric ordering. The vertices of a patch are used by tessellation |
| shaders and the 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 PatchParameteriOES(enum pname, int value); |
| |
| with <pname> set to PATCH_VERTICES_OES. |
| |
| Errors |
| |
| An INVALID_ENUM error is generated if <pname> is not PATCH_VERTICES_OES. |
| |
| An INVALID_VALUE error is generated if <value> is less than or equal to |
| zero, or is greater than the implementation-dependent maximum patch size |
| (the value of MAX_PATCH_VERTICES_OES). 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. |
| |
| |
| Add to the end of section 10.3.4, "Primitive Restart" on p. 243: |
| |
| Implementations are not required to support primitive restart for |
| separate patch primitives (primitive type PATCHES_OES). Support can be |
| queried by calling GetBooleanv with the symbolic constant |
| PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED_OES. A value of FALSE indicates |
| that primitive restart is treated as disabled when drawing patches, no |
| matter the value of the enable. A value of TRUE indicates that primitive |
| restart behaves normally for patches. |
| |
| |
| Modify section 11.1.2.1, "Output Variables" on p. 262, starting with the |
| second paragraph of the section: |
| |
| ... These output variables are used to communicate values to the next |
| active stage in the vertex processing pipeline; either the tessellation |
| control or geometry shader, or the fixed-function vertex processing |
| stages leading to rasterization. |
| |
| ... |
| |
| The number of components (individual scalar numeric values) of output |
| variables that can be written by the vertex shader, whether or not a |
| tessellation control or geometry shader is active, is given by the value |
| of the implementation-dependent constant MAX_VERTEX_OUTPUT_COMPONENTS. |
| For the purposes of counting ... |
| |
| ... |
| |
| Each program object can specify a set of output variables from one |
| shader to be recorded in transform feedback mode (see section 2.14). The |
| variables that can be recorded are those emitted by the first active |
| shader, in order, from the following list: |
| |
| * geometry shader |
| * tessellation evaluation shader |
| * vertex shader |
| |
| The set of variables to record is specified with the command |
| |
| void TransformFeedbackVaryings ... |
| |
| |
| Modify the bullet point starting "the <count> specified" in the list of |
| TransformFeedbackVaryings link failures on p. 263: |
| |
| * the <count> specified by TransformFeedbackVaryings is non-zero, but |
| the program object has no vertex, tessellation evaluation, or geometry |
| shader; ... |
| |
| |
| Modify Section 11.1.3, Shader Execution |
| |
| Change the first paragraph and bullet list on p. 264: |
| |
| If there is an active program object present for the vertex, |
| tessellation control, tessellation evaluation, or geometry shader |
| stages, the executable code for those active programs is used to process |
| incoming vertex values. The following sequence of operations is |
| performed: |
| |
| * Vertices are processed by the vertex shader (see section 11.1) and |
| assembled into primitives as described in sections 10.1 through 10.3. |
| * If the current program contains a tessellation control shader, each |
| individual patch primitive is processed by the tessellation control |
| shader (section 11.1ts.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 11.1ts.2) and tessellation evaluation shader (see |
| section 11.1ts.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, ... |
| |
| |
| Modify the bullet list in section 11.1.3.5 "Texture Access" on p. 266 to |
| add limits for tessellation shaders: |
| |
| * MAX_VERTEX_TEXTURE_IMAGE_UNITS (for vertex shaders), |
| * MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS_OES (for tessellation control |
| shaders), |
| * MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS_OES (for tessellation |
| evaluation shaders), |
| * MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_OES (for geometry shaders), and |
| * MAX_TEXTURE_IMAGE_UNITS (for fragment shaders). |
| |
| |
| Modify the bullet list in section 11.1.3.6 "Atomic Counter Access" on p. |
| 268 to add a limit for geometry shaders: |
| |
| * MAX_TESS_CONTROL_ATOMIC_COUNTERS_OES (for tessellation control |
| shaders), |
| * MAX_TESS_EVALUATION_ATOMIC_COUNTERS_OES (for tessellation evaluation |
| shaders), |
| |
| |
| Modify the bullet list in section 11.1.3.7 "Image Access" on p. 268 to |
| add a limit for geometry shaders: |
| |
| * MAX_TESS_CONTROL_IMAGE_UNIFORMS_OES (for tessellation control |
| shaders), |
| * MAX_TESS_EVALUATION_IMAGE_UNIFORMS_OES (for tessellation evaluation |
| shaders), |
| |
| |
| Modify the bullet list in section 11.1.3.8 "Shader Storage Buffer |
| Access" on p. 268 to add a limit for geometry shaders: |
| |
| * MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS_OES (for tessellation control |
| shaders), |
| * MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS_OES (for tessellation |
| evaluation shaders), |
| |
| |
| Modify section 11.1.3.11, "Validation" to replace the bullet point |
| starting "There is an active program for the geometry stage ..." on p. |
| 270: |
| |
| * There is an active program for tessellation control, tessellation |
| evaluation, or geometry stages with corresponding executable shader, |
| but there is no active program with an executable vertex shader. |
| |
| |
| Add a new bullet point in the same section: |
| |
| * One but not both of the tessellation control and tessellation |
| evaluation stages have an active program with corresponding executable |
| shader. |
| |
| |
| Insert new section 11.1ts, "Tessellation", between section 11.1 "Vertex |
| Shaders" and section 11.1gs "Geometry Shaders": |
| |
| 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 the active |
| program object or program pipeline object includes both a tessellation |
| control shader and a tessellation 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, patch primitives |
| may not be provided by the application. |
| |
| 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. |
| |
| 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. |
| |
| Patch primitives are not supported by pipeline stages below the |
| tessellation evaluation shader. |
| |
| A non-separable program object or program pipeline object that includes |
| a tessellation shader of any kind must also include a vertex shader. |
| |
| |
| Errors |
| |
| An INVALID_OPERATION error is generated by any command that transfers |
| vertices to the GL if the current program state has one but not both of |
| a tessellation control shader and tessellation evaluation shader. |
| |
| An INVALID_OPERATION error is generated by any command that transfers |
| vertices to the GL if tessellation is active and the primitive mode is |
| not PATCHES_OES. |
| |
| An INVALID_OPERATION error is generated by any command that transfers |
| vertices to the GL if tessellation is not active and the primitive mode |
| is PATCHES_OES. |
| |
| An INVALID_OPERATION error is generated by any command that transfers |
| vertices to the GL if the current program state has a tessellation |
| shader but no vertex shader. |
| |
| |
| Section 11.1ts.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 |
| ES Shading Language Specification. A program will fail to link if the |
| output patch vertex count is not specified by the tessellation control |
| shader object attached to the program, 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_OES. |
| |
| Tessellation control shaders are created as described in section 7.1, |
| using a <type> of TESS_CONTROL_SHADER_OES. 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 11.1ts.1.1, Tessellation Control Shader Variables |
| |
| Tessellation control shaders can access uniforms belonging to the |
| current program object. Limits on uniform storage and methods for |
| manipulating uniforms are described in section 7.6. |
| |
| Tessellation control shaders also have access to samplers to perform |
| texturing operations, as described in section 7.9. |
| |
| 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 |
| variables. Values for any inputs 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 ES Shading Language. The |
| per-vertex and per-patch attributes of the output patch are used by the |
| tessellation primitive generator (section 11.1ts.2) and may be read by |
| tessellation evaluation shader (section 11.1ts.3). |
| |
| |
| Section 11.1ts.1.2, Tessellation Control Shader Execution Environment |
| |
| If there is an active program for the tessellation control stage, the |
| executable version of the program's 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. |
| |
| |
| Section 11.1ts.1.2.1, Texture Access |
| |
| Section 11.1.3.1 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. |
| |
| |
| Section 11.1ts.1.2.2, Tessellation Control Shader Inputs |
| |
| Section 7.1 ("Built-In Variables") of the OpenGL ES 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. 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 |
| [[ If OES_tessellation_point_size is supported: ]] |
| and gl_PointSize. |
| |
| 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 by the drawing command which generated the input vertices. |
| The first primitive generated by a drawing command is numbered zero, |
| and the primitive ID counter is incremented after every individual |
| point, line, or triangle primitive is processed. The counter is |
| reset to zero between each instance drawn. 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 inputs, each user-defined input 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 ES Shading Language doesn't |
| support multi-dimensional arrays as shader inputs or outputs; 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. |
| |
| Similarly to the limit on vertex shader output components (see section |
| 11.1.2.1), there is a limit on the number of components of input |
| variables that can be read by the tessellation control shader, given by |
| the value of the implementation-dependent constant |
| MAX_TESS_CONTROL_INPUT_COMPONENTS_OES. |
| |
| When a program is linked, all components of any input 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. |
| |
| Component counting rules for different variable types and variable |
| declarations are the same as for MAX_VERTEX_OUTPUT_COMPONENTS (see |
| section 11.1.2.1). |
| |
| |
| Section 11.1ts.1.2.3, Tessellation Control Shader Outputs |
| |
| Section 7.1 ("Built-In Variables") of the OpenGL ES 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. The members of each element of the gl_out[] |
| array are gl_Position |
| [[ If OES_tessellation_point_size is supported: ]] |
| and gl_PointSize. |
| They behave identically to equivalently named vertex shader outputs |
| (see section 11.1.2.1). |
| |
| 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 output patch size declared in the |
| shader. If a size is specified, it must match the maximum patch size; |
| otherwise, a compile or link error will occur. The OpenGL ES Shading |
| Language doesn't support multi-dimensional arrays as shader inputs or |
| outputs; 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_OES. The number of components of |
| active per-patch output variables may not exceed the value of |
| MAX_TESS_PATCH_COMPONENTS_OES. 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_OES. |
| |
| When a program is linked, all components of any output variable 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. |
| |
| Component counting rules for different variable types and variable |
| declarations are the same as for MAX_VERTEX_OUTPUT_COMPONENTS. (see |
| section 11.1.2.1). |
| |
| |
| Section 11.1ts.1.2.4, 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 ES 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 11.1ts.2, Tessellation Primitive Generation |
| |
| 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. This subdivision is |
| performed in an implementation- dependent manner. |
| |
| 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 11.X1. 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 11.X1: 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. |
| |
| 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 relevant 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 the |
| implementation-dependent maximum tessellation level (the value of |
| MAX_TESS_GEN_LEVEL_OES). 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 11.X1. 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 11.1ts.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 be |
| rounded up to result in a two- or three-segment subdivision according to |
| the tessellation spacing. |
| |
| 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 11.X2. |
| |
| (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 11.X2, 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 11.X2, 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 11.1ts.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 |
| 11.X3. |
| |
| (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 11.X3, 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 triangle. |
| 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 11.X3, 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". A line 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 |
| segments 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>, ..., (<n>-1)/<n>. |
| |
| Each of the <n> lines 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 11.X4. |
| |
| (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 11.X4, 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 11.1ts.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. Tessellation evaluation shaders are |
| created as described in section 7.1, using a <type> of |
| TESS_EVALUATION_SHADER_OES. |
| |
| 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. 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. |
| |
| 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. |
| |
| |
| Section 11.1ts.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, except for atomic counters, 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_OES. 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_OES. 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 uniform matrix in the default uniform |
| block with single-precision components will consume no more than 4 x |
| min(r,c) uniform components. 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.11.6. Tessellation evaluation shaders also have |
| access to samplers to perform texturing operations, as described in |
| section 2.11.7. |
| |
| Tessellation evaluation shaders can access the transformed attributes of |
| all vertices for their input primitive using input variables. 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. Values for any varying |
| variables that are not written by a tessellation control shader are |
| undefined. |
| |
| Additionally, tessellation evaluation shaders can write to one or more |
| output variables that will be passed to subsequent programmable shader |
| stages or fixed functionality vertex pipeline stages. |
| |
| |
| Section 11.1ts.3.2, Tessellation Evaluation Shader Execution Environment |
| |
| If there is an active program for the tessellation evaluation stage, the |
| executable version of the program's 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. |
| |
| |
| Section 11.1ts.3.2.1, Texture Access |
| |
| Section 11.1.3.1 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. |
| |
| |
| Section 11.1ts.3.3, Tessellation Evaluation Shader Inputs |
| |
| Section 7.1 ("Built-In Variables") of the OpenGL ES 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 11.1.3). 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 |
| [[ If OES_tessellation_point_size is supported: ]] |
| and gl_PointSize. |
| |
| 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 11.1ts.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. 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 11.1ts.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 ES Shading Language doesn't |
| support multi-dimensional arrays as shader inputs or outputs; therefore, |
| user-defined tessellation evaluation shader inputs corresponding to |
| 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. |
| |
| Similarly to the limit on vertex shader output components (see section |
| 11.1.2.1), there is a limit on the number of components of 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_OES and |
| MAX_TESS_PATCH_COMPONENTS_OES, 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 input 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. |
| |
| Component counting rules for different variable types and variable |
| declarations are the same as for MAX_VERTEX_OUTPUT_COMPONENTS (see |
| section 11.1.2.1). |
| |
| |
| Section 11.1ts.3.4, 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 |
| [[ If OES_tessellation_point_size is supported: ]] |
| and gl_PointSize, |
| and behave identically to equivalently named vertex shader outputs (see |
| section 11.1.3). A tessellation evaluation shader may also declare |
| user-defined per-vertex output variables. |
| |
| Similarly to the limit on vertex shader output components (see section |
| 11.1.2.1), 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_OES. |
| |
| When a program is linked, all components of any output 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. |
| |
| Component counting rules for different variable types and variable |
| declarations are the same as for MAX_VERTEX_OUTPUT_COMPONENTS. (see |
| section 11.1.2.1). |
| |
| |
| Modify section 12.1, "Transform Feedback" |
| |
| Replace the second paragraph of the section on p. 274 (as modified |
| by OES_geometry_shader): |
| |
| The data captured in transform feedback mode depends on the active |
| programs on each of the shader stages. If a program is active for the |
| geometry shader stage, transform feedback captures the vertices of each |
| primitive emitted by the geometry shader. Otherwise, if a program is |
| active for the tessellation evaluation shader stage, transform feedback |
| captures each primitive produced by the tessellation primitive generator, |
| whose vertices are processed by the tessellation evaluation shader. |
| Otherwise, transform feedback captures each primitive processed by the |
| vertex shader. |
| |
| Modify the second paragraph following ResumeTransformFeedback on p. 277 |
| (as modified by OES_geometry_shader): |
| |
| When transform feedback is active and not paused ... 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 for the purposes of this error check. 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. |
| Any primitive type may be used while transform feedback is paused. |
| |
| |
| Modify the second paragraph of section 12.2, "Primitive Queries" on p. |
| 281: |
| |
| When BeginQuery is called with a target of PRIMITIVES_GENERATED_OES, ... |
| This counter counts the number of primitives emitted by a geometry |
| shader, if active, possibly further tessellated into separate primitives |
| during the transform feedback stage, if active. |
| |
| |
| Modify section 13.3, "Points" |
| |
| Replace the text starting "The point size is determined ..." on p. 290: |
| |
| The point size is determined by the last active stage before the |
| rasterizer: |
| |
| * the geometry shader, if active; or |
| * the tessellation evaluation shader, if active and no geometry shader |
| is active; |
| * the vertex shader, otherwise. |
| |
| If the last active stage is not a vertex shader and does not statically |
| assign a value to gl_PointSize, the point size is 1.0. Otherwise, the |
| point size is taken from the shader built-in gl_PointSize written by |
| that stage. |
| [[ Note that it is impossible to assign a value to gl_PointSize |
| if OES_geometry_point_size or OES_tessellation_point_size is not |
| supported and enabled in the relevant shader stages. ]] |
| |
| If the last active stage is a vertex shader, the point size is taken |
| from the shader built-in gl_PointSize written by the vertex shader. |
| |
| In all cases, the point size is clamped to the implementation-dependent |
| point size range. If the value written to gl_PointSize is less than or |
| equal to zero, or if no value is written to gl_PointSize (except as |
| noted above) the point size is undefined. The supported range ... |
| |
| |
| Add new section A.3ts in Appendix A before section A.4, "Atomic Counter |
| Invariance" on p. 405: |
| |
| Section A.3ts, 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. |
| |
| |
| Dependencies on OES_shader_multisample_interpolation |
| |
| If OES_shader_multisample_interpolation is not supported ignore all |
| references to the "sample in" and "sample out" qualifiers. |
| |
| New State |
| |
| Add new table 20.1ts "Current Values and Associated Data" preceding table |
| 20.2 on p. 354: |
| |
| Default |
| Get Value Type Get Command Value Description Sec. |
| ------------------------ ---- -------------- --------- ------------------------ ------------ |
| PATCH_VERTICES_OES Z+ GetIntegerv 3 Number of vertices in 10.1.7sp |
| input patch |
| |
| Add to table 20.19, "Program Pipeline Object State": |
| |
| Initial |
| Get Value Type Get Command Value Description Sec |
| -------------------------- ---- -------------------- ------- -------------------------------- --- |
| TESS_CONTROL_SHADER_OES Z+ GetProgramPipelineiv 0 Name of current tess. control 7.4 |
| shader program object |
| TESS_EVALUATION_SHADER_OES Z+ GetProgramPipelineiv 0 Name of current tess. evaluation 7.4 |
| shader program object |
| |
| Add new table 20.25ts, "Program Object State (cont.)": |
| |
| Default |
| Get Value Type Get Command Value Description Sec. |
| -------------------------------- ---- ------------ --------- ------------------------ -------- |
| TESS_CONTROL_OUTPUT_VERTICES_OES Z+ GetProgramiv 0 Output patch size 11.1ts.1 |
| for tess. control shader |
| TESS_GEN_MODE_OES E GetProgramiv QUADS_OES Base primitive type for 11.1ts.2 |
| tess. prim. generator |
| TESS_GEN_SPACING_OES E GetProgramiv EQUAL Spacing of tess. prim. 11.1ts.2 |
| generator edge subdivision |
| TESS_GEN_VERTEX_ORDER_OES E GetProgramiv CCW Order of vertices in 11.1ts.2 |
| primitives generated by |
| tess. prim generator |
| TESS_GEN_POINT_MODE_OES B GetProgramiv FALSE Tess prim. generator 11.1ts.2 |
| emits points? |
| |
| Add to table 20.28, "Program Object Resource State (cont.)": |
| |
| Initial |
| Get Value Type Get Command Value Description Sec. |
| ---------------------------------------- ---- -------------------- ------- ----------------------- ----- |
| REFERENCED_BY_TESS_CONTROL_SHADER_OES Z+ GetProgramResourceiv - Active resource used by 7.3.1 |
| tess. control shader? |
| REFERENCED_BY_TESS_EVALUATION_SHADER_OES Z+ GetProgramResourceiv - Active resource used by 7.3.1 |
| tess. eval. shader? |
| |
| New Implementation Dependent State |
| |
| Add to table 20.39 "Implementation Dependent Values": |
| |
| Minimum |
| Get Value Type Get Command Value Description Sec. |
| ------------------------------------------- ---- ----------- ------- ---------------------------- ------ |
| PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED_OES B GetBooleanv - True if primitive restart is 10.3.4 |
| supported for patches |
| |
| Add new table 20.43ts "Implementation Dependent Tessellation Shader Limits" |
| following table 6.31 "Implementation Dependent Vertex Shader Limits": |
| |
| Minimum |
| Get Value Type Get Command Value Description Sec. |
| ------------------------- ---- ----------- ------- ------------------------------- ------ |
| MAX_TESS_GEN_LEVEL_OES Z+ GetIntegerv 64 Max. level supported by 11.1ts.2 |
| tess. primitive generator |
| MAX_PATCH_VERTICES_OES Z+ GetIntegerv 32 Maximum patch size 10.1 |
| MAX_TESS_CONTROL_UNIFORM_COMPONENTS_OES Z+ GetIntegerv 1024 No. of words for TCS uniforms 11.1ts.1.1 |
| MAX_TESS_EVALUATION_UNIFORM_COMPONENTS_OES Z+ GetIntegerv 1024 No. of words for TES uniforms 11.1ts.3.1 |
| MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS_OES Z+ GetIntegerv 16 No. of tex. image units for TCS 11.1.3.5 |
| MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS_OES Z+ GetIntegerv 16 No. of tex. image units for TES 11.1.3.5 |
| MAX_TESS_CONTROL_OUTPUT_COMPONENTS_OES Z+ GetIntegerv 64 No. components for per-patch 11.1ts.1.2 |
| vertex outputs in TCS |
| MAX_TESS_PATCH_COMPONENTS_OES Z+ GetIntegerv 120 No. components for per-patch 11.1ts.1.2 |
| output varyings for TCS |
| MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS_OES Z+ GetIntegerv 2048 Total no. components for TCS 11.1ts.1.2 |
| outputs |
| MAX_TESS_EVALUATION_OUTPUT_COMPONENTS_OES Z+ GetIntegerv 64 No. components for per-vertex 11.1ts.3.2 |
| outputs in TES |
| MAX_TESS_CONTROL_INPUT_COMPONENTS_OES Z+ GetIntegerv 64 No. components for per-vertex 11.1ts.1.2 |
| inputs in TCS |
| MAX_TESS_EVALUATION_INPUT_COMPONENTS_OES Z+ GetIntegerv 64 No. components for per-vertex 11.1ts.3.2 |
| inputs in TES |
| MAX_TESS_CONTROL_UNIFORM_BLOCKS_OES Z+ GetIntegerv 12 No. of supported uniform 7.6.2 |
| blocks for TCS |
| MAX_TESS_EVALUATION_UNIFORM_BLOCKS_OES Z+ GetIntegerv 12 No. of supported uniform 7.6.2 |
| blocks for TES |
| MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS_OES Z+ GetIntegerv 0 No. of AC (atomic counter) 7.7 |
| buffers accessed by a TCS |
| MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS_OES Z+ GetIntegerv 0 No. of AC (atomic counter) 7.7 |
| buffers accessed by a TES |
| MAX_TESS_CONTROL_ATOMIC_COUNTERS_OES Z+ GetIntegerv 0 Number of ACs accessed by a TCS 11.1.3.6 |
| MAX_TESS_EVALUATION_ATOMIC_COUNTERS_OES Z+ GetIntegerv 0 Number of ACs accessed by a TES 11.1.3.6 |
| MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS_OES Z+ GetIntegerv 0 No. of shader storage blocks 7.8 |
| accessed by a TCS |
| MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS_OES Z+ GetIntegerv 0 No. of shader storage blocks 7.8 |
| accessed by a TES |
| |
| |
| Add to table 20.46 "Implementation Dependent Aggregate Shader Limits" |
| ([fn] is a dagger mark referring to existing text in the table caption): |
| |
| |
| Minimum |
| Get Value Type Get Command Value Description Sec. |
| --------------------------------------------------- ---- ----------- ------- ----------------------------- ---------- |
| MAX_TESS_CONTROL_IMAGE_UNIFORMS_OES Z+ GetIntegerv 0 No. of image variables in TCS 11.1.3.7 |
| in TCS |
| MAX_TESS_EVALUATION_IMAGE_UNIFORMS_OES Z+ GetIntegerv 0 No. of image variables in TES 11.1.3.7 |
| MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS_OES Z+ GetIntegerv [fn] No. of words for TCS uniform 11.1ts.1.1 |
| variables in all uniform |
| blocks (including default) |
| MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS_OES Z+ GetIntegerv [fn] No. of words for TES uniform 11.1ts.3.1 |
| variables in all uniform |
| blocks (including default) |
| |
| Modify existing entries in table 20.46: |
| |
| Minimum |
| Get Value Type Get Command Value Description Sec. |
| -------------------------------------------- ---- ----------- ------- -------------------------- ------- |
| MAX_UNIFORM_BUFFER_BINDINGS Z+ GetIntegerv 72 Max. no. of uniform buffer 7.6.2 |
| binding points |
| MAX_COMBINED_UNIFORM_BLOCKS Z+ GetIntegerv 60 Max. no. of uniform 7.6.2 |
| buffers per program |
| MAX_COMBINED_TEXTURE_IMAGE_UNITS Z+ GetIntegerv 96 Total no. of tex. units 11.1.3.5 |
| accessible by the GL |
| |
| Additions to the OpenGL ES Shading Language 3.10 Specification |
| |
| Including the following line in a shader can be used to control the |
| language features described in this extension: |
| |
| #extension GL_OES_tessellation_shader : <behavior> |
| #extension GL_OES_tessellation_point_size : <behavior> |
| |
| where <behavior> is as specified in section 3.4. |
| |
| A new preprocessor #define is added to the OpenGL ES Shading Language: |
| |
| #define GL_OES_tessellation_shader 1 |
| #define GL_OES_tessellation_point_size 1 |
| |
| If the OES_tessellation_shader extension is enabled, the |
| OES_shader_io_blocks extension is also implicitly enabled. |
| |
| |
| Change the introduction to Chapter 2 "Overview of OpenGL ES Shading" as |
| follows: |
| |
| The OpenGL ES Shading Language is actually several closely related |
| languages. These languages are used to create shaders for each of the |
| programmable processors contained in the OpenGL ES processing pipeline. |
| Currently, these processors are the compute, vertex, tessellation |
| control, tessellation evaluation, geometry, and fragment processors. |
| |
| Unless otherwise noted in this Specification, 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: compute, vertex, tessellation control, |
| tessellation evalution, geometry, or fragment. |
| |
| |
| Add new subsections 2.ts1 and 2.ts2 preceding subsection 2.gs "Geometry |
| Processor": |
| |
| Section 2.ts1, 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 ES |
| Shading Language to run on this processor are called tessellation |
| control shaders. When a tessellation control shader is compiled and |
| linked, it results in a tessellation control shader executable that runs |
| on the tessellation control processor. |
| |
| The tessellation control processor is invoked for each 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.ts2, 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 ES |
| Shading Language to run on this processor are called tessellation |
| evaluation shaders. When a tessellation evaluation shader is compiled |
| and linked, it results in a tessellation evaluation shader executable |
| that runs on the tessellation evaluation processor. |
| |
| Each invocation of the tessellation evaluation executable computes 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. |
| |
| |
| Modifications to Section 3.7 (Keywords) |
| |
| Remove "patch" from the list of reserved keywords and add it to the list |
| of keywords. |
| |
| |
| Modify Section 4.3, Storage Qualifiers |
| |
| Add two new qualifiers to the storage qualifier table on p. 38: |
| |
| 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, Input Variables |
| |
| Replace the paragraphs starting with "Geometry shader input variables |
| get ..." and ending with "Fragment shader inputs get ..." on p. 40: |
| |
| Tessellation control, evaluation, and geometry shader input variables |
| get the per-vertex values written out by output variables of the same |
| names in the previous active (vertex) shader stage. For these inputs, |
| "centroid in", "sample in", and interpolation qualifiers are allowed, |
| but are equivalent to "in". Since these shader stages operate on a set |
| of vertices, each input variable or input block (see section 4.3.9 |
| "Interface Blocks") needs to be declared as an array. For example, |
| |
| in float foo[]; // geometry shader input for vertex "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.4.1 "Input Layout Qualifiers". |
| |
| Some inputs and outputs are <arrayed>, meaning that for an interface |
| between two shader stages either the input or output declaration |
| requires an extra level of array indexing for the declarations to match. |
| For example, with the interface between a vertex shader and a geometry |
| shader, vertex shader output variables and geometry shader input |
| variables of the same name must match in type and qualification (other |
| than precision and "out" matching to "in"), except that the geometry |
| shader will have one more array dimension than the vertex shader, to |
| allow for vertex indexing. If such an arrayed interface variable is not |
| declared with the necessary additional input or output array dimension, |
| a link-time error will result. |
| |
| For non-arrayed interfaces (meaning array dimensionally stays the same |
| between stages), it is a link-time error if the input variable is not |
| declared with the same type, including array dimensionality, and |
| qualification (other than precision and "out" matching to "in") as the |
| matching output variable. |
| |
| 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. Applying the "patch in" qualifier to inputs can only be done in |
| tessellation evaluation shaders. As with other input variables, |
| per-patch inputs must be declared using the same type and qualification |
| (other than precision and "out" matching to "in") as per-patch outputs |
| from the previous (tessellation control) shader stage. |
| |
| It is a compile-time error to use the "patch in" qualifier with inputs |
| in any type of shader other than tessellation evaluation. |
| |
| Fragment shader inputs get ... |
| |
| |
| Modify section 4.3.6 "Output Variables" starting with the third |
| paragraph of the section, on p. 42: |
| |
| Vertex, tessellation evaluation, and geometry output variables output |
| per-vertex data and are declared using the "out", "centroid out", or |
| "sample out" storage qualifiers. Applying the "patch out" qualifier to |
| an output can only be done in tessellation control shaders. Output |
| variables can only be floating-point scalars, floating-point vectors, |
| matrices, signed or unsigned integers or integer vectors, or arrays or |
| structures of any of these. |
| |
| It is a compile-time error to use the "patch out" qualifier with outputs |
| in any other type of shader other than tessellation control. |
| |
| Individual vertex, tessellation control, tessellation evaluation, and |
| geometry outputs are declared as in the following examples: ... |
| |
| |
| Following this modified language and leading into the last paragraph of |
| section 4.3.6 on p. 37 (starting "Fragment outputs output |
| per-fragment"), add: |
| |
| Tessellation control shader output variables are used to output |
| per-vertex and per-patch data. Per-vertex output variables are arrayed |
| (see "arrayed" in section 4.3.4, "Inputs") and declared using the "out", |
| "centroid out", or "sample out" qualifiers; the "patch out" qualifier is |
| not allowed. Per-patch output variables must be declared using the |
| "patch out" qualifier. Per-vertex and per-patch output variables can |
| only be floating-point scalars, vectors, or matrices, signed or unsigned |
| integers or integer vectors, or arrays or structures of these. Since |
| tessellation control shaders produce an arrayed 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.4.2.ts "Tessellation |
| Control Outputs". |
| |
| 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 a compile- or link-time error if the expression |
| indicating the vertex index 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 |
| barrier(), its execution pauses until all other invocations have reached |
| the same point of execution. 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 execute in undefined |
| order between barriers, the values of per-vertex or per-patch output |
| variables will sometimes be undefined. Consider the beginning and end of |
| shader execution and each call to barrier() as 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, or |
| * 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. |
| 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. |
| |
| Fragment outputs output per-fragment data and are declared ... |
| |
| |
| Modify section 4.4.1 "Input Layout Qualifiers" to add new subsections |
| 4.4.1.ts and 4.4.2.ts, preceding the new subsection 4.4.1.gs "Geometry |
| Shader Inputs": |
| |
| Section 4.4.1.ts, Tessellation Evaluation Inputs |
| |
| Additional 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 these identifiers, <primitive mode>, 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 these identifiers, <vertex spacing>, is used to |
| specify the 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 subset of these identifiers, <ordering>, specifies whether the |
| tessellation primitive generator produces triangles in clockwise or |
| counter-clockwise order, according to the coordinate system depicted in |
| the OpenGL ES 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. |
| |
| Finally, <point mode> is specified with the identifier "point_mode" |
| indicating 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. |
| |
| The tessellation evaluation shader object in a program must declare a |
| primitive mode in its input layout. Declaring vertex spacing, ordering, |
| or point mode identifiers is optional. 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. |
| |
| |
| Section 4.4.2.ts, Tessellation Control Outputs |
| |
| Other than for the transform feedback layout qualifiers, tessellation |
| control shaders allow output layout qualifiers only on the interface |
| qualifier "out", not on an output block, block member, or variable |
| declaration. 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 a |
| compile- or link-time 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 a tessellation control shader. |
| |
| |
| Modify section 7 to add new subsections 7.1ts1 and 7.1ts2 following |
| section 7.1.1 "Vertex Shader Special Variables": |
| |
| Section 7.1ts1, Tessellation Control Special Variables |
| |
| In the tessellation control language, built-in variables are |
| intrinsically declared as: |
| |
| [[ If OES_tessellation_point_size is supported and enabled: ]] |
| in gl_PerVertex { |
| highp vec4 gl_Position; |
| hihgp float gl_PointSize; |
| } gl_in[gl_MaxPatchVertices]; |
| |
| [[ Otherwise: ]] |
| in gl_PerVertex { |
| highp vec4 gl_Position; |
| } gl_in[gl_MaxPatchVertices]; |
| |
| in highp int gl_PatchVerticesIn; |
| in highp int gl_PrimitiveID; |
| in highp int gl_InvocationID; |
| |
| [[ If OES_tessellation_point_size is supported and enabled: ]] |
| out gl_PerVertex { |
| highp vec4 gl_Position; |
| highp float gl_PointSize; |
| } gl_out[]; |
| |
| [[ Otherwise: ]] |
| out gl_PerVertex { |
| highp vec4 gl_Position; |
| } gl_out[]; |
| |
| patch out highp float gl_TessLevelOuter[4]; |
| patch out highp float gl_TessLevelInner[2]; |
| |
| |
| Section 7.1ts1.1, Tessellation Control Input Variables |
| |
| gl_Position contains the output written in the previous shader stage to |
| gl_Position. |
| |
| [[ If OES_tessellation_point_size is supported: ]] |
| gl_PointSize contains the output written in the previous shader stage to |
| gl_PointSize. |
| |
| gl_PatchVerticesIn contains the number of vertices in the input patch |
| being processed by the shader. A single shader can read patches of |
| differing sizes, so the value of gl_PatchVerticesIn may differ between |
| patches. |
| |
| gl_PrimitiveID contains the number of primitives processed by the |
| shader since the current set of rendering primitives was started. |
| |
| gl_InvocationID contains the number of the output patch vertex assigned |
| to the tessellation control shader invocation. It is assigned integer |
| values in the range [0, N-1], where N is the number of output patch |
| vertices per primitive. |
| |
| |
| Section 7.1ts1.2, Tessellation Control Output Variables |
| |
| gl_Position is used in the same fashion as the |
| corresponding output variable in the vertex shader. |
| |
| [[ If OES_tessellation_point_size is supported: ]] |
| gl_PointSize is used in the same fashion as the corresponding output |
| variable in the vertex shader. |
| |
| The values written to gl_TessLevelOuter and gl_TessLevelInner 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. |
| |
| |
| Section 7.1ts2, Tessellation Evaluation Special Variables |
| |
| In the tessellation evaluation language, built-in variables are |
| intrinsically declared as: |
| |
| [[ If OES_tessellation_point_size is supported and enabled: ]] |
| in gl_PerVertex { |
| highp vec4 gl_Position; |
| highp float gl_PointSize; |
| } gl_in[gl_MaxPatchVertices]; |
| |
| [[ Otherwise: ]] |
| in gl_PerVertex { |
| highp vec4 gl_Position; |
| } gl_in[gl_MaxPatchVertices]; |
| |
| in highp int gl_PatchVerticesIn; |
| in highp int gl_PrimitiveID; |
| in highp vec3 gl_TessCoord; |
| patch in highp float gl_TessLevelOuter[4]; |
| patch in highp float gl_TessLevelInner[2]; |
| |
| [[ If OES_tessellation_point_size is supported and enabled: ]] |
| out gl_PerVertex { |
| highp vec4 gl_Position; |
| hihgp float gl_PointSize; |
| }; |
| |
| [[ Otherwise: ]] |
| out gl_PerVertex { |
| highp vec4 gl_Position; |
| }; |
| |
| Section 7.1ts2.1, Tessellation Evaluation Input Variables |
| |
| gl_Position contains the output written in the previous shader stage to |
| gl_Position. |
| |
| [[ If OES_tessellation_point_size is supported: ]] |
| gl_PointSize contains the output written in the previous shader stage to |
| gl_PointSize. |
| |
| gl_PatchVerticesIn and gl_PrimitiveID are defined in the same fashion as |
| the corresponding input variables in the tessellation control shader. |
| |
| gl_TessCoord 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. Its values will obey the properties |
| |
| gl_TessCoord.x == 1.0 - (1.0 - gl_TessCoord.x) // two operations performed |
| gl_TessCoord.y == 1.0 - (1.0 - gl_TessCoord.y) // two operations performed |
| gl_TessCoord.z == 1.0 - (1.0 - gl_TessCoord.z) // two operations performed |
| |
| gl_TessLevelOuter and gl_TessLevelInner are filled with the corresponding |
| output variables written by the active tessellation control shader. |
| |
| |
| Section 7.1ts2.2, Tessellation Evaluation Output Variables |
| |
| gl_Position is used in the same fashion as the |
| corresponding output variable in the vertex shader. |
| |
| [[ If OES_tessellation_point_size is supported: ]] |
| gl_PointSize is used in the same fashion as the corresponding output |
| variable in the vertex shader. |
| |
| |
| Add to Section 7.2 "Built-In Constants", matching the |
| corresponding API implementation-dependent limits: |
| |
| const mediump int gl_MaxTessControlInputComponents = 64; |
| const mediump int gl_MaxTessControlOutputComponents = 64; |
| const mediump int gl_MaxTessControlTextureImageUnits = 16; |
| const mediump int gl_MaxTessControlUniformComponents = 1024; |
| const mediump int gl_MaxTessControlTotalOutputComponents = 2048; |
| |
| const mediump int gl_MaxTessEvaluationInputComponents = 64; |
| const mediump int gl_MaxTessEvaluationOutputComponents = 64; |
| const mediump int gl_MaxTessEvaluationTextureImageUnits = 16; |
| const mediump int gl_MaxTessEvaluationUniformComponents = 1024; |
| |
| const mediump int gl_MaxTessPatchComponents = 120; |
| |
| const mediump int gl_MaxPatchVertices = 32; |
| const mediump int gl_MaxTessGenLevel = 64; |
| |
| Modify gl_MaxCombinedTextureImageUnits to match the API: |
| |
| const mediump int gl_MaxCombinedTextureImageUnits = 96; |
| |
| |
| Modify section 8.15 "Shader Invocation Control Functions": |
| |
| The shader invocation control function is only available in tessellation |
| control and compute shaders. It is used to control the relative |
| execution order of multiple shader invocations used to process a patch |
| (in the case of tessellation control shaders) or a workgroup (in |
| the case of compute shaders), which are otherwise executed with an |
| undefined order. |
| |
| +------------------+---------------------------------------------------------------+ |
| | Syntax | Description | |
| +------------------+---------------------------------------------------------------+ |
| | void | For any given static instance of barrier(), all | |
| | barrier(void) | tessellation control shader invocations for a single input | |
| | | patch, or all compute shader invocations for a single work | |
| | | group must enter it before any will continue beyond it. | |
| +------------------+---------------------------------------------------------------+ |
| |
| The function barrier() provides a partially defined order of execution |
| between shader invocations. This ensures that values written by one |
| invocation prior to a given static instance of barrier() can be safely |
| read by other invocations after their call to the same static instance |
| barrier(). Because invocations may execute in an undefined order between |
| these barrier calls, the values of a per-vertex or per-patch output |
| variable for tessellation control shaders, or the values of shared |
| variables for compute shaders will be undefined in a number of cases |
| enumerated in section 4.3.6 "Output Variables" (for tessellation control |
| shaders) and section 4.3.7 "Shared Variables" (for compute shaders). |
| |
| For tessellation control shaders, the barrier() function may only be |
| placed inside the function main() of the shader and may not be called |
| within any control flow. Barriers are also disallowed after a return |
| statement in the function main(). Any such misplaced barriers result in |
| a compile-time error. |
| |
| For compute shaders, the barrier() function ... |
| |
| |
| Issues |
| |
| Note: These issues apply specifically to the definition of the |
| OES_tessellation_shader specification, which is based on the OpenGL |
| extension ARB_tessellation_shader as updated in OpenGL 4.x. Resolved |
| issues from ARB_tessellation_shader have been removed, but remain |
| largely applicable to this extension. ARB_tessellation_shader can be |
| found in the OpenGL Registry. |
| |
| (1) What functionality was removed from ARB_tessellation_shader? |
| |
| Very little. Tessellation shaders are largely self-contained |
| functionality and the only removed interactions with features not |
| supported by the underlying OpenGL ES 3.1 API and Shading Language |
| were: |
| * Fixed-function inputs and outputs present only in the GL |
| compatibility profile. |
| * gl_ClipDistance shader inputs and outputs. |
| * While multi-dimensional arrays are supported by GLSL-ES 3.10, |
| they are explicitly not supported |
| as shader inputs and outputs, and that decision is respected |
| here. |
| * Using a tessellation evaluation shader without a tessellation |
| control shader is not allowed. See issue 13. |
| * PATCH_DEFAULT_*_LEVEL parameters (issue 13). |
| |
| (2) What functionality was changed and added relative to |
| ARB_tessellation_shader? |
| |
| - OES_tessellation_shader closely matches OpenGL 4.4 tessellation |
| shader language, rather than ARB_tessellation_shader language. |
| - Spec language is now based off of changes introduced by |
| OES_geometry_shader, especially with regard to input and output |
| blocks. |
| - Note that although this spec mentions quad primitives repeatedly, |
| this is not inconsistent with the lack of support for QUADS drawing |
| primitives in OpenGL ES. The quad primitives discussed here occur |
| only during patch tessellation and are emitted as triangles to later |
| stages of the pipeline. |
| - Writing point size from tessellation shaders is optional functionality. |
| If it's not supported or written, the point size of 1.0 is used. |
| - Added precision qualifiers to builtins. |
| - ARB_tessellation_shader required that the tessellation primitive |
| generator reject a patch when any outer tessellation level contained a |
| NaN, even if the outer tessellation level is irrelevant for the |
| primitive type. As that was likely unintended (see Khronos bug 11484), |
| OES_tessellation_shader only rejects patches if relevant outer |
| tessellation levels contain NaN. |
| - Added program interface query properties relevant to tessellation |
| shaders. |
| |
| (3) Are any grammar additions required in chapter 9? |
| |
| Probably, but such changes are not included in the original |
| ARB_tessellation_shader extension, either. TBD. |
| |
| (4) Should GetActiveUniformBlockiv |
| support queries for uniform blocks and atomic counter buffers |
| referenced by tessellation shaders? |
| |
| RESOLVED: No. Use the new generic query interface supported by |
| OpenGL ES 3.1, following the resolution for other features such as |
| compute shaders, which also dropped these legacy tokens / queries. |
| |
| (5) How are aggregate shader limits computed? |
| |
| RESOLVED: Following the GL 4.4 model, but we restrict uniform |
| buffer bindings to 12/stage instead of 14, this results in |
| |
| MAX_UNIFORM_BUFFER_BINDINGS = 72 |
| This is 12 bindings/stage * 6 shader stages, allowing a static |
| partitioning of the bindings even though at most 5 stages can |
| appear in a program object). |
| MAX_COMBINED_UNIFORM_BLOCKS = 60 |
| This is 12 blocks/stage * 5 stages, since compute shaders can't |
| be mixed with other stages. |
| MAX_COMBINED_TEXTURE_IMAGE_UNITS = 96 |
| This is 16 textures/stage * 6 stages. |
| |
| Khronos internal bugs 5870, 8891, and 9424 cover the ARB's thinking on |
| these limits for GL 4.0 and beyond. |
| |
| (6) Are arrays supported as shader inputs and outputs? |
| |
| RESOLVED: No. In several places in the tessellation and geometry API |
| language based on GL 4.4, it says that "the OpenGL ES Shading Language |
| doesn't support multi-dimensional arrays" and restricts declarations of |
| inputs and outputs which are array members to blocks themselves declared |
| as arrays. |
| |
| Strictly speaking this is no longer true. GLSL-ES 3.10 supports |
| multi-dimensional arrays, but also notes in issue 0 that "arrays of |
| arrays are not allowed as shader inputs or outputs." |
| |
| Given this constraint, and since the same constraint is in OpenGL 4.4, I |
| propose we resolve this by continuing to limit array inputs and outputs |
| in this fashion, and change the language to "...doesn't support |
| multi-dimensional arrays as shader inputs or outputs". |
| |
| (7) What component counting rules are used for inputs and outputs? |
| |
| RESOLVED: In several places I've inserted language from OpenGL 4.4 to |
| the effect of |
| |
| "Component counting rules for different variable types and variable |
| declarations are the same as for MAX_VERTEX_OUTPUT_COMPONENTS (see |
| section 11.1.2.1)." |
| |
| I think this is essentially cleaning up an oversight in the earlier ARB |
| extension language but it is a bit orthogonal to the extension |
| functionality and I'm bringing it up in case this is a potential issue. |
| |
| (8) What component counting rules are used for the default |
| uniform block? |
| |
| RESOLVED: In several places I've inserted language from OpenGL 4.2 to |
| the effect of |
| |
| "A uniform matrix in the default uniform block with single-precision |
| components will consume no more than 4 x min(r,c) uniform |
| components." |
| |
| This is based on bug 5432 and is language that was later expanded in |
| OpenGL 4.4 and refactored into the generic "Uniform Variables" section, |
| which is something we should consider in the OES extensions as well to |
| avoid duplication. I believe it is what we want but am noting it for the |
| same reason as the language in issue (8). I'm hoping to be able to |
| include this refactored language into the OpenGL ES 3.1 Specification, |
| so we can refer to it more easily here. Tracking bug 11192 has been |
| opened for this and this language was approved there. |
| |
| (9) The edits on section 4.4.1.ts (Tessellation Evaluation Inputs) |
| says that "Any or all of these identifiers may be specified one or more |
| times in a single input layout declaration." Do we need to add in the |
| language from GLSL 4.40 Section 4.4 "Layout Qualifiers" that defines this? |
| |
| RESOLVED: ES 3.1 will be picking up the relaxed qualifier ordering |
| and it is presumed that this language will be coming along with it. |
| In any case, the OES_shader_io_blocks extension clarifies this. |
| |
| (10) Due to HW limitations, some vendors may not be able |
| to support writing gl_PointSize from tessellation shaders, how should we |
| accomodate this? |
| |
| RESOLVED: There are two extensions described in this document. The |
| base extension does not support writing to gl_PointSize from tessellation |
| shaders and the gl_PerVertex block does not include gl_PointSize. |
| Additionally there is a layered extension which provides the ability |
| to write to gl_PointSize from tessellation shaders. When this extension |
| is enabled, the gl_PerVertex block does include gl_PointSize and it |
| can be written from a tessellation control or evaluation shader as normal. |
| |
| If the point-size extension is not supported, all points written |
| from a tessellation shader will have size of one. If the point-size |
| extension is supported but not enabled, or if it's enabled but |
| gl_PointSize is not written, it as if a point size of one was written. |
| Otherwise, if you statically assign gl_PointSize in the last stage |
| before the rasterizer, the (potentially clamped) value written will |
| determine the size of the point for rasterization. |
| |
| (11) Do we need a separate point_size extension from the one included |
| in OES_geometry_shader or can we use the some one? |
| |
| RESOLVED. We will use a separate extension to allow for maximum |
| implementation flexibility. |
| |
| (12) Can a tessellation evaluation shader be used without a tessellation |
| control shader? |
| |
| RESULT: No. This isn't allowed in other graphics APIs, and some vendors |
| designed hardware based on those APIs. Attempts to draw with only one of the |
| two tessellation shaders active results in an INVALID_OPERATION error. |
| Vendors that designed hardware for ARB_tessellation_shader or versions of |
| OpenGL that included it may choose to relax this restriction via extension. |
| One implication of this is that the default tessellation levels are useless, |
| since an active tessellation control shader always overrides them, so they |
| are not included in this spec. |
| |
| (13) What happens if you use "patch out" in a tessellation evaluation |
| shader or "patch in" in a tessellation control shader? |
| |
| RESOLVED. GLSL 4.40 spec only says "Applying the patch qualifier to |
| inputs can only be done in tessellation evaluation shaders." and |
| "Applying patch to an output can only be done in a tessellation control |
| shader." There is also a statement that says "It is a compile-time error |
| to use patch in a fragment shader." In Bug 11527 the ARB decided this |
| should be a compile-time error as this can be determined by solely by |
| looking at variable declaration. |
| |
| (14) Do we need to make accommodations for tile-based implementations? |
| |
| RESOLVED. Yes, but it will be done as a separate extension as it is |
| applicable to more than just tessellation shaders. |
| |
| (15) Can inputs and outputs from tessellation shaders be arrays of |
| structures? |
| |
| RESOLVED. Yes they can. OpenGL ES 3.1 disallows passing arrays of |
| structures between stages. However, since vertex shader outputs |
| can be structures we need to add the extra level of |
| array-ness when these are accessed from a tessellation control shader. |
| Similarly this applies to outputs from a tessellation control shader |
| and inputs to a tessellation evaluation shader. However as in GL, |
| arrays of arrays are not supported. |
| |
| (16) 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 |
| ---- ---------- --------- ------------------------------------------------- |
| 7 12/10/2018 Jon Leech Use 'workgroup' consistently throughout (Bug |
| 11723, internal API issue 87). |
| |
| 6 05/31/2016 Jon Leech Note that primitive ID counters are reset to zero |
| after each instance drawn (Bug 14024). |
| |
| 5 04/29/2016 Jon Leech Fix GLSL-ES built-in constants to match API |
| limits (Bug 12823). |
| |
| 4 04/27/2016 Jon Leech Reduce minimum value of |
| MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS |
| from 4096 to 2048 (Bug 12823). |
| |
| 3 07/23/2015 Jon Leech Reduce minimum value of |
| MAX_TESS_{CONTROL,EVALUATION}_{IN,OUT}PUT_COMPONENTS |
| to 64 (Bug 12823) |
| |
| 2 05/05/2015 dkoch Remove "per-patch" part of description of |
| MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS |
| (Bug 13765). |
| Allow arrays for both per-patch and per-vertex |
| TCS outputs (Bug 13658). |
| Fix typo in issue 15 suggesting that VS outputs |
| could be an array of structures (Bug 13824). |
| |
| 1 06/18/2014 dkoch Initial OES version based on EXT. |
| No functional changes. |