Name

    KHR_robustness

Name Strings

    GL_KHR_robustness

Contributors

    Daniel Koch, NVIDIA
    Nicolas Capens, TransGaming
    Contributors to ARB_robustness

Contact

    Jon Leech (oddhack 'at' sonic.net) 
    Greg Roth, NVIDIA (groth 'at' nvidia.com)

Notice

    Copyright (c) 2012-2014 The Khronos Group Inc. Copyright terms at
        http://www.khronos.org/registry/speccopyright.html

Specification Update Policy

    Khronos-approved extension specifications are updated in response to
    issues and bugs prioritized by the Khronos OpenGL and OpenGL ES Working Groups. For
    extensions which have been promoted to a core Specification, fixes will
    first appear in the latest version of that core Specification, and will
    eventually be backported to the extension document. This policy is
    described in more detail at
        https://www.khronos.org/registry/OpenGL/docs/update_policy.php

Status

    Complete. 
    Approved by the OpenGL ES Working Group on June 25, 2014.
    Approved by the ARB on June 26, 2014.
    Ratified by the Khronos Board of Promoters on August 7, 2014.

Version

    Version 11, August 21, 2014

Number

    ARB Extension #170
    OpenGL ES Extension #190

Dependencies

    OpenGL ES 2.0 or OpenGL 3.2 are required. Some features of this
    extension are supported by OpenGL ES only if OpenGL ES 3.0 or later is
    supported.

    EGL_EXT_create_context_robustness is used to determine if a context
    implementing this extension supports robust buffer access, and if it
    supports reset notification.

    This extension is written against the OpenGL ES 3.1 Specification
    (version of June 4, 2014) and the OpenGL ES 3.10.3 Shading Language
    Specification (version of June 6, 2014).

Overview

    Several recent trends in how OpenGL ES integrates into modern computer
    systems have created new requirements for robustness and security for GL
    rendering contexts.
    
    Additionally GPU architectures now support hardware fault detection;
    for example, video memory supporting ECC (error correcting codes)
    and error detection.  GL contexts should be capable of recovering
    from hardware faults such as uncorrectable memory errors.  Along with
    recovery from such hardware faults, the recovery mechanism can
    also allow recovery from video memory access exceptions and system
    software failures.  System software failures can be due to device
    changes or driver failures.

    GL queries that return (write) some number of bytes to a
    buffer indicated by a pointer parameter introduce risk of buffer
    overflows that might be exploitable by malware. To address this,
    queries with return value sizes that are not expressed directly by
    the parameters to the query itself are given additional API
    functions with an additional parameter that specifies the number of
    bytes in the buffer and never writing bytes beyond that limit. This
    is particularly useful for multi-threaded usage of GL contexts
    in a "share group" where one context can change objects in ways that
    can cause buffer overflows for another context's GL queries.

    The original ARB_vertex_buffer_object extension includes an issue
    that explicitly states program termination is allowed when
    out-of-bounds vertex buffer object fetches occur. Modern graphics
    hardware is capable of well-defined behavior in the case of out-of-
    bounds vertex buffer object fetches. Older hardware may require
    extra checks to enforce well-defined (and termination free)
    behavior, but this expense is warranted when processing potentially
    untrusted content.

    The intent of this extension is to address some specific robustness
    goals:

    *   For all existing GL queries, provide additional "safe" APIs 
        that limit data written to user pointers to a buffer size in 
        bytes that is an explicit additional parameter of the query.

    *   Provide a mechanism for a GL application to learn about
        graphics resets that affect the context.  When a graphics reset
        occurs, the GL context becomes unusable and the application
        must create a new context to continue operation. Detecting a
        graphics reset happens through an inexpensive query.

    *   Define behavior of OpenGL calls made after a graphics reset.

    *   Provide an enable to guarantee that out-of-bounds buffer object
        accesses by the GPU will have deterministic behavior and preclude
        application instability or termination due to an incorrect buffer
        access.  Such accesses include vertex buffer fetches of
        attributes and indices, and indexed reads of uniforms or
        parameters from buffers.

New Procedures and Functions

    NOTE: when implemented in an OpenGL ES context, all entry points defined
    by this extension must have a "KHR" suffix. When implemented in an
    OpenGL context, all entry points must have NO suffix, as shown below.

    enum GetGraphicsResetStatus();

    void ReadnPixels(int x, int y, sizei width, sizei height,
                        enum format, enum type, sizei bufSize,
                        void *data);

    void GetnUniformfv(uint program, int location, sizei bufSize,
                          float *params);
    void GetnUniformiv(uint program, int location, sizei bufSize,
                          int *params);
    void GetnUniformuiv(uint program, int location, sizei bufSize,
                           uint *params);


New Tokens

    NOTE: when implemented in an OpenGL ES context, all tokens defined by
    this extension must have a "_KHR" suffix. When implemented in an OpenGL
    context, all tokens must have NO suffix, as described below.

    Returned by GetGraphicsResetStatus:

        NO_ERROR                                        0x0000
        GUILTY_CONTEXT_RESET                            0x8253
        INNOCENT_CONTEXT_RESET                          0x8254
        UNKNOWN_CONTEXT_RESET                           0x8255

    Accepted by the <value> parameter of GetBooleanv, GetIntegerv,
    and GetFloatv:

        CONTEXT_ROBUST_ACCESS                           0x90F3
        RESET_NOTIFICATION_STRATEGY                     0x8256

    Returned by GetIntegerv and related simple queries when <value> is
    RESET_NOTIFICATION_STRATEGY :

        LOSE_CONTEXT_ON_RESET                           0x8252
        NO_RESET_NOTIFICATION                           0x8261

    Returned by GetError:

        CONTEXT_LOST                                    0x0507


Additions to the OpenGL ES 3.1 Specification

    Add to section 2.3.1 "Errors" in the bullet list of implicit errors for
    GL commands on p. 14, and modify the following paragraph:

     * If the GL context has been reset as a result of a previous GL
       command, or if the context is reset as a side effect of execution of
       a command, a CONTEXT_LOST error is generated.

    The Specification attempts to explicitly describe these implicit error
    conditions (with the exception of OUT_OF_MEMORY [fn2] and CONTEXT_LOST
    [fn3]) wherever they apply. However ...

    [fn3] CONTEXT_LOST is not described because it occurs for reasons not
    directly related to the affected commands, and applies to almost all GL
    commands.


    Add to table 2.3 "Summary of GL errors" on p. 15:
    
    Error          Description               Offending command ignored?
    ------------   -----------------------   --------------------------
    CONTEXT_LOST   Context has been lost     Except as noted for
                   and reset by the driver   specific commands
    
    
    Add a new subsection 2.3.1rob after 2.3.1 "GL Errors", and renumber
    subsequent sections accordingly:

    2.3.1rob "Graphics Reset Recovery"

    Certain events can result in a reset of the GL context. After such an
    event, it is referred to as a <lost context> and is unusable for almost
    all purposes. Recovery requires creating a new context and recreating
    all relevant state from the lost context. The current status of the
    graphics reset state is returned by

        enum GetGraphicsResetStatus();

    The value returned indicates if the GL context has been in a reset state
    at any point since the last call to GetGraphicsResetStatus:

      * NO_ERROR indicates that the GL context has not been in a reset state
        since the last call.
      * GUILTY_CONTEXT_RESET indicates that a reset has been detected
        that is attributable to the current GL context.
      * INNOCENT_CONTEXT_RESET indicates a reset has been detected that
        is not attributable to the current GL context.
      * UNKNOWN_CONTEXT_RESET indicates a detected graphics reset whose
        cause is unknown.

    If a reset status other than NO_ERROR is returned and subsequent calls
    return NO_ERROR, the context reset was encountered and completed. If a
    reset status is repeatedly returned, the context may be in the process
    of resetting.

    Reset notification behavior is determined at context creation time, and
    may be queried by calling GetIntegerv with the symbolic constant
    RESET_NOTIFICATION_STRATEGY.

    If the reset notification behavior is NO_RESET_NOTIFICATION, then
    the implementation will never deliver notification of reset events, and
    GetGraphicsResetStatus will always return NO_ERROR[fn1].
       [fn1: In this case it is recommended that implementations should not
        allow loss of context state no matter what events occur. However,
        this is only a recommendation, and cannot be relied upon by
        applications.]

    If the behavior is LOSE_CONTEXT_ON_RESET, a graphics reset will
    result in a lost context and require creating a new context as described
    above. In this case GetGraphicsResetStatus will return an appropriate
    value from those described above.

    If a graphics reset notification occurs in a context, a notification
    must also occur in all other contexts which share objects with that
    context[fn2].
       [fn2: The values returned by GetGraphicsResetStatus in the
        different contexts may differ.]

    After a graphics reset has occurred on a context, subsequent GL commands
    on that context (or any context which shares with that context) will
    generate a CONTEXT_LOST error. Such commands will not have side effects
    (in particular, they will not modify memory passed by pointer for query
    results), and may not block indefinitely or cause termination of the
    application. Exceptions to this behavior include:

      * GetError and GetGraphicsResetStatus behave normally following a
        graphics reset, so that the application can determine a reset has
        occurred, and when it is safe to destroy and recreate the context.
      * Any commands which might cause a polling application to block
        indefinitely will generate a CONTEXT_LOST error, but will also
        return a value indicating completion to the application. Such
        commands include:

        + GetSynciv with <pname> SYNC_STATUS ignores the other parameters
          and returns SIGNALED in <values>.
        + GetQueryObjectuiv with <pname> QUERY_RESULT_AVAILABLE ignores the
          other parameters and returns TRUE in <params>.


    Modify section 7.12 "Shader, Program, and Program Pipeline Queries"
    on p. 125 to add the GetnUniform* commands:

    The commands

            [enumerate existing GetUniform*v commands, then add]

        void GetnUniformfv(uint program, int location, sizei bufSize,
                              float *params);
        void GetnUniformiv(uint program, int location, sizei bufSize,
                              int *params);
        void GetnUniformuiv(uint program, int location, sizei bufSize,
                               uint *params);

    return the value or values of the uniform at location <location> of the
    default uniform block for program object <program> in the array
    <params>. The type of the uniform at <location> determines the number of
    values returned. Calling GetnUniform*v ensures that no more than
    <bufSize> bytes are written into <params>.

    Add to the Errors section for Get*Uniform* on p. 126:

    An INVALID_OPERATION error is generated by GetnUniform* if the buffer
    size required to store the requested data is greater than <bufSize>


    Add subsection 10.3.1.1rob prior to section 10.3.2 "Vertex Attribute
    Divisors" on p. 241:

    10.3.1.1rob Robust Buffer Access Behavior

    Robust buffer access is enabled by creating a context with robust access
    enabled through the window system binding APIs. When enabled, indices
    within the element array that reference vertex data that lies outside
    the enabled attribute's vertex buffer object 
        [for OpenGL ES] result in undefined values
        [for OpenGL] result in reading zero
    for the corresponding attributes, but cannot result in application
    failure. 

    Robust buffer access behavior may be queried by calling
    GetIntegerv with the symbolic constant CONTEXT_ROBUST_ACCESS.


    Modify section 16.1.2 "ReadPixels" on p. 332 to add the ReadnPixels
    command:

    Pixels are read using

        void ReadPixels(int x, int y, sizei width, sizei height,
                        enum format, enum type, void *data);
        void ReadnPixels(int x, int y, sizei width, sizei height,
                            enum format, enum type, sizei bufSize,
                            void *data);

    The arguments after <x> and <y> to ReadPixels ... are summarized in
    table 16.1. ReadnPixels behaves identically to ReadPixels except that
    it does not write more than <bufSize> bytes into <data>.


    Add to the Errors section for ReadPixels and ReadnPixels:

    An INVALID_OPERATION error is generated by ReadnPixels if the buffer
    size required to store the requested data is greater than <bufSize>.


Additions to The OpenGL ES Shading Language Specification, Version 3.10

    Modify the first paragraph of section 4.1.9 "Arrays" on p. 30:

    Variables of the same type ... Undefined behavior results from indexing
    an array with a non-constant expression that is greater than or equal to
    the array size or less than 0. If robust buffer access is enabled (see
    section 10.3.1.1rob of the OpenGL ES 3.1 API Specification), such
    indexing must not result in abnormal program termination. The results
    are still undefined, but implementations are encouraged to produce zero
    values for such accesses. Arrays only have a single dimension ...

Dependencies on OpenGL ES

    For implementations against OpenGL ES, if OpenGL ES 3.0 or a later
    version is not supported, remove all references to GetnUniformuiv and
    remove the exceptional behavior of GetSynciv and GetQueryObjectuiv for
    lost contexts.

Interactions with EGL_EXT_create_context_robustness

    If the EGL window-system binding API is used to create a context, the
    EGL_EXT_create_context_robustness extension is supported, and the
    attribute EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT is set to EGL_TRUE when
    eglCreateContext is called, the resulting context will perform robust
    buffer access as described above in section 10.3.1.1rob, and the
    CONTEXT_ROBUST_ACCESS query will return GL_TRUE.

    If the EGL window-system binding API is used to create a context and the
    EGL_EXT_create_context_robustness extension is supported, then the value
    of attribute EGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_EXT determines the
    reset notification behavior and the value of
    RESET_NOTIFICATION_STRATEGY, as described in section 2.3.1rob.

New Implementation Dependent State

    Get Value                   Type  Get Command Minimum Value     Description                 Sec.        Attribute
    --------------------------- ----  ----------- ----------------- --------------------------- ----------- ---------
    CONTEXT_ROBUST_ACCESS       B     GetIntegerv -                 Robust access enabled       10.3.1.1rob -
    RESET_NOTIFICATION_STRATEGY Z_2   GetIntegerv See sec. 2.3.1rob Reset notification behavior 2.3.1rob    -

Issues

    (Issues 2-8 are identical to those in the base EXT_robustness
    extension).

    1. What should this extension be called?

       RESOLVED: KHR_robustness

       This is just the OpenGL ES EXT_robustness extension (itself based on
       ARB_robustness) promoted to KHR status, with consistency with OpenGL
       4.5 behavior and phrasing included.

    2. How does this extension differ from Desktop GL's ARB_robustness?

       RESOLVED: Because EGL_EXT_create_context_robustness uses a separate
       attribute to enable robust buffer access, a corresponding query is
       added here.

       Also see issue 12.

    3. Should we provide a context creation mechanism to enable this
       extension?

       RESOLVED. Yes.

       Currently, EGL_EXT_create_context_robustness provides this mechanism
       via two unique attributes. These attributes differ from those
       specified by KHR_create_context to allow for differences in what
       functionality those attributes define.
        
    4. What can cause a graphics reset?

       Either user or implementor errors may result in a graphics reset. If
       the application attempts to perform a rendering that takes too long
       whether due to an infinite loop in a shader or even just a rendering
       operation that takes too long on the given hardware. Implementation
       errors may produce badly formed hardware commands. Memory access
       errors may result from user or implementor mistakes. On some systems,
       power management events such as system sleep, screen saver
       activation, or pre-emption may also context resets to occur. Any of
       these events may result in a graphics reset event that will be
       detectable by the mechanism described in this extension.

    5. How should the application react to a reset context event?

       RESOLVED: For this extension, the application is expected to query
       the reset status until NO_ERROR is returned. If a reset is
       encountered, at least one *RESET* status will be returned. Once
       NO_ERROR is again encountered, the application can safely destroy the
       old context and create a new one.

       After a reset event, apps should not use a context for any purpose
       other than determining its reset status (using either GetError to
       identify a CONTEXT_LOST error, or GetGraphicsResetStatus()), and
       then destroying it. If a context receives a reset event, all other
       contexts in its share group will also receive reset events, and
       should be destroyed and recreated.

       Apps should be cautious in interpreting the GUILTY and INNOCENT reset
       statuses. These are guidelines to the immediate cause of a reset, but
       not guarantees of the ultimate cause.

    6. If a graphics reset occurs in a shared context, what happens in
       shared contexts?

       RESOLVED: A reset in one context will result in a reset in all other
       contexts in its share group.

    7. How can an application query for robust buffer access support, since
       this is now determined at context creation time?

       RESOLVED. The application can query the value of
       CONTEXT_ROBUST_ACCESS using GetIntegerv. If true, this
       functionality is enabled.

    8. How is the reset notification behavior controlled?

       RESOLVED: Reset notification behavior is determined at context
       creation time using EGL/GLX/WGL/etc. mechanisms. In order that shared
       objects be handled predictably, a context cannot share with another
       context unless both have the same reset notification behavior.

    9. How does this extension differ from EXT_robustness?

       RESOLVED: By adding the new CONTEXT_LOST error, removing support for
       ES 1.1 (for logistical reasons), and changing suffixes from EXT to
       KHR (for ES) or no suffix (for GL).

   10. How should this extension be enabled via EGL?

       PROPOSED: Either by using EGL 1.5 context creation APIs (see section
       3.7.1.5 of the EGL 1.5 spec), or EGL_EXT_create_context_robustness.
       This interaction will be noted in both the EGL 1.5 spec and the
       extension spec by allowing at least one, and possibly both of
       GL_EXT_robustness and GL_KHR_robustness to be supported by contexts
       created via these mechanisms. If a context supporting
       GL_KHR_robustness is created, it will optionally support
       GL_KHR_robust_buffer_access_behavior as well (see issue 5 of that
       extension).

   11. What should the behavior of GL calls made after a context is lost be?
       This can be expected to occur when the context has been lost, but the
       app hasn't polled the reset status yet.

       RESOLVED: Set a new CONTEXT_LOST error on all GL calls (except
       GetError and GetGraphicsReset).

       DISCUSSION: GetError and GetGraphicsResetStatus must continue to
       work at least to the extent of their interactions with robustness
       features, so that apps can determine a context was lost and see the
       effect on other commands. Commands which might block indefinitely or
       cause the app to block indefinitely while polling are defined to
       return immediately, with values which should end a polling loop. Such
       commands include sync and query object queries for completion.

       Special handling of these commands is defined to return values which
       should not cause blocking, but also to generate the CONTEXT_LOST
       error. This is intended to deal well both with apps that are polling
       on a query value, and apps that may test for the error immediately
       after each command (such as debuggers). There has been no pushback
       against

       We believe there are no other commands requiring this special
       handling in the core API. ClientWaitSync and WaitSync were also
       proposed, but with the current language (which specifies that
       commands on a lost context may not block) should not need exceptional
       handling.

       REJECTED OPTIONS:

       A) GL will try to handle the call as best as possible. Depending on
       the call this may use GPU resources which may now have undefined
       contents.

       B) GL calls become no-ops. This would be like having a null-dispatch
       table installed when you don't have a current context. The problem
       with this approach is that any call that has return parameters won't
       fill them in and the application won't be able to detect that a value
       was not returned.

       REJECTED SUB-FEATURES:

       We discussed using OUT_OF_MEMORY or INVALID_OPERATION. Both are
       misleading and don't uniquely identify the problem as a runtime error
       out of scope of anything the app did.

       We discussed allowing all commands to have side effects in addition
       to generating CONTEXT_LOST, such as putting a "safe" value into
       return parameters. Without compelling reason to allow this behavior,
       it is cleaner to define the spec to leave results unchanged aside
       from the exceptional cases intended to prevent hanging on polling
       loops.

   12. What changed in promoting OES_robustness to KHR_robustness? What
       remains to be done for consistency between GL and ES?

       DISCUSSION: The ARB agreed to support robustness and
       robust_buffer_access_behavior as a KHR extension, with the following
       chnages and issues to be resolved during the ratification period
       (none are IP-related):

       a) As was done for KHR_debug, the extension is defined to have KHR
          suffixes only in ES implementations. GL implementations do not
          have suffixes. This is so KHR_robustness can be used as a
          backwards-compatibility extension for OpenGL 4.5.

       b) Minor spec language tweaks were done for consistency with OpenGL
          4.5, to eliminate redundancy. None are functional with the
          exception of a change in section 10.3.1.1rob, which imposes
          stronger requirements on out-of-bounds indexed attribute access
          for GL (returns zero) relative to ES (undefined return values).

       c) The ARB wants to add these commands to the extension, as defined
          in OpenGL 4.5. They would be only be supported in GL contexts:

            GetnUniformdv
            GetnTexImage
            GetnCompressedTexImage

          We do not think we need to add the compatibility-mode Getn*
          queries defined by ARB_robustness.

       d) OpenGL 4.5 exposes support for robustness by setting
          CONTEXT_FLAG_ROBUST_ACCESS_BIT in the CONTEXT_FLAGS query. ES (and
          this extension) expose it with the CONTEXT_ROBUST_ACCESS query.
          Jon proposes we resolve this by only defining the CONTEXT_FLAGS
          query for GL, but defining the CONTEXT_ROBUST_ACCESS query for
          both GL and ES, and aliasing the flag bit with the access boolean.
          This will result in minor changes to both GL 4.5 and this
          extension.

       e) This extension modifies the Shading Language specification in
          section 4.1.9 to restrict behavior of out of bounds array
          accesses. GLSL 4.50 has a considerably broader section 5.11
          "Out-of-Bounds Accesses" which restricts behavior of arrays,
          vectors, structs, etc. We will want to include that language in
          KHR_robustness at least as GLSL-specific language; if ES wants to
          adopt the broader language for GLSL-ES that might still be doable.

Revision History

    Rev.    Date       Author     Changes
    ----  ------------ ---------  ------------------------------------------
     11   2014/08/21   Jon Leech  Fix typo.
     10   2014/06/26   Jon Leech  Change from OES to KHR. Update issues 1
                                  and 9; add issue 12 on ES / GL
                                  differences.
      9   2014/06/26   Jon Leech  Minor phrasing fixes to be more consistent
                                  with equivalent GL functionality.
      8   2014/06/24   Jon Leech  Fix typos & mention GetError in issue 5.
                                  Reorder API spec edits in section order.
                                  Resolve issues 9-11 (Bug 12104 comments
                                  #42-45). Assign CONTEXT_LOST enum.
      7   2014/06/02   Jon Leech  Remove "safe" return value behavior for
                                  queries when contexts are lost (Bug 12104
                                  comment #27).
      6   2014/06/02   Jon Leech  Rebase extension on OpenGL ES 3.1 specs
                                  and reflow paragraphs (no functionality
                                  changes are made in this version).
      5   2014/05/16   Jon Leech  Add CONTEXT_LOST error and exceptional
                                  behavior for potentially-blocking
                                  commands (Bug 8411).
      4   2014/05/14   Jon Leech  Add issue 11 on behavior of GL calls made
                                  after a context is lost.
      3   2014/05/07   Jon Leech  Add GetnUniformuivOES for ES 3.0.
      2   2014/04/26   Jon Leech  Updates based on Ken's comments in bug
                                  12104 and to reference EGL 1.5.
      1   2014/04/23   Jon Leech  Branch from EXT_robustness version 3 and
                                  promote to OES suffixes. Add issues 9-10.
