Name

    ANGLE_multiple_render_targets

Name Strings

    GL_ANGLE_multiple_render_targets

Contributors

    Contributors to GL_NV_draw_buffers
    Contributors to GL_NV_fbo_color_attachments
    Contributors to the OpenGL ES 2.0 specification
    Contributors to the OpenGLSL ES 1.0.17 specification
    Contributors to the OpenGL ES 3.0 specification
    Nicolas Capens, TransGaming Inc.
    Daniel Koch, TransGaming Inc.
    Alastair Patrick, Google Inc.
    Members of the WebGL working group

Contact

    TBD

Status

    Incomplete -- do not implement!

Version

    TBD

Number

    TBD

Dependencies

    OpenGL ES 2.0 is required.

    The extension is written against the OpenGL ES 2.0 specification.

    ANGLE_framebuffer_blit affects the definition of this extension.

Overview

    This extension increases the number of available framebuffer object
    color attachment points, extends OpenGL ES 2.0 to allow multiple output
    colors, and provides a mechanism for directing those outputs to
    multiple color buffers.

    This extension is similar to the combination of the GL_NV_draw_buffers
    and GL_NV_fbo_color_attachments extensions, but imposes certain
    restrictions informed by the OpenGL ES 3.0 API.

New Procedures and Functions

      void DrawBuffersANGLE(sizei n, const enum *bufs);

New Tokens

    Accepted by the <pname> parameter of GetIntegerv:

        MAX_COLOR_ATTACHMENTS_ANGLE                  0x8CDF

    Accepted by the <pname> parameters of GetIntegerv and GetFloatv:

        MAX_DRAW_BUFFERS_ANGLE                  0x8824
        DRAW_BUFFER0_ANGLE                      0x8825
        DRAW_BUFFER1_ANGLE                      0x8826
        DRAW_BUFFER2_ANGLE                      0x8827
        DRAW_BUFFER3_ANGLE                      0x8828
        DRAW_BUFFER4_ANGLE                      0x8829
        DRAW_BUFFER5_ANGLE                      0x882A
        DRAW_BUFFER6_ANGLE                      0x882B
        DRAW_BUFFER7_ANGLE                      0x882C
        DRAW_BUFFER8_ANGLE                      0x882D
        DRAW_BUFFER9_ANGLE                      0x882E
        DRAW_BUFFER10_ANGLE                     0x882F
        DRAW_BUFFER11_ANGLE                     0x8830
        DRAW_BUFFER12_ANGLE                     0x8831
        DRAW_BUFFER13_ANGLE                     0x8832
        DRAW_BUFFER14_ANGLE                     0x8833
        DRAW_BUFFER15_ANGLE                     0x8834

    Accepted by the <attachment> parameter of FramebufferRenderbuffer,
    FramebufferTexture2D and GetFramebufferAttachmentParameteriv, and by
    the <bufs> parameter of DrawBuffersANGLE:

        COLOR_ATTACHMENT0_ANGLE                      0x8CE0
        COLOR_ATTACHMENT1_ANGLE                      0x8CE1
        COLOR_ATTACHMENT2_ANGLE                      0x8CE2
        COLOR_ATTACHMENT3_ANGLE                      0x8CE3
        COLOR_ATTACHMENT4_ANGLE                      0x8CE4
        COLOR_ATTACHMENT5_ANGLE                      0x8CE5
        COLOR_ATTACHMENT6_ANGLE                      0x8CE6
        COLOR_ATTACHMENT7_ANGLE                      0x8CE7
        COLOR_ATTACHMENT8_ANGLE                      0x8CE8
        COLOR_ATTACHMENT9_ANGLE                      0x8CE9
        COLOR_ATTACHMENT10_ANGLE                     0x8CEA
        COLOR_ATTACHMENT11_ANGLE                     0x8CEB
        COLOR_ATTACHMENT12_ANGLE                     0x8CEC
        COLOR_ATTACHMENT13_ANGLE                     0x8CED
        COLOR_ATTACHMENT14_ANGLE                     0x8CEE
        COLOR_ATTACHMENT15_ANGLE                     0x8CEF

    The COLOR_ATTACHMENT0_ANGLE constant is equal to the
    COLOR_ATTACHMENT0 constant.

    Each COLOR_ATTACHMENT<i>_ANGLE adheres to COLOR_ATTACHMENT<i>_ANGLE
    = COLOR_ATTACHMENT0_ANGLE + <i>.

Changes to Chapter 3 of the OpenGL ES 2.0 Specification (Rasterization)

    Section 3.2, (Multisampling). Replace the second paragraph:

    An additional buffer, called the multisample buffer, is added to the
    window system-provided framebuffer. Pixel sample values, including
    color, depth, and stencil values, are stored in this buffer. Samples
    contain separate color values for each fragment color. When the
    window system-provided framebuffer includes a multisample buffer, it
    does not include depth or stencil buffers, even if the multi-sample
    buffer does not store depth or stencil values. Color buffers do
    coexist with the multisample buffer, however.

    Section 3.8.2, (Shader Execution) Replace subsection "Shader
    Outputs":

    The OpenGL ES Shading Language specification describes the values
    that may be output by a fragment shader. These are gl_FragColor and
    gl_FragData[n].  The final fragment color values or the final
    fragment data values written by a fragment shader are clamped to the
    range [0, 1] and then converted to fixed-point as described in
    section 2.1.2 for framebuffer color components.

    Writing to gl_FragColor specifies the fragment color (color number
    zero) that will be used by subsequent stages of the pipeline.
    Writing to gl_FragData[n] specifies the value of fragment color
    number n. Any colors, or color components, associated with a
    fragment that are not written by the fragment shader are undefined.
    A fragment shader may not statically assign values to both
    gl_FragColor and gl_FragData. In this case, a compile or link error
    will result. A shader statically assigns a value to a variable if,
    after preprocessing, it contains a statement that would write to the
    variable, whether or not run-time flow of control will cause that
    statement to be executed.

Changes to Chapter 4 of the OpenGL ES 2.0 Specification (Per-Fragment
Operations and the Frame Buffer)

    Insert Table 4.3 (and renumber subsequent tables): Arguments to
    DrawBuffersANGLE when the context is bound to a framebuffer
    object, and the buffers they indicate. <i> in
    COLOR_ATTACHMENT<i>_ANGLE may range from zero to the value of
    MAX_COLOR_ATTACHMENTS_ANGLE minus one.

    Symbolic Constant                         Meaning
    -----------------                         ---------------------
    NONE                                      No buffer

    COLOR_ATTACHMENT<i>_ANGLE (see caption)   Output fragment color to image 
                                              attached at color attachment
                                              point i


    Replace Section 4.2.1, "Selecting a Buffer for Writing"

    By default, color values are written into the front buffer for
    single buffered surfaces or into the back buffer for back buffered
    surfaces as determined when making the context current. To control
    the color buffer into which each of the fragment color values is
    written, DrawBuffersANGLE is used.

    The command

      void DrawBuffersANGLE(sizei n, const enum *bufs);

    defines the draw buffers to which all fragment colors are written.
    <n> specifies the number of buffers in <bufs>. <bufs> is a pointer
    to an array of symbolic constants specifying the buffer to which
    each fragment color is written.

#if defined(GL_ANGLE_framebuffer_blit)
    Each buffer listed in <bufs> must be BACK, NONE, or one of the
    values from table 4.3. Further, acceptable values for the constants
    in <bufs> depend on whether the GL is using the default framebuffer
    (i.e., DRAW_FRAMEBUFFER_BINDING is zero), or a framebuffer object
    (i.e., DRAW_FRAMEBUFFER_BINDING is non-zero). For more information
    about framebuffer objects, see section 4.4.
#else
    Each buffer listed in <bufs> must be BACK, NONE, or one of the
    values from table 4.3. Further, acceptable values for the constants
    in <bufs> depend on whether the GL is using the default framebuffer
    (i.e., FRAMEBUFFER_BINDING is zero), or a framebuffer object (i.e.,
    FRAMEBUFFER_BINDING is non-zero). For more information about
    framebuffer objects, see section 4.4.
#endif

    If the GL is bound to the default framebuffer, then <n> must be 1
    and the constant must be BACK or NONE. When draw buffer zero is
    BACK, color values are written into the sole buffer for single-
    buffered contexts, or into the back buffer for double-buffered
    contexts. If DrawBuffersANGLE is supplied with a constant other than
    BACK and NONE, the error INVALID_OPERATION is generated.

    If the GL is bound to a framebuffer object, then each of the
    constants must be one of the values listed in table 4.3.

    In both cases, the draw buffers being defined correspond in order to
    the respective fragment colors. The draw buffer for fragment
    colors beyond <n> is set to NONE.

    The maximum number of draw buffers is implementation-dependent. The
    number of draw buffers supported can be queried by calling
    GetIntegerv with the symbolic constant MAX_DRAW_BUFFERS_ANGLE. An
    INVALID_VALUE error is generated if <n> is greater than
    MAX_DRAW_BUFFERS_ANGLE.

    If the GL is bound to a framebuffer object, the <i>th buffer listed
    in <bufs> must be COLOR_ATTACHMENT<i>_ANGLE or NONE. Specifying a
    buffer out of order, BACK, or COLOR_ATTACHMENT<m>_ANGLE where <m> is
    greater than or equal to the value of MAX_COLOR_ATTACHMENTS_ANGLE,
    will generate the error INVALID_OPERATION.

    If a fragment shader writes to "gl_FragColor", DrawBuffersANGLE
    specifies a set of draw buffers into which the color written to
    "gl_FragColor" is written. If a fragment shader writes to
    "gl_FragData", DrawBuffersANGLE specifies a set of draw buffers
    into which each of the multiple output colors defined by these
    variables are separately written. If a fragment shader writes to
    neither "gl_FragColor" nor "gl_FragData" the values of the
    fragment colors following shader execution are undefined, and may
    differ for each fragment color.

    Indicating a buffer or buffers using DrawBuffersANGLE causes
    subsequent pixel color value writes to affect the indicated
    buffers. If the GL is bound to a framebuffer object and a draw
    buffer selects an attachment that has no image attached, then that
    fragment color is not written to any buffer.

    Specifying NONE as the draw buffer for a fragment color will inhibit
    that fragment color from being written to any buffer.

    The state required to handle color buffer selection for each
    framebuffer is an integer for each supported fragment color. For the
    default framebuffer, in the initial state the draw buffer for
    fragment color zero is BACK if there is a default framebuffer
    associated with the context, otherwise NONE. For framebuffer
    objects, in the initial state the draw buffer for fragment color
    zero is COLOR_ATTACHMENT0_ANGLE.

    For both the default framebuffer and framebuffer objects, the
    initial state of draw buffers for fragment colors other than zero is
    NONE.

    The value of the draw buffer selected for fragment color <i> can be
    queried by calling GetIntegerv with the symbolic constant
    DRAW_BUFFER<i>_ANGLE.

    Replace the second paragraph of Section 4.4.1 (Binding and Managing
    Framebuffer Objects) with the following:

    The namespace for framebuffer objects is the unsigned integers, with
    zero reserved by OpenGL ES to refer to the default framebuffer. A
    framebuffer object is created by binding an unused name to the
    target FRAMEBUFFER. The binding is effected by calling

        void BindFramebuffer(enum target, uint framebuffer);

    with target set to FRAMEBUFFER and framebuffer set to the unused
    name.  The resulting framebuffer object is a new state vector. There
    is a number of color attachment points, plus one each for the depth
    and stencil attachment points. The number of color attachment points
    is equal to the state of MAX_COLOR_ATTACHMENTS_ANGLE.

Changes to Chapter 3 of the OpenGL ES Shading Language 1.0.17 Specification (Basics)

    Add a new section:

    3.4.1 GL_ANGLE_multiple_render_targets Extension

    To use the GL_ANGLE_multiple_render_targets extension in a shader it
    must be enabled using the #extension directive.

    The shading language preprocessor #define
    GL_ANGLE_multiple_render_targets will be defined to 1, if the
    GL_ANGLE_multiple_render_targets extension is supported.

New State

    Add Table 6.X Framebuffer (State per framebuffer object):

        State                 Type Get Command  Initial Value Description 
        ---------------       ---- ------------ ------------- -----------
        DRAW_BUFFER<i>_ANGLE  Z10* GetIntegerv  see 4.2.1     Draw buffer selected 
                                                              for fragment color i

    Add the new Table 6.X "Framebuffer Dependent Values" :

        State                   Type Get Command Min Value Description
        -------------------     ---- ----------- --------- -----------
        MAX_DRAW_BUFFERS_ANGLE  Z+   GetIntegerv 1         Maximum number of
                                                           active draw buffers

    Add to Table 6.18 (Implementation Dependent Values)

    Get value                    Type Get Cmnd    Minimum Value Description             Sec.
    ------------------------     ---- ----------- ------------- -----------             -----
    MAX_COLOR_ATTACHMENTS_ANGLE  Z+   GetIntegerv 1             Number of framebuffer   4.4.1
                                                                color attachment points
Issues

    See ARB_draw_buffers for relevant issues.
