An Effects interface for Metal. Much of the code is copy-pasted from mojoshader_opengl.c with a few significant changes:
mtlCompileEffect concatenates all the MojoShader shader output into a single string, then compiles that conglomerate into a MTLLibrary. One Effect <=> One Metal Library.
Since Metal has no concept of a "shader program" like GL does, we store pointers to the MTLLibrary, vertex/fragment MTLFunctions, and the uniform buffers associated with each shader.
To make sure that we don't accidentally overwrite our uniform buffers before they get a chance to draw, we have to generate a new MTLBuffer and fill its contents with the constant register values whenever an effect's state gets changed. (These extra buffers are cached to prevent excessive allocation, of course.) Each shader struct has a "UBO" struct that chooses which buffer to use at any given time. This allows for a "single" buffer to update its contents throughout a frame without just totally overwriting any previous contents. It's an ugly solution but it works. I haven't found a better way to do this.
An Effects interface for Metal. Much of the code is copy-pasted from mojoshader_opengl.c with a few significant changes: