about using GL_ARB_get_program_binary

While trying to experiment with the GL_ARB_get_program_binary extension, I found various sample code that seemed a little flowed, while the 'official' sample code in the spec is fine.

To sum it up, when using glGetProgramBinary to fetch the binary representation of the shader (program is GL wording), OpenGL provides an 'opaque' binaryFormat value that is meant to be kept with the binary data. This value is needed when calling glProgramBinary to construct a shader from the binary data.

For a basic usage, there is no need to enumerate the available binary formats using a glGet with GL_PROGRAM_BINARY_FORMATS.

To retrieve the shader binary, one must call :

GLenum binaryFormat = 0;
GLsizei binaryLength = 0;
glGetProgramBinary( program, BUFFER_SIZE, &binaryLength, &binaryFormat, buffer );

To reconstruct a shader with the binary data :

glProgramBinary( program, binaryFormat, buffer, binaryLength );

One more thing is that, in order to be able to get the binary representation, you need to hint the driver about it ; and this must be done before linking the shader. This is done by calling :

/* must come before glLinkProgram or glProgramBinary */
glProgramParameteri( program, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GL_TRUE );

So far so good, it seems to work fine on latest drivers by NVidia or AMD, while it seems that the performance gain is more important on AMD - my preliminary measures give me strange results, so I got to double check them.


Discardable debug message logging in python

After a short discussion about handling of diagnostics messages in python, and the cost of calling 'do nothing' functions in python, I just had an idea.

The point is to be able to (quite) brainlessly insert calls to some debug logging function through python scripts.

Alas, these calls have a cost, which we are willing to pay for a 'debug' run, but not a 'release' run, where things should go fast (or python-fast to be relative).

One first option would be to have a 'do-nothing' function replacing the logging function in 'release' runs :
if __debug__:
def DBGLOG(message):
print "[D] " + message
def DBGLOG(message):
pass # do nothing
DBGLOG("some fancy message")

This works fine, but as CPython does not have any fancy dead code optimization combined with function inlining, it will always evaluate the arguments to the function before doing nothing. Hence, the following call will always cost some time :
DBGLOG("some message with costy parameter : '%s'" + str( [x for x in SOME_LIST ] ))

To prevent evaluating the arguments, we could use a good old if, but I don't like the thought of cluttering code with if statements...
if __debug__:
DBGLOG("some message with costy parameter : '%s'" + str( [x for x in SOME_LIST ] ))
The only form of conditional compilation I could find, in python, is related to the assert statement ; which is only evaluated if the interpreter constant __debug__ is true. We can use this at our advantage here :
assert DBGLOG("some message with costy parameter : '%s'" + str( [x for x in SOME_LIST ] ))
In this case, the parameters are not evaluated in 'release' runs (interpreter running with '-O' option).

Some quick and dirty benchmark comes below :

With the following results, on my machine :

'pass' time: 3.934145msec

'empty logging function' time: 247.512817msec

'if __debug__' time: 3.726006msec

'if ENABLE_DEBUG_MESSAGES' time: 6.114006msec

'assert logging function' time: 3.714085msec


Shameless plug, technical demo

At work, we've been up to creating a technical demonstration that features an architectural walk-through in an hotel lobby.

Our start point has been VRay renderings done with the model, to setup the ambience. We then worked with RTGU pipeline to export from 3dsmax, and reproduce the lighting.

The biggest challenge was reflections, that are present a little bit everywhere. I tried to approximate the glossy reflections using a volumetric texture storing spherical harmonics. We managed to tune something that's close enough, but reflections are tough beasts. Nest time, gotta try something mixing screen-space techniques maybe.

Another problem we faced was storing the HDR lighting in our lightmap system. The memory budget went up pretty quickly, so we could not afford as many details as we'd have liked. To improve to overall looks of lightmaps, especially in high-contrast zones, we're using Point-disk sampling to upsample the textures - it looks far better than bilinear filtering.

Some more information, and a demo download link, are available here.

Of course, and as always, any feedback is welcome !