Name

    ANGLE_multiview

Name Strings

    GL_ANGLE_multiview

Contributors

    Martin Radev, NVIDIA Corporation
    Olli Etuaho, NVIDIA Corporation
    Corentin Wallez, Google
    Geoff Lang, Google
    Jamie Madill, Google

Contact

    Olli Etuaho (oetuaho 'at' nvidia.com)

Status

    Incomplete

Version

    Last Modified Date: December 8, 2018
    Author Revision: 1

Number

    OpenGL ES Extension XX

Dependencies

    OpenGL ES 3.0 is required.

Overview

    Multi-view rendering, achieved through the functionality exposed by
    ANGLE, expects the user to issue for each view almost the same
    drawing commands and state changes sequentially. This rendering
    method scales with the number of views and can be detrimental for
    performance in scenes with many draw calls.

    This extension addresses the issue by adding means for multi-view
    side-by-side rendering onto a single 2D texture and layered
    rendering onto the many layers of a 2D texture array. The new vertex
    and fragment shader built-in - ViewID_OVR - is added which signifies
    the view for which the current vertex or fragment is being
    processed, so that per-view transformations can be applied.

IP Status

    No known IP claims.

New Tokens

    Accepted by the <pname> parameter of GetFramebufferAttachmentParameteriv:

        FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_ANGLE             0x9630
        FRAMEBUFFER_ATTACHMENT_TEXTURE_VIEWPORT_OFFSETS_ANGLE      0x969B
        FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_ANGLE       0x9632
        FRAMEBUFFER_ATTACHMENT_TEXTURE_MULTIVIEW_LAYOUT_ANGLE      0x969C

    Returned in <params> by GetFramebufferAttachmentParameteriv:

        FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE                   0x969D
        FRAMEBUFFER_MULTIVIEW_LAYERED_ANGLE                        0x969E

    Accepted by the <pname> parameter of GetIntegerv:

        MAX_VIEWS_ANGLE                                            0x9631

    Returned by CheckFramebufferStatus:

        FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_ANGLE                  0x9633

New Procedures and Functions

    void FramebufferTextureMultiviewLayeredANGLE(enum target,
                                                 enum attachment,
                                                 uint texture,
                                                 int level,
                                                 int baseViewIndex,
                                                 sizei numViews);
    void FramebufferTextureMultiviewSideBySideANGLE(enum target,
                                                    enum attachment,
                                                    uint texture,
                                                    int level,
                                                    sizei numViews,
                                                    const int *viewportOffsets);

Additions to Chapter 2 of the OpenGL ES 3.0 Specification (OpenGL ES Operation)

    Modify section 2.9.3 Drawing commands, p. 28

    Append to the end of the section:

    "
    If any drawing command is called the number of views specified in the
    program must match the number of views in the draw framebuffer. If
    there is a mismatch, an INVALID_OPERATION error is generated.

    If the active draw framebuffer has a side-by-side multi-view layout
    and the scissor test is not enabled, the result of any draw command
    is undefined, but is not followed by program termination.
    "

    Modify section 2.15.2 Transform Feedback Primitive Capture, p. 91

    In the list just after "The error INVALID_OPERATION is generated:"
    do the following:

    - Add another bullet point:
    "
        * by any Draw* command if the number of views in the draw
          framebuffer is greater than 1 and there is an active and not
          paused transform feedback object.
    "

Additions to Chapter 3 of the OpenGL ES 3.0 Specification (Rasterization)

    Modify section 3.8.5 (Alternate Texture Image Specification Commands),
    p. 145

    Add at the end of the section:

    "Calling CopyTexSubImage3D, CopyTexImage2D, or CopyTexSubImage2D will
    result in an INVALID_FRAMEBUFFER_OPERATION error if the multi-view
    layout of the current read framebuffer is
    FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE or the number of views in the
    current read framebuffer is more than one."

Additions to Chapter 4 of the OpenGL ES 3.0 Specification
(Per-Fragment Operations and the Framebuffer)

    Modify section 4.1.6 (Occlusion queries), p. 177

    Replace the first sentence with:

    "Occlusion queries use query objects to track whether any fragments
    or samples pass the depth test for any of the views."

    Append to the sentence

    "While that occlusion query is active, the samples-boolean state is
    set to TRUE if any fragment or sample passes the depth test"

    the text

    " for any of the views."

    Modify section 4.2.3 (Clearing the Buffers), p. 190

    Add a new subsection at the end:

    "4.2.3.2 Clearing Multi-view Buffers

    Clearing commands are applied to each view in the current multi-view
    framebuffer object and have the same constraints as described
    in section 4.2.3 Clearing the Buffers.

    If the active draw framebuffer has a side-by-side multi-view layout
    and the scissor test is not enabled, the clearing command clears
    the whole content of the specified buffers.
    "

    Modify section 4.3.2 (Reading pixels), p. 193

    Add to the end of the section:

    "   ReadPixels generates an INVALID_FRAMEBUFFER_OPERATION error if
    the multi-view layout of the current read framebuffer is
    FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE or the number of views in the
    current read framebuffer is more than one."

    Modify section 4.3.3 (Copying pixels), p. 198

    After the paragraph

    "Calling BlitFramebuffer will result in an INVALID_OPERATION error
    if filter is LINEAR and read buffer contains integer data."

    add a new paragraph:

    "Calling BlitFramebuffer will result in an INVALID_FRAMEBUFFER_OPERATION
    error if the multi-view layout of the current draw framebuffer is not NONE,
    or the multi-view layout of the current read framebuffer is
    FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE, or the number of views in the
    current read framebuffer is more than one."


    Modify section 4.4.2 (Attaching Images to Framebuffer Objects), p. 202

    Add the following bullet point:

    "* Layers of a two-dimensional array texture which can be used for
       multi-view rendering."

    Modify section 4.4.2.4 (Attaching Texture Images to a Framebuffer), p. 207

    Add just before the sentence "Effects of Attaching a Texture Image":

    "
    The command

        SelectView( id );

    does not exist in the GL, but it is used to describe the multi-view
    functionality in the rest of this section. The effect of this function
    is to select the view specified by <id> and set the value to the vertex
    and fragment shader built-in gl_ViewID_OVR.

    The command

        void FramebufferTextureMultiviewLayeredANGLE(enum target,
                                                     enum attachment,
                                                     uint texture,
                                                     int level,
                                                     int baseViewIndex,
                                                     sizei numViews);

    can be used to attach a 2D texture array object as one of the logical
    buffers of a framebuffer object which is to be used for layered
    multi-view rendering.

    basicViewIndex specifies the View-id offset.
    numViews specifies the number of views associated with the attachment.

    Any <Draw> command, while a layered multi-view framebuffer is bound,
    has the same effect as:

    for( int id = 0; i < numViews; id++ ) {
        for ( framebufferAttachment : framebuffer.getAllAttachments() )
        {
            attachment = framebufferAttachment.attachment
            texture = framebufferAttachment.texture
            level = framebufferAttachment.level
            baseViewIndex = framebufferAttachment.baseViewIndex
            FramebufferTextureLayer( target, attachment, texture, level,
                                     baseViewIndex + id );
        }
        SelectView( id );
        <Draw>
    }

    Errors:
        An INVALID_ENUM error is generated if target is not DRAW_FRAMEBUFFER,
        READ_FRAMEBUFFER, or FRAMEBUFFER.
        An INVALID_OPERATION error is generated if attachment is
        COLOR_ATTACHMENTm where m is greater than or equal to the value
        of MAX_COLOR_ATTACHMENTS.
        An INVALID_ENUM error is generated if attachment is not one of
        the attachments in table 4.6, and attachment is not
        COLOR_ATTACHMENTm where m is greater than or equal to the value
        of MAX_COLOR_ATTACHMENTS.
        An INVALID_OPERATION error is generated if zero is bound to target.
        An INVALID_VALUE error is generated if texture is not zero, and
        level is less than zero or greater than log2 of the value of
        MAX_TEXTURE_SIZE.
        An INVALID_OPERATION error is generated if texture is not zero,
        and does not name an existing texture object of type TEXTURE_2D_ARRAY.
        An INVALID_OPERATION error is generated if texture is not zero,
        and names a texture with a compressed texture format.
        An INVALID_VALUE error is generated if texture is not zero, and
        baseViewIndex+numViews is greater than GL_MAX_ARRAY_TEXTURE_LAYERS.
        An INVALID_VALUE error is generated if texture is not zero, and
        numViews is less than 1 or greater than MAX_VIEWS_ANGLE.
        An INVALID_VALUE error is generated if texture is not zero, and
        baseViewIndex is less than 0.

    The command

        void FramebufferTextureMultiviewSideBySideANGLE(enum target,
                                                        enum attachment,
                                                        uint texture,
                                                        int level,
                                                        sizei numViews,
                                                        const int *viewportOffsets);

    can be used to attach a 2D texture object as one of the logical buffers
    of a framebuffer object which is to be used for side-by-side multi-view
    rendering.

    numViews specifies the number of views associated with the attachment.
    viewportOffsets specifies the address of an array of integers containing
    the x and y viewport offset of each view.

    Any <Draw> command, while a side-by-side multi-view framebuffer is bound,
    has the same effect as:

    // Retrieve viewport and scissor state.
    Rectangle viewport
    GetIntegerv(VIEWPORT, viewport)
    Rectangle scissor
    GetIntegerv(SCISSOR_BOX, scissor)
    for ( int id = 0; id < numViews; id++ )
    {
        // Setup view state.
        for ( framebufferAttachment : framebuffer.getAllAttachments() )
        {
            attachment = framebufferAttachment.attachment
            texture = framebufferAttachment.texture
            level = framebufferAttachment.level
            FramebufferTexture2D( target, attachment, TEXTURE_2D, texture,
                                  level )
        }
        Viewport(viewport.x + viewportOffsets[id].x,
                 viewport.y + viewportOffsets[id].y,
                 viewport.width, viewport.height)
        Scissor(scissor.x + viewportOffsets[id].x,
                scissor.y + viewportOffsets[id].y,
                scissor.width, scissor.height)
        SelectView(id)
        // Draw.
        <Draw>
    }
    // Restore viewport and scissor state.
    Viewport(viewport.x, viewport.y, viewport.width, viewport.height)
    Scissor(scissor.x, scissor.y, scissor.width, scissor.height)

    Errors:
        An INVALID_ENUM error is generated if target is not DRAW_FRAMEBUFFER,
        READ_FRAMEBUFFER, or FRAMEBUFFER.
        An INVALID_OPERATION error is generated if attachment is
        COLOR_ATTACHMENTm where m is greater than or equal to the value
        of MAX_COLOR_ATTACHMENTS.
        An INVALID_ENUM error is generated if attachment is not one of
        the attachments in table 4.6, and attachment is not
        COLOR_ATTACHMENTm where m is greater than or equal to the value
        of MAX_COLOR_ATTACHMENTS.
        An INVALID_OPERATION error is generated if zero is bound to target.
        An INVALID_VALUE error is generated if texture is not zero and
        level is less than zero or greater than log2 of the value of
        MAX_TEXTURE_SIZE.
        An INVALID_OPERATION error is generated if texture is not zero,
        and does not name an existing texture object of type TEXTURE_2D.
        An INVALID_OPERATION error is generated if texture is not zero,
        and names a texture with a compressed texture format.
        An INVALID_VALUE error is generated if texture is not zero, and
        numViews is less than 1 or greater than MAX_VIEWS_ANGLE.
        An INVALID_VALUE error is generated if texture is not zero, and
        any of the first numViews * 2 values in viewportOffsets is negative.

    Having overlapping scissor rectangles after viewport offsets are
    applied causes undefined behavior.
    "

    Add the following bullet points in the list after
    "Effects of Attaching a Texture Image":

    "   * The value of FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_ANGLE is
          set to <numViews>.
        * The value of FRAMEBUFFER_ATTACHMENT_TEXTURE_MULTIVIEW_LAYOUT_ANGLE
          is set to:
            ** FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE if the texture
               is attached via a call to
               FramebufferTextureMultiviewSideBySideANGLE.
            ** FRAMEBUFFER_MULTIVIEW_LAYERED_ANGLE if the texture is
               attached via a call to FramebufferTextureMultiviewLayeredANGLE.
            ** NONE otherwise.
        * The value of FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_ANGLE
            is set to <baseViewIndex> if FramebufferTextureMultiviewLayeredANGLE
            is called. Otherwise, the default value remains.
        * The value of FRAMEBUFFER_ATTACHMENT_TEXTURE_VIEWPORT_OFFSETS_ANGLE
          is set to <viewportOffsets>.
    "

    Modify section 4.4.4.1 (Framebuffer Attachment Completeness), p. 213

    Add a bullet point to the end of the list:

    "If the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE is TEXTURE and
    the value of FRAMEBUFFER_ATTACHMENT_OBJECT_NAME names a two-dimensional
    array texture, then the sum of FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_ANGLE
    and FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_ANGLE must be less
    than the number of layers in the texture."

    Modify section 4.4.4.2 (Whole Framebuffer Completeness), p. 214

    Add a bullet point after "{ FRAMEBUFFER_INCOMPLETE_MULTISAMPLE }":

    "
    * All populated framebuffer attachments have the same number of views,
      same multi-view layout and same viewport offsets.
      { FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_ANGLE }
    "

Additions to Chapter 5 of the OpenGL ES 3.0 Specification (Special Functions)

    None

Additions to Chapter 6 of the OpenGL ES 3.0 Specification
(State and State Requests)

    Modify section 6.1.13 (Framebuffer Object Queries), p. 242

    Add a bullet point to the first list:

    " * If <pname> is FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_ANGLE,
        then <params> will contain the number of views for the specified
        attachment.
      * If <pname> is FRAMEBUFFER_ATTACHMENT_TEXTURE_VIEWPORT_OFFSETS_ANGLE,
        then <params> will contain the viewport offsets for the specified
        attachment. It is undefined behavior to provide an array with size
        less than 2 x <num views>.
      * If <pname> is FRAMEBUFFER_ATTACHMENT_TEXTURE_MULTIVIEW_LAYOUT_ANGLE,
        then <params> will contain FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE,
        FRAMEBUFFER_MULTIVIEW_LAYERED_ANGLE or NONE.
      * If <pname> is FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_ANGLE,
        then <params> will contain the base view index offset for the
        specified attachment."

    Changes to table 6.14, p. 259 (Framebuffer (state per attachment point))

    Get Value                                               Type        Get Command       Value     Description         Sec.
    ---------                                               -----       -----------       -------   -----------         ----
    FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_ANGLE          Z+          GetFramebuffer-
                                                                        Attachment-       1         Number of views     4.4.2.4
                                                                        Parameteriv

    FRAMEBUFFER_ATTACHMENT_TEXTURE_VIEWPORT_OFFSETS_ANGLE   n x Z^{2}   GetFramebuffer-   0,0       Viewport offset     4.4.2.4
                                                                        Attachment-                 of each view
                                                                        Parameteriv

    FRAMEBUFFER_ATTACHMENT_TEXTURE_MULTIVIEW_LAYOUT_ANGLE   Z+          GetFramebuffer-   NONE      Layout type -       4.4.2.4
                                                                        Attachment-                 non-multiview,
                                                                        Parameteriv                 layered or
                                                                                                    side-by-side

    FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_ANGLE    Z           GetFramebuffer-   0         Base view offset    4.4.2.4
                                                                        Attachment-
                                                                        Parameteriv

    Changes to table 6.28, p. 273 (Implementation Dependent Values):

    Add the following entry after MAX_VIEWPORT_DIMS:

    Get Value            Type   Get Command      Value        Description              Sec.
    ---------            -----  -----------      -------      -----------              ----
    MAX_VIEWS_ANGLE      Z+     GetIntegerv      4            Maximum number of        4.4
                                                              views

Additions to the OpenGL ES 3.0 Shading Language Specification

    Including the following line in a shader can be used to control the
    language features described in this extension:

      #extension GL_OVR_multiview : <behavior>

    where <behavior> is as specified in section 3.5.

    New preprocessor #defines are added to the OpenGL Shading Language:

      #define GL_OVR_multiview 1

    Modify section 4.3.8.1 (Input Layout Qualifiers)

    Replace the first sentence by:

    "Input variable declarations in the vertex shader can have input
    layout qualifiers."

    Add the following text just before the sentence "Fragment shaders
    cannot ...":

    "The number of views to which to the program must render to is
    specified through the num_views layout qualifier:

        layout-qualifier-id
            num_views = integer-constant

    For example, the following declaration in a vertex shader

        layout (num_views=4) in;

    is used to specify that the program renders to 4 views.

    If num_views is less than 1 or greater than the maximum number of
    supported views, a compile-time error is generated.
    If the layout qualifier is declared multiple times and not all
    declarations specify the same number of views, a compile-time error
    is generated."

    Modify section 7.1 (Vertex Shader Special Variables)

    Add to the list of built-ins just after the entry for gl_InstanceID:

    "   in highp uint gl_ViewID_OVR;"

    Add a description for gl_ViewID_OVR just after the paragraph for
    gl_InstanceID:

    "The variable gl_ViewID_OVR is a vertex shader input variable that
    holds the view id which designates the view which the current
    vertex is being processed for."

    Modify section 7.2 (Fragment Shader Special Variables)

    Add to the list of built-ins just after the entry for gl_InstanceID:

    "   in highp uint gl_ViewID_OVR;"

    Add a description for gl_ViewID_OVR just after the paragraph for
    gl_PointCoord:

    "The variable gl_ViewID_OVR is a fragment shader input variable that
    holds the view id which designates the view which the current
    fragment is being processed for."

Additions to Chapter 10 of the OpenGL ES 3.1 Specification
(Vertex Specification and Drawing Commands)

    Modify section 10.5 (Drawing Commands Using Vertex Arrays), p. 254

    Append to the list of errors for the command DrawArraysIndirect:

    "* An INVALID_OPERATION if the number of views in the draw framebuffer
       is greater than 1."

    Append to the list of errors for the command DrawElementsIndirect:

    "* An INVALID_OPERATION if the number of views in the draw framebuffer
       is greater than 1."

Additions to the AGL/EGL/GLX/WGL Specifications

    None

Interactions with EXT_disjoint_timer_query

    An INVALID_OPERATION error is generated by any Draw* command and the Clear
    command if there is an active query object for target TIME_ELAPSED_EXT and
    the number of views in the draw framebuffer is greater than 1.

Errors

    None

Issues