Tessellation levels in the 4.1 Specification

I am a bit confused about tessellation levels as described in the OpenGL specification, as well as their implementation. I’m hoping that someone here can help.

First, Figure 2.7 in the 4.1 core specification seems to indicate that Outer Level 0 (OL0) determines the number of isolines, each of which has a constant value for v. The number of subdivisions along a particular isoline then is determined by Outer Level 1 (OL1). However, near the bottom of page 120, it says, “each strip has a constant v coordinate…the number of segments in each strip is derived from the first outer tessellation level.”

The latter statement doesn’t seem to jive with the Figure. Am I interpreting this correctly?

In addition, when testing this out on a ATI 5670, Outer Level 0 seems to be the one that determines the number of segments in a given isoline. Therefore, it seems to follow the latter interpretation.

Could someone help clear this up for me?

Thanks!

Your interpretation is correct, and the OpenGL specification is in error. This same error exists in both the core 4.0 and core 4.1 OpenGL specifications.

I have an ATI 5750 which I have tested with all Catalyst driver versions that support OpenGL 4.0 (10.3 beta, 10.6, 10.7, 10.8, 10.9, 10.10, and 10.11) and they have all been consistent with the specification text rather than with figure 2.7 . The specification text explicitly describes (consistently and repeatedly) how each of the parameters is used.

Incidentally, I have discovered an AMD Catalyst driver bug (which I’ve reported to AMD each version beginning with version 10.7):

The vertex spacing qualifier of tessellation evaluation shaders is ignored when the primitive mode qualifier of tessellation evaluation shaders is isolines. The tessellation primitive generator incorrectly always uses equal_spacing when the primitive mode qualifier is isolines, whether the vertex spacing qualifier was specified as fractional_even_spacing, fractional_odd_spacing, or equal_spacing.

Furthermore, as a result of your question, for the first time I tried plotting isolines with a value other than 1.0 for gl_TessLevelOuter[1]. To my surprise, no matter what value I used (I only tried values greater than 1.0), only one isoline (with v = 0.0) was ever plotted. So, it appears there is another Catalyst driver bug regarding isolines. Have you had any luck plotting multiple isolines per patch?

Ooops! I screwed up my test case. The number of isolines drawn equals

ceil (gl_TessLevelOuter[1])

(up to 64).

Thanks for your feedback. Seems like there is still some issues with the tessellation portion of the spec.

I can confirm multiple isolines on Catalyst 10.11 when gl_TessLevelOuter[1] > 1.

I also tried the same test on my Vaio laptop (NVIDIA 425M), and found that the tess levels were reversed. gl_TessLevelOuter[0] controlled the number of isolines, and gl_TessLevelOuter[1] determined the number of segments per line strip. Looks like NVIDIA decided to follow the Figure instead of the text.

I also ran some tests with quad tessellation. I found some very strange behavior. With ATI Catalyst 10.11, it appears that the indexes are ignored. For example,

gl_TessLevelOuter[0] = 16.0;
gl_TessLevelOuter[1] = 4.0;
gl_TessLevelOuter[2] = 4.0;
gl_TessLevelOuter[3] = 4.0;

A run with the above settings produced the same tessellation as a run with the following sequence of statements:

gl_TessLevelOuter[1] = 16.0;
gl_TessLevelOuter[0] = 4.0;
gl_TessLevelOuter[2] = 4.0;
gl_TessLevelOuter[3] = 4.0;

It seems like the first assignment determines the value of index zero regardless of the index used. This is quite strange.

Could you confirm this?

I just ran a test as you suggested (with Catalyst 10.11 drivers) and I confirm that the driver bug exists as you found it.

I then conducted a few other similar tests. This one worked properly:

int  edge_ndx;

edge_ndx = 3;
gl_TessLevelOuter[edge_ndx] = 4.0;
gl_TessLevelOuter[1] = 16.0;
gl_TessLevelOuter[0] = 4.0;
gl_TessLevelOuter[2] = 4.0;
gl_TessLevelOuter[3] = 4.0;

But, this one did not work properly:

int  edge_ndx;

edge_ndx = 3;
gl_TessLevelOuter[1] = 16.0;
gl_TessLevelOuter[0] = 4.0;
gl_TessLevelOuter[2] = 4.0;
gl_TessLevelOuter[3] = 4.0;
gl_TessLevelOuter[edge_ndx] = 4.0;

You have uncovered two errors: the OpenGL Specification is in error (and Nvidia and AMD have each interpreted that error in opposite and incompatible ways). This error in the specification needs to be corrected quickly, and either AMD or Nvidia needs to change their driver accordingly, or soon the specification error will be cast in concrete in order to maintain backwards compatibility. Catalyst 10.11 has several errors: (presumably) the GLSL tessellation control shader compiler incorrectly compiles gl_TessLevelOuter when it has constant indices except under certain circumstances. And, as I had previously mentioned, the vertex spacing qualifier is ignored when the primitive mode qualifier is isolines (the Specification states that equal spacing is to be used for the spacing between the isolines (i.e., the v dimension), but that the vertex spacing qualifier must be used for the tessellation of each isoline (i.e., the u dimension)).

Continued discussion in this thread’s new directions belongs in the OpenGL Shading Language and OpenGL drivers forums. I’ve taken the liberty of creating new threads in those forums that summarize the relevant issues:
GLSL: http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Number=287486
drivers: http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Number=287487

I don’t know who or where to report errors in the OpenGL Specification to. I recommend that you report the Catalyst 10.11 driver bug you discovered to AMD. (I will add it to my list of unfixed driver errors I report to AMD with each release.) I also recommend you report to Nvidia that there is an OpenGL Specification error, and their interpretation is probably wrong (I believe repeated text ought to supercede a single figure), but in any case they should be aware of the Specification error and should seek its correction by the OpenGL ARB.