pygfx / pyshader

Write modern GPU shaders in Python!
BSD 2-Clause "Simplified" License
72 stars 1 forks source link

Support some form of templating of entry points? #55

Open almarklein opened 4 years ago

almarklein commented 4 years ago

When I started this, I thought that with allowing code to call other (python-defined) functions (#8) would solve all problems that we normally see for composing shaders from different snippets. It does solve the issue of being able to use common code in different places, in a very natural way.

However, quite often, you have a shader that you want to behave slightly slightly differently depending on the type of some inputs. E.g. Whether a texture is scalar, RGB or RGBA, whether texture coordinates are 1D, 2D or 3D. Or depending on the texture dtype. In pygfx we deal with that last issue (texture dtype) by modifying the functions signature in-place, which is obviously a bit of a hack. The only other current solution is to create a shader for each type of each input, but that can quickly result in many entry points that all have (nearly) the same code.

I'd like a more formal way to write a shader and being able to tweak inputs (e.g. dimensionality and dtype of textures, and changing vec2 for vec3 for texture coords). Along that line, a way to call a function inside a shader, and being able to swap-out that function for another one. Of course, after swapping things out, the bytecode will be regenerated, and in that process all the types and signatures are validated to match up.

almarklein commented 4 years ago

Perhaps, if helper functions (which are being called from an entrypoint) can specify their own module-level inputs (buffers, uniforms, textures), then any templating could be done at that level. So that all what's needed is a way to reset the types of input arguments. (And perhaps some helper builtin functions to deal with vectors of varying dimension.)

Korijn commented 4 years ago

Maybe you can draw some inspiration from Numba, actually.. they also translate python functions to cpu/gpu native code with a decorator and have the same issue. I believe they either compile at invocation time and read the types from the arguments and compile more type signatures as needed, or you specify the signature upfront as an argument to the decorator: https://numba.pydata.org/numba-doc/latest/index.htmluser/jit.html see the example code under "eager compilation". Sadly they only support one signature in this eager mode. Nevertheless this might give you some fresh ideas 🙂