PDA

View Full Version : Geometry Shader: Max output vertices



_x57_
06-27-2011, 07:17 AM
Hi everyone.

I just started experimenting with geometry shaders and ran into some strange behaviour ...
I wrote a simple pass-through geometry shader that takes a line and shall (later) subdivide that line into a linestrip. When i set


#version 330 compatibility

layout (lines) in;
layout (line_strip) out;
layout (max_vertices = X) out;

void main (void)
{
int i;
for (i=0; i<gl_in.length(); i++)
{
gl_Position = gl_in[i].gl_Position;
EmitVertex();
}
EndPrimitive();
};

in the shader, where X equals GL_MAX_GEOMETRY_OUTPUT_VERTICES = 1024, i get a compile error:

error C6033: Hardware limitation reached, can only emit 256 vertices of this size


I have three questions regarding this:

(1)
Does gl_Position count 4 times to the limit because it is a vec4?

(2)
When setting X>256 the shader won't compile/link, but when using glProgramParameteriEXT(program, GL_GEOMETRY_VERTICES_OUT_EXT, 1024) instead of the layout statement in the shader, the shader compiles and links successfully (and can be used). Why?

(3)
In both cases, whether using the layout statement in the shader or the glProgramParameteri(...) statement the program falls back to software rendering when X>128 (instead of >256). Is it a driver/compiler bug?

I'd appreciate if someone could shed some light on this.

PS: I am using a GeForce 9800 GT with the 266.58 whql driver on Vista64.

aqnuep
06-27-2011, 07:27 AM
(1)
max_vertices specifies the number of vertices, not the number of float components or number of vec4 sized elements. The max_vertices supported by the hardware depends on how large your output data for a single vertex is. In case of simply emitting gl_Position only, a single vertex takes 16 bytes (vec4). The size of the output buffer of the GS is hardware dependent.

(2)
EXT_geometry_shader4 is not compatible (aka they don't interact in the way you think) with the core GS functionality so setting GL_GEOMETRY_VERTICES_OUT_EXT should not affect core GS functionality but rather most probably max_vertices defaults to some value (most probably it is specified in the core spec).

(3)
That is exactly because what I explained in (1) and (2). Your hardware has the limit of 256 max_vertices for an output size of 16 bytes (aka gl_Position only). The potential maximum can be reached only if you output a single float only (at least I suppose that). Setting GL_GEOMETRY_VERTICES_OUT_EXT didn't affect your shader, thus it was using a default value (maybe 256 as it is the max for your hardware). The reason why software rendering path is chosen already above 128 vertices and not 256 vertices is a good question and it is most probably related to some other hardware limitation of the GeForce 9800 GT.

_x57_
06-27-2011, 07:55 AM
Thanks for the answer aqnuep.

(1) I find it slightly irritating that the spec states "It is an error for the maximum number of vertices to be greater than
gl_MaxGeometryOutputVertices." and that nothing in the spec seems to state that this limitation is a memory limitation. However, knowing that the behaviour seems deterministic ;)

(3) I do not see what other limitation that might be either...

aqnuep
06-27-2011, 08:03 AM
I find it slightly irritating that the spec states "It is an error for the maximum number of vertices to be greater than gl_MaxGeometryOutputVertices." and that nothing in the spec seems to state that this limitation is a memory limitation.
The spec does not usually talk about any implementation related issues. Hardware is free to support GS functionality in any particular way. However, in practice, the output of the GS is captured in a temporary buffer which can be accessed by multiple shader cores and that ensures that the emitted vertices are stored in the appropriate order.


I do not see what other limitation that might be either...
Actually the limitation may be related to the fact that this output buffer must ensure the ordering of the emitted data. Try to output points instead of triangle strips to see whether then you are allowed to really output those 256 vertices.
Even though I know some stuff about the hardware implementation of GS, I don't know that much about it, so it is pretty difficult to figure out why you hit that limit.
Most probably contacting NVIDIA devs is the best way to figure this out.

_x57_
06-27-2011, 08:13 AM
You are probably right. However, i solved my problem now and will not further pursue the issue...

At least i know now not to interpret specs like "It is an error for the maximum number of vertices to be greater than gl_MaxGeometryOutputVertices." as "It is NO an error for the maximum number of vertices to be LESS OR EQUAL than gl_MaxGeometryOutputVertices." ... ;)

aqnuep
06-27-2011, 11:16 AM
Yeah, dangerous assumption :)