Name

    ARB_framebuffer_object

Name Strings

    GL_ARB_framebuffer_object

Contributors

    Kurt Akeley
    Jason Allen
    Rob Barris
    Bob Beretta
    Pat Brown
    Matt Craighead
    Alex Eddy
    Cass Everitt
    Mark Galvan
    Michael Gold
    Evan Hart
    Jeff Juliano
    John Kessenich
    Mark Kilgard
    Dale Kirkland
    Daniel Koch
    Jon Leech
    Bill Licea-Kane
    Barthold Lichtenbelt
    Kent Lin
    Rob Mace
    Teri Morrison
    Chris Niederauer
    Brian Paul
    Paul Puey
    Ian Romanick
    John Rosasco
    R. Jason Sams
    Jeremy Sandmel
    Mark Segal
    Avinash Seetharamaiah
    Folker Schamel
    Eskil Steenberg
    Daniel Vogel
    Eric Werness
    Cliff Woolley

Contacts

    Rob Barris (rbarris 'at' gmail.com)
    Daniel Koch, TransGaming Inc.

Notice

    Copyright (c) 2008-2013 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 Working Group. 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

    Approved by the ARB on August 4, 2008

Version

    Last Modified Date: October 6, 2016
    Revision: #38

Number

    ARB Extension #45

Dependencies

    OpenGL 1.1 is required.

    WGL_ARB_make_current_read affects the definition of this extension.

    GLX 1.3 / GLX_SGI_make_current_read affects the definition of this
    extension.

    ATI_draw_buffers affects the definition of this extension.

    ARB_draw_buffers affects the definition of this extension.

    ARB_fragment_program affects the definition of this extension.

    ARB_fragment_shader affects the definition of this extension.

    ARB_texture_rectangle affects the definition of this extension.

    ARB_vertex_shader affects the definition of this extension.

    NV_float_buffer affects the definition of this extension.

    ARB_color_buffer_float affects the definition of this extension.

    NV_texture_shader affects the definition of this extension.

    This extension modifies NV_packed_depth_stencil.

    ARB_depth_texture affects the definition of this extension.

    SGIX_depth_texture affects the definition of this extension.

    ARB_texture_rg affects the definition of this extension.

    EXT_texture_array affects the definition of this extension.

    EXT_texture_integer affects the definition of this extension.

    ARB_framebuffer_sRGB affects the definition of this extension.

    Written based on the wording of the OpenGL 2.1 specification.

Overview

    ARB_framebuffer_object is an extension intended to address the following
    goals:

    - Reflect FBO-related functionality found in the OpenGL 3.0 specification.

    - Integrate multiple disjoint extensions into a single ARB extension.
      These extensions are:

        EXT_framebuffer_object
        EXT_framebuffer_blit
        EXT_framebuffer_multisample
        EXT_packed_depth_stencil

    - Where appropriate, relax some of the constraints expressed by previous
      FBO-related extensions. In particular the requirement of matching
      attachment dimensions and component sizes has been relaxed, to allow
      implementations the freedom to support more flexible usages where
      possible.


    ARB_framebuffer_object defines an interface for drawing to rendering
    destinations other than the buffers provided to the GL by the
    window-system.

    In this extension, these newly defined rendering destinations are
    known collectively as "framebuffer-attachable images".  This
    extension provides a mechanism for attaching framebuffer-attachable
    images to the GL framebuffer as one of the standard GL logical
    buffers: color, depth, and stencil.  (Attaching a
    framebuffer-attachable image to the accum logical buffer is left for
    a future extension to define).  When a framebuffer-attachable image
    is attached to the framebuffer, it is used as the source and
    destination of fragment operations as described in Chapter 4.

    By allowing the use of a framebuffer-attachable image as a rendering
    destination, this extension enables a form of "offscreen" rendering.
    Furthermore, "render to texture" is supported by allowing the images
    of a texture to be used as framebuffer-attachable images.  A
    particular image of a texture object is selected for use as a
    framebuffer-attachable image by specifying the mipmap level, cube
    map face (for a cube map texture), and layer (for a 3D texture)
    that identifies the image.  The "render to texture" semantics of
    this extension are similar to performing traditional rendering to
    the framebuffer, followed immediately by a call to CopyTexSubImage.
    However, by using this extension instead, an application can achieve
    the same effect, but with the advantage that the GL can usually
    eliminate the data copy that would have been incurred by calling
    CopyTexSubImage.

    This extension also defines a new GL object type, called a
    "renderbuffer", which encapsulates a single 2D pixel image.  The
    image of renderbuffer can be used as a framebuffer-attachable image
    for generalized offscreen rendering and it also provides a means to
    support rendering to GL logical buffer types which have no
    corresponding texture format (stencil, accum, etc).  A renderbuffer
    is similar to a texture in that both renderbuffers and textures can
    be independently allocated and shared among multiple contexts.  The
    framework defined by this extension is general enough that support
    for attaching images from GL objects other than textures and
    renderbuffers could be added by layered extensions.

    To facilitate efficient switching between collections of
    framebuffer-attachable images, this extension introduces another new
    GL object, called a framebuffer object.  A framebuffer object
    contains the state that defines the traditional GL framebuffer,
    including its set of images.  Prior to this extension, it was the
    window-system which defined and managed this collection of images,
    traditionally by grouping them into a "drawable".  The window-system
    API's would also provide a function (i.e., wglMakeCurrent,
    glXMakeCurrent, aglSetDrawable, etc.) to bind a drawable with a GL
    context (as is done in the WGL_ARB_pbuffer extension).  In this
    extension however, this functionality is subsumed by the GL and the
    GL provides the function BindFramebufferARB to bind a framebuffer
    object to the current context.  Later, the context can bind back to
    the window-system-provided framebuffer in order to display rendered
    content.

    Previous extensions that enabled rendering to a texture have been
    much more complicated.  One example is the combination of
    ARB_pbuffer and ARB_render_texture, both of which are window-system
    extensions.  This combination requires calling MakeCurrent, an
    operation that may be expensive, to switch between the window and
    the pbuffer drawables.  An application must create one pbuffer per
    renderable texture in order to portably use ARB_render_texture.  An
    application must maintain at least one GL context per texture
    format, because each context can only operate on a single
    pixelformat or FBConfig.  All of these characteristics make
    ARB_render_texture both inefficient and cumbersome to use.

    ARB_framebuffer_object, on the other hand, is both simpler to use
    and more efficient than ARB_render_texture.  The
    ARB_framebuffer_object API is contained wholly within the GL API and
    has no (non-portable) window-system components.  Under
    ARB_framebuffer_object, it is not necessary to create a second GL
    context when rendering to a texture image whose format differs from
    that of the window.  Finally, unlike the pbuffers of
    ARB_render_texture, a single framebuffer object can facilitate
    rendering to an unlimited number of texture objects.

    This extension differs from EXT_framebuffer_object by splitting the
    framebuffer object binding point into separate DRAW and READ
    bindings (incorporating functionality introduced by
    EXT_framebuffer_blit). This allows copying directly from one
    framebuffer to another. In addition, a new high performance blit
    function is added to facilitate these blits and perform some data
    conversion where allowed.

    This extension also enables usage of multisampling in conjunction with
    renderbuffers (incorporating functionality from
    EXT_packed_depth_stencil), as follows:

    The new operation RenderbufferStorageMultisample() allocates
    storage for a renderbuffer object that can be used as a multisample
    buffer.  A multisample render buffer image differs from a
    single-sample render buffer image in that a multisample image has a
    number of SAMPLES that is greater than zero.  No method is provided
    for creating multisample texture images.

    All of the framebuffer-attachable images attached to a framebuffer
    object must have the same number of SAMPLES or else the framebuffer
    object is not "framebuffer complete".  If a framebuffer object with
    multisample attachments is "framebuffer complete", then the
    framebuffer object behaves as if SAMPLE_BUFFERS is one.

    In traditional multisample rendering, where
    DRAW_FRAMEBUFFER_BINDING is zero and SAMPLE_BUFFERS is one, the
    GL spec states that "the color sample values are resolved to a
    single, displayable color each time a pixel is updated."  There are,
    however, several modern hardware implementations that do not
    actually resolve for each sample update, but instead postpones the
    resolve operation to a later time and resolve a batch of sample
    updates at a time.  This is OK as long as the implementation behaves
    "as if" it had resolved a sample-at-a-time. Unfortunately, however,
    honoring the "as if" rule can sometimes degrade performance.

    In contrast, when DRAW_FRAMEBUFFER_BINDING is an
    application-created framebuffer object, MULTISAMPLE is enabled, and
    SAMPLE_BUFFERS is one, there is no implicit per-sample-update
    resolve.  Instead, the application explicitly controls when the
    resolve operation is performed.  The resolve operation is affected
    by calling BlitFramebuffer where the source is a multisample
    application-created framebuffer object and the destination is a
    single-sample framebuffer object (either application-created or
    window-system provided).

    This design for multisample resolve more closely matches current
    hardware, but still permits implementations which choose to resolve
    a single sample at a time.  If hardware that implements the
    multisample resolution "one sample at a time" exposes
    ARB_framebuffer_object, it could perform the implicit resolve
    to a driver-managed hidden surface, then read from that surface when
    the application calls BlitFramebuffer.

    Another motivation for granting the application explicit control
    over the multisample resolve operation has to do with the
    flexibility afforded by ARB_framebuffer_object.  Previously, a
    drawable (window or pbuffer) had exclusive access to all of its
    buffers.  There was no mechanism for sharing a buffer across
    multiple drawables.  Under ARB_framebuffer_object, however, a
    mechanism exists for sharing a framebuffer-attachable image across
    several framebuffer objects, as well as sharing an image between a
    framebuffer object and a texture.  If we had retained the "implicit"
    resolve from traditional multisampled rendering, and allowed the
    creation of "multisample" format renderbuffers, then this type of
    sharing would have lead to two problematic situations:

      * Two contexts, which shared renderbuffers, might perform
        competing resolve operations into the same single-sample buffer
        with ambiguous results.

      * It would have introduced the unfortunate ability to use the
        single-sample buffer as a texture while MULTISAMPLE is ENABLED.

    Using BlitFramebuffer as an explicit resolve to serialize access to
    the multisampled contents and eliminate the implicit per-sample
    resolve operation, we avoid both of these problems.

    This extension also enables usage of packed depth-stencil formats in
    renderbuffers (incorporating functionality from
    EXT_packed_depth_stencil), as follows:

    Many OpenGL implementations have chosen to interleave the depth and
    stencil buffers into one buffer, often with 24 bits of depth
    precision and 8 bits of stencil data.  32 bits is more than is
    needed for the depth buffer much of the time; a 24-bit depth buffer,
    on the other hand, requires that reads and writes of depth data be
    unaligned with respect to power-of-two boundaries.  On the other
    hand, 8 bits of stencil data is more than sufficient for most
    applications, so it is only natural to pack the two buffers into a
    single buffer with both depth and stencil data.  OpenGL never
    provides direct access to the buffers, so the OpenGL implementation
    can provide an interface to applications where it appears the one
    merged buffer is composed of two logical buffers.

    One disadvantage of this scheme is that OpenGL lacks any means by
    which this packed data can be handled efficiently.  For example,
    when an application reads from the 24-bit depth buffer, using the
    type GL_UNSIGNED_SHORT will lose 8 bits of data, while
    GL_UNSIGNED_INT has 8 too many.  Both require expensive format
    conversion operations.  A 24-bit format would be no more suitable,
    because it would also suffer from the unaligned memory accesses that
    made the standalone 24-bit depth buffer an unattractive proposition
    in the first place.

    Many applications, such as parallel rendering applications, may also
    wish to draw to or read back from both the depth and stencil buffers
    at the same time.  Currently this requires two separate operations,
    reducing performance.  Since the buffers are interleaved, drawing to
    or reading from both should be no more expensive than using just
    one; in some cases, it may even be cheaper.

    This extension provides a new data format, GL_DEPTH_STENCIL,
    that can be used with the glDrawPixels, glReadPixels, and
    glCopyPixels commands, as well as a packed data type,
    GL_UNSIGNED_INT_24_8, that is meant to be used with
    GL_DEPTH_STENCIL.  No other data types are supported with
    GL_DEPTH_STENCIL.  If ARB_depth_texture or SGIX_depth_texture is
    supported, GL_DEPTH_STENCIL/GL_UNSIGNED_INT_24_8 data can
    also be used for textures; this provides a more efficient way to
    supply data for a 24-bit depth texture.

    GL_DEPTH_STENCIL data, when passed through the pixel path,
    undergoes both depth and stencil operations.  The depth data is
    scaled and biased by the current GL_DEPTH_SCALE and GL_DEPTH_BIAS,
    while the stencil data is shifted and offset by the current
    GL_INDEX_SHIFT and GL_INDEX_OFFSET.  The stencil data is also put
    through the stencil-to-stencil pixel map.

    glDrawPixels of GL_DEPTH_STENCIL data operates similarly to that
    of GL_STENCIL_INDEX data, bypassing the OpenGL fragment pipeline
    entirely, unlike the treatment of GL_DEPTH_COMPONENT data.  The
    stencil and depth masks are applied, as are the pixel ownership and
    scissor tests, but all other operations are skipped.

    glReadPixels of GL_DEPTH_STENCIL data reads back a rectangle
    from both the depth and stencil buffers.

    glCopyPixels of GL_DEPTH_STENCIL data copies a rectangle from
    both the depth and stencil buffers.  Like glDrawPixels, it applies
    both the stencil and depth masks but skips the remainder of the
    OpenGL fragment pipeline.

    glTex[Sub]Image[1,2,3]D of GL_DEPTH_STENCIL data loads depth and
    stencil data into a depth_stencil texture.  glGetTexImage of
    GL_DEPTH_STENCIL data can be used to retrieve depth and stencil
    data from a depth/stencil texture.

    In addition, a new base internal format, GL_DEPTH_STENCIL, can
    be used by both texture images and renderbuffer storage.  When an
    image with a DEPTH_STENCIL internal format is attached to both
    the depth and stencil attachment points of a framebuffer object,
    then it becomes both the depth and stencil
    buffers of the framebuffer.  This fits nicely with hardware that
    interleaves both depth and stencil data into a single buffer.  When
    a texture with DEPTH_STENCIL data is bound for texturing, only
    the depth component is accessible through the texture fetcher.  The
    stencil data can be written with TexImage or CopyTexImage, and can
    be read with GetTexImage.  When a DEPTH_STENCIL image is
    attached to the stencil attachment of the bound framebuffer object,
    the stencil data can be accessed through any operation that reads
    from or writes to the framebuffer's stencil buffer.


Glossary of Helpful Terms

        logical buffer:
            One of the color, depth, or stencil buffers of the
            framebuffer.

        framebuffer:
            The collection of logical buffers and associated state
            defining where the output of GL rendering is directed.

        texture:
            an object which consists of one or more 2D arrays of pixel
            images and associated state that can be used as a source of
            data during the texture-mapping process described in section
            3.8.

        texture image:
            one of the 2D arrays of pixels that are part of a texture
            object as defined in section 3.8.  Texture images contain
            and define the texels of the texture object.

        renderbuffer:
            A new type of storage object which contains a single 2D
            array of pixels and associated state that can be used as a
            destination for pixel data written during the rendering
            process described in Chapter 4.

        renderbuffer image:
            The 2D array of pixels that is part of a renderbuffer
            object.  A renderbuffer image contains and defines the
            pixels of the renderbuffer object.

        framebuffer-attachable image:
            A 2D pixel image that can be attached to one of the logical
            buffer attachment points of a framebuffer object.  Texture
            images and renderbuffer images are two examples of
            framebuffer-attachable images.

        attachment point:
            The set of state which references a specific
            framebuffer-attachable image, and allows that
            framebuffer-attachable image to be used to store the
            contents of a logical buffer of a framebuffer object.  There
            is an attachment point state vector for each color, depth,
            and stencil buffer of a framebuffer.

        attach:
            The act of connecting one object to another object.

            An "attach" operation is similar to a "bind" operation in
            that both represent a reference to the attached or bound
            object for the purpose of managing object lifetimes and both
            enable manipulation of the state of the attached or bound
            object.

            However, an "attach" is also different from a "bind" in that
            "binding" an unused object creates a new object, while
            "attaching" does not.  Additionally, "bind" establishes a
            connection between a context and an object, while "attach"
            establishes a connection between two objects.

            Finally, if object "A" is attached to object "B" and object
            "B" is bound to context "C", then in most respects, we treat
            "A" as if it is <implicitly> bound to "C".

        framebuffer attachment completeness:
            Similar to texture "mipmap" or "cube" completeness from
            section 3.8.10, defines a minimum set of criteria for
            framebuffer attachment points.  (for complete definition,
            see section 4.4.4.1)

        framebuffer completeness:
            Similar to texture "mipmap cube completeness", defines a
            composite set of "completeness" requirements and
            relationships among the attached framebuffer-attachable
            images.  (for complete definition, see section 4.4.4.2)


New Procedures and Functions

    boolean IsRenderbuffer(uint renderbuffer);
    void BindRenderbuffer(enum target, uint renderbuffer);
    void DeleteRenderbuffers(sizei n, const uint *renderbuffers);
    void GenRenderbuffers(sizei n, uint *renderbuffers);

    void RenderbufferStorage(enum target, enum internalformat,
                             sizei width, sizei height);

    void RenderbufferStorageMultisample(enum target, sizei samples,
                                        enum internalformat,
                                        sizei width, sizei height);

    void GetRenderbufferParameteriv(enum target, enum pname, int *params);

    boolean IsFramebuffer(uint framebuffer);
    void BindFramebuffer(enum target, uint framebuffer);
    void DeleteFramebuffers(sizei n, const uint *framebuffers);
    void GenFramebuffers(sizei n, uint *framebuffers);

    enum CheckFramebufferStatus(enum target);

    void FramebufferTexture1D(enum target, enum attachment,
                              enum textarget, uint texture, int level);
    void FramebufferTexture2D(enum target, enum attachment,
                              enum textarget, uint texture, int level);
    void FramebufferTexture3D(enum target, enum attachment,
                              enum textarget, uint texture,
                              int level, int layer);
    void FramebufferTextureLayer(enum target,enum attachment,
                                 uint texture,int level,int layer);

    void FramebufferRenderbuffer(enum target, enum attachment,
                                 enum renderbuffertarget, uint renderbuffer);

    void GetFramebufferAttachmentParameteriv(enum target, enum attachment,
                                             enum pname, int *params);

    void BlitFramebuffer(int srcX0, int srcY0, int srcX1, int srcY1,
                         int dstX0, int dstY0, int dstX1, int dstY1,
                         bitfield mask, enum filter);

    void GenerateMipmap(enum target);


New Types

    None.


New Tokens

    Accepted by the <target> parameter of BindFramebuffer,
    CheckFramebufferStatus, FramebufferTexture{1D|2D|3D},
    FramebufferRenderbuffer, and
    GetFramebufferAttachmentParameteriv:

        FRAMEBUFFER                     0x8D40
        READ_FRAMEBUFFER                0x8CA8
        DRAW_FRAMEBUFFER                0x8CA9

    Accepted by the <target> parameter of BindRenderbuffer,
    RenderbufferStorage, and GetRenderbufferParameteriv, and
    returned by GetFramebufferAttachmentParameteriv:

        RENDERBUFFER                    0x8D41

    Accepted by the <internalformat> parameter of
    RenderbufferStorage:

        STENCIL_INDEX1                  0x8D46
        STENCIL_INDEX4                  0x8D47
        STENCIL_INDEX8                  0x8D48
        STENCIL_INDEX16                 0x8D49

    Accepted by the <pname> parameter of GetRenderbufferParameteriv:

        RENDERBUFFER_WIDTH              0x8D42
        RENDERBUFFER_HEIGHT             0x8D43
        RENDERBUFFER_INTERNAL_FORMAT    0x8D44
        RENDERBUFFER_RED_SIZE           0x8D50
        RENDERBUFFER_GREEN_SIZE         0x8D51
        RENDERBUFFER_BLUE_SIZE          0x8D52
        RENDERBUFFER_ALPHA_SIZE         0x8D53
        RENDERBUFFER_DEPTH_SIZE         0x8D54
        RENDERBUFFER_STENCIL_SIZE       0x8D55
        RENDERBUFFER_SAMPLES            0x8CAB

    Accepted by the <pname> parameter of
    GetFramebufferAttachmentParameteriv:

        FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE            0x8CD0
        FRAMEBUFFER_ATTACHMENT_OBJECT_NAME            0x8CD1
        FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL          0x8CD2
        FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE  0x8CD3
        FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER          0x8CD4
        FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING         0x8210
        FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE         0x8211
        FRAMEBUFFER_ATTACHMENT_RED_SIZE               0x8212
        FRAMEBUFFER_ATTACHMENT_GREEN_SIZE             0x8213
        FRAMEBUFFER_ATTACHMENT_BLUE_SIZE              0x8214
        FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE             0x8215
        FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE             0x8216
        FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE           0x8217

    Returned in <params> by GetFramebufferAttachmentParameteriv:

        SRGB                                          0x8C40
        UNSIGNED_NORMALIZED                           0x8C17
        FRAMEBUFFER_DEFAULT                           0x8218
        INDEX                                         0x8222

    Accepted by the <attachment> parameter of
    FramebufferTexture{1D|2D|3D}, FramebufferRenderbuffer, and
    GetFramebufferAttachmentParameteriv

        COLOR_ATTACHMENT0                0x8CE0
        COLOR_ATTACHMENT1                0x8CE1
        COLOR_ATTACHMENT2                0x8CE2
        COLOR_ATTACHMENT3                0x8CE3
        COLOR_ATTACHMENT4                0x8CE4
        COLOR_ATTACHMENT5                0x8CE5
        COLOR_ATTACHMENT6                0x8CE6
        COLOR_ATTACHMENT7                0x8CE7
        COLOR_ATTACHMENT8                0x8CE8
        COLOR_ATTACHMENT9                0x8CE9
        COLOR_ATTACHMENT10               0x8CEA
        COLOR_ATTACHMENT11               0x8CEB
        COLOR_ATTACHMENT12               0x8CEC
        COLOR_ATTACHMENT13               0x8CED
        COLOR_ATTACHMENT14               0x8CEE
        COLOR_ATTACHMENT15               0x8CEF
        DEPTH_ATTACHMENT                 0x8D00
        STENCIL_ATTACHMENT               0x8D20
        DEPTH_STENCIL_ATTACHMENT         0x821A

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

        MAX_SAMPLES                     0x8D57
        FRAMEBUFFER_BINDING             0x8CA6 // alias DRAW_FRAMEBUFFER_BINDING
        DRAW_FRAMEBUFFER_BINDING        0x8CA6
        READ_FRAMEBUFFER_BINDING        0x8CAA
        RENDERBUFFER_BINDING            0x8CA7
        MAX_COLOR_ATTACHMENTS           0x8CDF
        MAX_RENDERBUFFER_SIZE           0x84E8


    Returned by CheckFramebufferStatus():

        FRAMEBUFFER_COMPLETE                          0x8CD5
        FRAMEBUFFER_INCOMPLETE_ATTACHMENT             0x8CD6
        FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT     0x8CD7
        FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER            0x8CDB
        FRAMEBUFFER_INCOMPLETE_READ_BUFFER            0x8CDC
        FRAMEBUFFER_UNSUPPORTED                       0x8CDD
        FRAMEBUFFER_INCOMPLETE_MULTISAMPLE            0x8D56
        FRAMEBUFFER_UNDEFINED                         0x8219

    Returned by GetError():

        INVALID_FRAMEBUFFER_OPERATION   0x0506

    Accepted by the <format> parameter of DrawPixels, ReadPixels,
    TexImage1D, TexImage2D, TexImage3D, TexSubImage1D, TexSubImage2D,
    TexSubImage3D, and GetTexImage, by the <type> parameter of
    CopyPixels, by the <internalformat> parameter of TexImage1D,
    TexImage2D, TexImage3D, CopyTexImage1D, CopyTexImage2D, and
    RenderbufferStorage, and returned in the <data> parameter of
    GetTexLevelParameter and GetRenderbufferParameteriv:

        DEPTH_STENCIL                              0x84F9

    Accepted by the <type> parameter of DrawPixels, ReadPixels,
    TexImage1D, TexImage2D, TexImage3D, TexSubImage1D, TexSubImage2D,
    TexSubImage3D, and GetTexImage:

        UNSIGNED_INT_24_8                          0x84FA

    Accepted by the <internalformat> parameter of TexImage1D,
    TexImage2D, TexImage3D, CopyTexImage1D, CopyTexImage2D, and
    RenderbufferStorage, and returned in the <data> parameter of
    GetTexLevelParameter and GetRenderbufferParameteriv:

        DEPTH24_STENCIL8                           0x88F0

    Accepted by the <value> parameter of GetTexLevelParameter:

        TEXTURE_STENCIL_SIZE                       0x88F1


Additions to Chapter 2 of the 2.1 Specification (OpenGL Operation)

    "The GL interacts with two classes of framebuffers: window
    system-provided and application-created. There is at most one window
    system-provided framebuffer at any time, referred to as the <default
    framebuffer>. Application-created framebuffers, referred to as
    <framebuffer objects>, may be created as desired. These two types of
    framebuffer are distinguished primarily by the interface for configuring
    and managing their state.

    The effects of GL commands on the default framebuffer are ultimately
    controlled by the window system, which allocates framebuffer resources,
    determines what portions of the default framebuffer the GL may access at
    any given time, and communicates to the GL how those portions are
    structured. Therefore, there are no GL commands to initialize a GL
    context or configure the default framebuffer. Similarly, display of
    framebuffer contents on a physical display device (including the
    transformation of individual framebuffer values by such techniques as
    gamma correction) is not addressed by the GL.

    Allocation and configuration of the default framebuffer occurs outside
    of the GL in conjunction with the window system, using companion APIs
    such as GLX, WGL, and AGL for GL implementations running on the X Window
    System, Microsoft Windows, and MacOS X respectively.

    Allocation and initialization of GL contexts is also done using these
    companion APIs. GL contexts can typically be associated with different
    default framebuffers, and some context state is determined at the time
    this association is performed.

    It is possible to use a GL context <without> a default framebuffer, in
    which case a framebuffer object must be used to perform all rendering.
    This is useful for applications needing to perform <offscreen
    rendering>."


    Add to table 2.3, "Summary of GL errors":

    Error                         Description        Offending command
                                                     ignored?
    ----------------------------- ------------------ -----------------
    ...
    INVALID_FRAMEBUFFER_OPERATION Framebuffer object Yes
                                  is not complete


    Append the following to section 2.6.1 "Begin and End":

    "Calling Begin will result in an INVALID_FRAMEBUFFER_OPERATION
    error if the object bound to DRAW_FRAMEBUFFER_BINDING is not
    "framebuffer complete" (see section 4.4.4.2)."

    Update the bulleted list in section 2.15.4 "Shader Execution" in
    the subsection titled "Texture Access" to say:

    "* The sampler used in a texture lookup function is not one of
      the shadow sampler types, the texture object's base internal
      format is DEPTH_COMPONENT or DEPTH_STENCIL, and the
      TEXTURE_COMPARE_MODE is not NONE.

    * The sampler used in a texture lookup function is one of the
      shadow sampler types, the texture object's base
      internal format is DEPTH_COMPONENT or DEPTH_STENCIL, and the
      TEXTURE_COMPARE_MODE is NONE.

    * The sampler used in a texture lookup function is one of the
      shadow sampler types, and the texture object's base
      internal format is not DEPTH_COMPONENT or DEPTH_STENCIL.

    The stencil index texture internal component is ignored if the base
    internal format is DEPTH_STENCIL.

    If a vertex shader uses..."


Additions to Chapter 3 of the OpenGL 2.1 Specification (Rasterization)

    Update section 3.6.3 "Pixel Transfer Modes", the first paragraph of
    the subsection "Color Table Specification", in the definition of
    ColorTable, to say:

    "... The <formats> COLOR_INDEX, DEPTH_COMPONENT, DEPTH_STENCIL,
    and STENCIL_INDEX and the <type> BITMAP are not allowed."

    Update section 3.6.3 "Pixel Transfer Modes", the third paragraph of
    the subsection "Color Table Specification", in the definition of
    ColorTable, to say:

    "... <internalformat> must be one of the formats in table 3.15 or
    table 3.16, other than the DEPTH_COMPONENT or DEPTH_STENCIL
    formats in those tables."

    Add to section 3.6.3 "Pixel Transfer Modes", at the end of the
    subsection titled "Alternate Color Table Specification Commands":

    "Calling CopyColorTable or CopyColorSubTable will result in an
    INVALID_FRAMEBUFFER_OPERATION error if the object bound to
    READ_FRAMEBUFFER_BINDING is not "framebuffer complete"
    (see section 4.4.4.2)."

    In section 3.6.3 "Pixel Transfer Modes", the subsection "Covolution
    Filter Specification", update the first paragraph in the definition
    of ConvolutionFilter2D to say:

    "... The formats COLOR_INDEX, DEPTH_COMPONENT, DEPTH_STENCIL,
    and STENCIL_INDEX and the type BITMAP are not allowed."

    In section 3.6.3 "Pixel Transfer Modes", update the third paragraph
    of the subsection "Convolution Filter Specification", in the definition
    of ConvolutionFilter2D, to say:

    "... <internalformat> accepts the same values as the corresponding
    argument of ColorTable."

    Add to section 3.6.3 "Pixel Transfer Modes", at the end of the
    subsection titled "Alternate Convolution Filter Specification Commands":

    "Calling CopyConvolutionFilter1D or CopyConvolutionFilter2D will
    result in an INVALID_FRAMEBUFFER_OPERATION error if the object
    bound to READ_FRAMEBUFFER_BINDING is not "framebuffer
    complete" (see section 4.4.4.2)."

    In section 3.6.3 "Pixel Transfer Modes", update the third paragraph
    of the "Histogram Table Specification" subsection , in the definition of
    Histogram, to say:

    "... is too large for the implementation. <internalformat> accepts the
    same values as the corresponding argument of ColorTable, with the
    exception of the values 1, 2, 3, and 4."

    In section 3.6.3 "Pixel Transfer Modes", update the second paragraph
    in the subsection titled "Minmax Table Specification", in the definition
    of Minmax to say:

    "<internalformat> accepts the same values as the corresponding argument
    of ColorTable, with the exception of the values 1, 2, 3, and 4, as well
    as the INTENSITY base and sized internal formats."

    In section 3.6.4 "Rasterization of Pixel Rectangles", modify the final
    paragraph of the definition of DrawPixels as follows:

    "... If the GL is in color index mode and <format> is not one of
    COLOR_INDEX, STENCIL_INDEX, DEPTH_COMPONENT, or DEPTH_STENCIL,
    then the error INVALID_OPERATION occurs.  If <type> is BITMAP and
    <format> is not COLOR_INDEX or STENCIL_INDEX then the error
    INVALID_ENUM occurs.  If <format> is DEPTH_STENCIL and <type> is
    not UNSIGNED_INT_24_8 then the error INVALID_ENUM occurs.  Some
    additional constraints on the combinations of <format> and <type>
    values that are accepted is discussed below.

   "Calling DrawPixels
    will result in an INVALID_FRAMEBUFFER_OPERATION error if the
    object bound to DRAW_FRAMEBUFFER_BINDING is not
    "framebuffer complete" (see section 4.4.4.2)."

    Add a row to Table 3.5, in section 3.6.4:

      type Parameter                GL Type Special
      ---------------------------   ------- -------
      ...                           ...     ...
      UNSIGNED_INT_2_10_10_10_REV   uint    Yes
      UNSIGNED_INT_24_8             uint    Yes

    Add a row to Table 3.6, in section 3.6.4:

      Format Name       Element Meaning and Order   Target Buffer
      ---------------   -------------------------   -----------------
      ...               ...                         ...
      DEPTH_COMPONENT   Depth                       Depth
      DEPTH_STENCIL     Depth and Stencil Index     Depth and Stencil
      ...               ...                         ...

    In section 3.6.4 "Rasterization of Pixel Rectangles", in the subsection
    titled "Unpacking", update the last paragraph on page 131 to say:

    "Calling DrawPixels with a <type> matching one of the types in table 3.8
    is a special case in which all the components of each group are packed
    into a single unsigned byte, unsigned short, or unsigned int, depending
    on the type. The number of components..."

    Add a row to Table 3.8, in section 3.6.4:

      type Parameter               GL Type  Components  Pixel Formats
      ---------------------------  -------  ----------  -------------
      ...                          ...      ...         ...
      UNSIGNED_INT_2_10_10_10_REV  uint     4           RGBA,BGRA
      UNSIGNED_INT_24_8            uint     2           DEPTH_STENCIL

    Add the following diagram to Table 3.11, in section 3.6.4:

    UNSIGNED_INT_24_8

       31 30 29 28 27 26 ... 12 11 10 9 8 7 6 5 4 3 2 1 0
      +----------------------------------+---------------+
      |           1st Component          | 2nd Component |
      +----------------------------------+---------------+

    Add a row to Table 3.12, in section 3.6.4:

      Format        |  1st     2nd     3rd     4th
      --------------+-------------------------------
      ...           |  ...     ...     ...     ...
      BGRA          |  blue    green   red     alpha
      DEPTH_STENCIL |  depth   stencil N/A     N/A

    In section 3.6.4 "Rasterization of Pixel Rectangles", add the
    following sentence to the end of the first paragraph in "Conversion
    to floating-point":

    "For groups containing both components and indices, such as
    DEPTH_STENCIL, the indices are not converted."

    In section 3.6.4 "Rasterization of Pixel Rectangles", update the
    last paragraph in the section "Conversion to Fragments" to say:

    "... Groups arising from DrawPixels with a <format> of STENCIL_INDEX
    or DEPTH_STENCIL are treated specially and are described in
    section 4.3.1."

    Update the first paragraph of section 3.6.5 "Pixel Transfer
    Operations" to say:

    "The GL defines five kinds of pixel groups:

       1. RGBA component: Each group comprises four color components:
          red, green, blue, and alpha.
       2. Depth component: Each group comprises a single depth
          component.
       3. Color index: Each group comprises a single color index.
       4. Stencil index: Each group comprises a single stencil index.
       5. Depth/stencil: Each group comprises a single depth component
          and a single stencil index."

    In section 3.6.5 "Pixel Transfer Operations" update the first paragraph
    in the subsection "Arithmetic on Components" to say:

    "This step applies only to RGBA component and depth component
    groups, and to the depth components in depth/stencil groups. ..."

    In section 3.6.5 "Pixel Transfer Operations" update the first paragraph
    in the subsection "Arithmetic on Indices" to say:

    "This step applies only to color index and stencil index groups, and
    to the stencil indices in depth/stencil groups. ..."

    In section 3.6.5 "Pixel Transfer Operations" update the first paragraph
    in the subsection "Stencil Index Lookup" to say:

    "This step applies only to stencil index groups and to the stencil
    indices in depth/stencil groups. ..."

    Add the following to section 3.7 "Bitmaps", following the description of
    Bitmap:

    "Calling Bitmap will result in an
    INVALID_FRAMEBUFFER_OPERATION error if the object bound to
    DRAW_FRAMEBUFFER_BINDING is not "framebuffer complete"
    (see section 4.4.4.2)."

    In section 3.8.1 "Texture Image Specification", update the following
    paragraphs as follows:

    Update the fourth paragraph to say:

    "The selected groups are processed exactly as for DrawPixels,
    stopping just before final conversion.  Each R, G, B, A, or depth
    value so generated is clamped to [0, 1], while the stencil index
    values are masked by 2^n-1, where n is the number of stencil bits in
    the internal format resolution (see below).  If the base internal
    format is DEPTH_STENCIL and <format> is not DEPTH_STENCIL,
    then the values of the stencil index texture component are
    undefined."

    Update the fifth paragraph to say:

    "Components are then selected from the resulting R, G, B, A, depth,
    or stencil index values to obtain a texture with the base internal
    format specified by (or derived from) <internalformat>.  Table 3.15
    summarizes the mapping of R, G, B, A, depth, or stencil values to
    texture components, as a function of the base internal format of the
    texture image.  <internalformat> may be specified as one of the
    eight internal format symbolic constants listed in table 3.15, as
    one of ..."

    Update the sixth paragraph to say:

    "Textures with a base internal format of DEPTH_COMPONENT or
    DEPTH_STENCIL are supported by texture image specification
    commands only if <target> is TEXTURE_1D, TEXTURE_2D,
    PROXY_TEXTURE_1D or PROXY_TEXTURE_2D.  Using these formats in
    conjunction with any other <target> will result in an
    INVALID_OPERATION error."

    Update the seventh paragraph to say:

    Textures with a base internal format of DEPTH_COMPONENT or
    DEPTH_STENCIL require either depth component data or
    depth/stencil component data.  Textures with other base internal
    formats require RGBA component data.  The error INVALID_OPERATION is
    generated if one of the base internal format and <format>
    is DEPTH_COMPONENT or DEPTH_STENCIL, and the other is neither
    of these values."

    Update the tenth paragraph to say:

    "...the mapping of the R, G, B, A, depth and stencil values to
    texture components..."

    Add a row to table 3.15 in section 3.8.1, and update the title of the
    second column:

      Base Internal Format  RGBA and Depth and Stencil Values  Internal Components
      --------------------  ---------------------------------  -------------------
      ...                   ...                                ...
      DEPTH_STENCIL         Depth,Stencil                      D,S
      ...                   ...                                ...

    Update the caption for table 3.15

    "Table 3.15: Conversion from RGBA, depth, and stencil pixel
    components to internal texture, table, or filter components.  See
    section 3.8.13 for a description of the texture components R, G, B,
    A, L, I, D, and S."

    Add a new column to table 3.16, in section 3.8.1, labeled "S bits".  The
    value of this column is blank for all rows except a new row:

      Sized            Base               R    G    B    A    L    I    D    S
      Internal Format  InternalFormat    bits bits bits bits bits bits bits bits
      ---------------- --------------    ---- ---- ---- ---- ---- ---- ---- ----
      ...                  ...           ...  ...  ...  ...  ...  ...  ...  ...
      DEPTH24_STENCIL8 DEPTH_STENCIL                                   24    8
      ...                  ...           ...  ...  ...  ...  ...  ...  ...  ...

    In section 3.8.2 "Alternate Texture Image Specification Commands",
    update the second paragraph, in the definition of CopyTexImage2D, to
    say:

    "...The image is taken from the framebuffer exactly as if these
    arguments were passed to CopyPixels with argument type set to COLOR
    DEPTH, or DEPTH_STENCIL, depending on <internalformat>, stopping
    after pixel transfer processing is complete.  RGBA data is taken
    from the current color buffer, while depth component and stencil
    index data are taken from the depth and stencil buffers,
    respectively.  If depth component data is required and no depth
    buffer is present, or if stencil index data is required and there is
    no stencil buffer, the error INVALID_OPERATION is generated.
    Subsequent processing is identical to that described for TexImage2D,
    beginning with clamping of the R, G, B, A, or depth values, and
    masking of the stencil index value, from the resulting pixel
    groups..."

    Update the third paragraph to say:

    "Subsequent processing is identical to that described for TexImage2D,
    beginning with clamping of the R, G, B, A, or depth values, and masking
    of the stencil index values from the resulting pixel groups..."

    In section 3.8.2 "Alternate Texture Image Specification Commands",
    update the seventh paragraph, in the description of the
    CopyTexSubImage{2|3}D arguments, to say:

    "...except that the assignment of R, G, B, A, depth, and stencil
    pixel group values to the texture components is controlled by the
    internalformat of the texture array, not by an argument to the
    command..."

    Append the following to section 3.8.2 "Alternate Texture Image
    Specification Commands":

    "Calling CopyTexSubImage3D, CopyTexImage2D,
    CopyTexSubImage2D, CopyTexImage1D or CopyTexSubImage1D will result
    in an INVALID_FRAMEBUFFER_OPERATION error if the object bound
    to READ_FRAMEBUFFER_BINDING is not "framebuffer complete"
    (see section 4.4.4.2)."

    Update section 3.8.5 "Depth Component Textures" to say:

    "Depth textures and the depth components of depth/stencil textures
    can be treated as LUMINANCE, INTENSITY or ALPHA textures during
    texture filtering and application. The initial state for depth and
    depth/stencil textures treats them as LUMINANCE textures."

    In section 3.8.8 "Texture Minification", add the following text
    immediately before the subsection "Mipmapping":

    "If all of the following conditions are satisfied, then the value of
    the selected Tau(ijk), Tau(ij), or Tau(i) in the above equations is
    undefined instead of referring to the value of the texel at location
    (i), (i,j), or (i,j,k).  See Chapter 4 for discussion of framebuffer
    objects and their attachments.

      * The current DRAW_FRAMEBUFFER_BINDING names an application-created
        framebuffer object <F>.

      * The texture is attached to one of the attachment points, <A>, of
        framebuffer object <F>.

      * The value of TEXTURE_MIN_FILTER is NEAREST or LINEAR, and the value
        of FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL for attachment point <A>
        is equal to the value of TEXTURE_BASE_LEVEL

        -or-

        The value of TEXTURE_MIN_FILTER is NEAREST_MIPMAP_NEAREST,
        NEAREST_MIPMAP_LINEAR, LINEAR_MIPMAP_NEAREST, or
        LINEAR_MIPMAP_LINEAR, and the value of
        FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL for attachment point
        <A> is within the inclusive range from TEXTURE_BASE_LEVEL to q."

    In subsection "Automatic Mipmap Generation" to section 3.8.8,
    replace the first paragraph with the following text and footnote:

    "If the value of texture parameter GENERATE MIPMAP is TRUE and a
    change is made to the interior or border texels of the level_base
    array of a mipmap by one of the texture image specification
    operations defined in sections 3.8.1 through 3.8.3, then a complete
    set of mipmap arrays (as defined in section 3.8.10) will be
    computed.  Array levels level_base + 1 through p are replaced with
    arrays derived from the modified level_base, regardless of their
    previous contents.  All other mipmap arrays, including the
    level_base array, are left unchanged by this computation[fn1]."

    "[fn1] Automatic mipmap generation is not performed for changes
           resulting from rendering operations targeting a texture array
           bound as a color buffer of a framebuffer object."


    Add a new subsection "Manual Mipmap Generation" to section 3.8.8,
    after "Automatic Mipmap Generation":

    "Manual Mipmap Generation

    Mipmaps can be generated manually with the command

      void GenerateMipmap(enum target);

    where <target> is one of TEXTURE_1D, TEXTURE_2D, TEXTURE_CUBE_MAP, or
    TEXTURE_3D. Mipmap generation affects the texture image attached to
    <target>. For cube map textures, an INVALID_OPERATION error is generated
    if the texture bound to <target> is not cube complete, as defined in
    section 3.8.10.

    Mipmap generation replaces texture array levels level_base + 1
    through q with arrays derived from the level_base array, as
    described above under Automatic Mipmap Generation.  All other mipmap
    arrays, including the level_base array, are left unchanged by this
    computation.  For arrays in the range level_base+1 through q,
    inclusive, automatic and manual mipmap generation generate the same
    derived arrays, given identical level_base arrays."

    Add a new section between sections 3.8.9 and 3.8.10:

    "3.8.10 DEPTH_STENCIL Textures

    If the texture image has a base internal format of
    DEPTH_STENCIL, then the stencil index texture component is
    ignored.  The texture value Tau does not include a stencil index
    component, but includes only the depth component."

    Update the first paragraph of section 3.8.11 "Texture State and
    Proxy State" to say:

    "...eight integer values describing the resolutions of each of the
    red, green, blue, alpha, luminance, intensity, depth, and stencil
    components of the image..."

    Update the second paragraph of section 3.8.11 "Texture State and
    Proxy State" to say:

    "... and internal format state values, as well as state for the red,
    green, blue, alpha, luminance, intensity, depth, and stencil
    component resolutions."

    Modify the definition of DeleteTextures in section 3.8.12 "Texture
    Objects", to read:

    "Texture objects are deleted by calling

        void DeleteTextures( sizei n, uint *textures );

    textures contains n names of texture objects to be deleted.  After a
    texture object is deleted, it has no contents or dimensionality, and
    its name is again unused.  If a texture that is currently bound to
    one of the targets TEXTURE 1D, TEXTURE 2D, TEXTURE 3D, or TEXTURE
    CUBE MAP is deleted, it is as though BindTexture had been executed
    with the same target and texture zero.  Additionally, special care
    must be taken when deleting a texture if any of the images of the
    texture are attached to a framebuffer object.  See section 4.4.2.3
    for details.

    Unused names in textures are silently ignored, as is the value
    zero."

    In section 3.8.14 "Texture Comparison Modes", update the first
    paragraph of "Depth Texture Comparison Mode" subsection to say:

    "If the currently bound texture's base internal format is
    DEPTH_COMPONENT or DEPTH_STENCIL..."

    In the section 3.8.16 "Texture Application", update the first
    paragraph of to say:

    "...Otherwise, a texture value is found according to the parameter
    values of the currently bound texture image of the appropriate
    dimensionality using the rules given in sections 3.8.6 through
    3.8.9.  Note that the texture value may contain R, G, B, A, L, I, or
    D components, but it does not contain an S component.  If the
    texture's base internal format is DEPTH_STENCIL, for the
    purposes of texture application, it is as if the base internal
    format were DEPTH_COMPONENT..."

    In section 3.11.2 "Shader Execution", in the bulleted list
    in the "Texture Access" subsection to say:

    "* The sampler used in a texture lookup function is not one of the
      shadow sampler types, the texture object's base internal
      format is DEPTH_COMPONENT or DEPTH_STENCIL, and the
      TEXTURE_COMPARE_MODE is not NONE.

    * The sampler used in a texture lookup function is one of the
      shadow sampler types, the texture object's base
      internal format is DEPTH_COMPONENT or DEPTH_STENCIL, and the
      TEXTURE_COMPARE_MODE is NONE.

    * The sampler used in a texture lookup function is one of the
      shadow sampler types, and the texture object's base
      internal format is not DEPTH_COMPONENT or DEPTH_STENCIL.

    The stencil index texture internal component is ignored if the base
    internal format is DEPTH_STENCIL.

    If a fragment shader uses..."


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

    In the introduction to chapter 4, modify the first
    three paragraphs to read as follows:

   "The framebuffer, whether it is the default framebuffer or a framebuffer
    object (see section 2.1), consists of a set of pixels arranged as a
    two-dimensional array.
    For purposes of this
    discussion, each pixel in the framebuffer is simply a set of some
    number of bits.  The number of bits per pixel may  vary
    depending on the GL implementation, the type of framebuffer
    selected, and parameters specified when the framebuffer was created.
    Creation and management of the default framebuffer is outside the scope
    of this specification, while creation and management of framebuffer
    objects is described in detail in section 4.4

    Corresponding bits from each pixel in the framebuffer are grouped
    together into a <bitplane>; each bitplane contains a single bit from
    each pixel.  These bitplanes are grouped into several <logical
    buffers>.  These are the color, accumulation, depth, and stencil
    buffers.  The color buffer actually consists of a number of buffers,
    and these color buffers serve related but slightly different
    purposes depending on whether the GL is bound to the default
    framebuffer or a framebuffer object.

    For the default framebuffer, the color buffers are the <front left>
    buffer, the <front right> buffer, the <back left> buffer, the <back
    right> buffer, and some number of <auxiliary> buffers. Typically, the
    contents of the front buffers are displayed on a color monitor while the
    contents of the back buffers are invisible. (Monoscopic contexts display
    only the front left buffer; stereoscopic contexts display both the front
    left and the front right buffers.) The contents of the auxiliary buffers
    are never visible. All color buffers must have the same number of
    bitplanes, although an implementation or context may choose not to
    provide right buffers, back buffers, or auxiliary buffers at all.
    Further, an implementation or context may choose not to provide
    accumulation, depth, or stencil buffers. If no default framebuffer is
    associated with the GL context, the framebuffer is incomplete except
    when a framebuffer object is bound (see sections 4.4.1 and 4.4.4).

    Framebuffer objects are not visible, and do not have any of the color
    buffers present in the default framebuffer. Instead, the buffers of an
    framebuffer object are specified by attaching individual textures or
    renderbuffers (see section 4.4) to a set of attachment points. A
    framebuffer object has an array of color buffer attachment points,
    numbered zero through <n>, a depth buffer attachment point, and a
    stencil buffer attachment point. In order to be used for rendering, a
    framebuffer object must be complete, as described in section 4.4.4. Not
    all attachments of a framebuffer object need to be populated.

    Each pixel in a color buffer consists of either an unsigned integer
    color index or of up to four color components. The four color components
    are named R, G, B, and A, in that order; color buffers are not required
    to have all four color components. R, G, B, and A components may be
    represented as signed or unsigned normalized fixed-point,
    floating-point, or signed or unsigned integer values; all components
    must have the same representation. Each pixel in a depth buffer consists
    of a single unsigned integer value in the format described in section
    2.12.1 or a floating-point value. Each pixel in a stencil buffer
    consists of a single unsigned integer value. Each pixel in an
    accumulation buffer consists of up to four color components. If an
    accumulation buffer is present, it must have at least as many bitplanes
    per component as in the color buffers.

    The number of bitplanes in the accumulation, color, depth, and stencil
    buffers is dependent on the currently bound framebuffer. For the default
    framebuffer, the number of bitplanes is fixed. For framebuffer objects,
    the number of bitplanes in a given logical buffer may change if the
    image attached to the corresponding attachment point changes.

    The GL has two active framebuffers; the <draw framebuffer> is the
    destination for rendering operations, and the <read framebuffer> is the
    source for readback operations. The same framebuffer may be used for
    both drawing and reading. Section 4.4.1 describes the mechanism for
    controlling framebuffer usage."

    The default framebuffer is initially used as the draw and read
    framebuffer [fn1], and the initial state of all provided bitplanes is
    undefined. The format and encoding of buffers in the draw and read
    framebuffers can be queried as described in section 6.1.3.
        [fn1] The window system binding API may allow associating a GL
              context with two separate ``default framebuffers'' provided by
              the window system as the draw and read framebuffers, but if
              so, both default framebuffers are referred to by the name zero
              at their respective binding points.

    Add a new paragraph to the end of section 4.1.1 "Pixel Ownership Test":

    "If the draw framebuffer is a framebuffer object (see section 4.2.1),
    the pixel ownership test always passes, since the pixels of framebuffer
    objects are owned by the GL, not the window system. If the draw
    framebuffer is the default framebuffer, the window system controls pixel
    ownership."

    Change section 4.1.5 "Stencil Test", the fifth paragraph,
    the second and third sentences, to read as follows:

    "<ref> is an integer reference value that is used in the unsigned
    stencil comparison.  Stencil comparison operations and queries of
    of <ref> clamp its value to the range [0,(2^s)-1], where <s> is the
    number of bits in the stencil buffer attached to the draw framebuffer.

    Replace the first three sentences of 4.1.10 "Logical Operation":

    "Finally, a logical operation is applied between the incoming
    fragment's color or index values and the color or index values
    stored at the corresponding location in the framebuffer. The result
    replaces the values in the framebuffer at the fragment's (x[w],
    y[w]) coordinates. If the selected draw buffers refer to the same
    framebuffer-attachable image more than once, then the values stored
    in that image are undefined."

    Change section 4.2.1 "Selecting a Buffer for Writing", to read as follows:

    "The first such operation is controlling the buffers into which each of
    the fragment color values is written.  This is accomplished with either
    DrawBuffer or DrawBuffers. The command

        void DrawBuffer( enum buf );

    defines the set of color buffers to which fragment color zero is
    written. <buf> must be one of the values from tables 4.4 or 10.nnn. In
    addition, acceptable values for <buf> 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). In the
    initial state, the GL is bound to the default framebuffer. For more
    information about framebuffer objects, see section 4.4.

    If the GL is bound to the default framebuffer, then
    <buf> must be one the values listed in table 4.4, which summarizes
    the constants and the buffers they indicate.  In this case, <buf> is
    a symbolic constant specifying zero, one, two, or four buffers for
    writing. These constants refer to the four potentially visible
    buffers front left, front right, back left, and back right, and to
    the auxiliary buffers.  Arguments other than AUXi that omit
    reference to LEFT or RIGHT refer to both left and right buffers.
    Arguments other than AUXi that omit reference to FRONT or BACK refer
    to both front and back buffers.  AUXi enables drawing only to
    auxiliary buffer i.  Each AUXi adheres to AUXi = AUX0 + i,
    and i must be in the range 0 to the value of AUX_BUFFERS minus one.

    If the GL is bound to a framebuffer object,
    <buf> must be one of the values listed in table 10.nnn, which
    summarizes the constants and the buffers they indicate. In this
    case, <buf> is a symbolic constant specifying a single color buffer
    for writing.  Specifying COLOR_ATTACHMENTi enables drawing only
    to the image attached to the framebuffer at COLOR_ATTACHMENTi.
    Each COLOR_ATTACHMENTi adheres to COLOR_ATTACHMENTi =
    COLOR_ATTACHMENT0 + i.  The initial value of DRAW_BUFFER for
    application-created framebuffer objects is COLOR_ATTACHMENT0.


    Symbolic Constant               Meaning
    -----------------               -------
    NONE                            no buffer
    COLOR_ATTACHMENTi (see caption) output fragment color to image attached
                                    at color attachment point i
    -------------------------------------------------------------------
    Table 10.nnn:  Arguments to DrawBuffer(s) and ReadBuffer when the
    context is bound to a framebuffer object, and
    the buffers they indicate. i in COLOR_ATTACHMENTi may range from
    zero to the value of MAX_COLOR_ATTACHMENTS - 1.

    If the GL is bound to the default framebuffer and
    DrawBuffer is supplied with a constant (other than NONE) that does
    not indicate any of the color buffers allocated to the GL context,
    the error INVALID_OPERATION results.

    If the GL is bound to a framebuffer object and <buf> is one of the
    constants from table 4.4, then the error INVALID_OPERATION results.
    If <buf> is COLOR_ATTACHMENT<m> and <m> is greater than or equal to
    the value of MAX_COLOR_ATTACHMENTS, then the error INVALID_VALUE
    results.

    If DrawBuffer is supplied with a constant that is neither legal for
    the default framebuffer nor a framebuffer object, then the error
    INVALID_ENUM results.

    DrawBuffer will set the draw buffer for fragment colors other than
    zero to NONE.

    The command

        void DrawBuffers( 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.

    Each buffer listed in <bufs> must be one of the values from tables
    10.nnn or 11.nnn.  Otherwise, an INVALID_ENUM error is generated.
    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 an
    framebuffer object (i.e.,
    DRAW_FRAMEBUFFER_BINDING is non-zero).  For more information about
    framebuffer objects, see section 4.4.


      symbolic       front  front   back   back   aux
      constant       left   right   left   right  i
      --------       -----  -----   ----   -----  ---
      NONE
      FRONT LEFT      X
      FRONT RIGHT             X
      BACK LEFT                      X
      BACK RIGHT                            X
      AUXi                                         X
      --------------------------------------------------
      Table 11.nnn: Arguments to DrawBuffers, when the context is bound
      to the default framebuffer, and the buffers that they indicate.

    If the GL is bound to the default
    framebuffer, then each of the constants must be one of the
    values listed in table 11.nnn.

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

    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 and
    must be at least 1.  The number of draw buffers supported can be
    queried by calling GetIntegerv with the symbolic constant
    MAX_DRAW_BUFFERS. An INVALID_VALUE error is generated if <n> is
    greater than MAX_DRAW_BUFFERS.

    Except for NONE, a buffer may not appear more then once in the array
    pointed to by <bufs>.  Specifying a buffer more then once will
    result in the error INVALID_OPERATION.

    If fixed-function fragment shading is being performed, DrawBuffers
    specifies a set of draw buffers into which the fragment color is
    written.

    If a fragment shader writes to "gl_FragColor", DrawBuffers specifies
    a set of draw buffers into which the single fragment color defined
    by "gl_FragColor" is written.  If a fragment shader writes to
    "gl_FragData", DrawBuffers specifies a set of draw buffers into which
    each of the multiple fragment colors defined by "gl_FragData" 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.

    For both the default framebuffer and framebuffer objects,
    the constants FRONT, BACK, LEFT, RIGHT, and
    FRONT_AND_BACK are not valid in the <bufs> array passed to
    DrawBuffers, and will result in the error INVALID_OPERATION.  This
    restriction is because these constants may themselves refer to
    multiple buffers, as shown in table 4.4.

    If the GL is bound to the default framebuffer and
    DrawBuffers is supplied with a constant (other than NONE) that does
    not indicate any of the color buffers allocated to the GL context by
    the window system, the error INVALID_OPERATION will be generated.

    If the GL is bound to a framebuffer object and
    DrawBuffers is supplied with a constant from table 11.nnn, or
    COLOR_ATTACHMENTm where m is greater than or equal to the value of
    MAX_COLOR_ATTACHMENTS, then the error INVALID_OPERATION results.

    Indicating a buffer or buffers using DrawBuffer or DrawBuffers
    causes subsequent pixel color value writes to affect the indicated
    buffers.

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

    Monoscopic contexts include only left buffers, while stereoscopic
    contexts include both left and right buffers.  Likewise, single
    buffered contexts include only front buffers, while double buffered
    contexts include both front and back buffers.  The type of context
    is selected at GL initialization.

    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 FRONT if there are no back
    buffers; otherwise it is BACK.  For framebuffer
    objects, in the initial state the draw buffer for fragment color zero is
    COLOR_ATTACHMENT0.  For both the default
    framebuffer and framebuffers objects, the initial state
    of draw buffers for fragment colors other then 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_BUFFERi.
    DRAW_BUFFER is equivalent to DRAW_BUFFER0."

    In section 4.2.2 "Fine Control of Buffer Updates", modify the beginning
    of the paragraph defining <mask> for StencilMask and StencilMaskSeparate
    as follows:

    Modify the second to last paragraph of section 4.2.4 "The Accumulation
    Buffer" as follows:

    "If there is no accumulation buffer, or if the DRAW_FRAMEBUFFER
    and READ_FRAMEBUFFER bindings (see section 4.4.4.2) do not refer to
    the same object, or if the GL is in color index mode, Accum
    generates the error INVALID_OPERATION."

    Replace section 4.3.1 "Writing to the Stencil Buffer" with the following:

    "4.3.1 Writing to the Stencil Buffer or to the Depth and Stencil
    Buffers

    The operation of DrawPixels was described in section 3.6.4, except
    if the <format> argument was STENCIL_INDEX or DEPTH_STENCIL.  In
    this case, all operations described for DrawPixels take place, but
    window (x,y) coordinates, each with the corresponding stencil index,
    or depth value and stencil index, are produced in lieu of fragments.
    Each coordinate-data pair is sent directly to the per-fragment
    operations, bypassing the texture, fog, and antialiasing application
    stages of rasterization.  Each pair is then treated as a fragment
    for purposes of the pixel ownership and scissor tests; all other
    per-fragment operations are bypassed.  Finally, each stencil index
    is written to its indicated location in the framebuffer, subject to
    the current front stencil mask (set with StencilMask or
    StencilMaskSeparate).  If a depth component is present, and if the
    setting of DepthMask is not FALSE, the depth component is also
    written to the framebuffer; the setting of DepthTest is ignored.

    The error INVALID_OPERATION results if the <format> argument is
    STENCIL_INDEX and there is no stencil buffer, or if <format> is
    DEPTH_STENCIL and there is not both a depth buffer and a stencil
    buffer."

    Add to 4.3.2 "Reading Pixels", right before the subsection titled
    "Obtaining Pixels from the Framebuffer":

    "ReadPixels generates an INVALID_OPERATION error
    if READ_FRAMEBUFFER_BINDING
    (see section 4.4) is non-zero, the read framebuffer is framebuffer
    complete, and the value of SAMPLE_BUFFERS for the read framebuffer
    is greater than zero."

    In section 4.3.2 "Reading Pixels", add the following paragraph
    after the second paragraph of the section "Obtaining Pixels from
    the Framebuffer":

    "If the <format> is DEPTH_STENCIL, then values are taken from
    both the depth buffer and the stencil buffer.  If there is no depth
    buffer or if there is no stencil buffer, then the error
    INVALID_OPERATION occurs.  If the <type> parameter is not
    UNSIGNED_INT_24_8, then the error INVALID_ENUM occurs.

    If there is a multisample buffer, then values are obtained from the
    depth and stencil samples in this buffer. It is recommended that the
    depth and stencil values of the centermost sample be used, though
    implementations may choose any function of the depth and stencil
    sample values at each pixel."

    In section 4.3.2 "Reading Pixels" in the subsection "Obtaining Pixels
    from the Framebuffer", modify the first two paragraphs of the
    definition of ReadBuffer to read as follows:

    "The command

         void ReadBuffer( enum src );

    takes a symbolic constant as argument.  <src> must be one of the
    values from tables 4.4 or 10.nnn.  Otherwise, INVALID_ENUM is
    generated.  Further, the acceptable values for <src> depend on
    whether the GL is using the default
    framebuffer (i.e., READ_FRAMEBUFFER_BINDING is zero), or a
    framebuffer object (i.e.,
    READ_FRAMEBUFFER_BINDING is non-zero).  For more information about
    framebuffer objects, see section 4.4.

    If the object bound to READ_FRAMEBUFFER_BINDING is not <framebuffer
    complete> (as defined in section 4.4.4.2), then ReadPixels generates
    the error INVALID_FRAMEBUFFER_OPERATION.  If ReadBuffer is
    supplied with a constant that is neither legal for the default
    framebuffer, nor legal for a
    framebuffer object, then the error INVALID_ENUM results.

    When READ_FRAMEBUFFER_BINDING is zero, i.e. the default framebuffer,
    <src> must be one of the values listed in table 4.4, including NONE.
    FRONT_AND_BACK, FRONT, and LEFT refer to the front left buffer, BACK
    refers to the back left buffer, and RIGHT refers to the front right
    buffer. The other constants correspond directly to the buffers that they
    name. If the requested buffer is missing, then the error
    INVALID_OPERATION is generated. For the default framebuffer, the initial
    setting for ReadBuffer is FRONT if there is no back buffer and BACK
    otherwise.

    When the GL is using a framebuffer object, <src> must be one of the
    values listed in table 10.nnn, including NONE. In a manner analogous to
    how the DRAW_BUFFERs state is handled, specifying COLOR_ATTACHMENTi
    enables reading from the image attached to the framebuffer at
    COLOR_ATTACHMENTi. For framebuffer objects, the initial setting for
    ReadBuffer is COLOR_ATTACHMENT0.

    ReadPixels generates an INVALID_OPERATION error if it attempts to select
    a color buffer while READ_BUFFER is NONE.

    ReadPixels obtains values from the selected buffer from each pixel
    with lower left hand corner at (x+i, y+j) for (0 <= i < width) and
    (0 <= j < height); this pixel is said to be the ith pixel in the jth
    row.  If any of these pixels lies outside of the window allocated to
    the current GL context, or outside of the image attached to the
    currently bound framebuffer object, then the values obtained for
    those pixels are undefined.  When READ_FRAMEBUFFER_BINDING is zero,
    results are also undefined for individual pixels that are not owned
    by the current context.  Otherwise, ReadPixels obtains values from
    the selected buffer, regardless of how those values were placed
    there."

    In section 4.3.2 "Reading Pixels", modify the last paragraph of the
    subsection "Obtaining Pixels from the Framebuffer", to say:

    "... If the GL is in color index mode, and <format> is not
    DEPTH_COMPONENT, STENCIL_INDEX, or DEPTH_STENCIL, then the color
    index is obtained at each pixel location."

    In section 4.3.2 "Reading Pixels", add a paragraph at the end of the
    subsection "Obtaining Pixels from the Framebuffer" immediately before
    "Conversion of RGBA values":

    "When READ_FRAMEBUFFER_BINDING is non-zero, the red, green, blue, and
    alpha values are obtained by first reading the internal component
    values of the corresponding value in the image attached to the
    selected logical buffer. Internal components are converted to an
    RGBA color by taking each R, G, B, and A component present according
    to the base internal format of the buffer (as shown in table 3.15).
    If G, B, or A values are not present in the internal format, they
    are taken to be zero, zero, and one respectively.

    In section 4.3.2 "Reading Pixels", update the first sentence of the
    subsection "Conversion of RGBA values" to say:

    "This step applies only if the GL is in RGBA mode, and then only if
    <format> is neither STENCIL_INDEX, DEPTH_COMPONENT, nor
    DEPTH_STENCIL."

    In section 4.3.2 "Reading Pixels", update the section "Conversion
    of Depth values" to say:

    "This step applies only if <format> is DEPTH_COMPONENT or
    DEPTH_STENCIL.  Each element taken from the depth buffer is
    taken to be a fixed-point value in [0,1] with m bits, where m is the
    number of bits in the depth buffer (see section 2.11.1)."

    Add a row to Table 4.6, in section 4.3.2 "Reading Pixels":

      type Parameter     Index Mask
      -----------------  ----------
      ...                ...
      INT                2^31-1
      UNSIGNED_INT_24_8  2^8-1

    Modify the first sentence of section 4.3.3 "Copying Pixels" as follows:

    "CopyPixels transfers a rectangle of pixel values from one region
    of the read framebuffer to another in the draw framebuffer."

    In section 4.3.3 "Copying Pixels", update the second and third
    paragraphs to say:

    "<type> is a symbolic constant that must be one of COLOR, STENCIL,
    DEPTH, or DEPTH_STENCIL, indicating that the values to be
    transferred are colors, stencil values, depth values, or
    depth/stencil values, respectively. The first four arguments have the
    same interpretation as the corresponding arguments to ReadPixels.

    Values are obtained from the framebuffer, converted (if
    appropriate), then subjected to the pixel transfer operations
    described in section 3.6.5, just as if ReadPixels were called with
    the corresponding arguments.  If the <type> is STENCIL or DEPTH,
    then it is as if the <format> for ReadPixels were STENCIL_INDEX, or
    DEPTH_COMPONENT, respectively.  If the <type> is DEPTH_STENCIL,
    then it is as if the <format> for ReadPixels were specified as
    described in table 4.6b.  If the <type> is COLOR, then if the GL is
    in RGBA mode, it is as if the <format> were RGBA, while if the GL is
    in color index mode, it is as if the <format> were COLOR_INDEX."

    Add Table 4.6b:

      DEPTH_BITS  STENCIL_BITS     format
      ----------  ------------  ---------------
         zero       zero        DEPTH_STENCIL
         zero       non-zero    DEPTH_COMPONENT
       non-zero     zero        STENCIL_INDEX
       non-zero     non-zero    DEPTH_STENCIL

       Table 4.6b: Effective ReadPixels format for DEPTH_STENCIL
       CopyPixels operation.

    Add a row to Table 4.7 (page 224):

      type Parameter                GL Type Component Conversion ...
      ---------------------------   ------- ---------------------------
      ...                           ...      ...
      UNSIGNED_INT_2_10_10_10_REV   uint    c = (2^N - 1)f
      UNSIGNED_INT_24_8             uint    c = (2^N - 1)f (depth only)

    Add the following text to section 4.3.3 "Copying Pixels", inside the
    definition of CopyPixels:

    "Finally, the behavior of several GL operations is specified "as if
    the arguments were passed to CopyPixels."  These operations include:
    CopyTex{Sub}Image*, CopyColor{Sub}Table, and CopyConvolutionFilter*.
    An INVALID_FRAMEBUFFER_OPERATION error will be generated if an attempt is
    made to execute one of these operations, or CopyPixels, while the
    object bound to READ_FRAMEBUFFER_BINDING (see section 4.4) is not
    "framebuffer complete" (as defined in section 4.4.4.2).
    An INVALID_OPERATION error will be generated if the object bound to
    READ_FRAMEBUFFER_BINDING is "framebuffer complete" and the value
    of SAMPLE_BUFFERS is greater than zero.

    CopyPixels will generate an INVALID_FRAMEBUFFER_OPERATION error
    if the object bound to DRAW_FRAMEBUFFER_BINDING (see section
    4.4) is not "framebuffer complete".

    Append to section 4.3.3 "Copying Pixels":

    "The command

    BlitFramebuffer(int srcX0, int srcY0, int srcX1, int srcY1,
                       int dstX0, int dstY0, int dstX1, int dstY1,
                       bitfield mask, enum filter);

    transfers a rectangle of pixel values from one
    region of the read framebuffer to another in the draw framebuffer.
    There are some important distinctions from CopyPixels, as
    described below.

    <mask> is the bitwise OR of a number of values indicating which
    buffers are to be copied. The values are COLOR_BUFFER_BIT,
    DEPTH_BUFFER_BIT, and STENCIL_BUFFER_BIT, which are described in
    section 4.2.3.  The pixels corresponding to these buffers are
    copied from the source rectangle bounded by the locations (srcX0,
    srcY0) and (srcX1, srcY1), to the destination rectangle bounded by
    the locations (dstX0, dstY0) and (dstX1, dstY1).  The lower bounds
    of the rectangle are inclusive, while the upper bounds are
    exclusive.

    When the color buffer is transferred, values are taken from the read
    buffer of the read framebuffer and written to each of the draw buffers
    of the draw framebuffer, just as with CopyPixels.

    The actual region taken from the read framebuffer is limited to the
    intersection of the source buffers being transferred, which may include
    the color buffer selected by the read buffer, the depth buffer, and/or
    the stencil buffer depending on <mask>.
    The actual region written to the draw framebuffer is limited to the
    intersection of the destination buffers being written, which may include
    multiple draw buffers, the depth buffer, and/or the stencil buffer
    depending on <mask>
    Whether or not the source or destination regions are altered due to
    these limits, the scaling and offset applied to pixels being transferred
    is performed as though no such limits were present.

    If the source and destination rectangle dimensions do not match,
    the source image is stretched to fit the destination
    rectangle. <filter> must be LINEAR or NEAREST and specifies the
    method of interpolation to be applied if the image is
    stretched. LINEAR filtering is allowed only for the color buffer;
    if <mask> includes DEPTH_BUFFER_BIT or STENCIL_BUFFER_BIT, and
    filter is not NEAREST, no copy is performed and an
    INVALID_OPERATION error is generated.  If the source and
    destination dimensions are identical, no filtering is applied.  If
    either the source or destination rectangle specifies a negative
    width or height (X1 < X0 or Y1 < Y0),
    the image is reversed in the corresponding direction.
    If both the source and destination rectangles specify a negative
    dimension for the same direction, no reversal is performed.
    If a linear filter is selected and the rules of LINEAR sampling
    would require sampling outside the bounds of a source buffer, it is
    as though CLAMP_TO_EDGE texture sampling were being performed. If a
    linear filter is selected and sampling would be required outside the
    bounds of the specified source region, but within the bounds of a
    source buffer, the implementation may choose to clamp while sampling
    or not.

    If the source and destination buffers are identical, and the
    source and destination rectangles overlap, the result of the blit
    operation is undefined.

    Blit operations bypass the fragment pipeline.  The only fragment
    operations which affect a blit are the pixel ownership test and
    the scissor test.

    If a buffer is specified in <mask> and does not exist in both the
    read and draw framebuffers, the corresponding bit is silently
    ignored.

    If the color formats of the read and draw framebuffers do not
    match, and <mask> includes COLOR_BUFFER_BIT, pixel groups are
    converted to match the destination format as in CopyPixels.
    However, no pixel transfer operations are applied, and clamping
    behaves as if CLAMP_FRAGMENT_COLOR_ARB is set to FIXED_ONLY_ARB.
    Format conversion is not supported for all data types. If the read
    buffer contains floating-point values and any draw buffer does not
    contain floating-point values, or if the read buffer contains
    non-floating-point values and any draw buffer contains
    floating-point values, an INVALID_OPERATION error is generated.

    Calling BlitFramebuffer will result in an
    INVALID_FRAMEBUFFER_OPERATION error if the objects bound to
    DRAW_FRAMEBUFFER_BINDING and READ_FRAMEBUFFER_BINDING are
    not "framebuffer complete" (see section 4.4.4.2)."

    Calling BlitFramebuffer will result in an INVALID_OPERATION
    error if <mask> includes DEPTH_BUFFER_BIT or STENCIL_BUFFER_BIT
    and the source and destination depth and stencil buffer formats do
    not match.

    If SAMPLE_BUFFERS for the read framebuffer is greater than zero and
    SAMPLE_BUFFERS for the draw framebuffer is zero, the samples
    corresponding to each pixel location in the source are converted to
    a single sample before being written to the destination.

    If SAMPLE_BUFFERS for the read framebuffer is zero and
    SAMPLE_BUFFERS for the draw framebuffer is greater than zero, the
    value of the source sample is replicated in each of the destination
    samples.

    If SAMPLE_BUFFERS for both the read and draw framebuffers are
    greater than zero, and the values of SAMPLES for the read and draw
    framebuffers are identical, the samples are copied without
    modification from the read framebuffer to the draw framebuffer.
    Otherwise, no copy is performed and an INVALID_OPERATION error is
    generated. Note that the samples in the draw buffer are not
    guaranteed to be at the same sample location as the read buffer,
    so rendering using this newly created buffer can potentially
    have geometry cracks or incorrect antialiasing. This may occur
    if the sizes of the framebuffers do not match, if the
    formats differ, or if the source and destination rectangles are
    not defined with the same (X0,Y0) and (X1,Y1) bounds.

    If SAMPLE_BUFFERS for either the read framebuffer or
    draw framebuffer is greater than zero, no copy is performed and an
    INVALID_OPERATION error is generated if the dimensions of the source
    and destination rectangles provided to BlitFramebuffer are not
    identical, or if the formats of the read and draw framebuffers are
    not identical.


    Add a new section "Framebuffer Objects" after section 4.3:

    "4.4 Framebuffer Objects

    As described in chapters 1 and 2, GL renders into (and reads values
    from) a framebuffer.  GL defines two classes of framebuffers:
    window-system-provided framebuffers and application-created
    framebuffers.  For each GL context, there is a single framebuffer
    provided by the window-system, and there may also be one or more
    framebuffer objects created and managed by the application.

    By default, the GL uses the window-system-provided framebuffer.  The
    storage, dimensions, allocation, and format of the images attached
    to this framebuffer are managed entirely by the window-system.
    Consequently, the state of the window-system-provided framebuffer,
    including its images, can not be changed by the GL, nor can the
    window-system-provided framebuffer itself, or its images, be deleted
    by the GL.

    The routines described in the following sections, however, can be
    used to create, destroy, and modify the state and attachments of
    application-created framebuffer objects.

    Application-created framebuffer objects encapsulate the state of a
    framebuffer in a similar manner to the way texture objects
    encapsulate the state of a texture.  In particular, a framebuffer
    object encapsulates state necessary to describe a collection of
    color, depth, and stencil logical buffers (accumulation and
    auxiliary buffers are not allowed).  For each
    logical buffer, a framebuffer-attachable image can be attached to
    the framebuffer to store the rendered output for that logical
    buffer.  Examples of framebuffer-attachable images include texture
    images and renderbuffer images.  Renderbuffers are described further
    in section 4.4.2.1

    By allowing the images of a renderbuffer to be attached to a
    framebuffer, the GL provides a mechanism to support "off-screen"
    rendering.  Further, by allowing the images of a texture to be
    attached to a framebuffer, the GL provides a mechanism to support
    "render to texture".

    4.4.1 Binding and Managing Framebuffer Objects

    The default framebuffer for rendering and readback operations is
    provided by the window system.  In addition, named framebuffer
    objects can be created and operated upon.  The namespace for
    framebuffer objects is the unsigned integers, with zero reserved
    by the GL for the default framebuffer.

    A framebuffer object is created by binding
    a name returned by GenFramebuffers (see below) to
    DRAW_FRAMEBUFFER or READ_FRAMEBUFFER.  The binding is
    effected by calling

        void BindFramebuffer(enum target, uint framebuffer);

    with <target> set to the desired framebuffer target and
    <framebuffer> set to the framebuffer object name.
    The resulting framebuffer
    object is a new state vector, comprising all the state values
    listed in table 4.nnn, as well as one set of the state values
    listed in table 5.nnn for each attachment point of the
    framebuffer, set to the same initial values.  There are
    MAX_COLOR_ATTACHMENTS color attachment points, plus one each
    for the depth and stencil attachment points.

    BindFramebuffer may also be used to bind an existing
    framebuffer object to DRAW_FRAMEBUFFER or
    READ_FRAMEBUFFER.  If the bind is successful no change is made
    to the state of the bound framebuffer object, and any previous
    binding to <target> is broken.

    BindFramebuffer fails and an INVALID_OPERATION error is generated if
    <framebuffer> is not zero or a name returned from a previous call to
    GenFramebuffers, or if such a name has since been deleted with
    DeleteFramebuffers.

    If a framebuffer object is bound to DRAW_FRAMEBUFFER or
    READ_FRAMEBUFFER, it becomes the target for rendering or
    readback operations, respectively, until it is deleted or another
    framebuffer is bound to the corresponding bind point. Calling
    BindFramebuffer with <target> set to FRAMEBUFFER binds the
    framebuffer to both the draw and read targets.

    While a framebuffer object is bound, GL operations on the target
    to which it is bound affect the images attached to the bound
    framebuffer object, and queries of the target to which it is bound
    return state from the bound object.  Queries of the values
    specified in table 6.31 (Implementation Dependent Pixel Depths)
    and table 8.nnn (Framebuffer-Dependent State Variables) are
    derived from the framebuffer object bound to DRAW_FRAMEBUFFER.

    The initial state of DRAW_FRAMEBUFFER and READ_FRAMEBUFFER
    refers to the default framebuffer.
    In order that access to the default framebuffer is not
    lost, it is treated as a framebuffer object with the name of zero.
    The default framebuffer is therefore rendered to and read from
    while zero is bound to the corresponding targets.  On some
    implementations, the properties of the default framebuffer can
    change over time (e.g., in response to window system events
    such as attaching the context to a new window system drawable.)

    Framebuffer objects (those with a non-zero
    name) differ from the default framebuffer in
    a few important ways.  First and foremost, unlike the
    default framebuffer, framebuffer objects
    have modifiable attachment points for each logical buffer in the
    framebuffer.  Framebuffer-attachable images can be attached to and
    detached from these attachment points, which are described further
    in section 4.4.2.  Also, the size and format of the images attached
    to application-created framebuffers are controlled entirely within
    the GL interface, and are not affected by window system events, such
    as pixel format selection, window resizes, and display mode changes.

    Additionally, when rendering to or reading from an application
    created-framebuffer object,

          - The pixel ownership test always succeeds.  In other words,
            framebuffer objects own all of their pixels.

          - There are no visible color buffer bitplanes.  This means
            there is no color buffer corresponding to the back, front,
            left, or right color bitplanes.

          - The only color buffer bitplanes are the ones defined by the
            framebuffer attachment points named COLOR_ATTACHMENT0
            through COLOR_ATTACHMENTn.

          - The only depth buffer bitplanes are the ones defined by the
            framebuffer attachment point DEPTH_ATTACHMENT.

          - The only stencil buffer bitplanes are the ones defined by
            the framebuffer attachment point STENCIL_ATTACHMENT.

          - There are no accum buffer bitplanes, so the value of the
            implementation-dependent state variables ACCUM_RED_BITS,
            ACCUM_GREEN_BITS, ACCUM_BLUE_BITS, and ACCUM_ALPHA_BITS, are
            all zero.

          - There are no AUX buffer bitplanes, so the value of the
            implementation-dependent state variable AUX_BUFFERS is zero.

          - If the attachment sizes are not all identical, rendering will be
            limited to the largest area that can fit in all of the
            attachments (i.e. an intersection of rectangles having a lower
            left of (0,0) and an upper right of (width,height) for each
            attachment)

          - If the attachment sizes are not all identical, the values of
            pixels outside the common intersection area after rendering are
            undefined.

    Framebuffer objects are deleted by calling

      void DeleteFramebuffers(sizei n, uint *framebuffers);

    <framebuffers> contains <n> names of framebuffer objects to be
    deleted.  After a framebuffer object is deleted, it has no
    attachments, and its name is again unused.  If a framebuffer that
    is currently bound to one or more of the targets
    DRAW_FRAMEBUFFER or READ_FRAMEBUFFER is deleted, it is as
    though BindFramebuffer had been executed with the corresponding
    <target> and <framebuffer> zero.   Unused names in
    <framebuffers> are silently ignored, as is the value zero.

    The command

      void GenFramebuffers(sizei n, uint *ids);

    returns <n> previously unused framebuffer object names in <ids>.
    These names are marked as used, for the purposes of
    GenFramebuffers only, but they acquire state and type only when
    they are first bound, just as if they were unused.

    The names bound to the draw and read framebuffer bindings can be
    queried by calling GetIntegerv with the symbolic constants
    DRAW_FRAMEBUFFER_BINDING and READ_FRAMEBUFFER_BINDING
    respectively. FRAMEBUFFER_BINDING is equivalent to
    DRAW_FRAMEBUFFER_BINDING.

    4.4.2 Attaching Images to Framebuffer Objects

    Framebuffer-attachable images may be attached to, and detached from,
    framebuffer objects.  In contrast, the image
    attachments of the default framebuffer may not be
    changed by the GL.

    A single framebuffer-attachable image may be attached to multiple
    framebuffer objects, potentially avoiding some
    data copies, and possibly decreasing memory consumption.

    For each logical buffer, a framebuffer object stores a set of
    state which defines the logical buffer's <attachment point>.  The
    attachment point state contains enough information to identify the
    single image attached to the attachment point, or to indicate that
    no image is attached.  The per-logical buffer attachment point
    state is listed in table 5.nnn

    There are two types of framebuffer-attachable images: the image of a
    renderbuffer object, and an image of a texture object.

    4.4.2.1 Renderbuffer Objects

    A renderbuffer is a data storage object containing a single image of
    a renderable internal format.  GL provides the methods described
    below to allocate and delete a renderbuffer's image, and to attach a
    renderbuffer's image to a framebuffer object.

    The name space for renderbuffer objects is the unsigned integers,
    with zero reserved for the GL.  A renderbuffer object is created by
    binding a name returned by GenRenderbuffers (see below)
    to RENDERBUFFER.  The binding is effected by calling

        void BindRenderbuffer( enum target, uint renderbuffer );

    with <target> set to RENDERBUFFER and <renderbuffer> set to the
    unused name.  If <renderbuffer> is not zero, then the resulting
    renderbuffer object is a new state vector, initialized with a
    zero-sized memory buffer, and comprising the state values listed in
    Table 8.nnn.  Any previous binding to <target> is broken.

    BindRenderbuffer may also be used to bind an existing
    renderbuffer object.  If the bind is successful, no change is made
    to the state of the newly bound renderbuffer object, and any
    previous binding to <target> is broken.

    While a renderbuffer object is bound, GL operations on the target to
    which it is bound affect the bound renderbuffer object, and queries
    of the target to which a renderbuffer object is bound return state
    from the bound object.

    The name zero is reserved.  A renderbuffer object cannot be created
    with the name zero.  If <renderbuffer> is zero, then any previous
    binding to <target> is broken and the <target> binding is restored
    to the initial state.

    In the initial state, the reserved name zero is bound to
    RENDERBUFFER.  There is no renderbuffer object corresponding to
    the name zero, so client attempts to modify or query renderbuffer
    state for the target RENDERBUFFER while zero is bound will
    generate GL errors, as described in section 6.1.3.

    The current RENDERBUFFER binding can be determined by calling
    GetIntegerv with the symbolic constant RENDERBUFFER_BINDING.

    BindRenderbuffer fails and an INVALID_OPERATION error is generated
    if <renderbuffer> is not a name returned from a previous call to
    GenRenderbuffers, or if such a name has since been deleted with
    DeleteRenderbuffers.

    Renderbuffer objects are deleted by calling

        void DeleteRenderbuffers( sizei n, const uint *renderbuffers );

    where <renderbuffers> contains <n> names of renderbuffer objects to be
    deleted.  After a renderbuffer object is deleted, it has no
    contents, and its name is again unused.  If a renderbuffer that is
    currently bound to RENDERBUFFER is deleted, it is as though
    BindRenderbuffer had been executed with the <target>
    RENDERBUFFER and <name> of zero.  Additionally, special care
    must be taken when deleting a renderbuffer if the image of the
    renderbuffer is attached to a framebuffer object (see section
    4.4.2.2 for details).  Unused names in <renderbuffers> are silently
    ignored, as is the value zero.

    The command

        void GenRenderbuffers( sizei n, uint *renderbuffers );

    returns <n> previously unused renderbuffer object names in
    <renderbuffers>.  These names are marked as used, for the purposes
    of GenRenderbuffers only, but they acquire renderbuffer state
    only when they are first bound, just as if they were unused.

    The command

        void RenderbufferStorageMultisample(enum target, sizei samples,
                                               enum internalformat,
                                               sizei width, sizei height);

    establishes the data storage, format, dimensions, and number of
    samples of a renderbuffer object's image.  <target> must be
    RENDERBUFFER.  <internalformat> must be color-renderable, depth-
    renderable, or stencil-renderable (as defined in section 4.4.4).
    <width> and <height> are the dimensions in pixels of the renderbuffer.
    If either <width> or <height> is greater than MAX_RENDERBUFFER_SIZE,
    or if <samples> is greater than MAX_SAMPLES,
    then the error INVALID_VALUE is
    generated. If the GL is unable to create a data store of the
    requested size, the error OUT_OF_MEMORY is generated.

    Upon success, RenderbufferStorageMultisample deletes any existing
    data store for the renderbuffer image and the contents of the data
    store after calling RenderbufferStorageMultisample are undefined.
    RENDERBUFFER_WIDTH is set to <width>, RENDERBUFFER_HEIGHT is
    set to <height>, and RENDERBUFFER_INTERNAL_FORMAT is set to
    <internalformat>.

    If <samples> is zero, then RENDERBUFFER_SAMPLES is set to zero.
    Otherwise <samples> represents a request for a desired minimum
    number of samples. Since different implementations may support
    different sample counts for multisampled rendering, the actual
    number of samples allocated for the renderbuffer image is
    implementation dependent.  However, the resulting value for
    RENDERBUFFER_SAMPLES is guaranteed to be greater than or equal
    to <samples> and no more than the next larger sample count supported
    by the implementation.

    Sized                 Base               S
    Internal Format       Internal format    Bits
    ---------------       ---------------    ----
    STENCIL_INDEX1        STENCIL_INDEX      1
    STENCIL_INDEX4        STENCIL_INDEX      4
    STENCIL_INDEX8        STENCIL_INDEX      8
    STENCIL_INDEX16       STENCIL_INDEX      16
    ----------------------------------------------------------------
    Table 2.nnn Desired component resolution for each sized internal
    format that can be used only with renderbuffers.

    A GL implementation may vary its allocation of internal component
    resolution based on any RenderbufferStorage parameter (except
    target), but the allocation and chosen internal format must not be a
    function of any other state and cannot be changed once they are
    established.

    The command

        void RenderbufferStorage(enum target, enum internalformat,
                                    sizei width, sizei height);

     is equivalent to calling RenderbufferStorageMultisample with
     <samples> equal to zero."

    4.4.2.2 Attaching Renderbuffer Images to a Framebuffer

    A renderbuffer can be attached as one of the logical buffers of the
    currently bound framebuffer object by calling

        void FramebufferRenderbuffer(enum target,
                                        enum attachment,
                                        enum renderbuffertarget,
                                        uint renderbuffer);

    <target> must be DRAW_FRAMEBUFFER, READ_FRAMEBUFFER, or
    FRAMEBUFFER. FRAMEBUFFER is equivalent to
    DRAW_FRAMEBUFFER.
    An INVALID_OPERATION error is generated if the value of the
    corresponding binding is zero. <attachment> should be set to
    one of the attachment points of the framebuffer listed in table
    1.nnn.  <renderbuffertarget> must be RENDERBUFFER and
    <renderbuffer> should be set to the name of the renderbuffer object
    to be attached to the framebuffer.  <renderbuffer> must be either
    zero or the name of an existing renderbuffer object of type
    <renderbuffertarget>, otherwise an INVALID_OPERATION error is
    generated. If <renderbuffer> is zero, then the value of
    <renderbuffertarget> is ignored.

    If <renderbuffer> is not zero and if FramebufferRenderbuffer is
    successful, then the renderbuffer named <renderbuffer> will be used
    as the logical buffer identified by <attachment> of the framebuffer
    currently bound to <target>.  The value of
    FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE for the specified attachment
    point is set to RENDERBUFFER and the value of
    FRAMEBUFFER_ATTACHMENT_OBJECT_NAME is set to <renderbuffer>. All
    other state values of the attachment point specified by <attachment>
    are set to their default values listed in table 5.nnn. No change is
    made to the state of the renderbuffer object and any previous
    attachment to the <attachment> logical buffer of the framebuffer
    object bound to framebuffer <target> is broken.  If
    the attachment is not successful, then no change is made to
    the state of either the renderbuffer object or the framebuffer
    object.

    Calling FramebufferRenderbuffer with the <renderbuffer> name zero
    will detach the image, if any, identified by <attachment>, in the
    framebuffer currently bound to <target>.  All state values of the
    attachment point specified by <attachment> in the object bound to
    <target> are set to their default values listed in table 5.nnn.

    Setting <attachment> to the value DEPTH_STENCIL_ATTACHMENT is a
    special case causing both the depth and stencil attachments of the
    framebuffer object to be set to <renderbuffer>, which should have
    base internal format DEPTH_STENCIL.

    If a renderbuffer object is deleted while its image is attached to
    one or more attachment points in the currently bound framebuffer,
    then it is as if FramebufferRenderbuffer had been called, with
    a <renderbuffer> of 0, for each attachment point to which this image
    was attached in the currently bound framebuffer.  In other words,
    this renderbuffer image is first detached from all attachment points
    in the currently bound framebuffer.  Note that the renderbuffer
    image is specifically *not* detached from any non-bound
    framebuffers.  Detaching the image from any non-bound framebuffers
    is the responsibility of the application.

        Name of attachment
        -----------------------------------------------------
        COLOR_ATTACHMENTi (see caption)
        DEPTH_ATTACHMENT
        STENCIL_ATTACHMENT
        DEPTH_STENCIL_ATTACHMENT
        -----------------------------------------------------
        Table 1.nnn: Framebuffer attachment points. <i> in
        COLOR_ATTACHMENTi may range from zero to the value of
         MAX_COLOR_ATTACHMENTS - 1.

    4.4.2.3 Attaching Texture Images to a Framebuffer

    GL supports copying the rendered contents of the framebuffer into
    the images of a texture object through the use of the routines
    CopyTexImage{1D|2D}, and CopyTexSubImage{1D|2D|3D}.  Additionally,
    GL supports rendering directly into the images of a texture object.

    To render directly into a texture image, a specified image from a
    texture object can be attached as one of the logical buffers of the
    currently bound framebuffer object by calling one of the following
    routines, depending on the type of the texture:

        void FramebufferTexture1D(enum target, enum attachment,
                                     enum textarget, uint texture,
                                     int level);
        void FramebufferTexture2D(enum target, enum attachment,
                                     enum textarget, uint texture,
                                     int level);
        void FramebufferTexture3D(enum target, enum attachment,
                                     enum textarget, uint texture,
                                     int level, int layer);

    In all three routines, <target> must be DRAW_FRAMEBUFFER,
    READ_FRAMEBUFFER or FRAMEBUFFER. FRAMEBUFFER is
    equivalent to DRAW_FRAMEBUFFER.
    An INVALID_OPERATION error is generated if the
    value of the corresponding binding is zero.
    <attachment> must be one of the attachment points of the
    framebuffer listed in table 1.nnn.

    If <texture> is zero, the image identified by <attachment>, if
    any, will be detached from the framebuffer currently bound to
    <target>. <textarget>, <level>, and <layer> are ignored. All
    state values of the attachment point specified by <attachment> are
    set to their default values listed in table 5.nnn.

    If <texture> is not zero, then <texture> must either name an existing
    texture object with a target of <textarget>, or <texture> must name an
    existing cube map texture and <textarget> must be one of
    TEXTURE_CUBE_MAP_POSITIVE_X, TEXTURE_CUBE_MAP_POSITIVE_Y,
    TEXTURE_CUBE_MAP_POSITIVE_Z, TEXTURE_CUBE_MAP_NEGATIVE_X,
    TEXTURE_CUBE_MAP_NEGATIVE_Y, or TEXTURE_CUBE_MAP_NEGATIVE_Z. Otherwise,
    an INVALID_OPERATION error is generated.

    <level> specifies the mipmap level of the texture image to be
    attached to the framebuffer.

    If <textarget> is TEXTURE_RECTANGLE_ARB, then <level> must be zero.
    If <textarget> is TEXTURE_3D, then <level> must be greater than or
    equal to zero and less than or equal to log base 2 of the value of
    MAX_3D_TEXTURE_SIZE.  If <textarget> is one of
    TEXTURE_CUBE_MAP_POSITIVE_X, TEXTURE_CUBE_MAP_POSITIVE_Y,
    TEXTURE_CUBE_MAP_POSITIVE_Z, TEXTURE_CUBE_MAP_NEGATIVE_X,
    TEXTURE_CUBE_MAP_NEGATIVE_Y, or TEXTURE_CUBE_MAP_NEGATIVE_Z, then
    <level> must be greater than or equal to zero and less than or equal
    to log base 2 of the value of MAX_CUBE_MAP_TEXTURE_SIZE. For all other
    values of <textarget>, <level> must be greater than or equal to zero and
    no larger than log base 2 of the value of MAX_TEXTURE_SIZE. Otherwise,
    an INVALID_VALUE error is generated.

    <layer> specifies the layer of a 2-dimensional image within a
    3-dimensional texture. An INVALID_VALUE error is generated if
    <layer> is larger than the value of MAX_3D_TEXTURE_SIZE-1.

    For FramebufferTexture1D, if <texture> is not zero, then
    <textarget> must be TEXTURE_1D.

    For FramebufferTexture2D, if <texture> is not zero, then
    <textarget> must be one of TEXTURE_2D, TEXTURE_RECTANGLE_ARB,
    TEXTURE_CUBE_MAP_POSITIVE_X, TEXTURE_CUBE_MAP_POSITIVE_Y,
    TEXTURE_CUBE_MAP_POSITIVE_Z, TEXTURE_CUBE_MAP_NEGATIVE_X,
    TEXTURE_CUBE_MAP_NEGATIVE_Y, or TEXTURE_CUBE_MAP_NEGATIVE_Z.

    For FramebufferTexture3D, if <texture> is not zero, then
    <textarget> must be TEXTURE_3D.

    If <texture> is not zero, and if FramebufferTexture{1D|2D|3D} is
    successful, then the specified texture image will be used as the
    logical buffer identified by <attachment> of the framebuffer
    currently bound to <target>.  The value of
    FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE for the specified attachment
    point is set to TEXTURE and the value of
    FRAMEBUFFER_ATTACHMENT_OBJECT_NAME is set to <texture>.
    Additionally, the value of FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL for
    the named attachment point is set to <level>.  If <texture> is a
    cube map texture, then the value of
    FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE the named attachment
    point is set to <textarget>.  If <texture> is a 3D texture, then the
    value of FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER for the named
    attachment point is set to <layer>.  All other state values of the
    attachment point specified by <attachment> are set to their default
    values listed in table 5.nnn.  No change is made to the state of the
    texture object, and any previous attachment to the <attachment>
    logical buffer of the framebuffer object bound to framebuffer
    <target> is broken.  If the attachment is not
    successful, then no change is made to the state of either the
    texture object or the framebuffer object.

    Setting <attachment> to the value DEPTH_STENCIL_ATTACHMENT is a
    special case causing both the depth and stencil attachments of the
    framebuffer object to be set to <texture>. <texture> must have base
    internal format DEPTH_STENCIL, or the depth and stencil
    framebuffer attachments will be incomplete (see section 4.4.4.1).

    The command

    void FramebufferTextureLayer(enum target,enum attachment,
                                    uint texture,int level,int layer);

    operates identically to FramebufferTexture3D, except that it
    attaches a single layer of a three-dimensional texture, or one- or
    two-dimensional array texture. <layer> is an integer indicating the
    layer number, and is treated identically to the <layer> parameter in
    FramebufferTexture3D. The error INVALID_VALUE is generated if
    <layer> is negative. The error INVALID_OPERATION is generated if
    <texture> is non-zero and is not the name of a three dimensional
    texture, or one- or two-dimensional array texture.

    Unlike FramebufferTexture3D, no <textarget> parameter is accepted.

    If <texture> is non-zero and the command does not result in an
    error, the framebuffer attachment state corresponding to
    <attachment> is updated as in the other FramebufferTexture commands,
    except that FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER is set to
    <layer>.

    If a texture object is deleted while its image is attached to one or
    more attachment points in the currently bound framebuffer, then it
    is as if FramebufferTexture* had been called, with a <texture> of
    zero, for each attachment point to which this image was attached in
    the currently bound framebuffer. In other words, this texture image
    is first detached from all attachment points in the currently bound
    framebuffer. Note that the texture image is specifically *not*
    detached from any other framebuffer objects. Detaching the texture
    image from any other framebuffer objects is the responsibility of
    the application.

    4.4.3  Rendering When an Image of a Bound Texture Object is Also
    Attached to the Framebuffer

    The mechanisms for attaching textures to a framebuffer object do not
    prevent a one- or two-dimensional texture level, a face of a cube
    map texture level, or a layer of a two-dimensional array or
    three-dimensional texture from being attached to the draw
    framebuffer while the same texture is bound to a texture unit. While
    any of these conditions hold, texturing operations accessing that
    image will produce undefined results, as described at the end of
    section 3.8.8. Conditions resulting in such undefined behavior are
    defined in more detail below. Such undefined texturing operations
    are likely to leave the final results of the shader or
    fixed-function fragment processing operations undefined, and should
    be avoided.

    Special precautions need to be taken to avoid attaching a texture
    image to the currently bound framebuffer while the texture object is
    currently bound and enabled for texturing.  Doing so could lead to
    the creation of a <feedback loop> between the writing of pixels by
    the GL's rendering operations and the simultaneous reading of those
    same pixels when used as texels in the currently bound texture.  In
    this scenario, the framebuffer will be considered framebuffer
    complete (see section 4.4.4), but the values of fragments rendered
    while in this state will be undefined.  The values of texture
    samples may be undefined as well, as described at the end of the
    "Scale Factor and Level of Detail" subsection of section 3.8.8.

    Specifically, the values of rendered fragments are undefined if all
    of the following conditions are true:

        - an image from texture object <T> is attached to the currently
          bound framebuffer at attachment point <A>, and

        - the texture object <T> is currently bound to a texture unit
          <U>, and

        - the current fixed-function texture state or programmable
          vertex and/or fragment processing state makes it possible(*)
          to sample from the texture object <T> bound to texture unit
          <U>

    while either of the following conditions are true:

        - the value of TEXTURE MIN FILTER for texture object <T> is
          NEAREST or LINEAR, and the value of
          FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL for attachment point
          <A> is equal to the value of TEXTURE_BASE_LEVEL for the
          texture object <T>, or

        - the value of TEXTURE_MIN_FILTER for texture object <T> is one
          of NEAREST_MIPMAP_NEAREST, NEAREST_MIPMAP LINEAR, LINEAR
          MIPMAP_NEAREST, or LINEAR_MIPMAP_LINEAR, and the value of
          FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL for attachment point
          <A> is within the range specified by the current values of
          TEXTURE_BASE_LEVEL to q, inclusive, for the texture object
          <T>.  (q is defined in the Mipmapping discussion of section
          3.8.8),

    (*) For the purpose of this discussion, it is <possible>
        to sample from the texture object <T> bound to texture unit <U>
        if any of the following are true:

        - Programmable vertex and fragment processing is disabled
          and the target of texture object <T> is enabled according
          to the texture target precedence rules of section 3.8.15
        - FRAGMENT_PROGRAM_ARB is enabled and the currently bound
          fragment program contains any instructions that
          sample from the texture object <T> bound to <U>
        - The active fragment or vertex shader contains any instructions
          that might sample from the texture object <T> bound to <U> if even
          those instructions might only be executed conditionally.

    Note that if TEXTURE_BASE_LEVEL and TEXTURE_MAX_LEVEL exclude any
    levels containing image(s) attached to the currently bound
    framebuffer, then the above conditions will not be met, (i.e., the
    above rule will not cause the values of rendered fragments to be
    undefined.)

    4.4.4 Framebuffer Completeness

    A framebuffer must be <framebuffer complete> to effectively be used
    as the draw or read framebuffer of the GL.

    The default framebuffer is always complete if it exists; however, if no
    default framebuffer exists (no window system-provided drawable is
    associated with the GL context), it is deemed to be incomplete.

    A framebuffer object is said to be framebuffer complete if all of
    its attached images, and all framebuffer parameters required to
    utilize the framebuffer for rendering and reading, are consistently
    defined and meet the requirements defined below.  The rules of
    framebuffer completeness are dependent on the properties of the
    attached images, and on certain implementation dependent
    restrictions.

    The internal formats of the attached images can affect the
    completeness of the framebuffer, so it is useful to first define the
    relationship between the internal format of an image and the
    attachment points to which it can be attached.

        * The following base internal formats from table 3.15 are
          <color-renderable>: ALPHA, LUMINANCE, LUMINANCE_ALPHA,
          INTENSITY, RED, RG, RGB, RGBA, FLOAT_R_NV, FLOAT_RG_NV,
          FLOAT_RGB_NV, and FLOAT_RGBA_NV. The sized
          internal formats from table 3.16 that have a color-renderable
          base internal format are also color-renderable. No other
          formats, including compressed internal formats, are
          color-renderable.

        * An internal format is <depth-renderable> if it is
          DEPTH_COMPONENT or one of the formats from table 3.16 whose
          base internal format is DEPTH_COMPONENT or DEPTH_STENCIL.
          No other formats are depth-renderable.

        * An internal format is <stencil-renderable> if it is
          STENCIL_INDEX or DEPTH_STENCIL, if it is one of the
          STENCIL_INDEX formats from table 2.nnn, or if it is one of the
          formats from table 3.16 whose base internal format is
          DEPTH_STENCIL.  No other formats are stencil-renderable."

    4.4.4.1 Framebuffer Attachment Completeness

    If the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE for the
    framebuffer attachment point <attachment> is not NONE, then it is
    said that a framebuffer-attachable image, named <image>, is attached
    to the framebuffer at the attachment point.  <image> is identified
    by the state in <attachment> as described in section 4.4.2.

    The framebuffer attachment point <attachment> is said to be
    <framebuffer attachment complete> if the value of
    FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE for <attachment> is NONE
    (i.e., no image is attached), or if all of the following conditions
    are true:

      * <image> is a component of an existing object with the name
        specified by FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, and of the
        type specified by FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE.

      * The width and height of <image> must be non-zero.

      * If FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE is TEXTURE and
        FRAMEBUFFER_ATTACHMENT_OBJECT_NAME names a 3-dimensional
        texture, then FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER must be
        smaller than the depth of the texture.

      * If <attachment> is COLOR_ATTACHMENTi, then <image> must have
        a color-renderable internal format.

      * If <attachment> is DEPTH_ATTACHMENT, then <image> must have
        a depth-renderable internal format.

      * If <attachment> is STENCIL_ATTACHMENT, then <image> must
        have a stencil-renderable internal format.

    4.4.4.2 Whole Framebuffer Completeness

    Each rule below is followed by an error enum enclosed in { brackets }.
    The meaning of these errors is explained below and under ``Effects of
    Framebuffer Completeness on Framebuffer Operations'' later in section
    4.4.4.

    The framebuffer object <target> is said to be "framebuffer complete" if
    all the following conditions are true:

      * <target> is the default framebuffer, and the default framebuffer
        exists.
        { FRAMEBUFFER_UNDEFINED }

      * All framebuffer attachment points are framebuffer attachment
        complete.
        { FRAMEBUFFER_INCOMPLETE_ATTACHMENT }

      * There is at least one image attached to the framebuffer.
        { FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT }

      * The value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE must not be
        NONE for any color attachment point(s) named by DRAW_BUFFERi.
        { FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER }

      * If READ_BUFFER is not NONE, then the value of
        FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE must not be NONE for the
        color attachment point named by READ_BUFFER.
        { FRAMEBUFFER_INCOMPLETE_READ_BUFFER }

      * The combination of internal formats of the attached
        images does not violate an implementation-dependent set of
        restrictions.
        { FRAMEBUFFER_UNSUPPORTED }

      * The value of RENDERBUFFER_SAMPLES is the same for all attached
        images.
        { FRAMEBUFFER_INCOMPLETE_MULTISAMPLE }


    The token in { brackets } after each clause of the framebuffer
    completeness rules specifies the return value of
    CheckFramebufferStatus (see below) that is generated when that
    clause is violated.  If more than one clause is violated, it is
    implementation-dependent exactly which value will be returned by
    CheckFramebufferStatus.

    Performing any of the following actions may change whether the
    framebuffer is considered complete or incomplete.

      - Binding to a different framebuffer with BindFramebuffer.

      - Attaching an image to the framebuffer with
        FramebufferTexture{1D|2D|3D} or FramebufferRenderbuffer.

      - Detaching an image from the framebuffer with
        FramebufferTexture{1D|2D|3D} or FramebufferRenderbuffer.

      - Changing the internal format of a texture image that is attached
        to the framebuffer by calling {Copy|Compressed}TexImage{1D|2D|3D}.

      - Changing the internal format of a renderbuffer that is attached
        to the framebuffer by calling RenderbufferStorage.

      - Deleting, with DeleteTextures or DeleteRenderbuffers, an object
        containing an image that is attached to a framebuffer object
        that is bound to the framebuffer.

      - Changing READ_BUFFER or one of the DRAW_BUFFERS.

      - Associating a different window system-provided drawable, or no
        drawable, with the default framebuffer using a window system binding
        API such as GLX, WGL, CGL, or EGL.

    Although GL defines a wide variety of internal formats for
    framebuffer-attachable images, such as texture images and
    renderbuffer images, some implementations may not support rendering
    to particular combinations of internal formats.  If the combination
    of formats of the images attached to a framebuffer object are not
    supported by the implementation, then the framebuffer is not
    complete under the clause labeled FRAMEBUFFER_UNSUPPORTED. There
    must exist, however, at least one combination of internal formats
    for which the framebuffer cannot be FRAMEBUFFER_UNSUPPORTED.

    Because of the <implementation-dependent> clause of the framebuffer
    completeness test in particular, and because framebuffer
    completeness can change when the set of attached images is modified,
    it is strongly advised, though is not required, that an application
    check to see if the framebuffer is complete prior to rendering.  The
    status of the framebuffer object currently bound to <target> can be
    queried by calling

        enum CheckFramebufferStatus(enum target);

    <target> must be DRAW_FRAMEBUFFER, READ_FRAMEBUFFER or
    FRAMEBUFFER. FRAMEBUFFER is equivalent to DRAW_FRAMEBUFFER.
    If CheckFramebufferStatus is called within a Begin/End pair,
    an INVALID_OPERATION error is generated. If
    CheckFramebufferStatus generates an error, 0 is returned.

    Otherwise, an enum is returned that identifies whether
    or not the framebuffer bound to <target> is complete, and if not
    complete the enum identifies one of the rules of framebuffer
    completeness that is violated.  If the framebuffer is complete, then
    FRAMEBUFFER_COMPLETE is returned.

    The values of SAMPLE_BUFFERS and SAMPLES are derived from the
    attachments of the currently bound framebuffer object.  If the
    current DRAW_FRAMEBUFFER_BINDING is not framebuffer complete,
    then both SAMPLE_BUFFERS and SAMPLES are undefined.  Otherwise,
    SAMPLES is equal to the value of RENDERBUFFER_SAMPLES for the
    attached images (which all must have the same value for
    RENDERBUFFER_SAMPLES).  Further, SAMPLE_BUFFERS is one if
    SAMPLES is non-zero.  Otherwise, SAMPLE_BUFFERS is zero.

    4.4.4.3 Effects of Framebuffer Completeness on Framebuffer Operations

    Attempting to render to or read from a framebuffer which is not
    framebuffer complete will generate an INVALID_FRAMEBUFFER_OPERATION
    error.  This means that rendering commands such as Begin,
    RasterPos, any command that performs an implicit Begin, as well as
    commands that read the framebuffer such as ReadPixels and
    CopyTex{Sub}Image will generate the error
    INVALID_FRAMEBUFFER_OPERATION if called while the framebuffer is
    not framebuffer complete.

    4.4.5 Effects of Framebuffer State on Framebuffer Dependent Values

    The values of the state variables listed in table 9.nnn (Framebuffer
    Dependent Values) may change when a change is made to
    DRAW_FRAMEBUFFER_BINDING, to the state of the currently bound
    framebuffer object, or to an image attached to the currently bound
    framebuffer object.

    When DRAW_FRAMEBUFFER_BINDING is zero, the values of the state
    variables listed in table 9.nnn are implementation defined.

    When DRAW_FRAMEBUFFER_BINDING is non-zero, if the currently bound
    framebuffer object is not framebuffer complete, then the values of
    the state variables listed in table 9.nnn are undefined.

    When DRAW_FRAMEBUFFER_BINDING is non-zero and the currently bound
    framebuffer object is framebuffer complete, then the values of the
    state variables listed in table 9.nnn are completely determined by
    DRAW_FRAMEBUFFER_BINDING, the state of the currently bound
    framebuffer object, and the state of the images attached to the
    currently bound framebuffer object.
    The values of RED_BITS, GREEN_BITS, BLUE_BITS, and ALPHA_BITS are
    defined only if all color attachments of the draw framebuffer have
    identical formats, in which case the color component depths of color
    attachment zero are returned. The values returned for DEPTH_BITS and
    STENCIL_BITS are the depth or stencil component depth of the
    corresponding attachment of the draw framebuffer, respectively. The
    actual sizes of the color, depth, or stencil bit planes can be
    obtained by querying an attachment point using
    GetFramebufferAttachmentParameteriv,
    or querying the object attached at that point.  If the value of
    FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE at a particular attachment
    point is RENDERBUFFER, the sizes may be determined by calling
    GetRenderbufferParameteriv as described in section 6.1.3. If
    the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE at a particular
    attachment point is TEXTURE, the sizes may be determined by calling
    GetTexParameter, as described in section 6.1.3.


    4.4.6 Mapping between Pixel and Element in Attached Image

    When DRAW_FRAMEBUFFER_BINDING is non-zero, an operation that writes
    to the framebuffer modifies the image attached to the selected
    logical buffer, and an operation that reads from the framebuffer
    reads from the image attached to the selected logical buffer.

    If the attached image is a renderbuffer image, then the window
    coordinates (x[w], y[w]) corresponds to the value in the
    renderbuffer image at the same coordinates.

    If the attached image is a texture image, then the window
    coordinates (x[w], y[w]) correspond to the texel (i, j, k), from
    figure 3.10 as follows:

                           i = (x[w] - b)

                           j = (y[w] - b)

                           k = (layer - b)

    where <b> is the texture image's border width, and <layer> is the
    value of FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER for the selected
    logical buffer.  For a two-dimensional texture, <k> and <layer> are
    irrelevant; for a one-dimensional texture, <j>, <k>, and <layer> are
    both irrelevant.

    (x[w], y[w]) corresponds to a border texel if x[w], y[w], or
    <layer> is less than the border width, or if x[w], y[w], or <layer>
    is greater than or equal to the border width plus the width or height or
    depth, respectively, of the texture image.

    Conversion to Framebuffer-Attachable Image Components

    When an enabled color value is written to the framebuffer while the
    draw framebuffer binding is non-zero, for each draw buffer the R, G, B,
    and A values are converted to internal components as described in
    table 3.15, according to the table row corresponding to the internal
    format of the framebuffer-attachable image attached to the selected
    logical buffer, and the resulting internal components are written to
    the image attached to logical buffer.  The masking operations
    described in section 4.2.2 are also effective.

    Conversion to RGBA Values

    When a color value is read or is used as the source of a logical
    operation or blending while the read framebuffer binding is non-zero,
    the components of the framebuffer-attachable image that is attached to
    the logical buffer selected by READ_BUFFER are first converted to R, G,
    B, and A values according to table 3.21 and the internal format of the
    attached image."


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

    Added to section 5.4, as part of the discussion of which commands
    are not compiled into display lists:

    "Certain commands, when called while compiling a display list, are
    not compiled into the display list but are executed immediately.
    These are: ..., GenFramebuffers, BindFramebuffer,
    DeleteFramebuffers, CheckFramebufferStatus,
    GenRenderbuffers, BindRenderbuffer, DeleteRenderbuffers,
    RenderbufferStorage, RenderbufferStorageMultisample,
    FramebufferTexture1D, FramebufferTexture2D,
    FramebufferTexture3D, FramebufferRenderbuffer, BlitFramebuffer,
    GenerateMipmap..."


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

    In section 6.1.3 "Enumerated Queries", modify the seventh paragraph
    to say:

    "For texture images with uncompressed internal formats, queries of
    <value> of TEXTURE_RED_SIZE, TEXTURE_GREEN_SIZE, TEXTURE_BLUE_SIZE,
    TEXTURE_ALPHA_SIZE, TEXTURE_LUMINANCE_SIZE, TEXTURE_INTENSITY_SIZE,
    TEXTURE_DEPTH_SIZE, and TEXTURE_STENCIL_SIZE return the actual
    resolutions of the stored image array components..."

    Section 6.1.4 "Texture Queries", in the second paragraph, replace
    the first second and third sentences as follows:

        "Calling GetTexImage with a color format (one of RED, GREEN,
        BLUE, ALPHA, RGB, BGR, RGBA, BGRA, LUMINANCE, or
        LUMINANCE_ALPHA) when the internal format of the texture image
        is not a color format causes the error INVALID_OPERATION.

        Calling GetTexImage with a <format> of DEPTH_COMPONENT when the
        base internal format of the texture image is not DEPTH_COMPONENT
        or DEPTH_STENCIL causes the error INVALID_OPERATION.

        Calling GetTexImage with a <format> of DEPTH_STENCIL when
        the base internal format of the texture image is not
        DEPTH_STENCIL causes the error INVALID_OPERATION.

        GetTexImage obtains component groups from a texture image with
        the indicated level-of-detail.  If <format> is a color format,
        then the components are assigned among R, G, B, and A according
        to Table 6.1, starting with the first group in the first row,
        and continuing by obtaining groups in order from each row and
        proceeding from the first row to the last, and from the first
        image to the last for three-dimensional textures.  If <format>
        is DEPTH_COMPONENT, then each depth component is assigned with
        the same ordering of rows and images.  If <format> is
        DEPTH_STENCIL, then each depth component and each stencil
        index is assigned with the same ordering of rows and images."

    After section 6.1.14 and before section 6.1.15 (which should be
    renumbered 6.1.17), add two new sections:

   "6.1.15 Framebuffer Object Queries

        The command

            boolean IsFramebuffer( uint framebuffer );

        returns TRUE if <framebuffer> is the name of a framebuffer
        object.  If <framebuffer> is zero, or if <framebuffer> is a
        non-zero value that is not the name of a framebuffer object,
        IsFramebuffer return FALSE.

        The command

        void GetFramebufferAttachmentParameteriv(enum target,
                                                 enum attachment,
                                                 enum pname,
                                                 int *params);

        returns information about attachments of a bound framebuffer object.
        <target> must be DRAW_FRAMEBUFFER, READ_FRAMEBUFFER or FRAMEBUFFER.
        FRAMEBUFFER is equivalent to DRAW_FRAMEBUFFER.

        If the default framebuffer is bound to <target>, then <attachment>
        must be one of FRONT_LEFT, FRONT_RIGHT, BACK_LEFT, BACK_RIGHT, or
        AUXi, identifying a color buffer; DEPTH, identifying the depth
        buffer; or STENCIL, identifying the stencil buffer.

        If a framebuffer object is bound to <target>, then <attachment> must
        be one of the attachment points of the framebuffer listed in table
        1.nnn.

        If <attachment> is DEPTH_STENCIL_ATTACHMENT, and different objects
        are bound to the depth and stencil attachment points of <target>,
        the query will fail and generate an INVALID_OPERATION error. If the
        same object is bound to both attachment points, information about
        that object will be returned.

        Upon successful return from GetFramebufferAttachmentParameteriv, if
        <pname> is FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, then <param> will
        contain one of NONE, FRAMEBUFFER_DEFAULT, TEXTURE, or RENDERBUFFER,
        identifying the type of object which contains the attached image.
        Other values accepted for <pname> depend on the type of object, as
        described below.

        If the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE is
        NONE, no framebuffer is bound to <target>. In this case
        querying <pname> FRAMEBUFFER_ATTACHMENT_OBJECT_NAME
        will return zero, and all other queries will generate an
        INVALID_OPERATION error.

        If the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE is not
        NONE, these queries apply to all other framebuffer types:

          * If <pname> is FRAMEBUFFER_ATTACHMENT_RED_SIZE,
            FRAMEBUFFER_ATTACHMENT_GREEN_SIZE,
            FRAMEBUFFER_ATTACHMENT_BLUE_SIZE,
            FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE,
            FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, or
            FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, then <param> will contain
            the number of bits in the corresponding red, green, blue, alpha,
            depth, or stencil component of the specified <attachment>. Zero
            is returned if the requested component is not present in
            <attachment>.

          * If <pname> is FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE, <param>
            will contain the format of components of the specified
            attachment, one of FLOAT, INT, UNSIGNED_INT, UNSIGNED_NORMALIZED
            or INDEX for floating-point, signed integer, unsigned integer,
            unsigned fixed-point, or index components respectively. Only
            color buffers may have index or integer components.

          * If <pname> is FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING, <param>
            will contain the encoding of components of the specified
            attachment, one of LINEAR or SRGB for linear or sRGB-encoded
            components, respectively. Only color buffer components may be
            sRGB-encoded; such components are treated as described in
            sections 4.1.8 "Blending" and 4.1.X "sRGB Conversion" (as
            modified by ARB_framebuffer_sRGB). For the default framebuffer,
            color encoding is determined by the implementation. For
            framebuffer objects, components are sRGB-encoded if the internal
            format of a color attachment is one of the color-renderable SRGB
            formats described in section 3.8.15 "sRGB Texture Color
            Conversion".

        If the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE is RENDERBUFFER,
        then

          * If <pname> is FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, <params> will
            contain the name of the renderbuffer object which contains the
            attached image.

        If the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE is TEXTURE, then

          * If <pname> is FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, then <params>
            will contain the name of the texture object which contains the
            attached image.

          * If <pname> is FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, then
            <params> will contain the mipmap level of the texture object
            which contains the attached image.

          * If <pname> is FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE and
            the texture object named FRAMEBUFFER_ATTACHMENT_OBJECT_NAME is a
            cube map texture, then <params> will contain the cube map face
            of the cubemap texture object which contains the attached image.
            Otherwise <params> will contain the value zero.

          * If <pname> is FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER and the
            texture object named FRAMEBUFFER_ATTACHMENT_OBJECT_NAME is a
            three-dimensional texture, then <params> will contain the layer
            of the 2D image of the 3D texture object which contains the
            attached image. Otherwise <params> will contain the value zero.

        Any combinations of framebuffer type and <pname> not described above
        will generate an INVALID_ENUM error."


    6.1.16 Renderbuffer Object Queries

       "The command

            boolean IsRenderbuffer( uint renderbuffer );

        returns TRUE if <renderbuffer> is the name of a renderbuffer
        object.  If <renderbuffer> is zero, or if <renderbuffer> is a
        non-zero value that is not the name of a renderbuffer object,
        IsRenderbuffer return FALSE.

        The command

        void GetRenderbufferParameteriv(enum target, enum pname,
                                        int* params);

        returns information about a bound renderbuffer object. <target> must
        be RENDERBUFFER and <pname> must be one of the symbolic values in
        table 8.nnn. If the renderbuffer currently bound to <target> is
        zero, then an INVALID_OPERATION error is generated.

        Upon successful return from GetRenderbufferParameteriv, if <pname>
        is RENDERBUFFER_WIDTH, RENDERBUFFER_HEIGHT,
        RENDERBUFFER_INTERNAL_FORMAT, or RENDERBUFFER_SAMPLES, then <params>
        will contain the width in pixels, height in pixels, internal format,
        or number of samples, respectively, of the image of the renderbuffer
        currently bound to <target>.

        If <pname> is RENDERBUFFER_RED_SIZE, RENDERBUFFER_GREEN_SIZE,
        RENDERBUFFER_BLUE_SIZE, RENDERBUFFER_ALPHA_SIZE,
        RENDERBUFFER_DEPTH_SIZE, or RENDERBUFFER_STENCIL_SIZE, then <params>
        will contain the actual resolutions, (not the resolutions specified
        when the image array was defined), for the red, green, blue, alpha
        depth, or stencil components, respectively, of the image of the
        renderbuffer currently bound to <target>.

        Otherwise, an INVALID_ENUM error is generated."

    In section 6.2 "State Tables", add a row to table 6.18 "Textures
    (state per texture image)":

      Get value             Type    Get Cmd               IV  Description                           Sec.
      ------------------    ------  --------------------  --- ----------------------------------  -----
      ...                   ...     ...                   ... ...                                   ...
      TEXTURE_STENCIL_SIZE  n x Z+  GetTexLevelParameter  0   texture image's stencil resolution  3.8.3


Errors

    The error INVALID_OPERATION is generated if DRAW_FRAMEBUFFER_BINDING
    is zero and DrawBuffer or DrawBuffers is called with a <buf>
    constant (other than NONE) that does not correspond to a buffer
    allocated to the GL by the window-system, including the constants
    COLOR_ATTACHMENT0 through COLOR_ATTACHMENTn, where n is
    MAX_COLOR_ATTACHMENTS - 1.

    The error INVALID_OPERATION is generated if DRAW_FRAMEBUFFER_BINDING
    is non-zero and DrawBuffer or DrawBuffer is called
    with a <buf> constant (other than NONE) that is not in the range
    COLOR_ATTACHMENT0 through COLOR_ATTACHMENTn, where n is
    MAX_COLOR_ATTACHMENTS - 1.

    The error INVALID_OPERATION is generated if READ_FRAMEBUFFER_BINDING
    is non-zero and ReadBuffer is called
    with a <buf> constant (other than NONE) that is not in the range
    COLOR_ATTACHMENT0 through COLOR_ATTACHMENTn, where n is
    MAX_COLOR_ATTACHMENTS - 1.

    The error INVALID_ENUM is generated if DrawBuffer or ReadBuffer is
    called with a <buf> constant that is not listed in table 4.4 or
    10.nnn.

    The error INVALID_ENUM is generated if DrawBuffers is called with a
    <buf> constant that is not listed in table 10.nnn or 11.nnn.

    The error INVALID_FRAMEBUFFER_OPERATION is generated if
    BlitFramebuffer, DrawPixels, or CopyPixels is called while the
    draw framebuffer is not framebuffer complete.

    The error INVALID_FRAMEBUFFER_OPERATION is generated if
    BlitFramebuffer, ReadPixels, CopyPixels, CopyTex{Sub}Image*,
    CopyColor{Sub}Table, or CopyConvolutionFilter* is called while the
    read framebuffer is not framebuffer complete.

    The error INVALID_OPERATION is generated if
    GetFramebufferAttachmentParameteriv is called while the value of
    DRAW_FRAMEBUFFER_BINDING is zero.

    The error INVALID_OPERATION is generated if
    FramebufferRenderbuffer or FramebufferTexture{1D|2D|3D} is
    called  while the value of DRAW_FRAMEBUFFER_BINDING is zero.

    The error INVALID_OPERATION is generated if RenderbufferStorage
    or GetRenderbufferParameteriv is called while the value of
    RENDERBUFFER_BINDING is zero.

    The error INVALID_ENUM is generated if
    GetFramebufferAttachmentParameteriv is called with an
    <attachment> other than COLOR_ATTACHMENT0 through
    COLOR_ATTACHMENTn, where n is MAX_COLOR_ATTACHMENTS - 1.

    The error INVALID_ENUM is generated if
    GetFramebufferAttachmentParameteriv is called with a <pname>
    other than FRAMEBUFFER_ATTACHMENT_OBJECT_NAME when the type of
    the attached object at the named attachment point is
    RENDERBUFFER.

    The error INVALID_ENUM is generated if
    GetFramebufferAttachmentParameteriv is called with a <pname>
    other than FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,
    FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL,
    FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE, or
    FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER when the type of the
    attached object at the named attachment point is TEXTURE.

    The error INVALID_ENUM is generated if GetRenderbufferParameteriv
    is called with a <pname> other than RENDERBUFFER_WIDTH,
    RENDERBUFFER_HEIGHT, or RENDERBUFFER_INTERNAL_FORMAT,
    RENDERBUFFER_RED_SIZE, RENDERBUFFER_GREEN_SIZE,
    RENDERBUFFER_BLUE_SIZE, RENDERBUFFER_ALPHA_SIZE,
    RENDERBUFFER_DEPTH_SIZE, or RENDERBUFFER_STENCIL_SIZE.

    The error INVALID_VALUE is generated if RenderbufferStorage is
    called with a <width> or <height> that is greater than
    MAX_RENDERBUFFER_SIZE.

    The error INVALID_ENUM is generated if RenderbufferStorage is
    called with an <internalformat> that is not RGB, RGBA,
    DEPTH_COMPONENT, STENCIL_INDEX, DEPTH_STENCIL, or one of the
    internal formats from table 3.16 or table 2.nnn that has a base
    internal format of RGB, RGBA, DEPTH_COMPONENT, STENCIL_INDEX, r
    DEPTH_STENCIL.

    The error INVALID_OPERATION is generated if
    FramebufferRenderbuffer is called and <renderbuffer> is not the
    name of a renderbuffer object.

    The error INVALID_OPERATION is generated if
    FramebufferTexture{1D|2D|3D} is called and <texture> is not the
    name of a texture object.

    The error INVALID_VALUE is generated if
    FramebufferTexture{1D|2D|3D} is called with a <level> that is
    less than zero.

    The error INVALID_VALUE is generated if FramebufferTexture2D is
    called with a <level> that is not zero and <textarget> is
    TEXTURE_RECTANGLE_ARB.

    The error INVALID_VALUE is generated if FramebufferTexture{1D|2D}
    is called with a <level> that is greater than the log base 2 of
    MAX_TEXTURE_SIZE and <texture> is a 1D or 2D texture.

    The error INVALID_VALUE is generated if FramebufferTexture2D
    is called with a <level> that is greater than the log base 2 of
    MAX_CUBE_MAP_TEXTURE_SIZE and <texture> is a cubemap texture.

    The error INVALID_VALUE is generated if FramebufferTexture3D is
    called with a <level> greater than the log base 2 of the
    MAX_3D_TEXTURE_SIZE.

    The error INVALID_VALUE is generated if FramebufferTexture3D is
    called with a <layer> that is larger than MAX_3D_TEXTURE_SIZE-1.

    The error INVALID_VALUE is generated by BlitFramebuffer if
    <mask> has any bits set other than those named by
    COLOR_BUFFER_BIT, DEPTH_BUFFER_BIT or STENCIL_BUFFER_BIT.

    The error INVALID_OPERATION is generated if BlitFramebuffer is
    called and <mask> includes DEPTH_BUFFER_BIT or STENCIL_BUFFER_BIT
    and <filter> is not NEAREST.

    The error INVALID_OPERATION is generated if BlitFramebuffer is
    called and <mask> includes DEPTH_BUFFER_BIT or STENCIL_BUFFER_BIT
    and the source and destination depth or stencil buffer formats do
    not match.

    The error INVALID_ENUM is generated by BlitFramebuffer if
    <filter> is not LINEAR or NEAREST.

    The error INVALID_OPERATION is generated if BlitFramebuffer
    is called within a Begin/End pair.

    The error INVALID_ENUM is generated if BindFramebuffer,
    CheckFramebufferStatus, FramebufferTexture{1D|2D|3D},
    FramebufferRenderbuffer, or
    GetFramebufferAttachmentParameteriv is called and <target> is
    not DRAW_FRAMEBUFFER, READ_FRAMEBUFFER or FRAMEBUFFER.

    The error INVALID_OPERATION is generated if
    CheckFramebufferStatus is called within a Begin/End pair.

    The error OUT_OF_MEMORY is generated if the GL is unable to create a
    data store of the required size when calling RenderbufferStorage.

    The error INVALID_OPERATION is generated if GenerateMipmap is
    called with a <target> of TEXTURE_CUBE_MAP and the texture object
    currently bound to TEXTURE_CUBE_MAP is not "cube complete" as
    defined in section 3.8.10

    The error INVALID_OPERATION is generated if ReadPixels,
    CopyPixels, CopyTex{Sub}Image*, CopyColor{Sub}Table, or
    CopyConvolutionFilter* is called while READ_FRAMEBUFFER_BINDING
    is non-zero, the read framebuffer is framebuffer complete, and the
    value of SAMPLE_BUFFERS for the read framebuffer is greater than
    zero.

    The error OUT_OF_MEMORY is generated when
    RenderbufferStorageMultisample cannot create storage of the
    specified size.

    If both the draw and read framebuffers are framebuffer complete and
    both have a value of SAMPLE_BUFFERS that is greater than zero, then
    the error INVALID_OPERATION is generated if BlitFramebuffer is
    called and the values of SAMPLES for the draw and read framebuffers
    do not match.

    If both the draw and read framebuffers are framebuffer complete and
    either has a value of SAMPLE_BUFFERS that is greater than zero, then
    the error INVALID_OPERATION is generated if BlitFramebuffer is
    called and the formats of the draw and read framebuffers are not
    identical.

    If either the draw or read framebuffer is framebuffer complete and
    has a value of SAMPLE_BUFFERS that is greater than zero, then the
    error INVALID_OPERATION is generated if BlitFramebuffer is called
    and the specified source and destination dimensions are not
    identical.

    If RenderbufferStorageMultisample is called with a value of
    <samples> that is greater than MAX_SAMPLES, then the error
    INVALID_VALUE is generated.

    The error INVALID_ENUM is generated if DrawPixels or ReadPixels is
    called where format is DEPTH_STENCIL and type is not
    UNSIGNED_INT_24_8.

    The error INVALID_OPERATION is generated if DrawPixels or ReadPixels
    is called where type is UNSIGNED_INT_24_8 and format is not
    DEPTH_STENCIL.

    The error INVALID_OPERATION is generated if DrawPixels or ReadPixels
    is called where format is DEPTH_STENCIL and there is not both a
    depth buffer and a stencil buffer.

    The error INVALID_OPERATION is generated if CopyPixels is called
    where type is DEPTH_STENCIL and there is not both a depth buffer
    and a stencil buffer.


New State

    (add new table 3.nnn, "Framebuffer (state per framebuffer target binding point)")

    Get Value                 Type   Get Command   Initial Value    Description               Section       Attribute
    ------------------------  ----   -----------   --------------   -------------------       ------------  ---------
    DRAW_FRAMEBUFFER_BINDING   Z+    GetIntegerv   0                Framebuffer object bound  4.4.1         -
                                                                    to DRAW_FRAMEBUFFER
    READ_FRAMEBUFFER_BINDING   Z+    GetIntegerv   0                Framebuffer object        4.4.1         -
                                                                    to READ_FRAMEBUFFER

    (insert new table 4.nnn, "Framebuffer (state per framebuffer object)")

    Get Value            Type         Get Command        Initial Value  Description             Section       Attribute
    ----------------     ------       -------------      -------------  --------------------    ------------  ---------
    DRAW_BUFFERi [1]     1 + xZ(10*)  GetIntegerv        see 4.2.1      Draw buffer selected    4.2.1         color-buffer
                                                                        for color output i
    READ_BUFFER  [2]     Z(3)         GetIntegerv        see 4.3.2      Read source buffer      4.3.2         pixel

        [1] prior to this extension, the DRAW_BUFFERi state was
            described in table 6.21 "Framebuffer Control" of the OpenGL
            2.0 specification.
        [2] prior to this extension, the READ_BUFFER state was described
            in table 6.26 "Pixel" of the OpenGL 2.0 specification.



    (insert new table 5.nnn, "Framebuffer (state per framebuffer object attachment point)")

    Get Value                                     Type    Get Command                            Initial Value  Description             Section       Attribute
    --------------------------------------------  ----    -------------------------------------- -------------  --------------------    ------------  ---------
    FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE            Z       GetFramebufferAttachmentParameteriv    NONE           type of                 4.4.2.2 and   -
                                                                                                                image attached to       4.4.2.3
                                                                                                                framebuffer attachment
                                                                                                                point

    FRAMEBUFFER_ATTACHMENT_OBJECT_NAME            Z       GetFramebufferAttachmentParameteriv    0              name of object          4.4.2.2 and   -
                                                                                                                attached to             4.4.2.3
                                                                                                                framebuffer attachment
                                                                                                                point

    FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL          Z       GetFramebufferAttachmentParameteriv    0              mipmap level of         4.4.2.2 and   -
                                                                                                                texture image           4.4.2.3
                                                                                                                attached, if object
                                                                                                                attached is texture.

    FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE  Z+      GetFramebufferAttachmentParameteriv    NONE           cubemap face of         4.4.2.2 and   -
                                                                                                                texture image           4.4.2.3
                                                                                                                attached, if object
                                                                                                                attached is cubemap
                                                                                                                texture.

    FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER          Z       GetFramebufferAttachmentParameteriv    0              layer of                4.4.2.2 and   -
                                                                                                                texture image           4.4.2.3
                                                                                                                attached, if object
                                                                                                                attached is 3D texture.

    FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING         Z_2     GetFramebufferAttachmentParameteriv    -              Encoding of components  6.1.3         -
                                                                                                                in the attached image

    FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE         Z_4     GetFramebufferAttachmentParameteriv    -              Data type of components 6.1.3         -
                                                                                                                in the attached image

    FRAMEBUFFER_ATTACHMENT_RED_SIZE               Z+      GetFramebufferAttachmentParameteriv    -              Size in bits of att.    6.1.3         -
                                                                                                                image's red component

    FRAMEBUFFER_ATTACHMENT_GREEN_SIZE             Z+      GetFramebufferAttachmentParameteriv    -              Size in bits of att.    6.1.3         -
                                                                                                                image's green component

    FRAMEBUFFER_ATTACHMENT_BLUE_SIZE              Z+      GetFramebufferAttachmentParameteriv    -              Size in bits of att.    6.1.3         -
                                                                                                                image's blue component

    FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE             Z+      GetFramebufferAttachmentParameteriv    -              Size in bits of att.    6.1.3         -
                                                                                                                image's alpha component

    FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE             Z+      GetFramebufferAttachmentParameteriv    -              Size in bits of att.    6.1.3         -
                                                                                                                image's depth component

    FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE           Z+      GetFramebufferAttachmentParameteriv    -              Size in bits of att.    6.1.3         -
                                                                                                                image's stencil component




    (insert new table 7.nnn, "Renderbuffers (state per renderbuffer target and binding point)")

    Get Value                      Type    Get Command     Initial Value  Description             Section       Attribute
    ----------------------------   ------  -------------   -------------  --------------------    ------------  ---------
    RENDERBUFFER_BINDING           Z       GetIntegerv     0              renderbuffer object     4.4.2.1       -
                                                                          bound to RENDERBUFFER


    (insert new table 8.nnn, "Renderbuffers (state per renderbuffer object)")

    Get Value                      Type    Get Command                 Initial Value  Description             Section       Attribute
    ----------------------------   ------  -------------               -------------  --------------------    ------------  ---------
    RENDERBUFFER_WIDTH             Z       GetRenderbufferParameteriv  0              width of renderbuffer   4.4.2.1       -

    RENDERBUFFER_HEIGHT            Z       GetRenderbufferParameteriv  0              height of renderbuffer  4.4.2.1       -

    RENDERBUFFER_INTERNAL_FORMAT   Z+      GetRenderbufferParameteriv  RGBA           internal format         4.4.2.1       -
                                                                                      of renderbuffer

    RENDERBUFFER_RED_SIZE          Z       GetRenderbufferParameteriv  0              size in bits of         4.4.2.1       -
                                                                                      renderbuffer image's
                                                                                      red component

    RENDERBUFFER_GREEN_SIZE        Z       GetRenderbufferParameteriv  0              size in bits of         4.4.2.1       -
                                                                                      renderbuffer image's
                                                                                      green component

    RENDERBUFFER_BLUE_SIZE         Z       GetRenderbufferParameteriv  0              size in bits of         4.4.2.1       -
                                                                                      renderbuffer image's
                                                                                      blue component

    RENDERBUFFER_ALPHA_SIZE        Z       GetRenderbufferParameteriv  0              size in bits of         4.4.2.1       -
                                                                                      renderbuffer image's
                                                                                      alpha component

    RENDERBUFFER_DEPTH_SIZE        Z       GetRenderbufferParameteriv  0              size in bits of         4.4.2.1       -
                                                                                      renderbuffer image's
                                                                                      depth component

    RENDERBUFFER_STENCIL_SIZE      Z       GetRenderbufferParameteriv  0              size in bits of         4.4.2.1       -
                                                                                      renderbuffer image's
                                                                                      stencil component

    RENDERBUFFER_SAMPLES           Z+      GetRenderbufferParameteriv  0              number of samples       4.4.2.1       -





Move the following existing state from "Implementation Dependent
Values", tables 6.33-6.37 to into a new table called "Framebuffer
Dependent Values", table 9.nnn.

    Get Value
    ---------
    AUX_BUFFERS
    MAX_DRAW_BUFFERS
    RGBA_MODE
    INDEX_MODE
    DOUBLEBUFFER
    STEREO
    SAMPLE_BUFFERS
    SAMPLES
    RED_BITS
    GREEN_BITS
    BLUE_BITS
    ALPHA_BITS
    INDEX_BITS
    DEPTH_BITS
    STENCIL_BITS
    ACCUM_RED_BITS
    ACCUM_GREEN_BITS
    ACCUM_BLUE_BITS
    ACCUM_ALPHA_BITS

To the same table called "Framebuffer Dependent Values", table 9.nnn
add the following new framebuffer dependent state.

    Get Value               Type  Get Command     Minimum Value    Description             Section  Attribute
    ---------               ----  -----------     -------------    -------------------     -------  ---------
    MAX_COLOR_ATTACHMENTS   Z+    GetIntegerv     1                Maximum number of       4.4.2.2  -
                                                                   attachment points
                                                                   for color buffers
                                                                   when using framebuffer
                                                                   objects

    MAX_SAMPLES             Z+    GetIntegerv     0                Maximum number of       4.4.2.1  -
                                                                   samples supported
                                                                   for multisampling

New Implementation Dependent State

    Get Value               Type  Get Command     Minimum Value    Description             Section  Attribute
    ---------               ----  -----------     -------------    -------------------     -------  ---------
    MAX_RENDERBUFFER_SIZE   Z+    GetIntegerv     64               Maximum width and       4.4.2.1  -
                                                                   height of
                                                                   renderbuffers
                                                                   supported by
                                                                   the implementation

Additions to the AGL/GLX/WGL Specifications and dependencies on
WGL_ARB_make_current_read, GLX_SGI_make_current_read, and GLX 1.3

    The color, depth, stencil, aux, and accum logical buffers defined by
    the <draw> and <read> drawables passed to glXMakeContextCurrent,
    glXMakeCurrent, and glXMakeCurrentRead are ignored while the value
    of DRAW_FRAMEBUFFER_BINDING is non-zero.

Dependencies on ATI_draw_buffers and ARB_draw_buffers

    If neither ATI_draw_buffers nor ARB_draw_buffers are supported, then
    all discussions of DrawBuffers should be ignored.

    In addition, the language describing DrawBuffers are derived from a
    combination of the ARB_draw_buffers specification and section 4.2.1
    of the OpenGL 2.0 specification.

Dependencies on ARB_fragment_program, ARB_fragment_shader, and
ARB_vertex_shader

    If ARB_fragment_program, ARB_fragment_shader, and ARB_vertex_shader
    are all not supported, then all references to the currently bound
    program or shader should be ignored.

Dependencies on ARB_texture_rectangle

    If ARB_texture_rectangle is not supported, then all references to
    TEXTURE_RECTANGLE_ARB should be ignored.

Dependencies on ARB_color_buffer_float

    The reference to CLAMP_FRAGMENT_COLOR_ARB in section 4.3.3 applies
    only if ARB_color_buffer_float is supported.

Dependencies on ARB_texture_rg

    If ARB_texture_rg is not supported, delete the references to RED and
    RG from the list of color-renderable base internal formats from
    section 4.4.4.

Dependencies on NV_float_buffer

    If NV_float_buffer is not supported, delete the references to
    FLOAT_R_NV, FLOAT_RG_NV, FLOAT_RGB_NV and FLOAT_RGBA_NV from the list
    of color-renderable base internal formats from section 4.4.4

Dependencies on EXT_framebuffer_object

    Framebuffer objects created with the commands defined by the
    GL_EXT_framebuffer_object extension are defined to be shared, while
    FBOs created with commands defined by the OpenGL core or
    GL_ARB_framebuffer_object extension are defined *not* to be shared.
    However, the following functions are viewed as aliases (in particular
    the opcodes for X are also the same) between the functions of
    GL_EXT_framebuffer_object and GL_ARB_framebuffer_object:

      IsRenderbufferEXT             / IsRenderbuffer
      DeleteRenderbuffersEXT        / DeleteRenderbuffers
      GenRenderbuffersEXT           / GenRenderbuffers
      RenderbufferStorageEXT        / RenderbufferStorage
      GetRenderbufferParameterivEXT / GetRenderbufferParameteriv
      IsFramebufferEXT              / IsFramebuffer
      DeleteFramebuffersEXT         / DeleteFramebuffers
      GenFramebuffersEXT            / GenFramebuffers
      CheckFramebufferStatusEXT     / CheckFramebufferStatus
      FramebufferTexture1DEXT       / FramebufferTexture1D
      FramebufferTexture2DEXT       / FramebufferTexture2D
      FramebufferRenderbufferEXT    / FramebufferRenderbuffer
      GenerateMipmapEXT             / GenerateMipmap
      GetFramebufferAttachmentParameterivEXT / GetFramebufferAttachmentParameteriv

   Since the above pairs are aliases, the functions of a pair are
   equivalent.  Note that the functions BindFramebuffer and
   BindFramebufferEXT are not aliases and neither are the functions
   BindRenderbuffer and BindRenderbufferEXT.  Because object creation
   occurs when the framebuffer object is bound for the first time, a
   framebuffer object can be shared across contexts only if it was first
   bound with BindFramebufferEXT.  Framebuffers first bound with
   BindFramebuffer may not be shared across contexts.  Framebuffer
   objects created with BindFramebufferEXT may subsequently be bound
   using BindFramebuffer.  Framebuffer objects created with
   BindFramebuffer may be bound with BindFramebufferEXT provided they are
   bound to the same context they were created on.

Dependencies on EXT_texture_array

    If EXT_texture_array is not supported, delete all references to
    one- and two-dimensional array textures.

Dependencies on EXT_texture_integer

    If EXT_texture_integer is not supported, the following changes should
    be made:

    The definition of GetFramebufferAttachmentParameteriv should be
    modified to remove any references to signed and unsigned integer
    components for color buffers and the values of INT and UNSIGNED_INT
    should be removed from the list of possible values for <param> when
    <pname> is FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE.

Dependencies on ARB_framebuffer_sRGB

    If ARB_framebuffer_sRGB is not supported, the following changes should
    be made:

    The definition of GetFramebufferAttachmentParameteriv should be
    modified to remove any reference to sRGB-encoded components or
    color buffers and sRGB conversion. The value of SRGB should be
    removed from the list of possible values for <param> when <pname> is
    FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING.

GLX Protocol

        Nineteen new GL commands are added.

        The following thirteen rendering commands are sent to the server
        as part of a glXRender request:

        BindRenderbuffer
            2        12              rendering command length
            2        235             rendering command opcode
            4        ENUM            target
            4        CARD32          renderbuffer

        DeleteRenderbuffer
            2        8+n*4           rendering command length
            2        4317            rendering command opcode
            4        CARD32          n
            n*4      LISTofCARD32    renderbuffers

        RenderbufferStorage
            2        20              rendering command length
            2        4318            rendering command opcode
            4        ENUM            target
            4        ENUM            internalFormat
            4        CARD32          width
            4        CARD32          height

        RenderbufferStorageMultisample

            2       24              rendering command length
            2       4331            rendering command opcode
            4       ENUM            target
            4       CARD32          samples
            4       ENUM            internalformat
            4       CARD32          width
            4       CARD32          height

        BindFramebuffer
            2        12              rendering command length
            2        236             rendering command opcode
            4        ENUM            target
            4        CARD32          framebuffer

        DeleteFramebuffer
            2        8+n*4           rendering command length
            2        4320            rendering command opcode
            4        CARD32          n
            n*4      LISTofCARD32    framebuffers

        FramebufferTexture1D
            2        24              rendering command length
            2        4321            rendering command opcode
            4        ENUM            target
            4        ENUM            attachment
            4        ENUM            textarget
            4        CARD32          texture
            4        CARD32          level

        FramebufferTexture2D
            2        24              rendering command length
            2        4322            rendering command opcode
            4        ENUM            target
            4        ENUM            attachment
            4        ENUM            textarget
            4        CARD32          texture
            4        CARD32          level

        FramebufferTexture3D
            2        28              rendering command length
            2        4323            rendering command opcode
            4        ENUM            target
            4        ENUM            attachment
            4        ENUM            textarget
            4        CARD32          texture
            4        CARD32          level
            4        CARD32          layer

        FramebufferTextureLayer
            2        24              rendering command length
            2        237             rendering command opcode
            4        ENUM            target
            4        ENUM            attachment
            4        CARD32          texture
            4        CARD32          level
            4        CARD32          layer

        FramebufferRenderbuffer
            2        20              rendering command length
            2        4324            rendering command opcode
            4        ENUM            target
            4        ENUM            attachment
            4        ENUM            renderbuffertarget
            4        CARD32          renderbuffer

        BlitFramebuffer
            2        44              rendering command length
            2        4330            rendering command opcode
            4        CARD32          source X0
            4        CARD32          source Y0
            4        CARD32          source X1
            4        CARD32          source Y1
            4        CARD32          destination X0
            4        CARD32          destination Y0
            4        CARD32          destination X1
            4        CARD32          destination Y1
            4        CARD32          mask
            4        ENUM            filter

        GenerateMipmap
            2        8               rendering command length
            2        4325            rendering command opcode
            4        ENUM            target

        The remaining seven commands are non-rendering commands.  These
        commands are sent separately (i.e., not as part of a glXRender or
        glXRenderLarge request), using the glXVendorPrivateWithReply
        request:

        IsRenderbuffer
            1        CARD8           opcode (X assigned)
            1        17              GLX opcode (X_GLXVendorPrivateWithReply)
            2        4               request length
            4        1422            vendor specific opcode
            4        GLX_CONTEXT_TAG context tag
            4        CARD32          renderbuffer
          =>
            1        1               reply
            1                        unused
            2        CARD16          sequence number
            4        0               reply length
            4        BOOL32          return value
            20                       unused

        GenRenderbuffers
            1        CARD8           opcode (X assigned)
            1        17              GLX opcode (X_GLXVendorPrivateWithReply)
            2        4               request length
            4        1423            vendor specific opcode
            4        GLX_CONTEXT_TAG context tag
            4        CARD32          n
          =>
            1        1               reply
            1                        unused
            2        CARD16          sequence number
            4        m               reply length
            4                        unused
            4        CARD32          n
            16                       unused
            n*4      LISTofCARD32    renderbuffers

        GetRenderbufferParameteriv
            1        CARD8           opcode (X assigned)
            1        17              GLX opcode (X_GLXVendorPrivateWithReply)
            2        5               request length
            4        1424            vendor specific opcode
            4        GLX_CONTEXT_TAG context tag
            4        ENUM            target
            4        ENUM            pname
          =>
            1        1               reply
            1                        unused
            2        CARD16          sequence number
            4        m               reply length, m = (n == 1 ? 0 : n)
            4                        unused
            4        CARD32          n

            if (n = 1) this follows:

            4        CARD32          params
            12                       unused

            otherwise this follows:

            16                       unused
            n*4      LISTofCARD32    params

        IsFramebuffer
            1        CARD8           opcode (X assigned)
            1        17              GLX opcode (X_GLXVendorPrivateWithReply)
            2        4               request length
            4        1425            vendor specific opcode
            4        GLX_CONTEXT_TAG context tag
            4        CARD32          framebuffer
          =>
            1        1               reply
            1                        unused
            2        CARD16          sequence number
            4        0               reply length
            4        BOOL32          return value
            20                       unused

        GenFramebuffers
            1        CARD8           opcode (X assigned)
            1        17              GLX opcode (X_GLXVendorPrivateWithReply)
            2        4               request length
            4        1426            vendor specific opcode
            4        GLX_CONTEXT_TAG context tag
            4        CARD32          n
          =>
            1        1               reply
            1                        unused
            2        CARD16          sequence number
            4        n               reply length
            4                        unused
            4        CARD32          n
            16                       unused
            n*4      LISTofCARD32    framebuffers

        CheckFramebufferStatus
            1        CARD8           opcode (X assigned)
            1        17              GLX opcode (X_GLXVendorPrivateWithReply)
            2        4               request length
            4        1427            vendor specific opcode
            4        GLX_CONTEXT_TAG context tag
            4        ENUM            target
          =>
            1        1               reply
            1                        unused
            2        CARD16          sequence number
            4        0               reply length
            4        ENUM            return value
            20                       unused

        GetFramebufferAttachmentParameteriv
            1        CARD8           opcode (X assigned)
            1        17              GLX opcode (X_GLXVendorPrivateWithReply)
            2        6               request length
            4        1428            vendor specific opcode
            4        GLX_CONTEXT_TAG context tag
            4        ENUM            target
            4        ENUM            attachment
            4        ENUM            pname
          =>
            1        1               reply
            1                        unused
            2        CARD16          sequence number
            4        m               reply length, m = (n == 1 ? 0 : n)
            4                        unused
            4        CARD32          n

            if (n = 1) this follows:

            4        CARD32          params
            12                       unused

            otherwise this follows:

            16                       unused
            n*4      LISTofCARD32    params


Usage Examples

    The following examples use a helper macro for
    CHECK_FRAMEBUFFER_STATUS, defined below.

    Example (6) gives a (very slightly) more robust example of handling
    the possible return values for glCheckFramebufferStatus.

    #define CHECK_FRAMEBUFFER_STATUS()                            \
      {                                                           \
        GLenum status;                                            \
        status = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER);   \
        switch(status) {                                          \
          case GL_FRAMEBUFFER_COMPLETE:                           \
            break;                                                \
          case GL_FRAMEBUFFER_UNSUPPORTED:                        \
            /* choose different formats */                        \
            break;                                                \
          default:                                                \
            /* programming error; will fail on all hardware */    \
            assert(0);                                            \
        }
      }

    (1) Render to 2D texture with a depth buffer

        // Given:  color_tex - TEXTURE_2D color texture object
        //         depth_rb  - GL_DEPTH renderbuffer object
        //         fb        - framebuffer object

        // Enable render-to-texture
        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fb);

        // Set up color_tex and depth_rb for render-to-texture
        glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER,
                                  GL_COLOR_ATTACHMENT0,
                                  GL_TEXTURE_2D, color_tex, 0);
        glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER,
                                     GL_DEPTH_ATTACHMENT,
                                     GL_RENDERBUFFER, depth_rb);

        // Check framebuffer completeness at the end of initialization.
        CHECK_FRAMEBUFFER_STATUS();

        <draw to the texture and renderbuffer>

        // Re-enable rendering to the window
        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);

        glBindTexture(GL_TEXTURE_2D, color_tex);
        <draw to the window, reading from the color_tex>


    (2) Application that supports both RBBCTT (render back buffer, copy to
    texture) and RTT (render to texture).  The migration path from RBBCTT
    to RTT is easy.

        if (useFramebuffer) {
            glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fb);
            glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER,
                                      GL_COLOR_ATTACHMENT0,
                                      GL_TEXTURE_2D, color_tex, 0);
            CHECK_FRAMEBUFFER_STATUS();
        }

        draw_to_texture();

        glBindTexture (GL_TEXTURE_2D, color_tex);
        if (useFramebuffer) {
            glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
        } else { // copy tex path
            glCopyTexSubImage(...);
        }


    (3) Simple render-to-texture loop with initialization.  Create an
    RGB8 texture, a 24-bit depth renderbuffer, and a stencil
    renderbuffer.  In a loop, alternate between rendering to, and
    texturing out of, the color texture.

        glGenFramebuffers(1, &fb);
        glGenTextures(1, &color_tex);
        glGenRenderbuffers(1, &depth_rb);
        glGenRenderbuffers(1, &stencil_rb);

        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fb);

        // initialize color texture
        glBindTexture(GL_TEXTURE_2D, color_tex);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, 512, 512, 0,
                     GL_RGB, GL_INT, NULL);
        glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER,
                                  GL_COLOR_ATTACHMENT0,
                                  GL_TEXTURE_2D, color_tex, 0);

        // initialize depth renderbuffer
        glBindRenderbuffer(GL_RENDERBUFFER, depth_rb);
        glRenderbufferStorage(GL_RENDERBUFFER,
                                 GL_DEPTH_COMPONENT24, 512, 512);
        glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER,
                                     GL_DEPTH_ATTACHMENT,
                                     GL_RENDERBUFFER, depth_rb);

        // initialize stencil renderbuffer
        glBindRenderbuffer(GL_RENDERBUFFER, stencil_rb);
        glRenderbufferStorage(GL_RENDERBUFFER,
                                 GL_STENCIL_INDEX, 512, 512);
        glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER,
                                     GL_STENCIL_ATTACHMENT,
                                     GL_RENDERBUFFER, stencil_rb);

        // Check framebuffer completeness at the end of initialization.
        CHECK_FRAMEBUFFER_STATUS();

        loop {
            glBindTexture(GL_TEXTURE_2D, 0);
            glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fb);

            <draw to the texture>

            glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
            glBindTexture(GL_TEXTURE_2D, color_tex);

            <draw to the window, reading from the color texture>
        }


    (4) Render-to-texture loop with automatic mipmap generation.  There
    are N framebuffers, N mipmap color textures, and a single shared
    depth renderbuffer.  The depth renderbuffer is not a mipmap.

        GLuint fb_array[N];
        GLuint color_tex_array[N];
        GLuint depth_rb;

        glGenFramebuffers(N, fb_array);
        glGenTextures(N, color_tex_array);
        glGenRenderbuffers(1, &depth_rb);

        // initialize color textures
        for (int i=0; i<N; i++) {
          glBindTexture(GL_TEXTURE_2D, color_tex_array[N]);
          glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, 512, 512, 0,
                       GL_RGB, GL_INT, NULL);

          // establish a mipmap chain for the texture
          glGenerateMipmap(GL_TEXTURE_2D);
        }

        // initialize depth renderbuffer
        glBindRenderbuffer(GL_RENDERBUFFER, depth_rb);
        glRenderbufferStorage(GL_RENDERBUFFER,
                                 GL_DEPTH_COMPONENT24, 512, 512);

        // setup framebuffers, sharing depth
        for (int i=0; i<N; i++) {
          glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fb_array[i]);
          glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER,
                                    GL_COLOR_ATTACHMENT0,
                                    GL_TEXTURE_2D, color_tex_array[i], 0);
          glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER,
                                       GL_DEPTH_ATTACHMENT,
                                       GL_RENDERBUFFER, depth_rb);
        }

        // Check framebuffer completeness at the end of initialization.
        CHECK_FRAMEBUFFER_STATUS();

        loop {
            glBindTexture(GL_TEXTURE_2D, 0);

            for (int i=0; i<N; i++) {
              glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fb_array[i]);
              <draw to texture i>
            }

            glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);

            // automatically generate mipmaps
            for (int i=0; i<N; i++) {
              glBindTexture(GL_TEXTURE_2D, color_tex_array[i]);
              glGenerateMipmap(GL_TEXTURE_2D);
            }

            <draw to the window, reading from the color textures>
        }


    (5) Render-to-texture loop with custom mipmap generation.
        The depth renderbuffer is not a mipmap.

        glGenFramebuffers(1, &fb);
        glGenTextures(1, &color_tex);
        glGenRenderbuffers(1, &depth_rb);

        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fb);

        // initialize color texture and establish mipmap chain
        glBindTexture(GL_TEXTURE_2D, color_tex);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, 512, 512, 0,
                     GL_RGB, GL_INT, NULL);
        glGenerateMipmap(GL_TEXTURE_2D);
        glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER,
                                  GL_COLOR_ATTACHMENT0,
                                  GL_TEXTURE_2D, color_tex, 0);

        // initialize depth renderbuffer
        glBindRenderbuffer(GL_RENDERBUFFER, depth_rb);
        glRenderbufferStorage(GL_RENDERBUFFER,
                                 GL_DEPTH_COMPONENT24, 512, 512);
        glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER,
                                     GL_DEPTH_ATTACHMENT,
                                     GL_RENDERBUFFER, depth_rb);

        // Check framebuffer completeness at the end of initialization.
        CHECK_FRAMEBUFFER_STATUS();

        loop {
            glBindTexture(GL_TEXTURE_2D, 0);

            glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fb);
            glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER,
                                      GL_COLOR_ATTACHMENT0,
                                      GL_TEXTURE_2D, color_tex, 0);
            glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER,
                                         GL_DEPTH_ATTACHMENT,
                                         GL_RENDERBUFFER, depth_rb);

            <draw to the base level of the color texture>

            // custom-generate successive mipmap levels
            glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER,
                                         GL_DEPTH_ATTACHMENT,
                                         GL_RENDERBUFFER, 0);
            glBindTexture(GL_TEXTURE_2D, color_tex);
            foreach (level > 0, in order of increasing values of level) {
                glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER,
                                          GL_COLOR_ATTACHMENT0,
                                          GL_TEXTURE_2D, color_tex, level);
                glTexParameteri(TEXTURE_2D, TEXTURE_BASE_LEVEL, level-1);
                glTexParameteri(TEXTURE_2D, TEXTURE_MAX_LEVEL, level-1);

                <draw to level>
            }
            glTexParameteri(TEXTURE_2D, TEXTURE_BASE_LEVEL, 0);
            glTexParameteri(TEXTURE_2D, TEXTURE_MAX_LEVEL, max);

            glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
            <draw to the window, reading from the color texture>
        }


    (6) Pseudo-code example of one method of responding to
        FRAMEBUFFER_UNSUPPORTED

        bool done = false;
        bool success = false;
        int  configurationNumber = 0;
        GLenum status;

        while (!done)
        {
            for (each framebuffer-attachable image)
            {
                ChooseInternalFormatForFramebufferAttachableImage(configurationNumber);

                CreateFramebufferAttachableImage();

                AttachFramebufferAttachableImageToFramebuffer();
            }

            status = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER);
            switch(status)
            {
                case GL_FRAMEBUFFER_COMPLETE:
                    success = true;
                    done = true;
                    break;

                case GL_FRAMEBUFFER_UNSUPPORTED:
                    if (configCount < MAX_NUM_CONFIGS_I_WANT_TO_TRY)
                    {
                        printf("current config not supported, trying again);
                        configurationNumber++;
                    }
                    else
                    {
                        printf("couldn't find a supported config\n");
                        success = false;
                        done = true;
                    }
                    break;

                default:
                    // programming error; will fail on all hardware
                    FatalError();
                    exit(1);
            }
        }

        if (!success)
        {
            printf("couldn't find a supported config\n");
            FatalError();
            exit(1);
        }

        // Current framebuffer is supported and complete!!
        Draw();


    (7) Render to depth texture with no color attachments

        // Given:  depth_tex - TEXTURE_2D depth texture object
        //         fb        - framebuffer object

        // Enable render-to-texture
        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fb);

        // Set up depth_tex for render-to-texture
        glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER,
                                  GL_DEPTH_ATTACHMENT,
                                  GL_TEXTURE_2D, depth_tex, 0);

        // No color buffer to draw to or read from
        glDrawBuffer(GL_NONE);
        glReadBuffer(GL_NONE);

        // Check framebuffer completeness at the end of initialization.
        CHECK_FRAMEBUFFER_STATUS();

        <draw something>

        // Re-enable rendering to the window
        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);

        glBindTexture(GL_TEXTURE_2D, depth_tex);
        <draw to the window, reading from the depth_tex>

    (8) FBO and ARB_draw_buffers

        // Given: color_texA - TEXTURE_2D color texture object
        // Given: color_texB - TEXTURE_2D color texture object
        //        depth_rb   - GL_DEPTH renderbuffer object
        //        fb         - framebuffer object

        // Set up the framebuffer object
        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fb);
        glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER,
                                  GL_COLOR_ATTACHMENT0,
                                  GL_TEXTURE_2D, color_texA, 0);
        glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER,
                                  GL_COLOR_ATTACHMENT1,
                                  GL_TEXTURE_2D, color_texB, 0);
        glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER,
                                     GL_DEPTH_ATTACHMENT,
                                     GL_RENDERBUFFER, depth_rb);

        // Enable both attachments as draw buffers
        GLenum drawbuffers = {GL_COLOR_ATTACHMENT0,
                              GL_COLOR_ATTACHMENT1};
        glDrawBuffers(2, drawbuffers);

        // Check framebuffer completeness at the end of initialization.
        CHECK_FRAMEBUFFER_STATUS();

        // Enable fragment program that writes to both gl_FragData[0]
        // and gl_FragData[1]

        <draw something>

        // Disable fragment program

        // Re-enable rendering to the window
        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);

        // Bind both textures, each to a different texture unit
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, color_texA);
        glActiveTexture(GL_TEXTURE1);
        glBindTexture(GL_TEXTURE_2D, color_texB);

        <draw to the window>

Sample Code (from framebuffer_blit)

    /* Render to framebuffer object 2 */
    glBindFramebuffer(DRAW_FRAMEBUFFER, 2);
    RenderScene();

    /* Blit contents of color buffer, depth buffer and stencil buffer
     * from framebuffer object 2 to framebuffer object 1.
     */
    glBindFramebuffer(GL_READ_FRAMEBUFFER, 2);
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 1);
    glBlitFramebuffer(0, 0, 640, 480,
                       0, 0, 640, 480,
                       GL_COLOR_BUFFER_BIT |
                       GL_DEPTH_BUFFER_BIT |
                       GL_STENCIL_BUFFER_BIT,
                       GL_NEAREST);

    /* Blit contents of color buffer from framebuffer object 1 to
     * framebuffer object 2, inverting the image in the X direction.
     */
    glBindFramebuffer(GL_READ_FRAMEBUFFER, 1);
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 2);
    glBlitFramebuffer(0, 0, 640, 480,
                       640, 0, 0, 480,
                       GL_COLOR_BUFFER_BIT,
                       GL_NEAREST);

    /* Blit color buffer from framebuffer object 1 to framebuffer
     * object 3 with a 2X zoom and linear filtering.
     */
    glBindFramebuffer(GL_READ_FRAMEBUFFER, 1);
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 3);
    glBlitFramebuffer(0, 0, 640, 480,
                       0, 0, 1280, 960,
                       GL_COLOR_BUFFER_BIT, GL_LINEAR);

Usage Examples (from packed_depth_stencil)

    (1) Attach a DEPTH_STENCIL texture image to an FBO as both the
        depth and stencil buffers.

        glGenFramebuffers(1, &fb);
        glGenTextures(1, &tex_color);
        glGenTextures(1, &tex_depthstencil);

        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fb);

        // Setup color texture (mipmap)
        glBindTexture(GL_TEXTURE_2D, tex_color);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8,
                     512, 512, 0, GL_RGBA, GL_INT, NULL);
        glGenerateMipmap(GL_TEXTURE_2D);
        glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER,
                                  GL_COLOR_ATTACHMENT0,
                                  GL_TEXTURE_2D, tex_color, 0);

        // Setup depth_stencil texture (not mipmap)
        glBindTexture(GL_TEXTURE_2D, tex_depthstencil);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8,
                     512, 512, 0, GL_DEPTH_STENCIL,
                      GL_UNSIGNED_INT_24_8, NULL);
        glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER,
                                  GL_DEPTH_ATTACHMENT,
                                  GL_TEXTURE_2D, tex_depthstencil, 0);
        glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER,
                                  GL_STENCIL_ATTACHMENT,
                                  GL_TEXTURE_2D, tex_depthstencil, 0);

        // Check framebuffer completeness at the end of initialization.

        loop {
            glBindTexture(GL_TEXTURE_2D, 0);
            glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fb);
            <render to color, depth, and stencil textures>
            glBindFramebuffer(GL_FRAMEBUFFER, 0);

            glBindTexture(GL_TEXTURE_2D, tex_color);
            glGenerateMipmap(GL_TEXTURE_2D);
            <draw to the window, reading from the color texture>

            glBindTexture(GL_TEXTURE_2D, tex_depthstencil);
            <draw to the window, reading depth from the depthstencil texture>
        }


Issues

    (1) What should this extension be named?

        RESOLVED. We will call this ARB_framebuffer_object.

    (2) What additional functionality does this extension include over
        EXT_framebuffer_object?

        RESOLVED.

        Currently we incorporate the following layered extensions:

         * EXT_framebuffer_multisample
         * EXT_framebuffer_blit
         * EXT_packed_depth_stencil

        As well as the following features:

         * Permit attachments with different width and height (mixed
           dimensions)

         * Permit color attachments with different formats (mixed
           formats).

         * Render to 1 and 2 component R/RG formats that are provided
           via the ARB_texture_rg extension. L/A/LA/I will be
           left for a separate (trivial) extension.

         * Gen'ed names must be used for framebuffer objects and
           renderbuffers.

         * Added FramebufferTextureLayer.

        Other features we have considered include:

         * Render to Vertex Attrib (RTVA)

         * Format compatibility API that can guarantee a set of textures
           images have framebuffer-compatible formats.

         * Infolog or other means for communicating framebuffer
           incompleteness information to the application for debugging
           purposes.

         * A technique for page flipping framebuffer-attachable images.

         * Relaxing framebuffer completeness restrictions, possibly even
           remove FRAMEBUFFER_UNSUPPORTED.  Maybe go so far as to remove
           CheckFramebufferStatus.

        Features we have rejected include:

         * GetRenderbufferImage (benefit/demand does not seem to
           outweigh the additional complexity.)

         * READ_BUFFER == NONE for framebuffer zero.

         * Attach images from a window or from a pbuffer to an
           application-created framebuffer object.

    (3) What are the other differences from EXT_framebuffer_object.

         * Framebuffer completeness only considers the attachments named
           by DRAW_BUFFERi and READ_BUFFER.  Any other attachments do
           not affect framebuffer completeness.  (In
           EXT_framebuffer_object, all attachments affected framebuffer
           completeness, independent of the DRAW_BUFFERi and READ_BUFFER
           state.)
         * Added new queries for the sizes of the bit planes for color,
           depth and stencil attachments at a framebuffer attachment point.
         * Added new queries for framebuffer attachment component type and
           color encoding.
         * Many other minor tweaks to synchronize with the GL3 framebuffer
           objects.
         * ARB FBOs are not shareable.

    (4) Do we need new enum values, or can we re-use the ones from the EXT
        versions?

        RESOLVED. This extension is designed to be compatible with
        EXT_framebuffer_object, and thus we can reuse the enumerants. There
        are also a number of additional enumerants added in this extension.

    (5) What should a query of RED_BITS, GREEN_BITS, BLUE_BITS, ALPHA_BITS.
        return if the attached color-renderable images have different
        formats?

        RESOLVED. The values of RED_BITS, GREEN_BIT, BLUE_BITS and
        ALPHA_BITS are only defined if all color attachments of the draw
        framebuffer have identical formats, in which case the color
        component sizes of color attachment zero are return. This is
        necessary for backwards compatibility with EXT_framebuffer_object.
        The actual sizes of the color, depth, or stencil bit planes can be
        obtained by querying an attachment point using
        GetFramebufferAttachmentParameteriv using the new
        FRAMEBUFFER_ATTACHMENT_*_SIZE enumerants, or by querying the object
        attached at that point.

    (6) What are the proper names for the 1 and 2 component fixed-point,
        float, and pure integer texture formats?

        RESOLVED: as introduced in the 3.0 spec, using RED and RG base
        internal format terminology. The new RED/RG formats have also been
        spun out of 3.0 as the ARB_texture_rg extension.

    (7) This extension and EXT_framebuffer_object both have "bind
        framebuffer" functions (BindFramebuffer and BindFramebufferEXT). Are
        there any differences in functionality between the two functions?

        RESOLVED: Yes. Both extensions will create a new framebuffer object
        if called with an unused name. However, BindFramebuffer defined in
        this extension will generate an INVALID_OPERATION error if the name
        provided has not been generated by GenFramebuffer. That error did
        not exist in EXT_framebuffer_object, and this extension does not
        modify the behavior of BindFramebufferEXT. This difference also
        applies to BindRenderbuffer from this extension vs.
        BindRenderbufferEXT from EXT_framebuffer_object.

    (8) Why don't the new tokens and entry points in this extension have
       "ARB" suffixes like other ARB extensions?

        RESOLVED: Unlike most ARB extensions, this is a strict subset of
        functionality already approved in OpenGL 3.0. This extension
        exists only to support that functionality on older hardware that
        cannot implement a full OpenGL 3.0 driver. Since there are no
        possible behavior changes between the ARB extension and core
        features, source code compatibility is improved by not using
        suffixes on the extension.

    (9) Should color-renderable textures be limited to a subset of
        color base internal formats?

        RESOLVED:  No, all color base internal formats and
        sized internal formats should be supported by FBO; the FBO
        status can report what works and doesn't work.

        The glCheckFramebufferStatus provides a mechanism for FBOs to
        report whether or not the FBO configuration is supported or
        not (i.e. GL_FRAMEBUFFER_UNSUPPORTED).  If implementations
        have issues supporting certain color formats for rendering,
        the existing FBO mechanism is sufficient to report their lack
        of support.

        Prior to revision 29, the list of color-renderable base internal
        formats did not include LUMINANCE, LUMINANCE_ALPHA, or INTENSITY
        (and the EXT version of FBO did not list ALPHA either).

        This lead to inconsistent operation of FBO.  For example, you
        could use a glFramebufferTexture2D to attach a texture that
        was LUMINANCE, LUMINANCE_ALPHA, or INTENSITY to an FBO and find
        out via glCheckFramebufferStatus that this combination wasn't
        considered color-renderable, but if an internal format for one of
        these base internal formats was used with glRenderbufferStorage,
        then an OpenGL error would be generated according to the
        specification.  Such inconsistencies are undesirable and
        unnecessarily limit the render-to-texture functionality exposed by
        some implementations when hardware capable of rendering to
        LUMINANCE, LUMINANCE_ALPHA, and INTENSITY textures does exist.

        For this reason, revision 29 (specification version 1.1) adds
        these previously missing based internal formats.  Developers are
        warned that some implementations (specification version 1.0)
        will report OpenGL errors if glRenderbufferStorage is called for
        LUMINANCE, INTENSITY, LUMINANCE_ALPHA formats (or even possibly
        ALPHA in the case of the EXT version of FBO).

        Some thought was given to introducing a new, one-off extension
        (instead of a version 1.1) to allow the LUMINANCE, INTENSITY,
        LUMINANCE_ALPHA base internal formats and their respective
        sized formats to be color-renderable (both otherwise introduce
        no new API).  Given the existence of a mechanism for determine
        whether or not an FBO is supported, simply providing this version
        1.1 clarification was judged to be the most expedient approach.
        This approach also provides consistency with other approved
        ARB specifications such as ARB_framebuffer_sRGB which describes
        (see its issue #9) that formats such as GL_SLUMINANCE8.

   (10) Can ARB framebuffer objects be shared between contexts?
        ARB_framebuffer_object is supposed to be compatible with
        EXT_framebuffer_object, but also a subset of OpenGL 3.0.
        EXT_framebuffer_object (rev. 120) explicitly allows sharing in
        issue 76, but the 3.0 spec explicitly disallows it in Appendix D.

        Resolved: No. ARB_framebuffer_object is intended to capture the
        functionality that went into GL 3.0.  Furthermore, given that the
        entry points and tokens in this extension and the core are identical
        there is no way that an implementation could differentiate FBOs
        created with this extension from those created by core GL.

        ADDITIONAL COMMENTS:

        See the "Dependencies on EXT_framebuffer_object" section above for
        the interaction behaviour between EXT and non-EXT FBO interfaces.

Revision History

    #1, October 20, 2005: jjuliano
        - branch from EXT_framebuffer_object
        - Delete old issues and revision history

    #2, November 28, 2005: jjuliano
        - Add issues 1 and 2.
        - Describe RenderbufferStorage in terms of color/depth/stencil
          renderable with forward reference to 4.4.4.
        - Reword the definitions of color/depth/stencil renderable.
        - Explicitly state how framebuffer operations write to and read
          from texture images.
        - Incorporate feedback from Barthold.

    #3-draft2, January 16, 2006: jjuliano
        - Define the conversions to/from framebuffer in terms of the
          internal format(s) of the attached image(s).
        - Handle color mask in RGBA to internal component conversion.
        - Improve language in section 4.4.5.
        - Add dependencies on more extensions.

    #4c April 28, 2008: dgkoch
        - merge in framebuffer_blit and update other references to
          FRAMEBUFFER_EXT and FRAMEBUFFER_BINDING_EXT, eliminating all
          references to the obsolete bindings.

    #5 May 2, 2008: rbarris, dgkoch
        - merge in framebuffer_multisample

    #6 May 8, 2008: dgkoch
        - rebase against OpenGL 2.1 spec

    #7 May 8, 2008: dgkoch
        - merge in packed_depth_stencil

    #8 May 8, 2008: dgkoch
        - add caveat that MSAA to MSAA blit may have issues (khronos bug
          #3005)

    #9 May 9, 2008: dgkoch
        - renamed from EXT_fbo2 to ARB_fbo. Changed all suffixes to _ARB
          instead of _EXT.

   #10 May 19, 2008: rbarris
        - Bugzilla 3013: allow dimension mismatches (esp. depth)

   #11 May 21, 2008: dgkoch
        - Bugzilla 3014: allow different color formats when using MRT.
        - added Issues 4, 5
        - deleted FRAMEBUFFER_INCOMPLETE_FORMATS &
          FRAMEBUFFER_INCOMPLETE_DIMENSIONS
        - added text for proposed resolution of Issue (5)

   #12 May 22, 2008: dgkoch
        - Bugzilla 3015: define one- and two- component formats to be
          color-renderable
        - added Issue 6

   #13 May 29, 2008: Jon Leech
        - Many updates and minor fixes for consistency with the 3.0 spec
          draft. Replace DEPTH with DEPTH_COMPONENT in most uses. Increase
          MAX_RENDERBUFFER_SIZE to 64 matching MAX_TEXTURE_SIZE (pending
          resolution of bug 3454). Pose some open questions preceded by
          "***".

   #14 June 26: dgkoch
        - change MAX_SAMPLES to 0, to indicate the multisampling is not
          required. (bug 3551)

   #15 July 2: Jon Leech
        - More updates for 3.0 spec consistency. Define meaning of <src>
          NONE and FRONT_AND_BACK for ReadBuffer() - this was an
          oversight introduced with the original extension. Replace
          reference to nonexistent table 12.nnn with reference to
          table 3.15. Start introducing RED and RG formats from 3.0 spec.

   #16 July 10: dgkoch
        - backport error change for DrawBuffer in 4.2.1 (bug 3530)

   #17 July 12, 2008: Jon Leech
        - Use 'layer' instead of 'zoffset' terminology. Add
          FramebufferTextureLayer.
        - Add framebuffer attachment queries for attachment component
          size / type / color encoding.
        - Allow framebuffer incomplete if no default framebuffer is made
          current, with new framebuffer status error.
        - Allow multisample buffers in framebuffer objects.
        - Global renaming / simplification to "default framebuffer" and
          "framebuffer object". Did not yet re-flow those paragraphs for
          ease of comparison.
        - Add more introductory material about framebuffers in chapter 2.
        - Remove requirement that all color attachments have the same
          depth.
        - Restrict FBOs and renderbuffers to Gen'ed names as agreed for
          3.0.
        - Update clipping / buffer intersection / filtering rules for
          BlitFramebuffer.
        - Allow FRAMEBUFFER as a bind pseudotarget aliasing both read
          and draw framebuffer targets. Allow DEPTH_STENCIL_ATTACHMENT
          as an attachment alias for both depth and stencil attachments.
        - Add Pat's introductory paragraph describing feedback loops in
          section 4.4.3.
        - Make RED_BITS etc. context queries defined iff all draw color
          buffers have the same format.
        - Remove "Dependencies" sections for NV extensions since we no
          longer refer to their tokens. Need to add some dependencies
          sections for new ARB extensions and figure out which language
          goes here and which language with those extensions (e.g.
          texture_rg, framebuffer_sRGB,
        - Many minor non-functional language tweaks to match 3.0 core
          language.

    #18 July 14, 2008: Rob Barris
        - Tidy up introductory/overview section

    #19 July 16, 2008: Daniel Koch, Rob Barris
        - add interactions with ARB_texture_rg, EXT_texture_array and
          NV_float_buffer
        - restore FRAMEBUFFER enumerant and restore all the text where
          it had been accepted before (removed in version 4).
        - allow texture arrays via FramebufferTextureLayer
        - removed reference to required format list which we don't have here.
        - updated resolution of issue (6)

    #20 July 16, 2008: Daniel Koch, Rob Barris
        - simplification of language for logical operation when a FB-image
          is attached more than once
        - add interactions with EXT_texture_integer and ARB_framebuffer_sRGB
        - Resolved issues (2), (4) and (5)
        - Updated issue (3) (although the list is still not exhaustive)

    #21 July 17, 2008: Daniel Koch
        - add Issue (7) as suggested by pbrown
        - restore FRAMEBUFFER_BINDING alias
        - fix incorrect references to FRAMEBUFFER_BINDING

    #22 July 17, 2008: Jon Leech
        - minor language cleanup for consistency with the 3.0 core spec.

    #23 July 24, 2008: Jon Leech
        - Use new GLX rendering opcodes for BindRenderbuffer and
          BindFramebuffer so they can be semantically distinguished
          from the EXT entry points.
        - Add GLX protocol for FramebufferTextureLayer.

    #24 August 7, 2008: Jon Leech
        - Remove ARB suffixes.

    #25 August 8, 2008: Jon Leech
        - Add missing framebuffer attachment state for component type /
          encoding / size to state tables.

    #26 August 8, 2008: Jon Leech
        - Add missing INDEX token for legacy default framebuffer
          color buffer component types.

    #27 August 20, 2008: Jon Leech
        - Add ALPHA to list of color-renderable base internal formats to
          sync with 3.0 spec language.

    #28 November 17, 2008: Mark Kilgard & Nigel Stewart
        - glFramebufferTexturLayerARB -> glFramebufferTextureLayerARB
          (add final e to Texture)

    #29 March 12, 2009: Jon Leech
        - Edits in chapter 4 intro for consistency with GL core spec
          language, including removing the completeness requirement that all
          color buffers of an FBO be the same depth. Reflow some text for
          readability.

    #30 March 31, 2009: Mark Kilgard & Jeff Juliano
        - Change color-renderable to be any color texture format.
          Fix some typos.

    #31 May 27, 2009: Jon Leech
        - Change default value of FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE
          to NONE (bug 4407).

    #32 July 21, 2010: Daniel Koch
        - Add issue 10 clarifying that ARB fbos cannot be shared.

    #33 July 22, 2011: Jon Leech
        - Remove error which disallowed non-multisample <-> sample blits
          (bug 7367).

    #34 October 2, 2011: Jon Leech
        - Bring chapter 6 language changes in sync with the OpenGL 3.0 API
          specification phrasing, and fix the description of
          GetFramebufferAttachmentParameteriv to use DEPTH and STENCIL as
          attachment names, rather than the nonexistent DEPTH_BUFFER and
          STENCIL_BUFFER tokens (Bug 8102).

    #35 June 29, 2013: Jon Leech
        - Rearrange New Tokens section to allow all simple queries to be
          queried with GetBooleanv as well, since it's defined to work for
          all of them (Bug 6838).

    #36, September 23, 2013: Jon Leech
        - Specify that undefined behavior results when mixing EXT and
          ARB_framebuffer_object / OpenGL 3.0 API framebuffer objects
          (Bug 10738).

    #37, June 20, 2016: Kevin Rogvin, James Jones
        - Specify behaviour of mixing EXT and ARB_framebuffer_object /
          OpenGL 3.0 framebuffer objects so that the aliases of the
          functions are correctly observed (Bug 1485)

    #38, October 6, 2016: Jon Leech
        - Remove STENCIL_REF from list of state moved to become framebuffer
          dependent (Bug 8422).
