7 Replies Latest reply on Feb 12, 2011 3:00 AM by frali

    Using precompiled OpenGL shaders across multiple machines with ARB_get_program_binary

    avasquez

      Hello,

      I have recently created a tool to precompile a set of glsl shaders using the ARB_get_program_binary extension. This tool logs the binary program results to a file. I have a second application which loads and uses them. I am able to sucessfully use these shaders in the secondary program on my machine, however, when I hand the file off to another machine with a similar setup, the shaders fail to link.

      Now, I'm aware that the get_program_binary_extension does not garauntee that shaders will run on setups with varying hardware/drivers. I would like to get a grasp on where I can expect to be able to run these shaders.

      To start off with, here is my info:
      Windows 7 64 bit
      AMD Radeon HD 6800 Series
      Device ID 6738
      Catalyst Version: 10.12
      OpenGL Version: 6.14.10.10362
      Supported Program Binary Formats: { 36894 }


      When I 'precompile' the shaders in the tool I follow this flow:
      1. Compile all sources with glCompileShader
      2. Set the GL_PROGRAM_BINARY_RETRIEVABLE_HINT hint
      3. Link the program and verify the link was successful.
      4. Get the length of the program with glGetProgramiv and GL_PROGRAM_BINARY_LENGTH
      5. Get the binary version of the program with glGetProgramBinary
      6. Log the binary format and data to a file.

      On loading in the secondary application I do:
      1. Read the binary format and data from the file.
      2. Load the stream into a program using glProgramBinary.
      3. Verify the link status.

      Now, on the machine that ran the precompilation step, the link status (using GL_LINK_STATUS) is successful and the shaders run as I would expect. If that file is transferred to any other machine however, the shaders fail to link. If I run the precompilation step on the other machine, it successfully loads on that machine, but not mine.

      From reading the extension spec, it seems that you can query the supported binary formats for your driver using GL_NUM_PROGRAM_BINARY_FORMATS and GL_PROGRAM_BINARY_FORMATS. On all of the machines, this results in a single binary format: 36894.

      It would make sense to me for the shaders to fail to link if that format was different on each machine, however it is consistent. Lastly, there is a paragraph (Q/A #5, last paragraph) in the extension spec that says that a binary format in the GL_PROGRAM_BINARY_FORMATS list can still fail to compile if the driver wants the user to 'upgrade' their format to a newer supported one. However, this does not seem to make sense in my case where the card only claims to support a single format.

      Is the ability for the driver to link a binary program determined by more than this binary format enum? Does the format of the compiled binary depend on more than just the driver version and hardware?

      This is the extension spec I am referencing btw. I apologize for linking an NVIDIA article on an ATI site.

      http://developer.download.nvidia.com/opengl/specs/GL_ARB_get_program_binary.txt