The GLSL Shader Interfaces
The shader system is a central module of a graphics engine, providing ﬂexibility,
performance, and reliability to an application. In this chapter we explore various
aspects of the GLSL shader interfaces to improve its quality.
These interfaces are the elements of the language that expose buffers and textures
within a shader stage. They allow communication between shader stages and between
the application and the shader stages. This includes input interfaces, output inter-
faces, interface blocks, atomic counters, samplers, and image units [Kessenich 12].
On the OpenGL Insights website, www.openglinsights.com, code samples are pro-
vided to illustrate each section. A direct output from this chapter is a series of func-
tions that can be directly used in any OpenGL program for detecting silent errors,
errors that OpenGL doesn’t catch by design, but eventually result in an unexpected
I target three main goals:
• Performance. Description of some effects of the shader interface on mem-
ory consumption, bandwidth, and reduction of the CPU overhead.
• Flexibility. Exploration of cases to ensure the reuse of a maximum number
• Reliability. Options in debug mode for detecting silent errors.
5.2 Variables and Blocks
5.2.1 User-Deﬁned Variables and Blocks
The GLSL shader interfaces are the elements of the OpenGL API and GLSL that
allo w communication. On the application side, we can create various kinds of buffers
and textures that are used in a shader pipeline. In GLSL, these resources need to be
exposed through variables and blocks. It’s the duty of the OpenGL programmer to
make sure that the required resources are bound and that these resources are actually
compatible with the variables a nd blocks that expose them. It is called shader interf ace
matching [Leech 12].
A GLSL variable may be a scalar, a vector, a matrix, an array, a structure, or an
opaque type according to which interface it is declared for. See Table 5.1.
vertex varying fragment uniform
scalar yes yes yes yes
vector yes yes yes yes
matrix yes yes no yes
array yes yes yes yes
structure no yes no yes
opaque type no no no yes
block no yes no yes
Tabl e 5 .1. Elements of languages and interfaces where they can be used.
An opaque type is a type that abstracts and exposes an element of the GPU ﬁxed
functions. GLSL 4.20 has three different opaque types: samplers, images, and atomic
Blocks (Listing 5.1) were introduced in OpenGL 3.1 and GLSL 1.40 to expose
uniform buffers in shaders. With OpenGL 3.2 and the introduction of the geometry-
shader stage, the use of blocks has been extended to varying variables in GLSL 1.50
to cope with a namespace issue, which block-name and instance-name solve.
Blocks are containers of variables, called block members, which can be anything
but opaque types or blocks. A block looks like a str ucture at ﬁrst, but it has at least
two differences: a block can’t be declared and deﬁned at two different spots in the
shader; a block decouples its name into two parts: the block name and the instance
[layout -qualifier] interface - qualifier block - name
} [instance - name];
Listing 5.1. Block syntax.