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