I wish to pipe 2 geometry shaders. The first one takes one point and releases multiple points. The second one takes one of those points and releases a rectangle to fragment shader.
Geometry shader 1:
layout (points) in;
layout (points, max_vertices = 16) out;
in GEO1 {
uint name_tile_atlas;
uint name_tile_map;
uint subtiles;
} geo1[];
out GEO2 {
vec2 pos_ones_atlas;
vec2 pos_ones_target;
} geo2;
void main {...}
Geometry shader 2:
layout (points) in;
layout (triangle_strip, max_vertices = 4) out;
in GEO2 {
vec2 pos_ones_atlas;
vec2 pos_ones_target;
} geo2[];
out vec2 frag_uv;
void main {...}
I naively attached those geometry shaders to one program, and they go to a single geometry stage which can only have one main function. Is there any way to pipe these shaders?
I can merge them by moving the code in shader 2 into a for-loop, but I don't want to loop 16 times for parallellizable logic, and this gets worse when piping an arbitrary number of geometry shaders...
Daisy chaining multiple Geometry Shaders is not possible, as OpenGL uses a predetermined rendering pipeline with one (optional) Geometry Shader stage. However, using two Geometry Shaders in series is effectively possible using two drawing commands, Transform Feedback and an extra buffer.
The procedure is like this:
glEnable(GL_RASTERIZER_DISCARD)
).GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN
to keep track of the number of primitives written by Geometry Shader 1 (we need this later).glDisable(GL_RASTERIZER_DISCARD)
).The Primitive Query (and thus a host-device-host data transfer) can be avoided by using Transform Feedback Rendering, which is part of core OpenGL since 4.0, but is often available in OpenGL 3.x implementations as an extension.
This is all assuming that you need the capability of Geometry Shaders to ouput a dynamic number of primitives. If each invokation outputs the same number of primitives (or if this number is dynamic but easily computed), there is probably a better implementation available, such as using Transform Feedback with only a Vertex Shader, or using a Compute Shader (OpenGL >=4.3).
Source used for OpenGL all specifications and usage: Khronos OpenGL Wiki