15bd8deadSopenharmony_ciName
25bd8deadSopenharmony_ci
35bd8deadSopenharmony_ci    ARB_get_program_binary
45bd8deadSopenharmony_ci
55bd8deadSopenharmony_ciName Strings
65bd8deadSopenharmony_ci
75bd8deadSopenharmony_ci    GL_ARB_get_program_binary
85bd8deadSopenharmony_ci
95bd8deadSopenharmony_ciContributors
105bd8deadSopenharmony_ci
115bd8deadSopenharmony_ci    Acorn Pooley
125bd8deadSopenharmony_ci    Aske Simon Christensen
135bd8deadSopenharmony_ci    Bruce Merry
145bd8deadSopenharmony_ci    David Garcia
155bd8deadSopenharmony_ci    Eric Werness
165bd8deadSopenharmony_ci    Georg Kolling
175bd8deadSopenharmony_ci    Greg Roth
185bd8deadSopenharmony_ci    Jason Green
195bd8deadSopenharmony_ci    Jeff Bolz
205bd8deadSopenharmony_ci    Jeremy Sandmel
215bd8deadSopenharmony_ci    Joey Blankenship
225bd8deadSopenharmony_ci    Jon Leech
235bd8deadSopenharmony_ci    Mark Callow
245bd8deadSopenharmony_ci    Pat Brown
255bd8deadSopenharmony_ci    Robert Simpson
265bd8deadSopenharmony_ci    Tom Olson
275bd8deadSopenharmony_ci
285bd8deadSopenharmony_ciContact
295bd8deadSopenharmony_ci
305bd8deadSopenharmony_ci    Benj Lipchak, APPLE (lipchak 'at' apple.com)
315bd8deadSopenharmony_ci    Greg Roth, NVIDIA (groth 'at' nvidia.com)
325bd8deadSopenharmony_ci    Piers Daniell, NVIDIA (pdaniell 'at' nvidia.com)
335bd8deadSopenharmony_ci
345bd8deadSopenharmony_ciNotice
355bd8deadSopenharmony_ci
365bd8deadSopenharmony_ci    Copyright (c) 2010-2016 The Khronos Group Inc. Copyright terms at
375bd8deadSopenharmony_ci        http://www.khronos.org/registry/speccopyright.html
385bd8deadSopenharmony_ci
395bd8deadSopenharmony_ciSpecification Update Policy
405bd8deadSopenharmony_ci
415bd8deadSopenharmony_ci    Khronos-approved extension specifications are updated in response to
425bd8deadSopenharmony_ci    issues and bugs prioritized by the Khronos OpenGL Working Group. For
435bd8deadSopenharmony_ci    extensions which have been promoted to a core Specification, fixes will
445bd8deadSopenharmony_ci    first appear in the latest version of that core Specification, and will
455bd8deadSopenharmony_ci    eventually be backported to the extension document. This policy is
465bd8deadSopenharmony_ci    described in more detail at
475bd8deadSopenharmony_ci        https://www.khronos.org/registry/OpenGL/docs/update_policy.php
485bd8deadSopenharmony_ci
495bd8deadSopenharmony_ciStatus
505bd8deadSopenharmony_ci
515bd8deadSopenharmony_ci    Complete. Approved by the ARB on June 9, 2010.
525bd8deadSopenharmony_ci    Approved by the Khronos Board of Promoters on July 23, 2010.
535bd8deadSopenharmony_ci
545bd8deadSopenharmony_ciVersion
555bd8deadSopenharmony_ci
565bd8deadSopenharmony_ci    Last Modified Date: January 11, 2019
575bd8deadSopenharmony_ci    Revision: #10
585bd8deadSopenharmony_ci
595bd8deadSopenharmony_ciNumber
605bd8deadSopenharmony_ci
615bd8deadSopenharmony_ci    ARB Extension #96
625bd8deadSopenharmony_ci
635bd8deadSopenharmony_ciDependencies
645bd8deadSopenharmony_ci
655bd8deadSopenharmony_ci    OpenGL 3.0 is required.
665bd8deadSopenharmony_ci
675bd8deadSopenharmony_ci    Written based on the wording of the OpenGL 3.2 compatibility specification.
685bd8deadSopenharmony_ci
695bd8deadSopenharmony_ciOverview
705bd8deadSopenharmony_ci
715bd8deadSopenharmony_ci    This extension introduces new commands to retrieve and set the binary
725bd8deadSopenharmony_ci    representation of a program object.  GetProgramBinary allows an
735bd8deadSopenharmony_ci    application to cache compiled and linked programs to avoid compiling and
745bd8deadSopenharmony_ci    linking when used again. This may even allow the GL itself to act as an
755bd8deadSopenharmony_ci    offline compiler.  The resulting program binary can be reloaded into the
765bd8deadSopenharmony_ci    GL via ProgramBinary.  This is a very useful path for applications that
775bd8deadSopenharmony_ci    wish to remain portable by shipping pure GLSL source shaders, yet would
785bd8deadSopenharmony_ci    like to avoid the cost of compiling their shaders at runtime.  Instead an
795bd8deadSopenharmony_ci    application can supply its GLSL source shaders during first application run,
805bd8deadSopenharmony_ci    or even during installation.  The application then compiles and links its
815bd8deadSopenharmony_ci    shaders and reads back the program binaries.  On subsequent runs, only the
825bd8deadSopenharmony_ci    program binaries need be supplied.
835bd8deadSopenharmony_ci
845bd8deadSopenharmony_ci    ProgramBinary may also accept binaries in vendor-specific formats
855bd8deadSopenharmony_ci    produced by specialized offline compilation tools. This extension does not
865bd8deadSopenharmony_ci    add any such formats, but allows for them in further extensions. Though the
875bd8deadSopenharmony_ci    level of optimization may not be identical -- the offline shader compiler
885bd8deadSopenharmony_ci    may have the luxury of more aggressive optimization at its disposal --
895bd8deadSopenharmony_ci    program binaries generated online by the GL are interchangeable with those
905bd8deadSopenharmony_ci    generated offline by an SDK tool.
915bd8deadSopenharmony_ci
925bd8deadSopenharmony_ciIP Status
935bd8deadSopenharmony_ci
945bd8deadSopenharmony_ci    No known IP claims.
955bd8deadSopenharmony_ci
965bd8deadSopenharmony_ciNew Procedures and Functions
975bd8deadSopenharmony_ci
985bd8deadSopenharmony_ci    void GetProgramBinary(uint program, sizei bufSize, sizei *length,
995bd8deadSopenharmony_ci                          enum *binaryFormat, void *binary);
1005bd8deadSopenharmony_ci
1015bd8deadSopenharmony_ci    void ProgramBinary(uint program, enum binaryFormat,
1025bd8deadSopenharmony_ci                       const void *binary, sizei length);
1035bd8deadSopenharmony_ci
1045bd8deadSopenharmony_ci    void ProgramParameteri(uint program, enum pname, int value);
1055bd8deadSopenharmony_ci
1065bd8deadSopenharmony_ciNew Tokens
1075bd8deadSopenharmony_ci
1085bd8deadSopenharmony_ci    Accepted by the <pname> parameter of ProgramParameteri and
1095bd8deadSopenharmony_ci    GetProgramiv:
1105bd8deadSopenharmony_ci
1115bd8deadSopenharmony_ci        PROGRAM_BINARY_RETRIEVABLE_HINT             0x8257
1125bd8deadSopenharmony_ci
1135bd8deadSopenharmony_ci    Accepted by the <pname> parameter of GetProgramiv:
1145bd8deadSopenharmony_ci
1155bd8deadSopenharmony_ci        PROGRAM_BINARY_LENGTH                       0x8741
1165bd8deadSopenharmony_ci
1175bd8deadSopenharmony_ci    Accepted by the <pname> parameter of GetBooleanv, GetIntegerv,
1185bd8deadSopenharmony_ci    GetInteger64v, GetFloatv and GetDoublev:
1195bd8deadSopenharmony_ci
1205bd8deadSopenharmony_ci        NUM_PROGRAM_BINARY_FORMATS                  0x87FE
1215bd8deadSopenharmony_ci        PROGRAM_BINARY_FORMATS                      0x87FF
1225bd8deadSopenharmony_ci
1235bd8deadSopenharmony_ciAdditions to Chapter 2 of the OpenGL 3.2 Specification (OpenGL Operation)
1245bd8deadSopenharmony_ci
1255bd8deadSopenharmony_ci    Update section 2.14 "Vertex Shaders", insert before the last sentence of
1265bd8deadSopenharmony_ci    the third paragraph:
1275bd8deadSopenharmony_ci
1285bd8deadSopenharmony_ci
1295bd8deadSopenharmony_ci    "... which generates executable code from all the compiled shader objects
1305bd8deadSopenharmony_ci    attached to the program. Alternatively, pre-compiled program binary code
1315bd8deadSopenharmony_ci    may be directly loaded into a program object. When a linked program object
1325bd8deadSopenharmony_ci    is used..."
1335bd8deadSopenharmony_ci
1345bd8deadSopenharmony_ci    Add the following paragraphs above the description of DeleteProgram, p. 86:
1355bd8deadSopenharmony_ci
1365bd8deadSopenharmony_ci    To set a program object parameter, call
1375bd8deadSopenharmony_ci
1385bd8deadSopenharmony_ci        void ProgramParameteri(uint program, enum pname, int value)
1395bd8deadSopenharmony_ci
1405bd8deadSopenharmony_ci    <pname> identifies which parameter to set for <program>. <value> holds the
1415bd8deadSopenharmony_ci    value being set.
1425bd8deadSopenharmony_ci
1435bd8deadSopenharmony_ci    If <pname> is PROGRAM_BINARY_RETRIEVABLE_HINT, <value> must be TRUE or
1445bd8deadSopenharmony_ci    FALSE, and indicates whether a program binary is likely to be retrieved
1455bd8deadSopenharmony_ci    later, as described for ProgramBinary in section 2.14.3. This hint will
1465bd8deadSopenharmony_ci    not take effect until the next time LinkProgram or ProgramBinary has
1475bd8deadSopenharmony_ci    been called successfully.
1485bd8deadSopenharmony_ci
1495bd8deadSopenharmony_ci    Add section 2.14.3, Program Binaries
1505bd8deadSopenharmony_ci
1515bd8deadSopenharmony_ci    "The command
1525bd8deadSopenharmony_ci
1535bd8deadSopenharmony_ci        void GetProgramBinary(uint program, sizei bufSize, sizei *length,
1545bd8deadSopenharmony_ci                              enum *binaryFormat, void *binary);
1555bd8deadSopenharmony_ci
1565bd8deadSopenharmony_ci    returns a binary representation of the program object's compiled and
1575bd8deadSopenharmony_ci    linked executable source, henceforth referred to as its program binary.
1585bd8deadSopenharmony_ci    The maximum number of bytes that may be written into <binary> is specified
1595bd8deadSopenharmony_ci    by <bufSize>.  If <bufSize> is less than the number of bytes in the program
1605bd8deadSopenharmony_ci    binary, then an INVALID_OPERATION error is thrown.  Otherwise, the actual
1615bd8deadSopenharmony_ci    number of bytes written into <binary> is returned in <length> and its
1625bd8deadSopenharmony_ci    format is returned in <binaryFormat>.  If <length> is NULL, then no
1635bd8deadSopenharmony_ci    length is returned.
1645bd8deadSopenharmony_ci
1655bd8deadSopenharmony_ci    The number of bytes in the program binary can be queried by calling
1665bd8deadSopenharmony_ci    GetProgramiv with <pname> PROGRAM_BINARY_LENGTH.  When a program object's
1675bd8deadSopenharmony_ci    LINK_STATUS is FALSE, its program binary length is zero, and a call
1685bd8deadSopenharmony_ci    to GetProgramBinary will generate an INVALID_OPERATION error.
1695bd8deadSopenharmony_ci
1705bd8deadSopenharmony_ci    The command
1715bd8deadSopenharmony_ci
1725bd8deadSopenharmony_ci        void ProgramBinary(uint program, enum binaryFormat,
1735bd8deadSopenharmony_ci                           const void *binary, sizei length);
1745bd8deadSopenharmony_ci
1755bd8deadSopenharmony_ci    loads a program object with a program binary previously returned from
1765bd8deadSopenharmony_ci    GetProgramBinary.  This is useful for future instantiations of the GL to
1775bd8deadSopenharmony_ci    avoid online compilation, while still using OpenGL Shading Language source
1785bd8deadSopenharmony_ci    shaders as a portable initial format.  <binaryFormat> and <binary> must be
1795bd8deadSopenharmony_ci    those returned by a previous call to GetProgramBinary, and <length> must
1805bd8deadSopenharmony_ci    be the length of the program binary as returned by GetProgramBinary or
1815bd8deadSopenharmony_ci    GetProgramiv with <pname> PROGRAM_BINARY_LENGTH. Loading the program
1825bd8deadSopenharmony_ci    binary will fail, setting the LINK_STATUS of <program> to FALSE, if
1835bd8deadSopenharmony_ci    these conditions are not met.
1845bd8deadSopenharmony_ci
1855bd8deadSopenharmony_ci    Loading a program binary may also fail if the implementation determines
1865bd8deadSopenharmony_ci    that there has been a change in hardware or software configuration from
1875bd8deadSopenharmony_ci    when the program binary was produced such as having been compiled with
1885bd8deadSopenharmony_ci    an incompatible or outdated version of the compiler. In this case the
1895bd8deadSopenharmony_ci    application should fall back to providing the original OpenGL Shading
1905bd8deadSopenharmony_ci    Language source shaders, and perhaps again retrieve the program binary
1915bd8deadSopenharmony_ci    for future use.
1925bd8deadSopenharmony_ci
1935bd8deadSopenharmony_ci    A program object's program binary is replaced by calls to LinkProgram or
1945bd8deadSopenharmony_ci    ProgramBinary. Where linking success or failure is concerned,
1955bd8deadSopenharmony_ci    ProgramBinary can be considered to perform an implicit linking operation.
1965bd8deadSopenharmony_ci    LinkProgram and ProgramBinary both set the program object's LINK_STATUS
1975bd8deadSopenharmony_ci    to TRUE or FALSE, as queried with GetProgramiv, to reflect success or
1985bd8deadSopenharmony_ci    failure and update the information log, queried with GetProgramInfoLog, to
1995bd8deadSopenharmony_ci    provide details about warnings or errors.
2005bd8deadSopenharmony_ci
2015bd8deadSopenharmony_ci    A successful call to ProgramBinary will reset all uniform variables to
2025bd8deadSopenharmony_ci    their initial values. The initial value is either the value of the
2035bd8deadSopenharmony_ci    variable's initializer as specified in the original shader source, or 0
2045bd8deadSopenharmony_ci    if no initializer was present.
2055bd8deadSopenharmony_ci
2065bd8deadSopenharmony_ci    Additionally, all vertex shader input and fragment shader output
2075bd8deadSopenharmony_ci    assignments that were in effect when the program was linked before saving
2085bd8deadSopenharmony_ci    are restored when ProgramBinary is called.
2095bd8deadSopenharmony_ci
2105bd8deadSopenharmony_ci    If ProgramBinary fails to load a binary, no error is generated, but any
2115bd8deadSopenharmony_ci    information about a previous link or load of that program object is
2125bd8deadSopenharmony_ci    lost. Thus, a failed load does not restore the old state of <program>.
2135bd8deadSopenharmony_ci    The failure does not alter other program state not affected by linking
2145bd8deadSopenharmony_ci    such as the attached shaders, and the vertex attribute and fragment data
2155bd8deadSopenharmony_ci    location bindings as set by BindAttribLocation and BindFragDataLocation.
2165bd8deadSopenharmony_ci
2175bd8deadSopenharmony_ci    Queries of values NUM_PROGRAM_BINARY_FORMATS and PROGRAM_BINARY_FORMATS
2185bd8deadSopenharmony_ci    return the number of program binary formats and the list of program binary
2195bd8deadSopenharmony_ci    format values supported by an implementation.  The <binaryFormat> returned
2205bd8deadSopenharmony_ci    by GetProgramBinary must be present in this list.
2215bd8deadSopenharmony_ci
2225bd8deadSopenharmony_ci    Any program binary retrieved using GetProgramBinary and submitted using
2235bd8deadSopenharmony_ci    ProgramBinary under the same configuration must be successful. Any
2245bd8deadSopenharmony_ci    programs loaded successfully by ProgramBinary must be run properly with
2255bd8deadSopenharmony_ci    any legal GL state vector.
2265bd8deadSopenharmony_ci
2275bd8deadSopenharmony_ci    If a GL implementation needs to recompile or otherwise modify program
2285bd8deadSopenharmony_ci    executables based on GL state outside the program, GetProgramBinary is
2295bd8deadSopenharmony_ci    required to save enough information to allow such recompilation.
2305bd8deadSopenharmony_ci
2315bd8deadSopenharmony_ci    To indicate that a program binary is likely to be retrieved,
2325bd8deadSopenharmony_ci    ProgramParameteri should be called with <pname>
2335bd8deadSopenharmony_ci    PROGRAM_BINARY_RETRIEVABLE_HINT and <value> TRUE. This setting will not
2345bd8deadSopenharmony_ci    be in effect until the next time LinkProgram or ProgramBinary has been
2355bd8deadSopenharmony_ci    called successfully. Additionally, GetProgramBinary calls may be
2365bd8deadSopenharmony_ci    deferred until after using the program with all non-program state
2375bd8deadSopenharmony_ci    vectors that it is likely to encounter. Such deferral may allow
2385bd8deadSopenharmony_ci    implementations to save additional information in the program binary
2395bd8deadSopenharmony_ci    that would minimize recompilation in future uses of the program binary."
2405bd8deadSopenharmony_ci
2415bd8deadSopenharmony_ci    Modify Section 2.14.8, Required State
2425bd8deadSopenharmony_ci
2435bd8deadSopenharmony_ci    Add the following bullet to the state required per program object:
2445bd8deadSopenharmony_ci
2455bd8deadSopenharmony_ci      * boolean holding the hint to the retrievability of the program binary,
2465bd8deadSopenharmony_ci      initially FALSE.
2475bd8deadSopenharmony_ci
2485bd8deadSopenharmony_ci
2495bd8deadSopenharmony_ciAdditions to Chapter 6 of the OpenGL 3.2 Specification (State and State
2505bd8deadSopenharmony_ciRequests)
2515bd8deadSopenharmony_ci
2525bd8deadSopenharmony_ci    Modify section 6.1.16, Shader and Program Objects
2535bd8deadSopenharmony_ci
2545bd8deadSopenharmony_ci    Add to the end of the description of GetProgramiv, p. 385:
2555bd8deadSopenharmony_ci
2565bd8deadSopenharmony_ci    If <pname> is PROGRAM_BINARY_RETRIEVABLE_HINT, the current value of
2575bd8deadSopenharmony_ci    whether the binary retrieval hint is enabled for <program> is returned.
2585bd8deadSopenharmony_ci
2595bd8deadSopenharmony_ciGLX Protocol
2605bd8deadSopenharmony_ci
2615bd8deadSopenharmony_ci    None.
2625bd8deadSopenharmony_ci
2635bd8deadSopenharmony_ciErrors
2645bd8deadSopenharmony_ci
2655bd8deadSopenharmony_ci    An INVALID_VALUE error is generated if the <program> argument to
2665bd8deadSopenharmony_ci    GetProgramBinary, ProgramBinary, or ProgramParameteri is not the name of
2675bd8deadSopenharmony_ci    a program object previously created with CreateProgram.
2685bd8deadSopenharmony_ci
2695bd8deadSopenharmony_ci    An INVALID_ENUM error is generated if the <pname> argument to
2705bd8deadSopenharmony_ci    ProgramParameteri is not PROGRAM_BINARY_RETRIEVABLE_HINT.
2715bd8deadSopenharmony_ci
2725bd8deadSopenharmony_ci    An INVALID_VALUE error is generated if the <value> argument to
2735bd8deadSopenharmony_ci    ProgramParameteri is not TRUE or FALSE.
2745bd8deadSopenharmony_ci
2755bd8deadSopenharmony_ci    An INVALID_OPERATION error is generated if GetProgramBinary is called
2765bd8deadSopenharmony_ci    when the program object, <program>, does not contain a valid program
2775bd8deadSopenharmony_ci    binary as reflected by its LINK_STATUS state; if <bufSize> is not big
2785bd8deadSopenharmony_ci    enough to contain the entire program binary; or if the value of
2795bd8deadSopenharmony_ci    NUM_PROGRAM_BINARY_FORMATS is zero.
2805bd8deadSopenharmony_ci
2815bd8deadSopenharmony_ciNew State
2825bd8deadSopenharmony_ci
2835bd8deadSopenharmony_ci    (table 6.42, Program Object State) add the following:
2845bd8deadSopenharmony_ci
2855bd8deadSopenharmony_ci    Get Value                       Type  Get Command      Initial Value  Description                      Section
2865bd8deadSopenharmony_ci    -------------                   ----  -----------      -------------  -----------                      -------
2875bd8deadSopenharmony_ci    PROGRAM_BINARY_LENGTH           Z+    GetProgramiv     0              Length of program binary         2.14.3
2885bd8deadSopenharmony_ci    PROGRAM_BINARY_RETRIEVABLE_HINT Z     GetProgramiv     FALSE          Retriavable binary hint enabled  2.14.3
2895bd8deadSopenharmony_ci    -                               Z1    GetProgramBinary N/A            Binary representation of program 2.14.3
2905bd8deadSopenharmony_ci
2915bd8deadSopenharmony_ci    (table 6.51, Implementation Dependent Values) add the following:
2925bd8deadSopenharmony_ci
2935bd8deadSopenharmony_ci    Get Value                       Type    Get Command          Minimum Value  Description                        Section
2945bd8deadSopenharmony_ci    -------------                   ----    -----------          -------------  -----------                        -------
2955bd8deadSopenharmony_ci    PROGRAM_BINARY_FORMATS          0* x Z  GetIntegerv          N/A            Enumerated program binary formats  2.14.3
2965bd8deadSopenharmony_ci    NUM_PROGRAM_BINARY_FORMATS      Z       GetIntegerv          0              Number of program binary formats   2.14.3
2975bd8deadSopenharmony_ci
2985bd8deadSopenharmony_ciSample Usage
2995bd8deadSopenharmony_ci
3005bd8deadSopenharmony_ci    void retrieveProgramBinary(const GLchar* vsSource, const GLchar* fsSource,
3015bd8deadSopenharmony_ci                               const char* myBinaryFileName,
3025bd8deadSopenharmony_ci                               GLenum* binaryFormat)
3035bd8deadSopenharmony_ci    {
3045bd8deadSopenharmony_ci        GLuint        newFS, newVS;
3055bd8deadSopenharmony_ci        GLuint        newProgram;
3065bd8deadSopenharmony_ci        const GLchar* sources[1];
3075bd8deadSopenharmony_ci        GLint         success;
3085bd8deadSopenharmony_ci
3095bd8deadSopenharmony_ci        GLint   binaryLength;
3105bd8deadSopenharmony_ci        void*   binary;
3115bd8deadSopenharmony_ci        FILE*   outfile;
3125bd8deadSopenharmony_ci
3135bd8deadSopenharmony_ci        //
3145bd8deadSopenharmony_ci        //  Create new shader/program objects and attach them together.
3155bd8deadSopenharmony_ci        //
3165bd8deadSopenharmony_ci        newVS = glCreateShader(GL_VERTEX_SHADER);
3175bd8deadSopenharmony_ci        newFS = glCreateShader(GL_FRAGMENT_SHADER);
3185bd8deadSopenharmony_ci        newProgram = glCreateProgram();
3195bd8deadSopenharmony_ci        glAttachShader(newProgram, newVS);
3205bd8deadSopenharmony_ci        glAttachShader(newProgram, newFS);
3215bd8deadSopenharmony_ci
3225bd8deadSopenharmony_ci        //
3235bd8deadSopenharmony_ci        //  Supply GLSL source shaders, compile, and link them
3245bd8deadSopenharmony_ci        //
3255bd8deadSopenharmony_ci        sources[0] = vsSource;
3265bd8deadSopenharmony_ci        glShaderSource(newVS, 1, sources, NULL);
3275bd8deadSopenharmony_ci        glCompileShader(newVS);
3285bd8deadSopenharmony_ci
3295bd8deadSopenharmony_ci        sources[0] = fsSource;
3305bd8deadSopenharmony_ci        glShaderSource(newFS, 1, sources, NULL);
3315bd8deadSopenharmony_ci        glCompileShader(newFS);
3325bd8deadSopenharmony_ci
3335bd8deadSopenharmony_ci        glProgramParameteri(newProgram, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GL_TRUE);
3345bd8deadSopenharmony_ci        glLinkProgram(newProgram);
3355bd8deadSopenharmony_ci        glGetProgramiv(newProgram, GL_LINK_STATUS, &success);
3365bd8deadSopenharmony_ci
3375bd8deadSopenharmony_ci        if (!success)
3385bd8deadSopenharmony_ci        {
3395bd8deadSopenharmony_ci            //
3405bd8deadSopenharmony_ci            // Fallback to simpler source shaders?  Take my toys and go home?
3415bd8deadSopenharmony_ci            //
3425bd8deadSopenharmony_ci        }
3435bd8deadSopenharmony_ci
3445bd8deadSopenharmony_ci        glUseProgram(newProgram);
3455bd8deadSopenharmony_ci
3465bd8deadSopenharmony_ci        //
3475bd8deadSopenharmony_ci        // Perform rendering and state changes likely to be encountered.
3485bd8deadSopenharmony_ci        //
3495bd8deadSopenharmony_ci        DoRendering(newProgram);
3505bd8deadSopenharmony_ci
3515bd8deadSopenharmony_ci        //
3525bd8deadSopenharmony_ci        //  Retrieve the binary from the program object
3535bd8deadSopenharmony_ci        //
3545bd8deadSopenharmony_ci        glGetProgramiv(newProgram, GL_PROGRAM_BINARY_LENGTH, &binaryLength);
3555bd8deadSopenharmony_ci        binary = (void*)malloc(binaryLength);
3565bd8deadSopenharmony_ci        glGetProgramBinary(newProgram, binaryLength, NULL, binaryFormat, binary);
3575bd8deadSopenharmony_ci
3585bd8deadSopenharmony_ci        //
3595bd8deadSopenharmony_ci        //  Cache the program binary for future runs
3605bd8deadSopenharmony_ci        //
3615bd8deadSopenharmony_ci        outfile = fopen(myBinaryFileName, "wb");
3625bd8deadSopenharmony_ci        fwrite(binary, binaryLength, 1, outfile);
3635bd8deadSopenharmony_ci        fclose(outfile);
3645bd8deadSopenharmony_ci        free(binary);
3655bd8deadSopenharmony_ci
3665bd8deadSopenharmony_ci        //
3675bd8deadSopenharmony_ci        // Clean up
3685bd8deadSopenharmony_ci        //
3695bd8deadSopenharmony_ci        glDeleteShader(newVS);
3705bd8deadSopenharmony_ci        glDeleteShader(newFS);
3715bd8deadSopenharmony_ci        glDeleteProgram(newProgram);
3725bd8deadSopenharmony_ci    }
3735bd8deadSopenharmony_ci
3745bd8deadSopenharmony_ci    void loadProgramBinary(const char* myBinaryFileName, GLenum binaryFormat,
3755bd8deadSopenharmony_ci                           GLuint progObj)
3765bd8deadSopenharmony_ci    {
3775bd8deadSopenharmony_ci        GLint   binaryLength;
3785bd8deadSopenharmony_ci        void*   binary;
3795bd8deadSopenharmony_ci        GLint   success;
3805bd8deadSopenharmony_ci        FILE*   infile;
3815bd8deadSopenharmony_ci
3825bd8deadSopenharmony_ci        //
3835bd8deadSopenharmony_ci        //  Read the program binary
3845bd8deadSopenharmony_ci        //
3855bd8deadSopenharmony_ci        infile = fopen(myBinaryFileName, "rb");
3865bd8deadSopenharmony_ci        fseek(infile, 0, SEEK_END);
3875bd8deadSopenharmony_ci        binaryLength = (GLint)ftell(infile);
3885bd8deadSopenharmony_ci        binary = (void*)malloc(binaryLength);
3895bd8deadSopenharmony_ci        fseek(infile, 0, SEEK_SET);
3905bd8deadSopenharmony_ci        fread(binary, binaryLength, 1, infile);
3915bd8deadSopenharmony_ci        fclose(infile);
3925bd8deadSopenharmony_ci
3935bd8deadSopenharmony_ci        //
3945bd8deadSopenharmony_ci        //  Load the binary into the program object -- no need to link!
3955bd8deadSopenharmony_ci        //
3965bd8deadSopenharmony_ci        glProgramBinary(progObj, binaryFormat, binary, binaryLength);
3975bd8deadSopenharmony_ci        free(binary);
3985bd8deadSopenharmony_ci
3995bd8deadSopenharmony_ci        glGetProgramiv(progObj, GL_LINK_STATUS, &success);
4005bd8deadSopenharmony_ci
4015bd8deadSopenharmony_ci        if (!success)
4025bd8deadSopenharmony_ci        {
4035bd8deadSopenharmony_ci            //
4045bd8deadSopenharmony_ci            // Something must have changed since the program binaries
4055bd8deadSopenharmony_ci            // were cached away.  Fallback to source shader loading path,
4065bd8deadSopenharmony_ci            // and then retrieve and cache new program binaries once again.
4075bd8deadSopenharmony_ci            //
4085bd8deadSopenharmony_ci        }
4095bd8deadSopenharmony_ci    }
4105bd8deadSopenharmony_ci
4115bd8deadSopenharmony_ciIssues
4125bd8deadSopenharmony_ci
4135bd8deadSopenharmony_ci    1. Do we need to consider state dependencies when using this extension?
4145bd8deadSopenharmony_ci
4155bd8deadSopenharmony_ci    RESOLVED: A little. A program binary retrieved with GetProgramBinary
4165bd8deadSopenharmony_ci    can be expected to work regardless of the current GL state in effect at the
4175bd8deadSopenharmony_ci    time it was retrieved with GetProgramBinary, loaded with
4185bd8deadSopenharmony_ci    ProgramBinary, installed as part of render state with UseProgram, or used
4195bd8deadSopenharmony_ci    for drawing with DrawArrays or DrawElements.
4205bd8deadSopenharmony_ci
4215bd8deadSopenharmony_ci    However, in many cases, internal state dependencies affect the way source
4225bd8deadSopenharmony_ci    shaders are compiled. State considerations may indicate whether
4235bd8deadSopenharmony_ci    optimizations are available or if workarounds are necessary. In
4245bd8deadSopenharmony_ci    consideration of these issues, users of this extension should be advised
4255bd8deadSopenharmony_ci    that querying the program binary after the full range of state
4265bd8deadSopenharmony_ci    configurations have been seen may allow the implementation to include
4275bd8deadSopenharmony_ci    optimized versions and avoid recompiles that may affect performance.
4285bd8deadSopenharmony_ci
4295bd8deadSopenharmony_ci    2. How are shader objects involved, if at all?
4305bd8deadSopenharmony_ci
4315bd8deadSopenharmony_ci    RESOLVED: Shader objects play no part in the specification of program
4325bd8deadSopenharmony_ci    binaries.  (See also Issue 3.)
4335bd8deadSopenharmony_ci
4345bd8deadSopenharmony_ci    The program binary retrieved by GetProgramBinary is the one installed
4355bd8deadSopenharmony_ci    during the most recent call to LinkProgram or ProgramBinary, i.e. the one
4365bd8deadSopenharmony_ci    which would go into effect if we were to call UseProgram.  Attaching
4375bd8deadSopenharmony_ci    different shader objects after the most recent call to LinkProgram is
4385bd8deadSopenharmony_ci    inconsequential.
4395bd8deadSopenharmony_ci
4405bd8deadSopenharmony_ci    3. Should we throw an error as a programming aid if there are shader objects
4415bd8deadSopenharmony_ci       attached to the program object when ProgramBinary is called?
4425bd8deadSopenharmony_ci
4435bd8deadSopenharmony_ci    RESOLVED: No, they are irrelevant but harmless, and GL precedent is to throw
4445bd8deadSopenharmony_ci    errors on bad state combinations, not on harmless ones.  Besides, the
4455bd8deadSopenharmony_ci    programmer should discover pretty quickly that they're getting the wrong
4465bd8deadSopenharmony_ci    shader, if they accidentally called ProgramBinary instead of LinkProgram.
4475bd8deadSopenharmony_ci    Also, an app may intentionally leave the attachments in place if it for some
4485bd8deadSopenharmony_ci    reason is switching back and forth between loading a program object with
4495bd8deadSopenharmony_ci    program binaries, and loading it with compiled GLSL shaders.
4505bd8deadSopenharmony_ci
4515bd8deadSopenharmony_ci    4. Where are the binary formats defined and described?
4525bd8deadSopenharmony_ci
4535bd8deadSopenharmony_ci    RESOLVED: This extension provides a common infrastructure for retrieving and
4545bd8deadSopenharmony_ci    loading program binaries.  A vendor extension must also be present in order
4555bd8deadSopenharmony_ci    to define one or more binary formats, thereby populating the list of
4565bd8deadSopenharmony_ci    PROGRAM_BINARY_FORMATS.  The <binaryFormat> returned by
4575bd8deadSopenharmony_ci    GetProgramBinary is always one of the binary formats in this list.  If
4585bd8deadSopenharmony_ci    ProgramBinary is called with a <binaryFormat> not in this list, the
4595bd8deadSopenharmony_ci    implementation will throw an INVALID_ENUM error.
4605bd8deadSopenharmony_ci
4615bd8deadSopenharmony_ci    The beauty of this extension, however, is that an application does not need
4625bd8deadSopenharmony_ci    to be aware of the vendor extension on any given implementation.  It only
4635bd8deadSopenharmony_ci    needs to retrieve a program binary with an anonymous <binaryFormat> and
4645bd8deadSopenharmony_ci    resupply that same <binaryFormat> when loading the program binary.
4655bd8deadSopenharmony_ci
4665bd8deadSopenharmony_ci    5. Under what conditions might a call to ProgramBinary fail?
4675bd8deadSopenharmony_ci
4685bd8deadSopenharmony_ci    RESOLVED: Even if a program binary is successfully retrieved with
4695bd8deadSopenharmony_ci    GetProgramBinary and then in a future run the program binary is
4705bd8deadSopenharmony_ci    resupplied with ProgramBinary, and all of the parameters are correct,
4715bd8deadSopenharmony_ci    the program binary load may still fail.
4725bd8deadSopenharmony_ci
4735bd8deadSopenharmony_ci    This can happen if there has been a change to the hardware or software on
4745bd8deadSopenharmony_ci    the system, such as a hardware upgrade or driver update.  In this case the
4755bd8deadSopenharmony_ci    PROGRAM_BINARY_FORMATS list may no longer contain the binary format
4765bd8deadSopenharmony_ci    associated with the cached program binary, and INVALID_ENUM will be thrown
4775bd8deadSopenharmony_ci    if the cached program binary format is passed into ProgramBinary anyway.
4785bd8deadSopenharmony_ci
4795bd8deadSopenharmony_ci    Even if the cached program binary format is still valid, ProgramBinary
4805bd8deadSopenharmony_ci    may still fail to load the cached binary.  This is the driver's way of
4815bd8deadSopenharmony_ci    signaling to the app that it needs to recompile and recache its program
4825bd8deadSopenharmony_ci    binaries because there has been some important change to the online
4835bd8deadSopenharmony_ci    compiler, such as a bug fix or a significant new optimization.
4845bd8deadSopenharmony_ci
4855bd8deadSopenharmony_ci    6. Can BindAttribLocation be called after ProgramBinary to remap an
4865bd8deadSopenharmony_ci       attribute location used by the program binary?
4875bd8deadSopenharmony_ci
4885bd8deadSopenharmony_ci    RESOLVED: No.  BindAttribLocation only affects the result of a subsequent
4895bd8deadSopenharmony_ci    call to LinkProgram.  LinkProgram operates on the attached shader objects
4905bd8deadSopenharmony_ci    and replaces any program binary loaded prior to LinkProgram.  So there is no
4915bd8deadSopenharmony_ci    mechanism to remap an attribute location after loading a program binary.
4925bd8deadSopenharmony_ci
4935bd8deadSopenharmony_ci    However, an application is free to remap an attribute location prior to
4945bd8deadSopenharmony_ci    retrieving the program binary.  By calling BindAttribLocation followed by
4955bd8deadSopenharmony_ci    LinkProgram, an application can remap the attribute location.  If this is
4965bd8deadSopenharmony_ci    followed by a call to GetProgramBinary, the retrieved program binary will
4975bd8deadSopenharmony_ci    include the desired attribute location assignment.
4985bd8deadSopenharmony_ci
4995bd8deadSopenharmony_ci    7. How does this spec differ from the OES_get_program_binary and why?
5005bd8deadSopenharmony_ci
5015bd8deadSopenharmony_ci    To better facilitate state-dependent optimizations and workarounds, a hint
5025bd8deadSopenharmony_ci    is provided to ensure that the implementation includes any state-based
5035bd8deadSopenharmony_ci    variants it might encounter. These dependencies also encourage the
5045bd8deadSopenharmony_ci    programmer to retrieve binary programs late in the execution, after
5055bd8deadSopenharmony_ci    relevant state changes have already occurred.
5065bd8deadSopenharmony_ci
5075bd8deadSopenharmony_ci    There are other areas where language was clarified, but this is meant to
5085bd8deadSopenharmony_ci    be consistent with the intent of the original specification and not to
5095bd8deadSopenharmony_ci    alter previously established behavior.
5105bd8deadSopenharmony_ci
5115bd8deadSopenharmony_ci    8. How does ProgramBinary interact with uniform values, including
5125bd8deadSopenharmony_ci       shader-specified defaults?
5135bd8deadSopenharmony_ci
5145bd8deadSopenharmony_ci    RESOLVED: All uniforms specified in the binary are reset to their shader-
5155bd8deadSopenharmony_ci    specified defaults, or to zero if they aren't specified, when the program
5165bd8deadSopenharmony_ci    binary is loaded. The spec language has been updated to specify this
5175bd8deadSopenharmony_ci    behavior.
5185bd8deadSopenharmony_ci
5195bd8deadSopenharmony_ci    9. Should ProgramBinary be expected to load a previously saved program
5205bd8deadSopenharmony_ci       binary even if non-program state has changed enough such that a
5215bd8deadSopenharmony_ci       recompile is needed by the GL implementation.
5225bd8deadSopenharmony_ci
5235bd8deadSopenharmony_ci    RESOLVED: Yes. Given the same configuration, for example hardware, driver
5245bd8deadSopenharmony_ci    version, etc., the GL implementation should save as much data as it needs
5255bd8deadSopenharmony_ci    with the program binary such that if a recompile is necessary it has all
5265bd8deadSopenharmony_ci    the data it needs to do this. Only if the configuration changes, it is
5275bd8deadSopenharmony_ci    acceptable to fail ProgramBinary.
5285bd8deadSopenharmony_ci
5295bd8deadSopenharmony_ci    The application may use the PROGRAM_BINARY_RETRIEVABLE_HINT hint to
5305bd8deadSopenharmony_ci    indicate to the GL implementation that this program will likely be saved
5315bd8deadSopenharmony_ci    with GetProgramBinary at some point. This will give the GL implementation
5325bd8deadSopenharmony_ci    the opportunity to track any state changes made to the program before
5335bd8deadSopenharmony_ci    being saved such that when it is loaded again a recompile can be avoided.
5345bd8deadSopenharmony_ci
5355bd8deadSopenharmony_ciRevision History
5365bd8deadSopenharmony_ci
5375bd8deadSopenharmony_ci    10 01/11/2019 Add an error for ProgramBinary if there are no binary
5385bd8deadSopenharmony_ci                  formats (Bug 16155).
5395bd8deadSopenharmony_ci
5405bd8deadSopenharmony_ci    09 07/05/2016 Fix missing GL_ prefix in example code.
5415bd8deadSopenharmony_ci
5425bd8deadSopenharmony_ci    08 10/08/2013 Change GLvoid -> void (Bug 10412).
5435bd8deadSopenharmony_ci
5445bd8deadSopenharmony_ci    07 06/14/2012 Clean up descriptions of "failed binary", add errors,
5455bd8deadSopenharmony_ci                  and move HINT description back to ProgramParameteri.
5465bd8deadSopenharmony_ci
5475bd8deadSopenharmony_ci    06 07/19/2010 Fixed a teenie typo with OES left on ProgramBinaryOES in
5485bd8deadSopenharmony_ci                  issue #3.
5495bd8deadSopenharmony_ci
5505bd8deadSopenharmony_ci    05 05/26/2010 Modifications based on feedback from Pat Brown and the
5515bd8deadSopenharmony_ci                  ARB f2f.
5525bd8deadSopenharmony_ci
5535bd8deadSopenharmony_ci    04 05/17/2010 Restore the old "int" type for the length parameter
5545bd8deadSopenharmony_ci                  to ProgramBinary since matching the ratified GLES is more
5555bd8deadSopenharmony_ci                  important in this case.
5565bd8deadSopenharmony_ci
5575bd8deadSopenharmony_ci    03 05/10/2010 Various minor cleanup based on feedback from Bruce.
5585bd8deadSopenharmony_ci
5595bd8deadSopenharmony_ci    02 04/09/2010 Converted to ARB version for inclusion in OpenGL 4.1.
5605bd8deadSopenharmony_ci
5615bd8deadSopenharmony_ci    01 01/11/2010 Initial EXT version.
562