• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1Name
2
3    ARB_get_program_binary
4
5Name Strings
6
7    GL_ARB_get_program_binary
8
9Contributors
10
11    Acorn Pooley
12    Aske Simon Christensen
13    Bruce Merry
14    David Garcia
15    Eric Werness
16    Georg Kolling
17    Greg Roth
18    Jason Green
19    Jeff Bolz
20    Jeremy Sandmel
21    Joey Blankenship
22    Jon Leech
23    Mark Callow
24    Pat Brown
25    Robert Simpson
26    Tom Olson
27
28Contact
29
30    Benj Lipchak, APPLE (lipchak 'at' apple.com)
31    Greg Roth, NVIDIA (groth 'at' nvidia.com)
32    Piers Daniell, NVIDIA (pdaniell 'at' nvidia.com)
33
34Notice
35
36    Copyright (c) 2010-2016 The Khronos Group Inc. Copyright terms at
37        http://www.khronos.org/registry/speccopyright.html
38
39Specification Update Policy
40
41    Khronos-approved extension specifications are updated in response to
42    issues and bugs prioritized by the Khronos OpenGL Working Group. For
43    extensions which have been promoted to a core Specification, fixes will
44    first appear in the latest version of that core Specification, and will
45    eventually be backported to the extension document. This policy is
46    described in more detail at
47        https://www.khronos.org/registry/OpenGL/docs/update_policy.php
48
49Status
50
51    Complete. Approved by the ARB on June 9, 2010.
52    Approved by the Khronos Board of Promoters on July 23, 2010.
53
54Version
55
56    Last Modified Date: January 11, 2019
57    Revision: #10
58
59Number
60
61    ARB Extension #96
62
63Dependencies
64
65    OpenGL 3.0 is required.
66
67    Written based on the wording of the OpenGL 3.2 compatibility specification.
68
69Overview
70
71    This extension introduces new commands to retrieve and set the binary
72    representation of a program object.  GetProgramBinary allows an
73    application to cache compiled and linked programs to avoid compiling and
74    linking when used again. This may even allow the GL itself to act as an
75    offline compiler.  The resulting program binary can be reloaded into the
76    GL via ProgramBinary.  This is a very useful path for applications that
77    wish to remain portable by shipping pure GLSL source shaders, yet would
78    like to avoid the cost of compiling their shaders at runtime.  Instead an
79    application can supply its GLSL source shaders during first application run,
80    or even during installation.  The application then compiles and links its
81    shaders and reads back the program binaries.  On subsequent runs, only the
82    program binaries need be supplied.
83
84    ProgramBinary may also accept binaries in vendor-specific formats
85    produced by specialized offline compilation tools. This extension does not
86    add any such formats, but allows for them in further extensions. Though the
87    level of optimization may not be identical -- the offline shader compiler
88    may have the luxury of more aggressive optimization at its disposal --
89    program binaries generated online by the GL are interchangeable with those
90    generated offline by an SDK tool.
91
92IP Status
93
94    No known IP claims.
95
96New Procedures and Functions
97
98    void GetProgramBinary(uint program, sizei bufSize, sizei *length,
99                          enum *binaryFormat, void *binary);
100
101    void ProgramBinary(uint program, enum binaryFormat,
102                       const void *binary, sizei length);
103
104    void ProgramParameteri(uint program, enum pname, int value);
105
106New Tokens
107
108    Accepted by the <pname> parameter of ProgramParameteri and
109    GetProgramiv:
110
111        PROGRAM_BINARY_RETRIEVABLE_HINT             0x8257
112
113    Accepted by the <pname> parameter of GetProgramiv:
114
115        PROGRAM_BINARY_LENGTH                       0x8741
116
117    Accepted by the <pname> parameter of GetBooleanv, GetIntegerv,
118    GetInteger64v, GetFloatv and GetDoublev:
119
120        NUM_PROGRAM_BINARY_FORMATS                  0x87FE
121        PROGRAM_BINARY_FORMATS                      0x87FF
122
123Additions to Chapter 2 of the OpenGL 3.2 Specification (OpenGL Operation)
124
125    Update section 2.14 "Vertex Shaders", insert before the last sentence of
126    the third paragraph:
127
128
129    "... which generates executable code from all the compiled shader objects
130    attached to the program. Alternatively, pre-compiled program binary code
131    may be directly loaded into a program object. When a linked program object
132    is used..."
133
134    Add the following paragraphs above the description of DeleteProgram, p. 86:
135
136    To set a program object parameter, call
137
138        void ProgramParameteri(uint program, enum pname, int value)
139
140    <pname> identifies which parameter to set for <program>. <value> holds the
141    value being set.
142
143    If <pname> is PROGRAM_BINARY_RETRIEVABLE_HINT, <value> must be TRUE or
144    FALSE, and indicates whether a program binary is likely to be retrieved
145    later, as described for ProgramBinary in section 2.14.3. This hint will
146    not take effect until the next time LinkProgram or ProgramBinary has
147    been called successfully.
148
149    Add section 2.14.3, Program Binaries
150
151    "The command
152
153        void GetProgramBinary(uint program, sizei bufSize, sizei *length,
154                              enum *binaryFormat, void *binary);
155
156    returns a binary representation of the program object's compiled and
157    linked executable source, henceforth referred to as its program binary.
158    The maximum number of bytes that may be written into <binary> is specified
159    by <bufSize>.  If <bufSize> is less than the number of bytes in the program
160    binary, then an INVALID_OPERATION error is thrown.  Otherwise, the actual
161    number of bytes written into <binary> is returned in <length> and its
162    format is returned in <binaryFormat>.  If <length> is NULL, then no
163    length is returned.
164
165    The number of bytes in the program binary can be queried by calling
166    GetProgramiv with <pname> PROGRAM_BINARY_LENGTH.  When a program object's
167    LINK_STATUS is FALSE, its program binary length is zero, and a call
168    to GetProgramBinary will generate an INVALID_OPERATION error.
169
170    The command
171
172        void ProgramBinary(uint program, enum binaryFormat,
173                           const void *binary, sizei length);
174
175    loads a program object with a program binary previously returned from
176    GetProgramBinary.  This is useful for future instantiations of the GL to
177    avoid online compilation, while still using OpenGL Shading Language source
178    shaders as a portable initial format.  <binaryFormat> and <binary> must be
179    those returned by a previous call to GetProgramBinary, and <length> must
180    be the length of the program binary as returned by GetProgramBinary or
181    GetProgramiv with <pname> PROGRAM_BINARY_LENGTH. Loading the program
182    binary will fail, setting the LINK_STATUS of <program> to FALSE, if
183    these conditions are not met.
184
185    Loading a program binary may also fail if the implementation determines
186    that there has been a change in hardware or software configuration from
187    when the program binary was produced such as having been compiled with
188    an incompatible or outdated version of the compiler. In this case the
189    application should fall back to providing the original OpenGL Shading
190    Language source shaders, and perhaps again retrieve the program binary
191    for future use.
192
193    A program object's program binary is replaced by calls to LinkProgram or
194    ProgramBinary. Where linking success or failure is concerned,
195    ProgramBinary can be considered to perform an implicit linking operation.
196    LinkProgram and ProgramBinary both set the program object's LINK_STATUS
197    to TRUE or FALSE, as queried with GetProgramiv, to reflect success or
198    failure and update the information log, queried with GetProgramInfoLog, to
199    provide details about warnings or errors.
200
201    A successful call to ProgramBinary will reset all uniform variables to
202    their initial values. The initial value is either the value of the
203    variable's initializer as specified in the original shader source, or 0
204    if no initializer was present.
205
206    Additionally, all vertex shader input and fragment shader output
207    assignments that were in effect when the program was linked before saving
208    are restored when ProgramBinary is called.
209
210    If ProgramBinary fails to load a binary, no error is generated, but any
211    information about a previous link or load of that program object is
212    lost. Thus, a failed load does not restore the old state of <program>.
213    The failure does not alter other program state not affected by linking
214    such as the attached shaders, and the vertex attribute and fragment data
215    location bindings as set by BindAttribLocation and BindFragDataLocation.
216
217    Queries of values NUM_PROGRAM_BINARY_FORMATS and PROGRAM_BINARY_FORMATS
218    return the number of program binary formats and the list of program binary
219    format values supported by an implementation.  The <binaryFormat> returned
220    by GetProgramBinary must be present in this list.
221
222    Any program binary retrieved using GetProgramBinary and submitted using
223    ProgramBinary under the same configuration must be successful. Any
224    programs loaded successfully by ProgramBinary must be run properly with
225    any legal GL state vector.
226
227    If a GL implementation needs to recompile or otherwise modify program
228    executables based on GL state outside the program, GetProgramBinary is
229    required to save enough information to allow such recompilation.
230
231    To indicate that a program binary is likely to be retrieved,
232    ProgramParameteri should be called with <pname>
233    PROGRAM_BINARY_RETRIEVABLE_HINT and <value> TRUE. This setting will not
234    be in effect until the next time LinkProgram or ProgramBinary has been
235    called successfully. Additionally, GetProgramBinary calls may be
236    deferred until after using the program with all non-program state
237    vectors that it is likely to encounter. Such deferral may allow
238    implementations to save additional information in the program binary
239    that would minimize recompilation in future uses of the program binary."
240
241    Modify Section 2.14.8, Required State
242
243    Add the following bullet to the state required per program object:
244
245      * boolean holding the hint to the retrievability of the program binary,
246      initially FALSE.
247
248
249Additions to Chapter 6 of the OpenGL 3.2 Specification (State and State
250Requests)
251
252    Modify section 6.1.16, Shader and Program Objects
253
254    Add to the end of the description of GetProgramiv, p. 385:
255
256    If <pname> is PROGRAM_BINARY_RETRIEVABLE_HINT, the current value of
257    whether the binary retrieval hint is enabled for <program> is returned.
258
259GLX Protocol
260
261    None.
262
263Errors
264
265    An INVALID_VALUE error is generated if the <program> argument to
266    GetProgramBinary, ProgramBinary, or ProgramParameteri is not the name of
267    a program object previously created with CreateProgram.
268
269    An INVALID_ENUM error is generated if the <pname> argument to
270    ProgramParameteri is not PROGRAM_BINARY_RETRIEVABLE_HINT.
271
272    An INVALID_VALUE error is generated if the <value> argument to
273    ProgramParameteri is not TRUE or FALSE.
274
275    An INVALID_OPERATION error is generated if GetProgramBinary is called
276    when the program object, <program>, does not contain a valid program
277    binary as reflected by its LINK_STATUS state; if <bufSize> is not big
278    enough to contain the entire program binary; or if the value of
279    NUM_PROGRAM_BINARY_FORMATS is zero.
280
281New State
282
283    (table 6.42, Program Object State) add the following:
284
285    Get Value                       Type  Get Command      Initial Value  Description                      Section
286    -------------                   ----  -----------      -------------  -----------                      -------
287    PROGRAM_BINARY_LENGTH           Z+    GetProgramiv     0              Length of program binary         2.14.3
288    PROGRAM_BINARY_RETRIEVABLE_HINT Z     GetProgramiv     FALSE          Retriavable binary hint enabled  2.14.3
289    -                               Z1    GetProgramBinary N/A            Binary representation of program 2.14.3
290
291    (table 6.51, Implementation Dependent Values) add the following:
292
293    Get Value                       Type    Get Command          Minimum Value  Description                        Section
294    -------------                   ----    -----------          -------------  -----------                        -------
295    PROGRAM_BINARY_FORMATS          0* x Z  GetIntegerv          N/A            Enumerated program binary formats  2.14.3
296    NUM_PROGRAM_BINARY_FORMATS      Z       GetIntegerv          0              Number of program binary formats   2.14.3
297
298Sample Usage
299
300    void retrieveProgramBinary(const GLchar* vsSource, const GLchar* fsSource,
301                               const char* myBinaryFileName,
302                               GLenum* binaryFormat)
303    {
304        GLuint        newFS, newVS;
305        GLuint        newProgram;
306        const GLchar* sources[1];
307        GLint         success;
308
309        GLint   binaryLength;
310        void*   binary;
311        FILE*   outfile;
312
313        //
314        //  Create new shader/program objects and attach them together.
315        //
316        newVS = glCreateShader(GL_VERTEX_SHADER);
317        newFS = glCreateShader(GL_FRAGMENT_SHADER);
318        newProgram = glCreateProgram();
319        glAttachShader(newProgram, newVS);
320        glAttachShader(newProgram, newFS);
321
322        //
323        //  Supply GLSL source shaders, compile, and link them
324        //
325        sources[0] = vsSource;
326        glShaderSource(newVS, 1, sources, NULL);
327        glCompileShader(newVS);
328
329        sources[0] = fsSource;
330        glShaderSource(newFS, 1, sources, NULL);
331        glCompileShader(newFS);
332
333        glProgramParameteri(newProgram, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GL_TRUE);
334        glLinkProgram(newProgram);
335        glGetProgramiv(newProgram, GL_LINK_STATUS, &success);
336
337        if (!success)
338        {
339            //
340            // Fallback to simpler source shaders?  Take my toys and go home?
341            //
342        }
343
344        glUseProgram(newProgram);
345
346        //
347        // Perform rendering and state changes likely to be encountered.
348        //
349        DoRendering(newProgram);
350
351        //
352        //  Retrieve the binary from the program object
353        //
354        glGetProgramiv(newProgram, GL_PROGRAM_BINARY_LENGTH, &binaryLength);
355        binary = (void*)malloc(binaryLength);
356        glGetProgramBinary(newProgram, binaryLength, NULL, binaryFormat, binary);
357
358        //
359        //  Cache the program binary for future runs
360        //
361        outfile = fopen(myBinaryFileName, "wb");
362        fwrite(binary, binaryLength, 1, outfile);
363        fclose(outfile);
364        free(binary);
365
366        //
367        // Clean up
368        //
369        glDeleteShader(newVS);
370        glDeleteShader(newFS);
371        glDeleteProgram(newProgram);
372    }
373
374    void loadProgramBinary(const char* myBinaryFileName, GLenum binaryFormat,
375                           GLuint progObj)
376    {
377        GLint   binaryLength;
378        void*   binary;
379        GLint   success;
380        FILE*   infile;
381
382        //
383        //  Read the program binary
384        //
385        infile = fopen(myBinaryFileName, "rb");
386        fseek(infile, 0, SEEK_END);
387        binaryLength = (GLint)ftell(infile);
388        binary = (void*)malloc(binaryLength);
389        fseek(infile, 0, SEEK_SET);
390        fread(binary, binaryLength, 1, infile);
391        fclose(infile);
392
393        //
394        //  Load the binary into the program object -- no need to link!
395        //
396        glProgramBinary(progObj, binaryFormat, binary, binaryLength);
397        free(binary);
398
399        glGetProgramiv(progObj, GL_LINK_STATUS, &success);
400
401        if (!success)
402        {
403            //
404            // Something must have changed since the program binaries
405            // were cached away.  Fallback to source shader loading path,
406            // and then retrieve and cache new program binaries once again.
407            //
408        }
409    }
410
411Issues
412
413    1. Do we need to consider state dependencies when using this extension?
414
415    RESOLVED: A little. A program binary retrieved with GetProgramBinary
416    can be expected to work regardless of the current GL state in effect at the
417    time it was retrieved with GetProgramBinary, loaded with
418    ProgramBinary, installed as part of render state with UseProgram, or used
419    for drawing with DrawArrays or DrawElements.
420
421    However, in many cases, internal state dependencies affect the way source
422    shaders are compiled. State considerations may indicate whether
423    optimizations are available or if workarounds are necessary. In
424    consideration of these issues, users of this extension should be advised
425    that querying the program binary after the full range of state
426    configurations have been seen may allow the implementation to include
427    optimized versions and avoid recompiles that may affect performance.
428
429    2. How are shader objects involved, if at all?
430
431    RESOLVED: Shader objects play no part in the specification of program
432    binaries.  (See also Issue 3.)
433
434    The program binary retrieved by GetProgramBinary is the one installed
435    during the most recent call to LinkProgram or ProgramBinary, i.e. the one
436    which would go into effect if we were to call UseProgram.  Attaching
437    different shader objects after the most recent call to LinkProgram is
438    inconsequential.
439
440    3. Should we throw an error as a programming aid if there are shader objects
441       attached to the program object when ProgramBinary is called?
442
443    RESOLVED: No, they are irrelevant but harmless, and GL precedent is to throw
444    errors on bad state combinations, not on harmless ones.  Besides, the
445    programmer should discover pretty quickly that they're getting the wrong
446    shader, if they accidentally called ProgramBinary instead of LinkProgram.
447    Also, an app may intentionally leave the attachments in place if it for some
448    reason is switching back and forth between loading a program object with
449    program binaries, and loading it with compiled GLSL shaders.
450
451    4. Where are the binary formats defined and described?
452
453    RESOLVED: This extension provides a common infrastructure for retrieving and
454    loading program binaries.  A vendor extension must also be present in order
455    to define one or more binary formats, thereby populating the list of
456    PROGRAM_BINARY_FORMATS.  The <binaryFormat> returned by
457    GetProgramBinary is always one of the binary formats in this list.  If
458    ProgramBinary is called with a <binaryFormat> not in this list, the
459    implementation will throw an INVALID_ENUM error.
460
461    The beauty of this extension, however, is that an application does not need
462    to be aware of the vendor extension on any given implementation.  It only
463    needs to retrieve a program binary with an anonymous <binaryFormat> and
464    resupply that same <binaryFormat> when loading the program binary.
465
466    5. Under what conditions might a call to ProgramBinary fail?
467
468    RESOLVED: Even if a program binary is successfully retrieved with
469    GetProgramBinary and then in a future run the program binary is
470    resupplied with ProgramBinary, and all of the parameters are correct,
471    the program binary load may still fail.
472
473    This can happen if there has been a change to the hardware or software on
474    the system, such as a hardware upgrade or driver update.  In this case the
475    PROGRAM_BINARY_FORMATS list may no longer contain the binary format
476    associated with the cached program binary, and INVALID_ENUM will be thrown
477    if the cached program binary format is passed into ProgramBinary anyway.
478
479    Even if the cached program binary format is still valid, ProgramBinary
480    may still fail to load the cached binary.  This is the driver's way of
481    signaling to the app that it needs to recompile and recache its program
482    binaries because there has been some important change to the online
483    compiler, such as a bug fix or a significant new optimization.
484
485    6. Can BindAttribLocation be called after ProgramBinary to remap an
486       attribute location used by the program binary?
487
488    RESOLVED: No.  BindAttribLocation only affects the result of a subsequent
489    call to LinkProgram.  LinkProgram operates on the attached shader objects
490    and replaces any program binary loaded prior to LinkProgram.  So there is no
491    mechanism to remap an attribute location after loading a program binary.
492
493    However, an application is free to remap an attribute location prior to
494    retrieving the program binary.  By calling BindAttribLocation followed by
495    LinkProgram, an application can remap the attribute location.  If this is
496    followed by a call to GetProgramBinary, the retrieved program binary will
497    include the desired attribute location assignment.
498
499    7. How does this spec differ from the OES_get_program_binary and why?
500
501    To better facilitate state-dependent optimizations and workarounds, a hint
502    is provided to ensure that the implementation includes any state-based
503    variants it might encounter. These dependencies also encourage the
504    programmer to retrieve binary programs late in the execution, after
505    relevant state changes have already occurred.
506
507    There are other areas where language was clarified, but this is meant to
508    be consistent with the intent of the original specification and not to
509    alter previously established behavior.
510
511    8. How does ProgramBinary interact with uniform values, including
512       shader-specified defaults?
513
514    RESOLVED: All uniforms specified in the binary are reset to their shader-
515    specified defaults, or to zero if they aren't specified, when the program
516    binary is loaded. The spec language has been updated to specify this
517    behavior.
518
519    9. Should ProgramBinary be expected to load a previously saved program
520       binary even if non-program state has changed enough such that a
521       recompile is needed by the GL implementation.
522
523    RESOLVED: Yes. Given the same configuration, for example hardware, driver
524    version, etc., the GL implementation should save as much data as it needs
525    with the program binary such that if a recompile is necessary it has all
526    the data it needs to do this. Only if the configuration changes, it is
527    acceptable to fail ProgramBinary.
528
529    The application may use the PROGRAM_BINARY_RETRIEVABLE_HINT hint to
530    indicate to the GL implementation that this program will likely be saved
531    with GetProgramBinary at some point. This will give the GL implementation
532    the opportunity to track any state changes made to the program before
533    being saved such that when it is loaded again a recompile can be avoided.
534
535Revision History
536
537    10 01/11/2019 Add an error for ProgramBinary if there are no binary
538                  formats (Bug 16155).
539
540    09 07/05/2016 Fix missing GL_ prefix in example code.
541
542    08 10/08/2013 Change GLvoid -> void (Bug 10412).
543
544    07 06/14/2012 Clean up descriptions of "failed binary", add errors,
545                  and move HINT description back to ProgramParameteri.
546
547    06 07/19/2010 Fixed a teenie typo with OES left on ProgramBinaryOES in
548                  issue #3.
549
550    05 05/26/2010 Modifications based on feedback from Pat Brown and the
551                  ARB f2f.
552
553    04 05/17/2010 Restore the old "int" type for the length parameter
554                  to ProgramBinary since matching the ratified GLES is more
555                  important in this case.
556
557    03 05/10/2010 Various minor cleanup based on feedback from Bruce.
558
559    02 04/09/2010 Converted to ARB version for inclusion in OpenGL 4.1.
560
561    01 01/11/2010 Initial EXT version.
562