Transform Feedback and Geometry Shaders

I have a question regarding the interplay between transform feedback and geometry shaders.
(And, of course, I’d be happy the hear about alternative approaches.)

On every triangle that gets rendered (I don’t need to consider others), I want to check a (simple) geometric condition.
To do that, I wrote a geometry shader (GS).
After the test, the GS outputs the triangle unmodified.
(I already checked that the performance hit by this additional shader is negligible on a modern NVidia card.)

AFAIK, the output of the GS can, in addition to being rendered, be stored in a transform feedback buffer (TFB).
That’s perfect.

However, I would like to store only those triangles in the TFB that pass the geometric test.
(After the frame, I would like to read back the TFB on the CPU side.)

Does anyone know whether this is possible?

Something like a KILL statement in the GS? except that it should apply only to the TFB, the triangle should still be rendered.

As a fallback, I thought about the following work-around:
I store all triangles in the TFB, together with a flag that contains the outcome of the geometric test.
After the frame, I perform a sort of a prefix sum using a CUDA program on the TFB that leaves only those triangles that have the flag set.
The question here is whether it is possible to make the TFB (which is AFAIK just a VBO) available to a CUDA program, and how much time that switch would cost.

I have also just seen the slides from the Siggraph 2011 OpenGL BOF, which talk about a concept called “Images” which can be written to be shaders.
Unfortunately, I don’t know anything detailed about them.
The question here is, if the above approaches are not feasible: would such “images” be a solution to my problem? If so, could some kind soul point me to a tutorial or similar that would help me to understand exactly how they work?

Thanks a million in advance for all kinds of insights, pointers, suggestions, etc.

Best regards,

If the triangle doesn’t pass your test, then don’t have the geometry shader emit any vertices for that triangle. It’s perfectly acceptable to have a geometry shader produce nothing.

I think danharibo meant that he wants unconditional geometry output towards the rasterizer but conditional geometry output towards the transform feedback buffer.

This can be done as well, using multiple streams as introduced by ARB_transform_feedback3. Simply you output to the first stream unconditionally and use the second stream for the conditional output (which will be backed up by an output buffer). However, with this you are limited to GL4 class hardware.

Thanks for your response, malexander.
Maybe I wasn’t clear in my question.

But I want to render the triangles in any case.
The test should only influence whether or not the triangle ends up in the TFB.

In other words, I would like the geometry shader to act like a fork, where all triangles go one way, and some also go the other way.

aqnuep’s correct, if you want more than one vertex stream, you need GL4 hardware. I somehow missed that, sorry.

However, if you’re merely passing through the triangle to the fragment shader as-is from the vertex shader and the only thing your geometry shader is actually doing is your triangle test, it may be faster to rasterize the geometry without a geometry shader first, then render again with another shader to write to the TF buffer. Geometry shaders do incur some overhead. In fact, you’d have to do this for GL3 hardware.

This is very good news!
GL4 is absolutely fine.

Could you please point me to places / papers / books where I can read more about this?
(streams, backing something up by an output buffer)
Or an example that shows how to output something to 2 streams?

Well, I think reading the extension spec should be enough. I also have a demo application that uses output to multiple streams, even though the actual use case is pretty different than that what you need. Here you can find the demo:

I think I have managed to write a little stand-alone program with multiple output streams.

However, there is still the limitation that only POINTS can be used with multiple output streams (according to the spec of ARB_ transform_feedback3 .
But I need triangles …

I took the liberty to start a new thread about this problem:

Any hints, suggestions, insights will be highly appreciated.

Best regards,