halide/Halide — pull request #278 by DanielHeck (2014-04-28 17:14:29+00:00)
Title: OpenGL/GLSL backend for Halide

Sorry for dumping such a large pull request on you, but I think it's easier to continue our previous discussions in the context of real code. Let me know if you'd like me to split the changes into more manageable chunks.

I tried to keep the changes to the Halide core minimal and make sure that existing behavior is unaffected. All tests still work, but I didn't check the existing GPU backends.

The main changes are:

- Load/Store nodes now carry multiple indices since OpenGL textures are inherently 2D, so storage flattening is no real option. I'm using an OpenGL-specific pass over the IR to create these multi-index nodes before storage flattening. (In fact, the coordinates are already normalized at this point Load((x+0.5f)/extent[0], ...); I tried to move the normalization to the codegen stage, but optimizations like CSE work far better if the full expressions are known early.)

- For all buffers accessed from within a GLSL loop, I use create_buffer_t to fill a buffer_t. I tried to use the extent information in Allocate instead, but copy_to_dev and copy_to_host require min/extent/stride to function properly.

- libHalideOpenGLRuntime.so is a new dynamic lib used for during JIT execution. It links to the system's OpenGL implementation and performs some system-specific tasks like managing the OpenGL context.

- GLSL code is scheduled almost like regular GPU code. The main difference is the treatment of the color channel, which requires special handling because OpenGL performs implicit vectorization over it. (I'm currently unrolling the color loop, but generating vectorized GLSL code should also be possible.) I added Func::glsl() to perform this scheduling.

- There are a few basic JIT-based tests in test/opengl and an AOT test in apps/glsl. They should run on Linux and OS X.

Most of the remaining changes are in the GLSL code generator and the runtime code.