cancel
Showing results for 
Search instead for 
Did you mean: 

Archives Discussions

avasquez
Journeyman III

Using precompiled OpenGL shaders across multiple machines with ARB_get_program_binary

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

 

0 Likes
7 Replies
nou
Exemplar

this extension is not intented to provide this "offline compilation" use case. if link from binary shader fail then it is expected that application provide normal source code and recompile it from source.

it can fail even with driver update. it is intended as cache for shaders.

0 Likes

So are you implying that the format of the binary program has to do with more than driver version? We all currently have the same video card and driver version.

I may end up having to just make a local cache at runtime for the application, but I would like to at least understand the logic being used to determine whether a binary program is compatible or not.

0 Likes

The link status is failed when the graphics card is changed or the driver version is changed possibly. The binary format is always the same for OpenGL binary. It may be different from OpenGL ES's binary. Are you sure the two machines are the same on the graphics envirionment?

0 Likes

I have reinstalled the driver packages on both machines and they both read in the device manager:
Driver Data: 11/25/2010
Driver Version: 8.801.0.0

However, now when I run the binary programs on machine 1, they run succesfully and on machine 2 there is a crash in the ati driver dll stemming from the call to glProgramBinary. If I use a version of the binary programs created on machine 2 on machine 2, then it runs successfully.

So, it seems to me that more than driver version and hardware is being taken into account here. Ultimately, I think I've decided just to make local caches when the application starts up to avoid the headaches of keeping everyone on the same exact driver version here at the company.

0 Likes

I use a local cache too, according to this logic:

- if there is no cache file present, load and compile the source and save the cache file

- if the cache file is present and the source's file timestamp is not newer than the cache, load the cache, otherwise load the source and save the cache file

- if the cache file fails to load, fall back to the source

This makes my app compile all shaders on the first startup on a foreign system and save the caches.

0 Likes

Another point is that the two machine operator systems should be the same. We don't support 32bit binary used on a 64bit system right now.

We have two fix on the extension but I don't know if they help you. If you want to try the fix, you could contact me by frank.li@amd.com. If the problem still exists, I would like to fix it as soon as possible.

Thanks
Frank

0 Likes

I have a try with the latest Catalyst11.1 driver(8.812). The binary that is got from the Win7 32bit could be loaded without any error on Vista 32bit. You'd better check that
1. If the problem exists with the latest 11.1 driver
2. Is there any other changes between the two machines

Thanks 

0 Likes