28/10/2012 10th Anniversary contest: and the winner is...

Congratulation to Wilhansen Li who answered all the questions correctly and won a copy of OpenGL Insights! Here is the answers with some details.

What shader stages are available?

Vertex shader, Tessellation Control Shader, Tessellation Evaluation Shader, Geometry Shader, Fragment Shader, Compute Shader.

What's the minimum maximum number of uniform blocks we can use simultanously?

14 blocks per stage. This limits has been raised with OpenGL 4.3 from 12 to 14 and is given by querying GL_MAX_VERTEX_UNIFORM_BLOCKS, GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS, GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS, GL_MAX_GEOMETRY_UNIFORM_BLOCKS, GL_MAX_GEOMETRY_UNIFORM_BLOCKS and GL_MAX_COMPUTE_UNIFORM_BLOCKS. In practice, AMD implementation supports 15 blocks per stage, Intel implementation supports 12 blocks per stage and NVIDIA implementation supports 14 blocks per stage.

What's the minimum maximum size for a uniform block?

The minimum maximum size for a uniform block is given by the GL_MAX_UNIFORM_BLOCK_SIZE query. OpenGL 4.3 set this minimum to 16384 bytes. This limit remains the same as the one set when the GL_ARB_uniform_buffer_object was introduce as part of OpenGL 3.1 specification. In practice, AMD and NVIDIA implementation support 65536 bytes for this limit but Intel implementation is limited to 16384 bytes.

What ressources can only be indexed with dynamically uniform expressions?

Dynamically uniform expressions restrict the access to ressources within a shader stage set of invocations, that is to say within a work group. Every ressources are evolved: textures, images, atomic counter buffer, uniform blocks and shader storage buffers. This is both true for indexing arrays of these resources and selecting ressources through if statements. For example, it is not legal to use a built-in variable that evolves for each shader invocation to index ressources. However, this index might be used to index ressources in a subsequent shader stage where all the shader invocations per work group will access the same ressources.

Illegal indexing of uniform blocks:
  • // --- Vertex Shader ---
  • layout(binding = INSTANCES) uniform perInstance {
  • ...
  • } Instance[MAX_INSTANCE_COUNT];
  • void main() {
  • ...
  • // /!\ Any indexing of ressources, no error but the rendering result is undefined. /!\
  • mat4 Transform = Instance[gl_InstanceID].Transform;
  • ...
  • }
Illegal ressource selection of uniform blocks:
  • // --- Vertex Shader ---
  • layout(binding = LOW_QUALITY_LOD) uniform lowQuality {
  • ...
  • } LowQuality;
  • layout(binding = HIGH_QUALITY_LOD) uniform highQuality {
  • ...
  • } HighQuality;
  • vec4 highQualityTransform() {
  • ... // Access HighQuality block
  • }
  • vec4 lowQualityTransform() {
  • ... // Access LowQuality block
  • }
  • void main() {
  • if(isObjectCloseToCamera())
  • gl_Position = highQualityTransform();
  • else
  • gl_Position = lowQualityTransform();
  • ...
  • }
How to ensure that an OpenGL implementation will be able to build GLSL shaders in parallels?

Single core CPU performances haven't significantly evolve for years now so that it's important to take advantge of the multi core architechture to ensure that shader compilation will be as fast as possible which is especially important for large application building thousand of shaders. For this it is extremely simple that the application only need to issue all the compilation commands before querying the individual compilation results.

Single CPU core shader compilation:
  • for(std::size_t i = 0; i < n; ++n) {
  • ...
  • GLuint Name = glCreateShader(Type);
  • glShaderSource(Name, 1, &Source, NULL);
  • glCompileShader(Name);
  • GLint Result = GL_FALSE;
  • glGetShaderiv(Name, GL_COMPILE_STATUS, &Result);
  • ...
  • }
Multiple CPU core shader compilation:
  • for(std::size_t i = 0; i < n; ++n) {
  • ...
  • GLuint Name = glCreateShader(Type);
  • glShaderSource(Name, 1, &Source, NULL);
  • glCompileShader(Name);
  • }
  • for(std::size_t i = 0; i < n; ++n) {
  • ...
  • GLint Result = GL_FALSE;
  • glGetShaderiv(ShaderName, GL_COMPILE_STATUS, &Result);
  • ...
  • }
OpenGL Samples Pack 4.3.0.3 released >
< 10th Anniversary: win a copy of OpenGL Insights
Copyright Christophe Riccio 2002-2016 all rights reserved
Designed for Chrome 9, Firefox 4, Opera 11 and Safari 5