PDA

View Full Version : Geometry Shader Output Limits



Stephen Ranger
02-23-2012, 07:17 AM
I am trying to determine the maximum number of vertices a geometry shader is able to output. I am trying to use the below code but the value printed out via an exception (128) works and my code gives me half that (64). I am using Java/JOGL and #version 150 for my shader. I am dividing by two because my geometry shader is outputting glPosition and a vec4 for color to my fragment shader.



Math.min(gl.glGetInteger(GL3.GL_MAX_GEOMETRY_OUTPU T_VERTICES), gl.glGetInteger(GL3.GL_MAX_GEOMETRY_OUTPUT_COMPONE NTS) / 2);


The output is



MAX_GEOMETRY_OUTPUT_VERTICES = 1024
GEOMETRY_OUTPUT_COMPONENTS = 128


The spec says the max number of vertices shouldn't exceed the MAX_GEOMETRY_OUTPUT_VERTICES and the product of the number of compunents and the value of MAX_GEOMETRY_OUTPUT_COMPONENTS. What exactly is a component? Why does the math say the value SHOULD be 64 when 128 works? How are you supposed to compute the max number of vertices allowed to be outputted by a geometry shader?

Any help would be appreciated; thanks!


- Stephen

Alfonse Reinheart
02-23-2012, 09:47 AM
The number of output vertices and the number of output components are unrelated.

MAX_*_OUTPUT_COMPONENT, which exists for both VERTEX and GEOMETRY, refers to the number of individual values you can output. A vec4 takes up 4 components. A float takes up 1 component.

So it's a count of the total number of values you can squeeze out of the geometry shader per vertex. It's the number of values you can declare as `out` in the geometry shader. It has nothing to do with the number of times you can call `EmitVertex`.

Stephen Ranger
02-23-2012, 10:25 AM
The spec states



There are two implementation-dependent limits on the value of
GEOMETRY_VERTICES_OUT; it may not exceed the value of
MAX_GEOMETRY_OUTPUT_VERTICES, and the product of the total
number of vertices and the sum of all components of all
active output variables may not exceed the value of
MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS.

http://www.opengl.org/registr/doc/glspec42.core.20110808.pdf
Page 149


So does this mean that MAX_GEOMETRY_VERTICES_OUT is the maximum number of vertices you can emit and that MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS / components is the maximum number of float able to be outputted per vertex? Because this is not the case. I'm outputting 8 floats (position and color) and MAX_GEOMETRY_VERTICES_OUT = 1024 and it will only let me output 128 (MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS = 128). Or is the MAX_GEOMETRY_VERTICES_OUT / component floats <= MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS? (1024 / 8 <= 128 which is true)?

Alfonse Reinheart
02-23-2012, 11:53 AM
So does this mean that MAX_GEOMETRY_VERTICES_OUT is the maximum number of vertices you can emit and that MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS / components is the maximum number of float able to be outputted per vertex?

No. The spec means exactly what it says.

There is a limit on the number of vertices you can output from a geometry shader. There is a limit on the number of components you can output per-vertex. And there is a limit on the total number of components you can output per-geometry shader instance. That is, you can only write out so much stuff in one execution of a GS.

For example, my HD 3300 can output 1024 vertices max. It can output 128 componets per-vertex maximum. But it *cannot* output 1024 vertices that each have 128 components, because the total number of components a single geometry shader can output is 16384. 1024*128 is 131072. which is rather larger than 16384.

Therefore, given my hardware, the only way to output 1024 vertices is to write 16 components or less. Even if I write 8 components, I can still only wrote 1024 vertices, because that's the vertex limit.

If I'm only writing 64 vertices, then I can write 128 components to each of those vertices. If I write 32 vertices, I can still only write 128 components, because that's the component limit.

I highly doubt that `MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS` is 128 for you. It would make no sense for `MAX_GEOMETRY_VERTICES_OUT` to be so large that you could never actually use it, even if you were outputting a single float. What hardware are you using?

Scratch that: it can't be 128. The spec requires a minimum value of 1024 for `MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS`.

Stephen Ranger
02-23-2012, 12:03 PM
So, I think I've figured out my mistake.

Requirements:

1. GEOMETRY_VERTICES_OUT must be less than MAX_GEOMETRY_OUTPUT_VERTICES

2. MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS >= components * GEOMETRY_VERTICES_OUT


Which gives me:

1. GEOMETRY_VERTICES_OUT <= 1024
2. GEOMETRY_VERTICES_OUT <= 1024 / 8

So, my GEOMETRY_VERTICES_OUT must be less than 128. My dev system that had an ATI FirePro V9800 card was causing me to mis-understand as well. It gave an error stating that GEOMETRY_VERTICES_OUT must be less than MAX_GEOMETRY_OUTPUT_VERTICES *only* so when the nVidia system ran it, I wasn't taking into account the other piece. By chance, part two of the equation on the ATI system just happened to be >1024 so the output vertices value of 1024 was okay.

Though, when I query GEOMETRY_VERTICES_OUT on the ATI system, it returns 0 and the nVidia system returns the valid 128 value; not sure why. Probably a bug...



ATI System for those that read this later and want clarification:

MAX_GEOMETRY_OUTPUT_VERTICES = 1024
MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS = 16384

So, 16384 / 8 components > 1024; so GEOMETRY_VERTICES_OUT = 1024 was valid.

Stephen Ranger
02-23-2012, 12:09 PM
Alfonse, thanks for the reply. It came in as I was typing up my results. Yes, the MAX_GEOMETRY_OUTPUT_VERTICES on the nVidia card is 1024 as is the MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS.

The OpenGL spec is a bit tough to parse sometimes; I appreciate the help.