Geometry shaders
I've forked GPipe-Core to support geometry shaders. It works, but it's quite experimental and I'm still thriving to get a clear picture of GPipe's internals. Even if it's far from being a proper PR at this time, other people could be interested in this draft. I do reckon however that a detailled documentation on how things work in the first place would be quite helpful here.
A brief excerpt from the forked GPipe-Test project:
let geometryShaderEnabled = True
fragNormalsUV <- if geometryShaderEnabled
then do
geometries :: GeometryStream (Geometry Triangles (VPos, (V3 FlatVFloat, V2 VFloat))) <- geometrize projectedSides
let
makePrimitive :: Int
-> Geometry Triangles (VPos, (V3 FlatVFloat, V2 VFloat))
-> GGenerativeGeometry Triangles (VPos, (V3 FlatVFloat, V2 VFloat))
-> GGenerativeGeometry Triangles (VPos, (V3 FlatVFloat, V2 VFloat))
makePrimitive depth (Triangle p1 p2 p3) g = ...
depth = 2
expandedGeometries :: GeometryStream (GGenerativeGeometry Triangles (VPos, (V3 FlatVFloat, V2 VFloat)))
expandedGeometries = (\t -> makePrimitive depth t generativeTriangleStrip) <$> geometries
verticeCount = 3 * 4 ^ depth
generateAndRasterize rasterOptions verticeCount expandedGeometries
else
rasterize rasterOptions projectedSides
I'm very interested in this draft. I haven't been able to get it to work, but maybe I did something wrong when porting your changes to my fork (a very manual process, because I made a whole bunch of small changes). Right now, the problem I'm facing is that createFragment is never called, so the vgf outputs aren't emitted, causing compilation failure. Is that expected, or did I introduce a bug? Btw, I'm on freenode in #implicitcad.
To quote my own code:
TODO Bug in my geometry shader support: not using every varying will lead to a crash.
It could be the reason why your GS fails to compile.
By the way, which branch of my fork did you use: the "old" geometry-shader or the last "transform-feedback"?
Oh, I was using geometry-shader. Yikes :).
Anyway, I got it to work, except it only works with 1 shader input. Here are some working examples: https://github.com/homectl/lambdaray/blob/main/GPipe-GLFW/tools/gshader3d_test.hs https://github.com/homectl/lambdaray/blob/main/GPipe-GLFW/tools/gshader2d_test.hs
I'll look at your other branch now.
Looks like you did a lot there :P that's going to be a bit of a pain to merge into mine, but I'll get to it.
On second thought, it might be better for me to just redo all of my own refactorings on top of your fork.
I tested my example with transform-feedback, and it doesn't work.
GPipeException "A geometry shader compilation failed:\n0(18) : error C1503: undefined variable \"vgf3\"\n0(19) : ...
Mea culpa. You need to replace your calls to emitVertex by emitVertexPosition (outputting a position is not mandatory if you don’t have a FS after your GS). In addition, you also need to use your whole input (it’s an old problem I need to fix but people usually use their whole input anyway). Per instance: frag (ShaderAttachment c n) = c + n*0
Ah, thanks. Now that works :). I'm going to re-do my own refactorings on top of this now.
@Chatanga http://hackage.haskell.org/package/GPipe-Core (repo: https://github.com/homectl/workspace) contains your transform feedback and geometry shader stuff, as well as some optimisations I did yesterday that make shader compilation 10-18x faster.