Name NV_tessellation_program5 Name Strings (none) Contact Pat Brown, NVIDIA Corporation (pbrown 'at' nvidia.com) Status Shipping. Version Last Modified Date: 12/19/2011 NVIDIA Revision: 3 Number 391 Dependencies OpenGL 1.1 is required. This extension is written against the OpenGL 2.1 specification. NV_gpu_program5 is required. This extension is supported if and only "GL_NV_gpu_program5" is found in the extension string. This extension is written against the NV_gpu_program5 extension. This specification interacts with ARB_tessellation_shader. This specification interacts with NV_parameter_buffer_object. Overview This extension, in conjunction with the ARB_tessellation_shader extension, introduces a new tessellation stage to the OpenGL primitive processing pipeline. The ARB_tessellation_shader extension provides programmable shading functionality using the OpenGL Shading Language as its base; this extension provides assembly programmable shaders building on the family of assembly programmability extensions including ARB_vertex_program, ARB_fragment_program, NV_gpu_program4, and NV_geometry_program4. This extension adds a new basic primitive type, called a patch, which consists of an array of vertices plus some associated per-patch state. It also adds two new assembly program types: a tessellation control program that transforms a patch into a new patch and a tessellation evaluation program that computes the position and attributes of each vertex produced by the tesselator. When tessellation is active, it begins by running the optional tessellation control program, if enabled. This program consumes a variable-size 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 program invocations are performed -- one per output patch vertex. Each tessellation control program invocation writes all the attributes of its corresponding output patch vertex. A tessellation control program may also read the per-vertex outputs of other tessellation control program invocations, as well as read and write shared per-patch outputs. The tessellation control program invocations for a single patch effectively run as a group. The GL automatically synchronizes threads to ensure that when executing a given instruction, all previous instructions have completed for all program invocations in the group. 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_NV splits a quad-shaped patch into a set of line strips spanning the patch. 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 program is run to compute its position and other attributes of the vertex, using its (u,v) or (u,v,w) coordinate. When computing the final vertex attributes, the tessellation evaluation program can also read the attributes of any of the vertices of the patch written by the tessellation control program. Tessellation evaluation program 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 program or fixed-function vertex processing. The primitives generated by the tessellator are passed further down the OpenGL pipeline, where they can be used as inputs to geometry programs, transform feedback, and the rasterizer. The tessellation control and evaluation programs are both optional. If neither program type is present, the tessellation stage has no effect. If no tessellation control program is present, the input patch provided by the application is passed directly to the tessellation primitive generator, and a set of fixed tessellation level parameters (specified via the PatchParameterfv function) is used to control primitive generation. If no tessellation evaluation program is present, the output patch produced by the tessellation control program is passed as a patch to subsequent pipeline stages, where it can be consumed by geometry programs, transform feedback, or the rasterizer. New Procedures and Functions None (Note: The PatchParameteri and PatchParameterfv functions from ARB_tessellation_shader will also be used by this extension.) New Tokens Accepted by the parameter of Disable, Enable, and IsEnabled, by the parameter of GetBooleanv, GetIntegerv, GetFloatv, and GetDoublev, and by the parameter of ProgramStringARB, BindProgramARB, ProgramEnvParameter4[df][v]ARB, ProgramLocalParameter4[df][v]ARB, GetProgramEnvParameter[df]vARB, GetProgramLocalParameter[df]vARB, GetProgramivARB and GetProgramStringARB: TESS_CONTROL_PROGRAM_NV 0x891E TESS_EVALUATION_PROGRAM_NV 0x891F Accepted by the parameter of ProgramBufferParametersfvNV, ProgramBufferParametersIivNV, and ProgramBufferParametersIuivNV, BindBufferRangeNV, BindBufferOffsetNV, BindBufferBaseNV, and BindBuffer and the parameter of GetIntegerIndexedvEXT: TESS_CONTROL_PROGRAM_PARAMETER_BUFFER_NV 0x8C74 TESS_EVALUATION_PROGRAM_PARAMETER_BUFFER_NV 0x8C75 Accepted by the parameter of GetProgramivARB: MAX_PROGRAM_PATCH_ATTRIBS_NV 0x86D8 (Note: Various enumerants from ARB_tessellation_shader will also be used by this extension.) Additions to Chapter 2 of the OpenGL 1.5 Specification (OpenGL Operation) (Incorporate Section 2.X of the ARB_tessellation_shader specification, Tessellation in its entirety.) Insert a new section after Section 2.X.1 in ARB_tessellation_shader, Tessellation Control Shaders Tessellation Control Programs Each patch primitive may be optionally processed by a tessellation control program, which operates similarly to the tessellation control shader described above. Tessellation control programs are enabled by calling Enable with the value TESS_CONTROL_PROGRAM_NV. If a GLSL program is active, the tessellation control program enable is ignored and treated as disabled unless the program contains only fragment shaders. When enabled, each patch primitive received by the GL will be processed by the tessellation control program to produce a new patch. The tessellation control program emits a patch with a fixed number of vertices, given by the value specified in the VERTICES_OUT declaration. It computes the attributes of each vertex of the output patch in parallel, and assembles the emitted vertices into an output patch. The program also computes per-patch tessellation level values that control the number of vertices produced by the tessellation primitive generator when that patch is processed. The program may also compute additional generic per-patch attributes that may be accessed by invocations of the tessellation evaluation program or a subsequent geometry program when processing the patch. When the tessellation control program completes, the input patch is discarded and the output patch is processed by the remainder of the GL pipeline. Each patch processed by the tessellation control program will result in multiple program invocations (threads), with one invocation per output patch vertex. Each program invocation has a corresponding output patch vertex, and can write per-vertex attributes only for that vertex. All program invocations may read and write per-patch attributes of the output patch, and may read per-vertex attributes of any vertex in the output patch. The tessellation control program threads are run as a group, and execute effectively in lock-step. In this model, the execution of each instruction completes for all active threads before the execution of subsequent instruction is started. All threads in the group are initially active, but the set of active threads change as flow-control instructions are encountered. Full details on the execution model are specified in Section 2.X.5. Tessellation control programs execute using the instruction set documented in the GL_NV_gpu_program5 extension specification. Tessellation control programs can read attributes from all vertices of the input patch, and each vertex attribute access must identify the vertex number being accessed. For example, "vertex[1].position" and "vertex.in[1].position" identify the position of the second vertex (numbered "1") in the input patch. Programs may also read attributes of all vertices of the output patch (e.g., "vertex.out[2].position") and per-patch attributes of the output patch (e.g., "primitive.out.attrib[3]"). In both cases, the output patch vertices or attributes accessed in this manner are undefined unless written by a previous instruction executed on one of the threads. Programs may also write attributes of their corresponding vertex in the output patch (e.g., "result.attrib[0]") and shared per-patch attributes (e.g., "result.patch.attrib[4]"). When writing output patch vertex attributes, a vertex number is not supplied. The only input primitives supported by tessellation control programs are patches. The error INVALID_OPERATION is generated by Begin (or vertex array functions that implicitly call Begin) if a tessellation control program is active and is not PATCHES_NV. Modify section after Section 2.X.2 of ARB_tessellation_shader, Tessellation Primitive Generation (add to the end of the section describing the operation of the tessellation primitive generator when assembly tessellation evaluation programs are used) If no GLSL program object is active, or if the active program contains only a fragment shader, the tessellation primitive generator will be active if and only if an assembly tessellation evaluation program is enabled. When a tessellation evaluation program is used, the tessellation primitive generator will operate in exactly the manner describe above, except that the parameters controlling tessellation will be taken from declaration statements in the tessellation evaluation program. The declaration statements used to specify each tessellation parameter are as described in Table X.1. GLSL Program Parameter TEP Declaration ------------------------ ----------------- TESS_GEN_MODE_NV TESS_MODE TESS_GEN_SPACING_NV TESS_SPACING TESS_GEN_VERTEX_ORDER_NV TESS_VERTEX_ORDER TESS_GEN_POINT_MODE_NV TESS_POINT_MODE Table X.1, Parameters used to control tessellation when a program object with a tessellation evaluation shader is active and their tessellation evaluation program equivalents. If no tessellation control program is enabled, the default tessellation levels specified by calling PatchParameterfvNV with a of PATCH_DEFAULT_OUTER_LEVEL_NV or PATCH_DEFAULT_INNER_LEVEL_NV. If a GLSL program containing only a fragment shader is active, any tessellation-related program parameters in effect when the program was linked have no effect on tessellation. Insert a new section after Section 2.X.3 in ARB_tessellation_shader, Tessellation Evaluation Shaders Tessellation Evaluation Programs If a tessellation evaluation program is active, the tessellation primitive generator will subdivide a basic primitive and run the tessellation evaluation program on each generated vertex. Tessellation evaluation programs are enabled by calling Enable with the value TESS_EVALUATION_PROGRAM_NV. If a GLSL program is active, the tessellation evaluation program enable is ignored and treated as disabled unless the program contains only fragment shaders. When tessellation evaluation programs are enabled, each patch primitive received by the GL will trigger the tessellation primitive generator to perform primitive subdivision and generate a new set of vertices. For each generated vertex, the tessellation evaluation program is invoked. Each tessellation evaluation program invocation produces a single output vertex. These vertices are assembled into primitives according to the subdivision produced by the tessellation primitive generator, and these primitives are processed by the remainder of the GL pipeline. The input patch used by the tessellation evaluation program is discarded. Tessellation evaluation programs execute using the instruction set documented in the GL_NV_gpu_program5 extension specification and in a manner similar to vertex programs. Tessellation control programs can read attributes from all vertices of the input patch, and each vertex attribute access must identify the vertex number being accessed. For example, "vertex[1].position" identifies the transformed position of "vertex[1]", which is the second vertex in the input patch. Additionally, the special attribute variable "vertex.tesscoord" is available to specify the location of the vertex within the subdivided primitive. Per-patch attributes, including the tessellation levels, are also available. The only input primitives supported by tessellation evaluation programs are patches. The error INVALID_OPERATION is generated by Begin (or vertex array functions that implicitly call Begin) if a tessellation evaluation program is active and is not PATCHES_NV. Modify Section 2.X.2 of NV_gpu_program4, Program Grammar (replace third paragraph) Tessellation control programs are required to begin with the header string "!!NVtcp5.0". Tessellation evaluation programs are required to begin with the header string "!!NVtep5.0". These header strings identify the subsequent program body as being a tessellation control or evaluation program, respectively, and indicate that they should be parsed according to the base NV_gpu_program5 grammar plus the additions below. Program string parsing begins with the character immediately following the header string. (For tessellation control programs, add the following grammar rules to the NV_gpu_program5 base grammar) ::= ::= "." | "." "." ::= | | "." | "." | "." "." "." ::= | ::= | "." ::= "VERTICES_OUT" ::= "position" | "fogcoord" | "pointsize" | "id" | | | | "." "id" | "." "invocation" | "." "vertexcount" | | | ::= "color" ::= | | | | | ::= "texcoord" ::= "clip" ::= "attrib" ::= "." "tessouter" ::= "." "tessinner" ::= "." "patch" "." "attrib" ::= "vertex" "." | "vertex" "." | "vertex" "." "in" "." | "vertex" "." "out" "." ::= "primitive" "." | "primitive" "." "in" "." | "primitive" "." "out" "." ::= "position" | "fogcoord" | "pointsize" | | | | "id" | | | ::= "color" ::= | | | | | ::= "texcoord" ::= "clip" ::= "attrib" ::= "." "patch" "." "tessouter" ::= "." "patch" "." "tessinner" ::= "." "patch" "." "attrib" ::= "result" "." (For tessellation evaluation programs, add the following grammar rules to the NV_gpu_program5 base grammar) ::= ::= "." | "." "." ::= | | "." | "." | "." "." "." ::= | ::= | "." ::= "TESS_MODE" | "TESS_SPACING" | "TESS_VERTEX_ORDER" | "TESS_POINT_MODE" ::= "TRIANGLES" | "QUADS" | "ISOLINES" ::= "EQUAL" | "FRACTIONAL_ODD" | "FRACTIONAL_EVEN" ::= "CW" | "CCW" ::= "position" | "fogcoord" | "pointsize" | "id" | | | | "vertex" "." "tesscoord" | "id" | "vertexcount" | | | ::= "color" ::= | | | | | ::= "texcoord" ::= "clip" ::= "attrib" ::= "." "tessouter" ::= "." "tessinner" ::= "." "patch" "." "attrib" ::= "vertex" "." | "vertex" "." | "vertex" "." "in" "." | "vertex" "." "out" "." ::= "primitive" "." | "primitive" "." "in" "." ::= "position" | "fogcoord" | "pointsize" | | | | "id" ::= "color" ::= | | ::= "texcoord" ::= "clip" ::= "attrib" ::= "result" "." (add the following subsection to section 2.X.3.2 of NV_gpu_program4, Program Attribute Variables) Tessellation control and evaluation program attribute variables describe inputs accessible to the program. There are several different classes of attribute bindings available, identified by the binding prefix. The set of attribute binding classes and their corresponding prefixes are described in Table X.2. The specific attributes for each class are identified by a binding suffix. Attribute Binding Prefix Description ------------------------ ------------------------------------------ vertex[m] Vertex of the input patch vertex.in[m] Vertex of the input patch vertex Array spanning vertices of the input patch or the specific vertex being evaluated vertex.in Array spanning vertices of the input patch or the specific vertex being evaluated primitive Per-patch value of the input patch primitive.in Per-patch value of the input patch vertex.out[m] Vertex of the output patch vertex.out Array spanning vertices of the output patch primitive.out Per-patch value of the output patch Table X.2, Tessellation Control and Evaluation Program Attribute Binding Prefixes. refers to a constant integer vertex number in the input or output patch. If an attribute binding prefix matches "vertex[m]" or "vertex.in[m]", the attribute binding refers to an attribute of the vertex numbered in the input patch. If is greater than or equal to the number of vertices in the input patch, the values corresponding to the binding are undefined. If an attribute binding prefix matches "vertex" or "vertex.in" and the suffix identifies an attribute of the vertex being processed by a tessellation evaluation program (e.g., "tesscoord"), the attribute binding refers to that attribute. If an attribute binding prefix matches "vertex" or "vertex.in" and the suffix identifies any other vertex attribute, the attribute binding refers to that specific attribute for each of the vertices of the input patch. Bindings of this form may only be used in explicit variable declarations. If the variable declaration identifies an array, the program will fail to load unless each binding in the binding list uses an attribute prefix of this form. When such variables are used in instructions, they must be accessed as an array, with the first array index identifying the vertex number. If such variables are declared as an array, a second array index must be provided to identify the specific per-vertex attribute to select. If the first array index is negative or greater than or equal to the number of vertices in the input patch, the value obtained is undefined. If an attribute binding prefix matches "primitive" or "primitive.in", the attribute binding refers to an attribute of the input patch. If a tessellation control program attribute binding prefix matches "vertex.out[m]", the attribute binding refers to an attribute of the vertex numbered in the output patch. These attributes correspond to per-vertex output values written by the tessellation control program thread numbered . A program will fail to load if the vertex number is greater than or equal to the number of vertices in the output patch. Tessellation evaluation programs do not have an output patch and do not support this attribute binding prefix. If a tessellation control program attribute binding prefix matches "vertex.out", the attribute binding identifies a specific attribute for each of the vertices of the output patch. Bindings of this form may only be used in explicit variable declarations, and all the usage rules described above for bindings using the prefix "vertex.in" apply. If the vertex number identified when accessing such variables is negative or greater than or equal to the number of vertices in the output patch, the resulting values are undefined. Tessellation evaluation programs do not have an output patch and do not support this attribute binding suffix. If an attribute binding prefix matches "primitive.out", the attribute binding refers to a per-patch attribute of the output patch. These attributes correspond to per-patch result values written by one of the tessellation control program threads. Tessellation evaluation programs do not have an output patch and do not support this attribute binding suffix. The following examples illustrate various legal and illegal program bindings and their meanings. ATTRIB pos = vertex.position; ATTRIB pos2 = vertex.in[2].position; ATTRIB outpos = vertex.out.position; ATTRIB outpos2 = vertex.out[2].position; ATTRIB texcoords[] = { vertex.texcoord[0..3] }; ATTRIB tcoords1[4] = { vertex[1].texcoord[1..4] }; ATTRIB outattr[2] = { vertex.out.attrib[0..1] }; INT TEMP A0; ... MOV R0, pos[1]; # position of input vertex 1 MOV R0, vertex[1].position; # position of input vertex 1 MOV R0, pos2; # position of input vertex 2 MOV R0, outpos; # ILLEGAL - needs a vertex number MOV R0, outpos[1]; # position of output vertex 1 (TCP) MOV R0, outpos2; # position of output vertex 2 (TCP) MOV R0, texcoords[A0.x][1]; # texcoord 1 of input vertex A0.x MOV R0, texcoords[A0.x][A0.y]; # texcoord A0.y of input vertex A0.x MOV R0, tcoords1[2]; # texcoord 3 of input vertex 1 MOV R0, outattr[A0.x][1]; # generic attr 1 of output vertex # A0.x (TCP) MOV R0, vertex[A0.x].texcoord[1]; # ILLEGAL -- vertex number must be # constant or must use variables like # "texcoords" using bindings w/o # vertex numbers Attributes from input patch vertices will be obtained from the per-vertex outputs of the previous program used to generate the vertex in question. For tessellation evaluation programs, that previous program would be the tessellation control program, if enabled, or the vertex program otherwise. For tessellation control programs, the previous program is always the vertex program. Tessellation control and evaluation program attributes should be read using the same component data type used to write the corresponding vertex program results. If input patch vertices are specified to come from vertex program outputs but no vertex program is enabled, the values are instead produced from fixed-function vertex processing. The value of any attribute corresponding to a vertex output not written by the previous program stage is undefined, as are the values of all generic attributes if the vertex was produced by fixed-function vertex processing. Attributes from output patch vertices are only available in tessellation control programs, and will be obtained from the per-vertex outputs of the same program. When executing an instruction, the values of any output patch vertex attribute are undefined unless the corresponding program output was written by a previously executed instruction. Per-patch attributes of the input patch are only available in tessellation evaluation and geometry programs. If a tessellation control program is enabled, they will be obtained from the corresponding per-patch outputs of the tessellation control program producing the patch, and any attributes not written by any thread of the control program are undefined. If no tessellation control program is enabled, the inner and outer tessellation levels are taken from the default tessellation levels, and all other per-patch attributes are undefined. Per-patch attributes of the output patch are available only in tessellation control programs and will be obtained from the per-patch outputs of the same program. When executing an instruction, the values of any output patch attribute are undefined unless the corresponding program output was written by a previously executed instruction. The attributes of the vertices of an input or output patch vertex are selected by an attribute binding suffix, as identified in Table X.3. All such bindings correspond to one of multiple patch vertices and require a vertex number, either in the binding prefix used in the instruction or as the first array index when using an explicitly declared attribute variable whose bindings have no vertex number. Vertex Binding Suffix Components Description ------------------------ ---------- ---------------------------- position (x,y,z,w) clip coordinates color (r,g,b,a) front primary color color.primary (r,g,b,a) front primary color color.secondary (r,g,b,a) front secondary color color.front (r,g,b,a) front primary color color.front.primary (r,g,b,a) front primary color color.front.secondary (r,g,b,a) front secondary color color.back (r,g,b,a) back primary color color.back.primary (r,g,b,a) back primary color color.back.secondary (r,g,b,a) back secondary color fogcoord (f,-,-,-) fog coordinate pointsize (s,-,-,-) point size texcoord (s,t,r,q) texture coordinate, unit 0 texcoord[n] (s,t,r,q) texture coordinate, unit n attrib[n] (x,y,z,w) generic interpolant n clip[n] (d,-,-,-) clip plane distance texcoord[n..o] (s,t,r,q) array of texture coordinates attrib[n..o] (x,y,z,w) array of generic interpolants clip[n..o] (d,-,-,-) array of clip distances id (id,-,-,-) vertex id Table X.3, Tessellation Control and Evaluation Program Per-Patch Vertex Attribute Bindings. and refer to integer constants. If an attribute binding suffix matches "position", the "x", "y", "z" and "w" components of the attribute variable are filled with the "x", "y", "z", and "w" components, respectively, of the transformed position of the specified vertex, in clip coordinates. If an attribute binding suffix matches any binding in Table X.3 beginning with "color", the "x", "y", "z", and "w" components of the attribute variable are filled with the "r", "g", "b", and "a" components, respectively, of the corresponding color of the specified vertex. Bindings containing "front" and "back" refer to the front and back colors, respectively. Bindings containing "primary" and "secondary" refer to primary and secondary colors, respectively. If face or color type is omitted in the binding, the binding is treated as though "front" and "primary", respectively, were specified. If an attribute binding suffix matches "fogcoord", the "x" component of the attribute variable is filled with the fog coordinate of the specified vertex. The "y", "z", and "w" components are undefined. If an attribute binding suffix matches "pointsize", the "x" component of the attribute variable is filled with the point size of the specified vertex. If the vertex was produced by fixed-function vertex processing, the point size attribute is undefined. The "y", "z", and "w" components are always undefined. If an attribute binding suffix matches "texcoord" or "texcoord[n]", the "x", "y", "z", and "w" coordinates of the attribute variable are filled with the "s", "t", "r", and "q" coordinates of texture coordinate set of the specified vertex. If is omitted, texture coordinate set zero is used. If an attribute binding suffix matches "attrib[n]", the "x", "y", "z", and "w" components of the attribute variable are filled with the "x", "y", "z", and "w" coordinates of generic interpolant of the specified. All generic interpolants will be undefined when the vertex is produced by fixed-function vertex processing. If an attribute binding suffix matches "clip[n]", the "x" component of the attribute variable is filled the clip distance of the specified vertex for clip plane , as written by the vertex program. If the vertex was produced by fixed-function vertex processing or a position-invariant vertex program, the clip distance is obtained by computing the per-clip plane dot product: (p_1' p_2' p_3' p_4') dot (x_e y_e z_e w_e), at the vertex location, as described in section 2.12. The clip distance for clip plane is undefined if clip plane is disabled. The "y", "z", and "w" components of the attribute are undefined. If an attribute binding suffix matches "texcoord[n..o]", "attrib[n..o]", or "clip[n..o]", a sequence of 1+- texture coordinate, generic attribute, or clip distance bindings is created. For texture coordinate bindings, it is as though the sequence "vertex[m].texcoord[n], vertex[m].texcoord[n+1], ... vertex[m].texcoord[o]" were specfied. These bindings are available only in explicit declarations of array variables. A program will fail to load if is greater than . If an attribute binding suffix matches "id", the "x" component is filled with the vertex ID of the specified vertex. If the vertex was generated by a previous program, the attribute variable is filled with the vertex ID result written by that program. Otherwise, the vertex ID is undefined. The "y", "z", and "w" components of the attribute are undefined. Attribute bindings other than those corresponding to individual vertices in input and output patch are identified in Table X.4. All of these items except for "vertex.tesscoord" are per-patch attributes, and require one of the prefixes beginning with "primitive". Primitive Binding Suffix Components Description ------------------------ ---------- ---------------------------- id (id,-,-,-) primitive number invocation (id,-,-,-) tess. control invocation vertexcount (c,-,-,-) vertices in primitive tessouter[n] (x,-,-,-) outer tess. level n tessinner[n] (x,-,-,-) inner tess. level n patch.attrib[n] (x,y,z,w) generic patch attribute n tessouter[n..o] (x,-,-,-) outer tess. levels n to o tessinner[n..o] (x,-,-,-) inner tess. levels n to o patch.attrib[n..o] (x,y,z,w) generic patch attrib n to o vertex.tesscoord (*) (u,v,w,-) tess. coordinate in [0,1] Table X.4, Tessellation Control and Evaluation Miscellaneous Attribute Bindings. and refer to integer constants. If an attribute binding suffix matches "id", the "x" component is filled with the number of primitives received by the GL since the last time Begin was called (directly or indirectly via vertex array functions). The first primitive generated after a Begin is numbered zero, and the primitive ID counter is incremented after every individual point, line, or polygon primitive is processed. Restarting a primitive topology using the primitive restart index has no effect on the primitive ID counter. The "y", "z", and "w" components of the variable are always undefined. This suffix may only be used with the prefixes "primitive", "primitive.in", or "primitive.out", and produces the same value in all cases. If a tessellation control program attribute binding suffix matches "invocation", the "x" component is filled with the thread number of the program invocation. The invocation number identifies the number of the vertex in the output patch whose attributes are produced by this invocation, and is in the range [0..-1], where is given by the VERTICES_OUT declaration. The "y", "z", and "w" components of the variable are always undefined. This suffix is not available to tessellation evaluation programs and may only be used with the prefixes "primitive", "primitive.in", or "primitive.out", and produces the same value in all cases. If an attribute binding suffix matches "vertexcount", the "x" component is filled with the number of vertices in the input primitive being processed. The "y", "z", and "w" components of the variable are always undefined. This suffix is available only with the prefixes "primitive" and "primitive.in". If an attribute binding suffix matches "tessouter[n]", the "x" component is filled with the per-patch outer tessellation level numbered of the identified input or output patch. must be less than four. The "y", "z", and "w" components are always undefined. This suffix is available only with the prefixes "primitive", "primitive.in", and "primitive.out". For tessellation control programs, this suffix is available only with "primitive.out". If an attribute binding suffix matches "tessinner[n]", the "x" component is filled with the per-patch inner tessellation level numbered of the identified input or output patch. must be less than two. The "y", "z", and "w" components are always undefined. This suffix is available only with the prefixes "primitive", "primitive.in", and "primitive.out". For tessellation control programs, this suffix is available only with "primitive.out". If an attribute binding suffix matches "patch.attrib[n]", the "x", "y", "z", and "w" components are filled with the corresponding components of the per-patch generic attribute numbered of the identified input or output patch. This suffix is available only with the prefixes "primitive", "primitive.in", and "primitive.out". For tessellation control programs, this suffix is available only with "primitive.out". If an attribute binding suffix matches "tessouter[n..o]", "tessinner[n..o]", or "patch.attrib[n..o]", a sequence of 1+- outer tessellation level, inner tessellation level, or per-patch generic attribute bindings is created. For per-patch generic attribute bindings, it is as though the sequence "primitive.patch.attrib[n], primitive.patch.attrib[n+1], ... primitive.patch.attrib[o]" were specfied. These bindings are available only in explicit declarations of array variables. A program will fail to load if is greater than . If a tessellation evaluation program attribute binding suffix matches "vertex.tesscoord", the "x", "y", and "z" components are filled with the floating-point (u,v,w) values, respectively, corresponding to the vertex being processed by the tessellation evaluation program. For triangle tessellation, the (u,v,w) values are barycentric coordinates that specify the location of the vertex relative to the three corners of the subdivided triangle. The (u,v,w) values are in the range [0,1] and sum to one. For quad and isoline tessellation, the (u,v) values are in the range [0,1] and specify the relative horizontal and vertical position in the subdivided quad. The third component of the (u,v,w) vector is undefined for quad and isoline tessellation. The "w" component of the variable is always undefined. This suffix is not available to tessellation control shaders and may only be used with the prefix "vertex". (add the following subsection to section 2.X.3.5 of NV_gpu_program4, Program Results.) The attributes of individual output vertices are written by tessellation control and evaluation programs. For tessellation control programs, these attributes are those of the output patch vertex corresponding to the program invocation. For tessellation evaluation programs, these attributes specify the attributes of the vertex in the tessellated patch corresponding to the program invocation. The set of allowable per-vertex result variable bindings is the same for tessellation control and evaluation programs correspond to attributes of output vertices and is given in Table X.5. Binding Components Description ----------------------------- ---------- ---------------------------- result.position (x,y,z,w) position in clip coordinates result.color (r,g,b,a) front-facing primary color result.color.primary (r,g,b,a) front-facing primary color result.color.secondary (r,g,b,a) front-facing secondary color result.color.front (r,g,b,a) front-facing primary color result.color.front.primary (r,g,b,a) front-facing primary color result.color.front.secondary (r,g,b,a) front-facing secondary color result.color.back (r,g,b,a) back-facing primary color result.color.back.primary (r,g,b,a) back-facing primary color result.color.back.secondary (r,g,b,a) back-facing secondary color result.fogcoord (f,*,*,*) fog coordinate result.pointsize (s,*,*,*) point size result.texcoord (s,t,r,q) texture coordinate, unit 0 result.texcoord[n] (s,t,r,q) texture coordinate, unit n result.attrib[n] (x,y,z,w) generic interpolant n result.clip[n] (d,*,*,*) clip plane distance result.texcoord[n..o] (s,t,r,q) texture coordinates n thru o result.attrib[n..o] (x,y,z,w) generic interpolants n thru o result.clip[n..o] (d,*,*,*) clip distances n thru o Table X.5: Tessellation Control and Evaluation Program Per-Vertex Result Variable Bindings. Components labeled "*" are unused. If a result variable binding matches "result.position", updates to the "x", "y", "z", and "w" components of the result variable modify the "x", "y", "z", and "w" components, respectively, of the transformed vertex's clip coordinates. Final window coordinates of vertices used for rasterization will be generated for the vertex as described in section 2.14.4.4. If a result variable binding match begins with "result.color", updates to the "x", "y", "z", and "w" components of the result variable modify the "r", "g", "b", and "a" components, respectively, of the corresponding vertex color attribute in Table X.3. Color bindings that do not specify "front" or "back" are consided to refer to front-facing colors. Color bindings that do not specify "primary" or "secondary" are considered to refer to primary colors. If a result variable binding matches "result.fogcoord", updates to the "x" component of the result variable set the transformed vertex's fog coordinate. Updates to the "y", "z", and "w" components of the result variable have no effect. If a result variable binding matches "result.pointsize", updates to the "x" component of the result variable set the transformed vertex's point size. Updates to the "y", "z", and "w" components of the result variable have no effect. If a result variable binding matches "result.texcoord" or "result.texcoord[n]", updates to the "x", "y", "z", and "w" components of the result variable set the "s", "t", "r" and "q" components, respectively, of the transformed vertex's texture coordinates for texture unit . If "[n]" is omitted, texture unit zero is selected. If a result variable binding matches "result.attrib[n]", updates to the "x", "y", "z", and "w" components of the result variable set the "x", "y", "z", and "w" components of the generic interpolant . If a result variable binding matches "result.clip[n]", updates to the "x" component of the result variable set the clip distance for clip plane . If a result variable binding matches "result.texcoord[n..o]", "result.attrib[n..o]", or "result.clip[n..o]", a sequence of 1+- bindings is created. For texture coordinates, it is as though the sequence "result.texcoord[n], result.texcoord[n+1], ... result.texcoord[o]" were specfied. These bindings are available only in explicit declarations of array variables. A program will fail to load if is greater than . In addition to per-vertex attribute bindings, a set of per-patch result bindings are available to tessellation control programs, as described in Table X.6. These bindings are not available to tessellation evaluation programs. Binding Components Description ----------------------------- ---------- ---------------------------- result.patch.tessouter[n] (x,*,*,*) tessctl outer level n result.patch.tessinner[n] (x,*,*,*) tessctl inner level n result.patch.attrib[n] (x,y,z,w) per-patch generic attrib n result.patch.tessouter[n..o] (x,*,*,*) tessctl outer levels n thru o result.patch.tessinner[n..o] (x,*,*,*) tessctl inner levels n thru o result.patch.attrib[n..o] (x,y,z,w) per-patch attribs n thru o Table X.4: Tessellation Control Per-Patch Result Variable Bindings. Components labeled "*" are unused. If a result variable binding matches "result.patch.tessouter[n]", updates to the "x" component set the outer tessellation level numbered for the output patch. Updates to the "y", "z", and "w" components have no effect. If a result variable binding matches "result.patch.tessinner[n]", updates to the "x" component set the inner tessellation level numbered for the output patch. Updates to the "y", "z", and "w" components have no effect. If a result variable binding matches "result.patch.attrib[n]", updates to the "x", "y", "z", and "w" components of the result variable set the "x", "y", "z", and "w" components of the per-patch generic attribute numbered for the output patch. If a result variable binding matches "result.patch.tessouter[n..o]", "result.patch.tessinner[n..o]", or "result.patch.attrib[n..o]", a sequence of 1+- bindings is created. For per-patch generic attributes, it is as though the sequence "result.patch.attrib[n], result.patch.attrib[n+1], ... result.patch.attrib[o]" were specfied. These bindings are available only in explicit declarations of array variables. A program will fail to load if is greater than . Modify Section 2.X.5 of NV_gpu_program4, Program Flow Control (modify spec language at the end of the section to account for the different flow control model for tessellation control programs) Tessellation Control Program Flow Control For tessellation control programs, there are multiple program invocations for each patch processed that run as a group. Any given program invocation can read per-vertex or per-patch attributes of the output patch, which may be computed during the execution of the program and may be computed by a different program invocation. To provide defined behavior for such accesses, we specify that all threads for each patch run as a group. When executing any block of instructions, all active threads will complete the excecution of one instruction before starting the execution of the subsequent instruction. Flow control instructions may cause the flow of threads in a group to diverge and will modify the set of active threads. The handling of flow control instructions is described in more detail below. A tessellation control program is handled by executing all instructions in a block of instructions corresponding to the main subroutine, with all threads initially active. This block consists of all instructions between the "main" label and the next subroutine label. If no "main" label is present, the block starts with the first instruction in the program. If there is no subroutine label following the beginning of the block, the block ends at the END instruction. Instructions in the block are executed in order until all threads reach a termination condition. A thread will terminate: * if it executes a RET anywhere within the main subroutine, unless the RET instruction is conditional and the condition code test fails; or * if it completes the execution of all instructions in the subroutine block. When an individual thread terminates processing of the main subroutine, the thread will become inactive and remain inactive for the remainder of program execution. When all threads have terminated the main subroutine block, program execution is complete and the output patch is passed to subsequent pipeline stages. When a CAL instruction is executed, the current set of active threads will execute a block of instructions corresponding to the specified subroutine label. This block consists of all instructions between the specified label and the next subroutine label. If there is no subroutine label following the beginning of the block, the block ends at the END instruction. Instructions in the block are executed in order until all active threads reach a termination condition. A thread will complete execution of a subroutine block: * if the CAL instruction is conditional and the condition code test fails; * if it executes a RET anywhere within the subroutine block, unless the RET instruction is conditional and the condition code test fails; or * if it completes the execution of all instructions in the subroutine block. When an individual thread terminates processing of a called subroutine, the thread will become inactive and remain inactive until all threads have reached their termination condition. When all threads have terminated the subroutine, execution continues at the instruction following the CAL instruction. All threads active for initial CAL instruction become active again; all other threads will remain inactive. When a REP instruction is executed, the current set of active threads will repeatedly execute the instructions between the REP and corresponding ENDREP instruction in order. Execution of this instruction loop will continue until all threads active when the REP instruction is executed reach a termination condition. A thread will terminate the processing of a REP/ENDREP block: * if the REP instruction specifies a loop count, and the initial loop count is not positive; * if the REP instruction specifies a loop count, and the current value of the loop count for the thread reaches zero when decremented by an ENDREP instruction; * if a RET instruction is executed anywhere within the REP/ENDREP block, unless the RET instruction is conditional and the condition code test fails; or * if a BRK instruction is executed inside the REP/ENDREP block, unless the BRK instruction is contained inside a more-deeply nested REP/ENDREP block or the BRK instruction is conditional and the condition code test fails. When an individual thread terminates processing of a REP/ENDREP loop, the thread will become inactive and remain inactive until all threads have terminated the loop. When all threads have terminated the loop, execution continues at the instruction following the ENDREP instruction. All threads active for initial REP instruction become active again, unless they executed a RET instruction inside the REP/ENDREP block. All other threads will be inactive. If a conditional CONT instruction is executed inside a REP/ENDREP block, all active threads passing the condition code test will become inactive and remain inactive until the next ENDREP instruction. If all active threads become inactive following the completion of a CONT instruction, processing continues at the next ENDIF or ENDREP instruction. An unconditional CONT instruction is treated identically to a conditional CONT instruction where all active threads pass the condition code test. When an IF instruction belonging to an IF/ELSE/ENDIF block is executed, the current set of active threads is split into two groups. The first group consists of all active threads passing the condition code test, and will execute a block of instructions between the IF and ELSE. The second group consists of all active threads failing the condition code test, and will execute a block of instructions between the ELSE and ENDIF. Instructions within each group are executed in lock-step order. However, the order of execution of instructions for threads in the first group are undefined relative to those in the second group. When executing a block of instructions for either of the two groups in an IF/ELSE/ENDIF block, instructions within the block will be executed in order with only the threads in that group active. The instructions of the block are executed until all threads in the group reach a block termination condition. A thread will terminate the processing of its block: * if it executes a RET instruction, unless the RET instruction is conditional and the condition code test fails; * if it executes a BRK or CONT instruction inside the IF/ENDIF block, unless that instruction is contained in a more-deeply nested REP/ENDREP block or if the instruction is conditional and the condition code test fails; or * if it completes the execution of all instructions in the instruction block. When both groups have completed their instruction blocks, execution continues at the instruction following the ENDIF. No instruction following the ENDIF will be executed until both groups have completed. At that point, any thread active for the IF instruction will become active again unless the execution of its instruction block was terminated due to the execution of a RET, BRK, or CONT instruction. All other threads will be inactive. An IF instruction belonging to an IF/ENDIF block (with no corresponding ELSE) is handled as above, except that only one thread group created. That group will consists of all active threads passing the condition code, and it executes a block of instructions between the IF and ENDIF. The order of execution imposed by this flow control model typically produces defined results when a tessellation control shader writes an output patch attribute, and then reads it (possibly on a different thread) for further computation. There are two cases where undefined instruction execution order will lead to undefined attribute values. When two or more threads access an attribute in a single executed instruction: * the value of the attribute after the instruction completes will be undefined if multiple threads write different values; and * the value of the attribute read by one thread will be undefined if the same attribute is written by another thread executing the same instruction. Also, when an IF/ELSE/ENDIF block is executed and a thread from each of the two thread groups access an attribute within its block: * the value of the attribute after the completion of the block will be undefined if both threads write different values; * the value of the attribute read by one thread will be undefined if the same attribute is written by another thread. If either thread group in an IF/ELSE/ENDIF block issue CAL instructions, these restrictions also apply to the instructions executed in the called subroutine. The additional complexities of this tessellation control program flow control model are not fundamentally incompatible with the simpler flow control rules above. They are simply intended to provide a useful model allowing for multiple cooperating threads. In particular, two models are completely equivalent if there is only number of tessellation control program threads per patch is one. (add the following subsections to section 2.X.6 of NV_gpu_program4, Program Options.) Section 2.X.6.Y, Tessellation Control Program Options No options are supported at present for tessellation control programs. Section 2.X.6.Y, Tessellation Evaluation Program Options No options are supported at present for tessellation evaluation programs. (add the following subsections to section 2.X.7 of NV_gpu_program4, Program Declarations.) Section 2.X.7.Y, Tessellation Control Program Declarations Tessellation control programs support one type of declaration statement, as described below. - Output Vertex Count (VERTICES_OUT) The VERTICES_OUT statement declares the number of vertices in the output patch produced by the tessellation control program, which also specifies the number of program invocations for each input patch. The single argument must be a positive integer less than or equal to the value of the implementation-dependent limit MAX_PATCH_VERTICES_NV. Each program invocation will have the same inputs except for the built-in input variable "primitive.invocation". This variable will be an integer between 0 and -1, where is the declared number of invocations. A program will fail to load unless it contains exactly one VERTICES_OUT declaration. Section 2.X.7.Y, Tessellation Evaluation Program Declarations Tessellation evaluation programs support several declaration statements. Each of these may be included at most in a tessellation evaluation program. - Tessellation Primitive Generation Mode (TESS_MODE) The TESS_MODE statement declares the type of subdivision performed by the tessellation primitive generator when the tessellation evaluation program, as described for the TESS_GEN_MODE_NV parameter in Section 2.X.2. The single argument must be "TRIANGLES", "QUADS", or "ISOLINES". A tessellation evaluation program will fail to load if it has no primitive generation mode declaration. - Tessellation Primitive Spacing (TESS_SPACING) The TESS_SPACING statement declares the type of spacing the tessellation primitive generator applies when subdivides primitive edge, as described for the TESS_GEN_SPACING_NV parameter in Section 2.X.2. The single argument must be "EQUAL", "FRACTIONAL_ODD", or "FRACTIONAL_EVEN". If a program omits a spacing declaration, "EQUAL" will be used. - Tessellation Vertex Order (TESS_VERTEX_ORDER) The TESS_VERTEX_ORDER statement declares the order of the vertices in the triangles emitted by the tessellation primitive generator in TRIANGLES or QUADS mode, as described for the TESS_GEN_VERTEX_ORDER_NV parameter in Section 2.X.2. The single argument must be "CW" or "CCW". If a program omits a vertex order declaration, "CCW" will be used. - Tessellation Point Mode (TESS_POINT_MODE) The TESS_POINT_MODE statement declares that the tessellation primitive generator will emit points for each vertex in the subdivided primitive instead of lines or triangles, as described for the TESS_GEN_POINT_MODE_NV parameter in Section 2.X.2. The declaration takes no arguments. If a program omits a point mode declaration, the primitives emitted will be lines (for ISOLINES mode) or triangles (for TRIANGLES and QUADS mode). Additions to Chapter 3 of the OpenGL 1.5 Specification (Rasterization) None. Additions to Chapter 4 of the OpenGL 1.5 Specification (Per-Fragment Operations and the Frame Buffer) None. Additions to Chapter 5 of the OpenGL 1.5 Specification (Special Functions) None. Additions to Chapter 6 of the OpenGL 1.5 Specification (State and State Requests) None. Additions to Appendix A of the OpenGL 1.5 Specification (Invariance) None. Additions to the AGL/GLX/WGL Specifications None. GLX Protocol None. Errors The error INVALID_OPERATION is generated if Begin, or any command that implicitly calls Begin, is called when tessellation control programs are enabled and the currently bound tessellation control program object does not contain a valid program. The error INVALID_OPERATION is generated if Begin, or any command that implicitly calls Begin, is called when tessellation evaluation programs are enabled and the currently bound tessellation evaluation program object does not contain a valid program. The error INVALID_OPERATION is generated if Begin, or any command that implicitly calls Begin, is called when tessellation control programs are enabled and is not PATCHES_NV. The error INVALID_OPERATION is generated if Begin, or any command that implicitly calls Begin, is called when tessellation evaluation programs are enabled and is not PATCHES_NV. New State (Modify ARB_vertex_program, Table X.6 -- Program State) Initial Get Value Type Get Command Value Description Sec. Attribute ------------------------- ---- ----------- ------- ------------------------ ------ --------- TESS_CONTROL_PROGRAM_NV B IsEnabled FALSE Tessellation control 2.14.6 enable program enable TESS_EVALUATION_PROGRAM_NV B IsEnabled FALSE Tess. evaluation 2.14.6 enable program enable TESS_CONTROL_PROGRAM_ Z+ GetIntegerv 0 Active tess control 2.14.1 - PARAMETER_BUFFER_NV program buffer object binding TESS_CONTROL_PROGRAM_ nxZ+ GetInteger- 0 Buffer objects bound for 2.14.1 - PARAMETER_BUFFER_NV IndexedvEXT tess. control program use TESS_EVALUATION_PROGRAM_ Z+ GetIntegerv 0 Active tess evaluation 2.14.1 - PARAMETER_BUFFER_NV program buffer object binding TESS_EVALUATION_PROGRAM_ nxZ+ GetInteger- 0 Buffer objects bound for 2.14.1 - PARAMETER_BUFFER_NV IndexedvEXT tess. eval. program use Additionally, some tessellation-related state applicable to this extension is added by ARB_tessellation_shader. New Implementation Dependent State Minimum Get Value Type Get Command Value Description Sec. Attrib -------------------------------- ---- --------------- ------- ----------------------- -------- ------ MAX_PROGRAM_PATCH_ATTRIBS_NV Z+ GetProgramivARB 30 number of generic patch 2.X.3.2 - attribute vectors supported Additionally, some tessellation-related state applicable to this extension is added by ARB_tessellation_shader. Dependencies on ARB_tessellation_shader This spec incorporates the text of ARB_tessellation_shader in its entirety. If ARB_tessellation_shader is not supported, language documenting GLSL tessellation control and evaluation shaders should be removed; tessellation would be available only using the assembly interface. Language describing the operation of patch primitives and the tessellation primitive generator would be retained. Dependencies on NV_parameter_buffer_object The NV_parameter_buffer_object (PaBO) extension provides the ability to bind buffer objects to be read by vertex, geometry, and fragment programs. If NV_parameter_buffer_object is supported, this extension adds the ability to bind buffer objects to be accessed by tessellation control and evaluation programs. The NV_parameter_buffer_object should be modified to accept the enums TESS_CONTROL_PROGRAM_PARAMETER_BUFFER_NV and TESS_EVALUATION_PROGRAM_PARAMETER_BUFFER_NV where the three previously defined enums (for vertex, geometry, and fragment programs) are accepted. If NV_parameter_buffer_object is not supported, references to the two new buffer object binding points should be removed. Issues (1) How does tessellation fit into the existing GL pipeline? RESOLVED: See issue (1) in the ARB_tessellation_shader specification, which contains beautifully crafted ASCII art depicting the pipeline. (2) What other considerations were involved in the design of the tessellation API? RESOLVED: Go look at the detailed issues section of the GLSL-based ARB_tessellation_shader specification. There are a good number of issues that apply equally to the assembly APIs that won't be duplicated here. (3) Should the tessellation-related parameters (e.g., the primitive decomposition, spacing, vertex orientation) be context state or provided with the program? If the latter, how should they be provided. RESOLVED: We are providing declaration statements to specify each of these parameters in the tessellation evaluation program. Because they are part of the program text, they can't be changed independently of the program. We don't think that limitation is serious, and the same limitation applies to GLSL shaders (you need to re-link when changing these parameters). Putting these declarations in the shader means that it wasn't necessary to create a new "tessellation parameter" API to set this state. Such an API would only apply to assembly programs and could be a source of confusion if developers thought it might apply to GLSL shaders as well. (4) The programming model for tessellation control programs supports multiple threads, each providing attributes for a single vertex. But it also supports the ability to read the per-vertex outputs written by other threads and to read and write shared per-patch attribute outputs. The latter capabilities require some sort of synchronization to ensure consistently ordered reads and writes whenever possible. How should this be handled? RESOLVED: We will expose a programming model where we run groups of parallel threads in lock-step. In this model, all threads effectively retire one instruction before starting the next. This execution model provides a simple abstraction, and provides an obvious instruction order allowing an application to avoid most read-write and write-write hazards. There are three places where we have explicitly undefined behavior: * If flow control diverges in an IF/ELSE/ENDIF block, the relative order of writes in the "IF" side of the block and those in the "ELSE" side of the block is undefined. * If multiple threads write different values to the same per-patch attribute in the same instruction, the order in which the writes land is undefined. * If any single instruction has one thread reading a per-vertex output or a per-patch attribute and another thread writing the same output, the order in which the reads and writes land is undefined. Implementations need not actually run the threads in this manner, as long as the compiler properly synchronizes threads at the points where execution order dependencies do occur. Since the NV_gpu_program4 programming model uses structured branching (e.g., IF/ELSE/ENDIF blocks), the points at which threads may diverge and converge again are easily identified. We expect that the number of such synchronization points will be low for most tessellation control programs. One other approach considered is to limit the flow control model and the capabilities of the system to result in a minimal number of required synchronization points. For example, the tessellation control program might be split into phases where the capabilities of each thread to access outputs would be limited. For example, one might have a three-phase model like the following: Per-Vertex Outputs Per-Patch Outputs Phase can read? can write? can read? can write? ----- --------- ---------- --------- ---------- 1 NO YES NO NO 2 YES NO NO YES(a) 3 YES NO YES(a) YES(b) In this model, there would be two explicit synchronization points -- between each pair of phases. The limits on access prevent most cases where conficts could occur (e.g., you can't read any per-vertex outputs until you're completely done writing all). To further limit conflicts, per-patch attributes might be divided into two sets -- set (a) can be written only in phase 2 and read only in phase (3), and set (b) can be written only in phase 3. We decided to expose a general model on the grounds that having the compiler automatically determine possible synchronization points was easy enough. Optimizing compilers that reorder instructions already have to deal with this exact type of issue -- they can't move instructions that write a variable past subsequent instructions that read it. The programming model adopted for GLSL in ARB_tessellation_shader similarly has a set of parallel threads running one executable, but it provides a barrier() call that serves as a synchronization point and can be used to split shader execution into phases. Note that while all previous OpenGL programmability extensions exposed a model of completely independent threads (i.e., one thread can't read the outputs of another), threads weren't always completely independent! In fragment programs/shaders, some texture and all partial derivative built-ins (dFdx, dFdy in GLSL) require screen-space derivatives. If the quantity used for derivatives is computed by the shader, OpenGL implementations generally run threads in groups arranged by screen-space location and approximate derivatives by computing differences of the inputs between threads. This approach requires the same sort of automatic synchronization between threads, since derivatives implicitly read values computed by other threads. Revision History Rev. Date Author Changes ---- -------- -------- ----------------------------------------- 3 12/19/11 pbrown Clarify that "primitive.tessouter[n]", "primitive.tessinner[n]", and "primitive. patch.attrib[n]" are not available on the input patch for tessellation control programs. Remove stray language referring to a non-existent vector tessellation level. 2 03/22/10 pbrown Rename references to ARB_tessellation_shader (formerly EXT). Minor other cleanups, including the issues section. 1 pbrown Internal revisions.