5.2 Binding Programs and Data

Eventually Sh will have an rendering interface to specify geometry and initiate rendering passes without having to make low-level graphics API calls. However, this is not yet the case, and even if Sh had its own rendering API, we would still want to be able to use it with existing graphics APIs such as OpenGL or DirectX.

In order to use Sh programs with existing graphics APIs we provide some interfaces to bind programs to the GPU so that they will be run when actual geometry is sent to the graphics card externally to Sh.

None of these functions are necessary for stream programs, as the interface to stream execution is always managed through Sh regardless of compilation target.

5.2.1 Binding Programs

A GPU program is bound by calling shBind on a previously defined ShProgram object. This will bind the program object to its target using its currently selected backend. If necessary this completes the optimization of the program (if it was deferred for more efficient execution of program manipulation operators) and uploads it to the appropriate shader unit of the GPU. Subsequent calls to draw geometry using the standard API of the current backend will then use this program as a shader.

It is possible to bind a program to a different target than what is was compiled for by using a second (string) argument to shBind(). This may be useful to select a more specific backend than the one declared at program definition time, or to pass in some extra target compilation targets. Program targets are explained in more detail in Section 5.1.

5.2.2 Binding and Updating Data

/ E  As soon as a program is bound, all of the textures and uniform parameters it accesses will be downloaded to the GPU (if necessary). One might however want to change some uniform values or textures without rebinding the entire shader. However, Sh tries to avoid uploading new values for every little change to a parameter; instead, it defers them until it is sure the user is done. This optimization is particularly important for textures. For this reason, the shUpdate() function is provided. It basically warns Sh that the user is about to start rendering with the standard API and that Sh should resolve any outstanding deferred updates.

Called without arguments, shUpdate will upload any textures and uniform parameters which are out-of-date but required on all compilation targets that currently have any programs bound. Depending on whether textures have been changed, this may be a fairly expensive operation or may have almost no cost at all. Sh may in fact upload uniforms earlier (for instance, as they are modified), but shUpdate() should always be called before rendering to ensure that all uniforms and textures are completely up to date. In particularly, once we implement uniform lifting, even uniform update may be deferred to avoid redundant computation on the host.

As with shBind, the shUpdate function can take an optional string argument specifying a compilation target. If this is given, only uniforms and textures used by programs bound to the specified target will be updated. As stated earlier, if no argument is given, all targets in use will be updated.

5.2.3 Unbinding

/ E  The shUnbind function takes a string argument specifying a target. It will disable all of the given target’s currently bound Sh programs. Future calls to shUpdate for that target will do nothing. Future rendering calls corresponding to that target will not use programmable shaders. If programmable shaders are always necessary for a particular backend, the effect of shUnbind() is to defined by that backend in particular (but is in general undefined).

/ E  If shUnbind is called without a target, every target which currently has a shader bound to it will be unbound.

5.2.4 Querying Binding State

/ E  By calling shIsBound with a string target, a user can determine if any Sh program is currently bound to a particular target. The shBound function, which also takes a string target, will return a pointer to the program object bound to a particular target. If no Sh program is currently bound to a given target, a NULL pointer will be returned.

/ E  The shBeginBound and shEndBound functions return iterators to pairs of strings and program objects, allowing access to all currently bound programs and the targets under which they are bound. Note that if shBind or shUnbind is called, previous values returned by these functions may no longer be valid and should be discarded.


Note: This manual is available as a bound book from AK Peters, including better formatting, in-depth examples, and about 200 pages not available on-line.