I am having a problem with shaders loaded using glProgramBinary, starting with the Catalyst 13.8 beta2 driver. It seems as though querying GL_PROGRAM_BINARY_LENGTH from such a program will corrupt it. Here is some example code, which illustrates the problem:
// Binary shader loaded data from file (saved from previous program session):
// Load format, buffer, and size from a file.
// Load the binary shader into a program.
GLuint Program = glCreateProgram();
glProgramBinary(Program, format, buffer, size);
glGetProgramiv(Program, GL_LINK_STATUS, &linkStatus); // linkStatus==GL_TRUE
glGetProgramiv(Program, GL_LINK_STATUS, &linkStatus); // linkStatus==GL_TRUE (still)
glGetProgramiv(Program, GL_PROGRAM_BINARY_LENGTH, &binSize); // binSize==672, original was 80128, seems like an error.
glGetProgramiv(Program, GL_LINK_STATUS, &linkStatus); // linkStatus==GL_FALSE
glGetProgramiv(Program, GL_PROGRAM_BINARY_LENGTH, &binSize); // binsize==672, should be 0 (per spec), if linkStatus==GL_FALSE
The program in question may generate different shaders on different invocations. For simplification of the binary shader saving code, it will save all shaders to a binary file on exit. This means that some binary shaders may be loaded from previous invocations of the program, while some may be new, however the saving code has no knowledge of this, it saves all shaders regardless. It was assuming that glGetProgramBinary would not fail, which is not true and subsequently crashes, because when the shader was loaded GL_LINK_STATUS was GL_TRUE (before the extra test code was added), and no intervening calls to glProgramBinary or glLinkProgram are made (which should be the only calls that change GL_LINK_STATUS).
This code worked as expected in previous driver versions, with other desktop drivers, and also on android (with the appropriate OES extension functions replaced).
Thanks for this report. Sorry for not noticing it sooner. We've put an engineer on this and will get it fixed.