Name

    EXT_framebuffer_object

Name Strings

    GL_EXT_framebuffer_object

Contributors

    Kurt Akeley
    Jason Allen
    Bob Beretta
    Pat Brown
    Matt Craighead
    Alex Eddy
    Cass Everitt
    Mark Galvan
    Michael Gold
    Evan Hart
    Jeff Juliano
    Mark Kilgard
    Dale Kirkland
    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
    Daniel Vogel
    Eric Werness
    Cliff Woolley

Contacts

    Jeff Juliano, NVIDIA Corporation (jjuliano 'at' nvidia.com)
    Jeremy Sandmel, Apple Computer (jsandmel 'at' apple.com)

Status

    Complete.
    Approved by the ARB "superbuffers" Working Group on January 31, 2005.
    Despite being controlled by the ARB WG, this is not an officially
    approved ARB extension at this time, thus the "EXT" tag.

Version

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

Number

    310

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_framebuffer_object and OpenGL 3.0 core affect the definition of
    this extension.

    ARB_texture_rectangle affects the definition of this extension.

    ARB_vertex_shader affects the definition of this extension.

    EXT_packed_depth_stencil affects the definition of this extension.

    NV_float_buffer affects the definition of this extension.

    NV_texture_shader affects the definition of this extension.

    Written based on the wording of the OpenGL 1.5 specification.

Overview

    This extension defines a simple 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 z-offset (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 BindFramebufferEXT 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.

    EXT_framebuffer_object, on the other hand, is both simpler to use
    and more efficient than ARB_render_texture.  The
    EXT_framebuffer_object API is contained wholly within the GL API and
    has no (non-portable) window-system components.  Under
    EXT_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.

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)


Issues

    Breaking from past convention, the very large issues section has
    been moved to the end of the document.  It can be found after
    Examples, before Revision History.


New Procedures and Functions

    boolean IsRenderbufferEXT(uint renderbuffer);
    void BindRenderbufferEXT(enum target, uint renderbuffer);
    void DeleteRenderbuffersEXT(sizei n, const uint *renderbuffers);
    void GenRenderbuffersEXT(sizei n, uint *renderbuffers);

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

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

    boolean IsFramebufferEXT(uint framebuffer);
    void BindFramebufferEXT(enum target, uint framebuffer);
    void DeleteFramebuffersEXT(sizei n, const uint *framebuffers);
    void GenFramebuffersEXT(sizei n, uint *framebuffers);

    enum CheckFramebufferStatusEXT(enum target);

    void FramebufferTexture1DEXT(enum target, enum attachment,
                                 enum textarget, uint texture,
                                 int level);
    void FramebufferTexture2DEXT(enum target, enum attachment,
                                 enum textarget, uint texture,
                                 int level);
    void FramebufferTexture3DEXT(enum target, enum attachment,
                                 enum textarget, uint texture,
                                 int level, int zoffset);

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

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

    void GenerateMipmapEXT(enum target);


New Types

    None.


New Tokens

    Accepted by the <target> parameter of BindFramebufferEXT,
    CheckFramebufferStatusEXT, FramebufferTexture{1D|2D|3D}EXT,
    FramebufferRenderbufferEXT, and
    GetFramebufferAttachmentParameterivEXT:

        FRAMEBUFFER_EXT                     0x8D40

    Accepted by the <target> parameter of BindRenderbufferEXT,
    RenderbufferStorageEXT, and GetRenderbufferParameterivEXT, and
    returned by GetFramebufferAttachmentParameterivEXT:

        RENDERBUFFER_EXT                    0x8D41

    Accepted by the <internalformat> parameter of
    RenderbufferStorageEXT:

        STENCIL_INDEX1_EXT                  0x8D46
        STENCIL_INDEX4_EXT                  0x8D47
        STENCIL_INDEX8_EXT                  0x8D48
        STENCIL_INDEX16_EXT                 0x8D49

    Accepted by the <pname> parameter of GetRenderbufferParameterivEXT:

        RENDERBUFFER_WIDTH_EXT              0x8D42
        RENDERBUFFER_HEIGHT_EXT             0x8D43
        RENDERBUFFER_INTERNAL_FORMAT_EXT    0x8D44
        RENDERBUFFER_RED_SIZE_EXT           0x8D50
        RENDERBUFFER_GREEN_SIZE_EXT         0x8D51
        RENDERBUFFER_BLUE_SIZE_EXT          0x8D52
        RENDERBUFFER_ALPHA_SIZE_EXT         0x8D53
        RENDERBUFFER_DEPTH_SIZE_EXT         0x8D54
        RENDERBUFFER_STENCIL_SIZE_EXT       0x8D55

    Accepted by the <pname> parameter of
    GetFramebufferAttachmentParameterivEXT:

        FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT            0x8CD0
        FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT            0x8CD1
        FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT          0x8CD2
        FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT  0x8CD3
        FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT     0x8CD4

    Accepted by the <attachment> parameter of
    FramebufferTexture{1D|2D|3D}EXT, FramebufferRenderbufferEXT, and
    GetFramebufferAttachmentParameterivEXT

        COLOR_ATTACHMENT0_EXT                0x8CE0
        COLOR_ATTACHMENT1_EXT                0x8CE1
        COLOR_ATTACHMENT2_EXT                0x8CE2
        COLOR_ATTACHMENT3_EXT                0x8CE3
        COLOR_ATTACHMENT4_EXT                0x8CE4
        COLOR_ATTACHMENT5_EXT                0x8CE5
        COLOR_ATTACHMENT6_EXT                0x8CE6
        COLOR_ATTACHMENT7_EXT                0x8CE7
        COLOR_ATTACHMENT8_EXT                0x8CE8
        COLOR_ATTACHMENT9_EXT                0x8CE9
        COLOR_ATTACHMENT10_EXT               0x8CEA
        COLOR_ATTACHMENT11_EXT               0x8CEB
        COLOR_ATTACHMENT12_EXT               0x8CEC
        COLOR_ATTACHMENT13_EXT               0x8CED
        COLOR_ATTACHMENT14_EXT               0x8CEE
        COLOR_ATTACHMENT15_EXT               0x8CEF
        DEPTH_ATTACHMENT_EXT                 0x8D00
        STENCIL_ATTACHMENT_EXT               0x8D20

    Returned by CheckFramebufferStatusEXT():

        FRAMEBUFFER_COMPLETE_EXT                          0x8CD5
        FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT             0x8CD6
        FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT     0x8CD7
        FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT             0x8CD9
        FRAMEBUFFER_INCOMPLETE_FORMATS_EXT                0x8CDA
        FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT            0x8CDB
        FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT            0x8CDC
        FRAMEBUFFER_UNSUPPORTED_EXT                       0x8CDD

    Accepted by GetIntegerv():

        FRAMEBUFFER_BINDING_EXT             0x8CA6
        RENDERBUFFER_BINDING_EXT            0x8CA7
        MAX_COLOR_ATTACHMENTS_EXT           0x8CDF
        MAX_RENDERBUFFER_SIZE_EXT           0x84E8

    Returned by GetError():

        INVALID_FRAMEBUFFER_OPERATION_EXT   0x0506

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

    "The GL interacts with two classes of framebuffers:
    window-system-provided framebuffers and application-created
    framebuffers.  There is always one window-system-provided
    framebuffer, while application-created framebuffers can 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 window-system-provided framebuffer
    are ultimately controlled by the window-system that allocates
    framebuffer resources.  It is the window-system that determines
    which portions of this framebuffer the GL may access at any given
    time and that communicates to the GL how those portions are
    structured.  Therefore, there are no GL commands to configure the
    window-system-provided framebuffer.  Similarly, display of
    framebuffer contents on a CRT monitor (including the transformation
    of individual framebuffer values by such techniques as gamma
    correction) is not addressed by the GL.  Framebuffer configuration
    occurs outside of the GL in conjunction with the window-system.

    The initialization of a GL context itself occurs when the
    window-system allocates a window for GL rendering and is influenced
    by the state of the window-system-provided framebuffer."

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

    In section 3.6.4, page 102, add the following text to the definiton
    of DrawPixels:

    "If the object bound to FRAMEBUFFER_BINDING_EXT is not "framebuffer
    complete" (as defined in section 4.4.4.2), then an attempt to call
    DrawPixels will generate the error
    INVALID_FRAMEBUFFER_OPERATION_EXT."

    In section 3.8.8, add the following text immediately before the
    subsection "Mipmapping" on page 151:

    "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 FRAMEBUFFER_BINDING_EXT names an application-created
        framebuffer object <F>.

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

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

        -or-

        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_EXT for attachment point
        <A> is within the 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:

    "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."

    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 GenerateMipmapEXT(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, INVALID_OPERATION 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] through q,
    inclusive, automatic and manual mipmap generation generate the same
    derived arrays, given identical level[base] arrays."

    Modify the third paragraph of section 3.8.12, page 157, 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."


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

    On page 170, in the introduction to chapter 4, modify the first
    three paragraphs to read as follows:

    "The framebuffer consists of a set of pixels arranged as a
    two-dimensional array.  The height and width of this array may vary
    from one GL implementation to another.  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 also vary
    depending on the particular GL implementation or context.

    Further there are two classes of framebuffers: the default
    framebuffer supplied by the window-system-provided and
    application-created framebuffer objects.  Every GL context has a
    single default window-system-provided framebuffer.  Applications can
    optionally create additional non-displayable framebuffer objects.
    (For more information on application-created framebuffer objects see
    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, depth, stencil, and accumulation
    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
    window-system-provided framebuffer or to an application-created
    framebuffer object.

    For the default window-system-provided 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 not provide depth, stencil, or
    accumulation buffers.

    For application-created framebuffer objects, the color buffers are
    not visible, and consequently the names of the color buffers are not
    related to a display device.  The names of the color buffers of an
    application-created framebuffer object are: COLOR_ATTACHMENT0_EXT
    through COLOR_ATTACHMENTn_EXT.  The names of the depth and stencil
    buffers are DEPTH_ATTACHMENT_EXT and STENCIL_ATTACHMENT_EXT.  For
    more information about the buffers of an application-created
    framebuffer object, see section 4.4.2.  To be considered framebuffer
    complete (see section 4.4.4), all color buffers attached to an
    application-created framebuffer object must have the same number of
    bitplanes.  Depth and stencil buffers may optionally be attached to
    application-created framebuffers as well.

    Color buffers consist of either unsigned integer color indices or R,
    G, B, and, optionally, A unsigned integer values.  The number of
    bitplanes in each of the color buffers, the depth buffer, the
    stencil buffer, and the accumulation buffer is dependent on the
    currently bound framebuffer.  For the default framebuffer, the
    number of bitplanes is fixed.  For application-created framebuffer
    objects, however, the number of bitplanes in a given logical buffer
    may change if the state of the corresponding framebuffer attachment
    or attached image changes (see sections 4.4.2 and 4.4.5).  If an
    accumulation buffer is provided, it must have at least as many
    bitplanes per R, G, and B color component as do the color buffers."

    Add a new paragraph to the end of section 4.1.1, page 171:

    "While an application-created framebuffer object is bound to
    FRAMEBUFFER_EXT, the pixel ownership test always passes.  The pixels
    of application-created frambuffer objects are always owned by the
    GL, not the window system.  Only while the window-system-provided
    framebuffer named zero is bound to FRAMEBUFFER_EXT does the window
    system control pixel ownership."

    Change section 4.1.5, page 174, third paragraph, first two 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
    <ref> use the value of <ref> clamped to the range [0, (2^s) - 1],
    where s is the current number of bits in the stencil buffer."

    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.  However, if the DRAW_BUFFERS state selects a
    single framebuffer-attachable image more than once, then an
    undefined value is written to those color buffers at the fragment's
    (x[w], y[x]) coordinates."

    Change section 4.2.1, to read as follows:

    "The first such operation is controlling the buffer into which color
    values are written.  This is accomplished with

        void DrawBuffer( enum buf );

    <buf> defines a buffer or set of buffers for writing.  <buf> must be
    one of the values from tables 4.4 or 10.nnn.  Otherwise,
    INVALID_ENUM is generated.  In addition, acceptable values for <buf>
    depend on whether the GL is using the default window-system-provided
    framebuffer (i.e., FRAMEBUFFER_BINDING_EXT is zero), or an
    application-created framebuffer object (i.e.,
    FRAMEBUFFER_BINDING_EXT is non-zero).  In the initial state, the GL
    is bound to the the window-system-provided framebuffer.  For more
    information about application-created framebuffer objects, see
    section 4.4.

    If the GL is bound to the window-system-provided 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.

    If the GL is bound to an application-created 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_EXT enables drawing only
    to the image attached to the framebuffer at COLOR_ATTACHMENTi_EXT.
    Each COLOR_ATTACHMENTi_EXT adheres to COLOR_ATTACHMENTi_EXT =
    COLOR_ATTACHMENT0_EXT + i.  The intial value of DRAW_BUFFER for
    application-created framebuffer objects is COLOR_ATTACHMENT0_EXT.


    Symbolic Constant     Meaning
    -----------------     -------
    NONE                  no buffer
    COLOR_ATTACHMENT0     output fragment color to image attached
                          at color attachment point 0
    COLOR_ATTACHMENT1     output fragment color to image attached
                          at color attachment point 1
    ...                   ...
    COLOR_ATTACHMENTn     output fragment color to image attached
                          at color attachment point n, where
                          n is MAX_COLOR_ATTACHMENTS - 1
    -------------------------------------------------------------------
    Table 10.nnn:  Arguments to DrawBuffer(s) and ReadBuffer when the
    context is bound to an application-created framebuffer object, and
    the buffers they indicate

    If the GL is bound to the window-system-provided 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 by
    the window-system (including those listed in table 10.nnn), then the
    error INVALID_OPERATION results.

    If the GL is bound to the application-created framebuffer and
    DrawBuffer is supplied with a constant from table 4.4, or
    COLOR_ATTACHMENTm where m is greater than or equal to
    MAX_COLOR_ATTACHMENTS, then the error INVALID_OPERATION results.

    If DrawBuffer is supplied with a constant that is neither legal for
    the window-system provided framebuffer nor legal for an
    application-created framebuffer object, then the error INVALID_ENUM
    results.

    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 enumerant listed in <bufs> must be one of the values from
    tables 10.nnn or 11.nnn.  Otherwise, INVALID_ENUM is generated.
    Further, acceptable values for the constants in <bufs> depend on
    whether the GL is using the default window-system-provided
    framebuffer (i.e., FRAMEBUFFER_BINDING_EXT is zero), or an
    application-created framebuffer object (i.e.,
    FRAMEBUFFER_BINDING_EXT is non-zero).  For more information about
    application-created 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 window-system-provided framebuffer, and the buffers that
      they indicate.

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

    If the GL is bound to an application-created 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.  INVALID_VALUE 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 window-system-provided and application-created
    framebuffers, 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 window-system-provided 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, then the error INVALID_OPERATION results.

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

    If DrawBuffers is supplied with a constant that is neither legal for
    the window-system provided framebuffer nor legal for an
    application-created framebuffer object, then the error INVALID_ENUM
    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 is an integer
    for each supported fragment color.  For the default
    window-system-provided 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 application-created framebuffer
    objects, the initial value of draw buffer for fragment color zero is
    COLOR_ATTACHMENT0_EXT.  For both the window-system-provided
    framebuffer and application-created framebuffers, the initial state
    of draw buffers for fragment colors other then zero is NONE."

    Modify section 4.2.2, page 185, third paragraph to read as follows:

    "The command

            void StencilMask( uint mask );

    controls the writing of particular bits into the stencil planes. The
    least significant s bits of mask comprise an integer mask (s is the
    number of bits in the stencil buffer), just as for IndexMask. The
    initial state is for the stencil plane mask to be 32 ones."

    In section 4.3.2, page 190, 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 window-system-provided
    framebuffer (i.e., FRAMEBUFFER_BINDING_EXT is zero), or an
    application-created framebuffer object (i.e.,
    FRAMEBUFFER_BINDING_EXT is non-zero).  For more information about
    application-created framebuffer objects, see section 4.4.

    If the object bound to FRAMEBUFFER_BINDING_EXT is not "framebuffer
    complete" (as defined in section 4.4.4.2), then ReadPixels generates
    the error INVALID_FRAMEBUFFER_OPERATION_EXT.  If ReadBuffer is
    supplied with a constant that is neither legal for the window-system
    provided framebuffer, nor legal for an application-created
    framebuffer object, then the error INVALID_ENUM results.

    When FRAMEBUFFER_BINDING_EXT is zero, i.e. the default
    window-system-provided framebuffer, <src> must be one of the values
    listed in table 4.4. 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
    window-system-provided framebuffer, the initial setting for
    ReadBuffer is FRONT if there is no back buffer and BACK otherwise.

    When the GL is using an application-created 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_EXT enables reading from the
    image attached to the framebuffer at COLOR_ATTACHMENTi_EXT.
    ReadPixels generates INVALID_OPERATION if it attempts to select a
    color buffer while READ_BUFFER is NONE.  For application-created
    framebuffer objects, the initial setting for ReadBuffer is
    COLOR_ATTACHMENT0_EXT.

    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 FRAMEBUFFER_BINDING_EXT 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", add a paragraph before
    "Conversion of RGBA values" on page 191:

    "When 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.  The internal component values are
    converted to red, green, blue, and alpha values as specified in the
    row of table 12.nnn corresponding to the internal format of the
    image attached to READ_BUFFER."

    Add the following text to section 4.3.3, page 194, inside the
    definiton of CopyPixels:

    "Furthermore, 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*.  INVALID_FRAMEBUFFER_OPERATION_EXT will be
    generated if an attempt is made to execute one of these operations,
    or CopyPixels, while the object bound to FRAMEBUFFER_BINDING_EXT is
    not "framebuffer complete" (as defined in section 4.4.4.2)."

    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, stencil, accum, and aux logical buffers.  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 operations described in chapter 4 affect the images attached to
    the framebuffer object bound to the target FRAMEBUFFER_EXT.  By
    default, framebuffer bound to the target FRAMEBUFFER_EXT is zero,
    specifying the default implementation dependent framebuffer provided
    by the windowing system.  When the framebuffer bound to target
    FRAMEBUFFER_EXT is not zero, but instead names an
    application-created framebuffer object, then the operations
    described in chapter 4 affect the application-created framebuffer
    object rather than the default framebuffer.

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

        void BindFramebufferEXT(enum target, uint framebuffer);

    with <target> set to FRAMEBUFFER_EXT and <framebuffer> set to the
    unused 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.  There are
    MAX_COLOR_ATTACHMENTS_EXT color attachment points, plus one each for
    the depth and stencil attachment points.

    BindFramebufferEXT may also be used to bind an existing framebuffer
    object to <target>.  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.  The current FRAMEBUFFER_EXT binding can be
    queried using GetIntegerv(FRAMEBUFFER_BINDING_EXT).

    While a framebuffer object is bound to the target FRAMEBUFFER_EXT,
    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.  In
    particular, 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
    currently bound framebuffer object.  The framebuffer object bound to
    the target FRAMEBUFFER_EXT is used as the destination of fragment
    operations and as the source of pixel reads such as ReadPixels, as
    described in chapter 4.

    In the initial state, the reserved name zero is bound to the target
    FRAMEBUFFER_EXT.  There is no application-created framebuffer object
    corresponding to the name zero.  Instead, the name zero refers to
    the window-system-provided framebuffer.  All queries and operations
    on the framebuffer while the name zero is bound to the target
    FRAMEBUFFER_EXT operate on this default framebuffer.  On some
    implementations, the properties of the default
    window-system-provided framebuffer can change over time (e.g., in
    response to window-system events such as attaching the context to a
    new window-system drawable.)

    Application-created framebuffer objects (i.e., those with a non-zero
    name) differ from the default window-system-provided framebuffer in
    a few important ways.  First and foremost, unlike the
    window-system-provided framebuffer, application-created-framebuffers
    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,
            application-created 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_EXT
            through COLOR_ATTACHMENTn_EXT.

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

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

          - There is no multisample buffer so the value of the
            implementation-dependent state variables SAMPLES and
            SAMPLE_BUFFERS are both 0

          - 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.

    Framebuffer objects are deleted by calling

      void DeleteFramebuffersEXT(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 the target FRAMEBUFFER_EXT is deleted, it is as
    though BindFramebufferEXT had been executed with the <target> of
    FRAMEBUFFER_EXT and <framebuffer> of zero.  Unused names in
    <framebuffers> are silently ignored, as is the value zero.

    The command

      void GenFramebuffersEXT(sizei n, uint *ids);

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

    4.4.2 Attaching Images to Framebuffer Objects

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

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

    For each logical buffer, the 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 an unused name to RENDERBUFFER_EXT.  The binding is effected
    by calling

        void BindRenderbufferEXT( enum target, uint renderbuffer );

    with <target> set to RENDERBUFFER_EXT 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.

    BindRenderbufferEXT 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_EXT.  There is no renderbuffer object corresponding to
    the name zero, so client attempts to modify or query renderbuffer
    state for the target RENDERBUFFER_EXT while zero is bound will
    generate GL errors, as described in section 6.1.3.

    Using GetIntegerv, the current RENDERBUFFER_EXT binding can be
    queried as RENDERBUFFER_BINDING_EXT.

    Renderbuffer objects are deleted by calling

        void DeleteRenderbuffersEXT( 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_EXT is deleted, it is as though
    BindRenderbufferEXT had been executed with the <target>
    RENDERBUFFER_EXT 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 GenRenderbuffersEXT( sizei n, uint *renderbuffers );

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

    The command

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

    establishes the data storage, format, and dimensions of a
    renderbuffer object's image.  <target> must be RENDERBUFFER_EXT.
    <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_EXT, the 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. RenderbufferStorageEXT deletes
    any existing data store for the renderbuffer and the contents of the
    data store after calling RenderbufferStorageEXT are undefined.

    Sized                 Base               S
    Internal Format       Internal format    Bits
    ---------------       ---------------    ----
    STENCIL_INDEX1_EXT    STENCIL_INDEX      1
    STENCIL_INDEX4_EXT    STENCIL_INDEX      4
    STENCIL_INDEX8_EXT    STENCIL_INDEX      8
    STENCIL_INDEX16_EXT   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 actual resolution in bits of each component of the
    allocated image can be queried with GetRenderbufferParameteriv as
    described in section 6.1.3.

    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 FramebufferRenderbufferEXT(enum target,
                                        enum attachment,
                                        enum renderbuffertarget,
                                        uint renderbuffer);

    <target> must be FRAMEBUFFER_EXT.  INVALID_OPERATION is generated if
    the current value of FRAMEBUFFER_BINDING_EXT is zero when
    FramebufferRenderbufferEXT is called.  <attachment> should be set to
    one of the attachment points of the framebuffer listed in table
    1.nnn.  <renderbuffertarget> must be RENDERBUFFER_EXT 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 INVALID_OPERATION is generated.  If
    <renderbuffer> is zero, then the value of <renderbuffertarget> is
    ignored.

    If <renderbuffer> is not zero and if FramebufferRenderbufferEXT 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_EXT for the specified attachment
    point is set to RENDERBUFFER_EXT and the value of
    FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT 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, on the other
    hand, the attachment is not successful, then no change is made to
    the state of either the renderbuffer object or the framebuffer
    object.

    Calling FramebufferRenderbufferEXT 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.

    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 FramebufferRenderbufferEXT() 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_ATTACHMENT0_EXT ... COLOR_ATTACHMENTn_EXT (where n is from 0 to MAX_COLOR_ATTACHMENTS_EXT-1)
        DEPTH_ATTACHMENT_EXT
        STENCIL_ATTACHMENT_EXT
        --------------------------------------------------------------------------------------
        Table 1.nnn:  "List of framebuffer attachment points"

    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 FramebufferTexture1DEXT(enum target, enum attachment,
                                     enum textarget, uint texture,
                                     int level);
        void FramebufferTexture2DEXT(enum target, enum attachment,
                                     enum textarget, uint texture,
                                     int level);
        void FramebufferTexture3DEXT(enum target, enum attachment,
                                     enum textarget, uint texture,
                                     int level, int zoffset);

    In all three routines, <target> must be FRAMEBUFFER_EXT.
    INVALID_OPERATION is generated if the current value of
    FRAMEBUFFER_BINDING_EXT is zero when FramebufferTexture{1D|2D|3D}EXT
    is called.  <attachment> must be one of the attachment points of the
    framebuffer listed in table 1.nnn.

    In all three routines, if <texture> is zero, then <textarget>,
    <level>, and <zoffset> are ignored.  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, GL_INVALID_OPERATION 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
    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 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 MAX_TEXTURE_SIZE.  Otherwise,
    INVALID_VALUE is generated.

    <zoffset> specifies the z-offset of a 2-dimensional image within a
    3-dimensional texture.  INVALID_VALUE is generated if <zoffset> is
    larger than MAX_3D_TEXTURE_SIZE-1.

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

    For FramebufferTexture2DEXT, 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 FramebufferTexture3DEXT, if <texture> is not zero, then
    <textarget> must be TEXTURE_3D.

    If <texture> is not zero, and if FramebufferTexture{1D|2D|3D}EXT 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_EXT for the specified attachment
    point is set to TEXTURE and the value of
    FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT 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
    cubemap 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_3D_ZOFFSET for the named
    attachment point is set to <zoffset>.  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, on the other hand, the attachment is not
    successful, then no change is made to the state of either the
    texture object or the framebuffer object.

    Calling FramebufferTexture{1D|2D|3D}EXT with <texture> name zero
    will detach the image identified by <attachment>, if any, in the
    framebuffer currently bound to <target>.  All state values of the
    attachment point specified by <attachment> are set to their default
    values listed in table 5.nnn.

    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{1D|2D|3D}EXT() had been called, with a
    <texture> of 0, 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

    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 in 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_EXT 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_EXT for attachment point
          <A> is within the 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, we consider it "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,
          or
        - if FRAGMENT_PROGRAM_ARB is enabled and the currently bound
          fragment program contains any instructions that
          sample from the texture object <T> bound to <U>,
          or
        - if 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 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.  A framebuffer must be complete to effectively be used
    as the destination for GL framebuffer rendering operations and the
    source for GL framebuffer read operations.

    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": 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 if it is one of the sized internal formats
          from table 3.16 that has a depth-renderable base internal
          format.  No other formats are depth-renderable.

        * An internal format is "stencil-renderable" if it is
          STENCIL_INDEX, or if it is one of the sized internal formats
          from table 2.nnn that has a stencil-renderable base internal
          format.  No other formats are stencil-renderable.

    4.4.4.1 Framebuffer Attachment Completeness

    If the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT 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_EXT 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_EXT, and of the
        type specified by FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT.

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

      * If FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT is TEXTURE and
        FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT names a 3-dimensional
        texture, then FRAMEBUFFER_ATTACHMENT_TEXTURE_ZOFFSET_EXT must be
        smaller than the depth of the texture.

      * If <attachment> is one of COLOR_ATTACHMENT0_EXT through
        COLOR_ATTACHMENTn_EXT, then <image> must have a color-renderable
        internal format.

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

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

    4.4.4.2 Framebuffer Completeness

    In this subsection, each rule is followed by an error enum enclosed
    in { brackets }.  Sections 4.4.4.2 and 4.4.4.3 explains the
    relevance of the error enums.

    The framebuffer object <target> is said to be "framebuffer complete"
    if it is the window-system-provided framebuffer, or if all the
    following conditons are true:

      * All framebuffer attachment points are "framebuffer attachment
        complete".
        { FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT }

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

      * All attached images have the same width and height.
        { FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT }

      * All images attached to the attachment points
        COLOR_ATTACHMENT0_EXT through COLOR_ATTACHMENTn_EXT must have
        the same internal format.
        { FRAMEBUFFER_INCOMPLETE_FORMATS_EXT }

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

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

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

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

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

      - Binding to a different framebuffer with BindFramebufferEXT.

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

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

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

      - Changing the width, height, or internal format of a renderbuffer
        that is attached to the framebuffer by calling
        RenderbufferStorageEXT.

      - 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.

    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_EXT. There
    must exist, however, at least one combination of internal formats
    for which the framebuffer cannot be FRAMEBUFFER_UNSUPPORTED_EXT.

    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 CheckFramebufferStatusEXT(enum target);

    If <target> is not FRAMEBUFFER_EXT, INVALID_ENUM is generated. If
    CheckFramebufferStatusEXT is called within a Begin/End pair,
    INVALID_OPERATION is generated.  If CheckFramebufferStatusEXT
    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_EXT is returned.

    4.4.4.3 Effects of Framebuffer Completeness on Framebuffer Operations

    If the currently bound framebuffer is not framebuffer complete, then
    it is an error to attempt to use the framebuffer for writing or
    reading.  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_EXT 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
    FRAMEBUFFER_BINDING_EXT, to the state of the currently bound
    framebuffer object, or to an image attached to the currently bound
    framebuffer object.

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

    When FRAMEBUFFER_BINDING_EXT 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 FRAMEBUFFER_BINDING_EXT 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
    FRAMEBUFFER_BINDING_EXT, the state of the currently bound
    framebuffer object, and the state of the images attached to the
    currently bound framebuffer object.

XXX [from jon leech] describe derivation of red green and blue size


    4.4.6 Mapping between Pixel and Element in Attached Image

    When FRAMEBUFFER_BINDING_EXT 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 = (zoffset - b)

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

    (x[w], y[w]) corresponds to a border texel if x[w] or y[w] or
    zoffset is less than the border size, or if x[w] or y[w] or zoffset
    is greater than the border size plus the width or height or depth,
    resp., of the texture image.

    Conversion to Framebuffer-Attachable Image Components

    When an enabled color value is written to the framebuffer while
    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 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 1.5 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: ..., GenFramebuffersEXT, BindFramebufferEXT,
    DeleteFramebuffersEXT, CheckFramebufferStatusEXT,
    GenRenderbuffersEXT, BindRenderbufferEXT, DeleteRenderbuffersEXT,
    RenderbufferStorageEXT, FramebufferTexture1DEXT,
    FramebufferTexture2DEXT, FramebufferTexture3DEXT,
    FramebufferRenderbufferEXT, GenerateMipmapEXT..."

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

    Add to section 6.1.3, Enumerated Queries:

        In the list of state query functions, add:

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

            <target> must be FRAMEBUFFER_EXT.  <attachment> must be one
            of the attachment points of the framebuffer listed in table
            1.nnn.  <pname> must be one of the following:
            FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT,
            FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT,
            FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT,
            FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT,
            FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT.

            If the framebuffer currently bound to <target> is zero, then
            INVALID_OPERATION is generated.

            Upon successful return from
            GetFramebufferAttachmentParameterivEXT, if <pname> is
            FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT, then param will
            contain one of NONE, TEXTURE, or RENDERBUFFER_EXT,
            identifying the type of object which contains the attached
            image.

            If the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT is
            RENDERBUFFER_EXT, then

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

                Otherwise, INVALID_ENUM is generated.

            If the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT is
            TEXTURE, then

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

                If <pname> is FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT,
                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_EXT and the
                texture object named
                FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT 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_3D_ZOFFSET_EXT and the
                texture object named
                FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT is a
                3-dimensional texture, then <params> will contain the
                zoffset of the 2D image of the 3D texture object which
                contains the attached image.  Otherwise <params> will
                contain the value zero.

                Otherwise, INVALID_ENUM is generated.

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

            <target> must be RENDERBUFFER_EXT.  <pname> must be one of
            the symbolic values in table 8.nnn.

            If the renderbuffer currently bound to <target> is zero,
            then INVALID_OPERATION is generated.

            Upon successful return from GetRenderbufferParameterivEXT,
            if <pname> is RENDERBUFFER_WIDTH_EXT,
            RENDERBUFFER_HEIGHT_EXT, or
            RENDERBUFFER_INTERNAL_FORMAT_EXT, then <params> will contain
            the width in pixels, height in pixels, or internal format,
            respectively, of the image of the renderbuffer currently
            bound to <target>.

            Upon successful return from GetRenderbufferParameterivEXT,
            if <pname> is RENDERBUFFER_RED_SIZE_EXT,
            RENDERBUFFER_GREEN_SIZE_EXT, RENDERBUFFER_BLUE_SIZE_EXT,
            RENDERBUFFER_ALPHA_SIZE_EXT, RENDERBUFFER_DEPTH_SIZE_EXT, or
            RENDERBUFFER_STENCIL_SIZE_EXT, 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, INVALID_ENUM is generated."

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

    6.1.14 Framebuffer Object Queries

        The command

            boolean IsFramebufferEXT( 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,
        IsFramebufferEXT return FALSE.

    6.1.15 Renderbuffer Object Queries

        The command

            boolean IsRenderbufferEXT( 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,
        IsRenderbufferEXT return FALSE.


Errors

    The error INVALID_OPERATION is generated if FRAMEBUFFER_BINDING_EXT
    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_EXT through COLOR_ATTACHMENTn_EXT, where n is
    MAX_COLOR_ATTACHMENTS_EXT - 1.

    The error INVALID_OPERATION is generated if FRAMEBUFFER_BINDING_EXT
    is non-zero and DrawBuffer, DrawBuffers, or ReadBuffer is called
    with a <buf> constant (other than NONE) that is not in the range
    COLOR_ATTACHMENT0_EXT through COLOR_ATTACHMENTn_EXT, where n is
    MAX_COLOR_ATTACHMENTS_EXT - 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_EXT is generated if the
    value of FRAMEBUFFER_STATUS_EXT is not FRAMEBUFFER_COMPLETE_EXT when
    any attempts to render to or read from the framebuffer are made.

    The error INVALID_OPERATION is generated if
    GetFramebufferAttachmentParameterivEXT is called while the value of
    FRAMEBUFFER_BINDING_EXT is zero.

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

    The error INVALID_OPERATION is generated if RenderbufferStorageEXT
    or GetRenderbufferParameterivEXT is called while the value of
    RENDERBUFFER_BINDING_EXT is zero.

    The error INVALID_ENUM is generated if
    GetFramebufferAttachmentParameterivEXT is called with an
    <attachment> other than COLOR_ATTACHMENT0_EXT through
    COLOR_ATTACHMENTn_EXT, where n is MAX_COLOR_ATTACHMENTS_EXT - 1.

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

    The error INVALID_ENUM is generated if
    GetFramebufferAttachmentParameterivEXT is called with a <pname>
    other than FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT,
    FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT,
    FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT, or
    FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT when the type of the
    attached object at the named attachment point is TEXTURE.

    The error INVALID_ENUM is generated if GetRenderbufferParameterivEXT
    is called with a <pname> other than RENDERBUFFER_WIDTH_EXT,
    RENDERBUFFER_HEIGHT_EXT, or RENDERBUFFER_INTERNAL_FORMAT_EXT,
    GL_RENDERBUFFER_RED_SIZE, GL_RENDERBUFFER_GREEN_SIZE,
    GL_RENDERBUFFER_BLUE_SIZE, GL_RENDERBUFFER_ALPHA_SIZE,
    GL_RENDERBUFFER_DEPTH_SIZE, or GL_RENDERBUFFER_STENCIL_SIZE.

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

    The error INVALID_ENUM is generated if RenderbufferStorageEXT is
    called with an <internalformat> that is not RGB, RGBA,
    DEPTH_COMPONENT, STENCIL_INDEX, 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, or STENCIL_INDEX.

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

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

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

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

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

    The error INVALID_VALUE is generated if FramebufferTexture2DEXT
    is called with a <level> that is greater than the log base 2 of
    MAX_CUBE_MAP_TEXTURE_SIZE and <texture> is a non-zero cubemap
    texture object name.

    The error INVALID_VALUE is generated if FramebufferTexture3DEXT is
    called with a <level> greater than the log base 2 of the
    MAX_3D_TEXTURE_SIZE and <texture> is not zero.

    The error INVALID_VALUE is generated if FramebufferTexture3DEXT is
    called with a <zoffset> that is larger than MAX_3D_TEXTURE_SIZE-1
    and <texture> is not zero.

    The error INVALID_ENUM is generated if CheckFramebufferStatusEXT is
    called and <target> is not FRAMEBUFFER_EXT.

    The error INVALID_OPERATION is generated if
    CheckFramebufferStatusEXT 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 RenderbufferStorageEXT.

    The error INVALID_OPERATION is generated if GenerateMipmapEXT 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

New State

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

    Get Value                          Type    Get Command                Initial Value           Description             Section       Attribute
    -------------------------------    ------  -------------              --------------          --------------------    ------------  ---------
    FRAMEBUFFER_BINDING_EXT            Z       GetIntegerv                0                       name of framebuffer     4.4.1         -
                                                                                                  object bound to
                                                                                                  FRAMEBUFFER_EXT
                                                                                                  target

    (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             4.3.2         pixel

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



    (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_EXT            Z       GetFramebufferAttachmentParameterivEXT    NONE           type of                 4.4.2.2 and   -
                                                                                                                       image attached to       4.4.2.3
                                                                                                                       framebuffer attachment
                                                                                                                       point

    FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT            Z       GetFramebufferAttachmentParameterivEXT    0              name of object          4.4.2.2 and   -
                                                                                                                       attached to             4.4.2.3
                                                                                                                       framebuffer attachment
                                                                                                                       point

    FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT          Z       GetFramebufferAttachmentParameterivEXT    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_EXT  Z+      GetFramebufferAttachmentParameterivEXT    TEXTURE_       cubemap face of         4.4.2.2 and   -
                                                                                                        CUBE_MAP_      texture image           4.4.2.3
                                                                                                        POSITIVE_X     attached, if object
                                                                                                                       attached is cubemap
                                                                                                                       texture.

    FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT     Z       GetFramebufferAttachmentParameterivEXT    0              zoffset of              4.4.2.2 and   -
                                                                                                                       texture image           4.4.2.3
                                                                                                                       attached, if object
                                                                                                                       attached is 3D
                                                                                                                       texture.



    (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_EXT           Z       GetIntegerv     0              renderbuffer object     4.4.2.1       -
                                                                              bound to
                                                                              RENDERBUFFER_EXT


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

    Get Value                          Type    Get Command                    Initial Value  Description             Section       Attribute
    -------------------------------    ------  -------------                  -------------  --------------------    ------------  ---------
    RENDERBUFFER_WIDTH_EXT             Z       GetRenderbufferParameterivEXT  0              width of renderbuffer   4.4.2.1       -

    RENDERBUFFER_HEIGHT_EXT            Z       GetRenderbufferParameterivEXT  0              height of renderbuffer  4.4.2.1       -

    RENDERBUFFER_INTERNAL_FORMAT_EXT   Z+      GetRenderbufferParameterivEXT  RGBA           internal format         4.4.2.1       -
                                                                                             of renderbuffer

    RENDERBUFFER_RED_SIZE_EXT          Z       GetRenderbufferParameterivEXT  0              size in bits of         4.4.2.1       -
                                                                                             renderbuffer image's
                                                                                             red component

    RENDERBUFFER_GREEN_SIZE_EXT        Z       GetRenderbufferParameterivEXT  0              size in bits of         4.4.2.1       -
                                                                                             renderbuffer image's
                                                                                             green component

    RENDERBUFFER_BLUE_SIZE_EXT         Z       GetRenderbufferParameterivEXT  0              size in bits of         4.4.2.1       -
                                                                                             renderbuffer image's
                                                                                             blue component

    RENDERBUFFER_ALPHA_SIZE_EXT        Z       GetRenderbufferParameterivEXT  0              size in bits of         4.4.2.1       -
                                                                                             renderbuffer image's
                                                                                             alpha component

    RENDERBUFFER_DEPTH_SIZE_EXT        Z       GetRenderbufferParameterivEXT  0              size in bits of         4.4.2.1       -
                                                                                             renderbuffer image's
                                                                                             depth component

    RENDERBUFFER_STENCIL_SIZE_EXT      Z       GetRenderbufferParameterivEXT  0              size in bits of         4.4.2.1       -
                                                                                             renderbuffer image's
                                                                                             stencil component

Move the following existing state from "Implementation Dependent
Values", tables 6.31-6.36 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
    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_EXT   Z+    GetIntegerv     1                Maximum number of       4.4.2.2  -
                                                                       attachment points
                                                                       for color buffers
                                                                       when using framebuffer
                                                                       objects

New Implementation Dependent State

    Get Value                   Type  Get Command     Minimum Value    Description             Section  Attribute
    ---------                   ----  -----------     -------------    -------------------     -------  ---------
    MAX_RENDERBUFFER_SIZE_EXT   Z+    GetIntegerv     1                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 FRAMEBUFFER_BINDING_EXT 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_framebuffer_object and OpenGL 3.0

    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 ARB_texture_rectangle

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

Dependencies on EXT_packed_depth_stencil

    If EXT_packed_depth_stencil is not supported, then all references to
    DEPTH_STENCIL internal formats should be ignored.

Dependencies on NV_float_buffer

    If NV_float_buffer is not supported, then all references to the
    following internal formats should be ignored: FLOAT_R_NV,
    FLOAT_RG_NV, FLOAT_RGB_NV, and FLOAT_RGBA_NV.

Dependencies on NV_texture_shader

    The following base internal formats are not color-renderable,
    depth-renderable, or stencil-renderable: HILO_NV, DSDT_NV,
    DSDT_MAG_NV, and DSDT_MAG_INTENSITY_NV.

GLX Protocol

        Seventeen new GL commands are added.

        The following ten rendering commands are sent to the sever as part
        of a glXRender request:

        BindRenderbufferEXT
            2        12              rendering command length
            2        4316            rendering command opcode
            4        ENUM            target
            4        CARD32          renderbuffer

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

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

        BindFramebufferEXT
            2        12              rendering command length
            2        4319            rendering command opcode
            4        ENUM            target
            4        CARD32          framebuffer

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

        FramebufferTexture1DEXT
            2        24              rendering command length
            2        4321            rendering command opcode
            4        ENUM            target
            4        ENUM            attachement
            4        ENUM            textarget
            4        CARD32          texture
            4        CARD32          level

        FramebufferTexture2DEXT
            2        24              rendering command length
            2        4322            rendering command opcode
            4        ENUM            target
            4        ENUM            attachement
            4        ENUM            textarget
            4        CARD32          texture
            4        CARD32          level

        FramebufferTexture3DEXT
            2        28              rendering command length
            2        4323            rendering command opcode
            4        ENUM            target
            4        ENUM            attachement
            4        ENUM            textarget
            4        CARD32          texture
            4        CARD32          level
            4        CARD32          zoffset

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

        GenerateMipmapEXT
            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:

        IsRenderbufferEXT
            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

        GenRenderbuffersEXT
            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

        GetRenderbufferParameterivEXT
            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

        IsFramebufferEXT
            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

        GenFramebuffersEXT
            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

        CheckFramebufferStatusEXT
            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

        GetFramebufferAttachementParameterivEXT
            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 glCheckFramebufferStatusEXT.

    #define CHECK_FRAMEBUFFER_STATUS()                            \
      {                                                           \
        GLenum status;                                            \
        status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); \
        switch(status) {                                          \
          case GL_FRAMEBUFFER_COMPLETE_EXT:                       \
            break;                                                \
          case GL_FRAMEBUFFER_UNSUPPORTED_EXT:                    \
            /* 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
        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);

        // Set up color_tex and depth_rb for render-to-texture
        glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
                                  GL_COLOR_ATTACHMENT0_EXT,
                                  GL_TEXTURE_2D, color_tex, 0);
        glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
                                     GL_DEPTH_ATTACHMENT_EXT,
                                     GL_RENDERBUFFER_EXT, 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
        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 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) {
            glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);
            glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
                                      GL_COLOR_ATTACHMENT0_EXT,
                                      GL_TEXTURE_2D, color_tex, 0);
            CHECK_FRAMEBUFFER_STATUS();
        }

        draw_to_texture();

        glBindTexture (GL_TEXTURE_2D, color_tex);
        if (useFramebuffer) {
            glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 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.

        glGenFramebuffersEXT(1, &fb);
        glGenTextures(1, &color_tex);
        glGenRenderbuffersEXT(1, &depth_rb);
        glGenRenderbuffersEXT(1, &stencil_rb);

        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 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);
        glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
                                  GL_COLOR_ATTACHMENT0_EXT,
                                  GL_TEXTURE_2D, color_tex, 0);

        // initialize depth renderbuffer
        glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depth_rb);
        glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT,
                                 GL_DEPTH_COMPONENT24, 512, 512);
        glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
                                     GL_DEPTH_ATTACHMENT_EXT,
                                     GL_RENDERBUFFER_EXT, depth_rb);

        // initialize stencil renderbuffer
        glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, stencil_rb);
        glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT,
                                 GL_STENCIL_INDEX, 512, 512);
        glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
                                     GL_STENCIL_ATTACHMENT_EXT,
                                     GL_RENDERBUFFER_EXT, stencil_rb);

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

        loop {
            glBindTexture(GL_TEXTURE_2D, 0);
            glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);

            <draw to the texture>

            glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 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;

        glGenFramebuffersEXT(N, fb_array);
        glGenTextures(N, color_tex_array);
        glGenRenderbuffersEXT(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
          glGenerateMipmapEXT(GL_TEXTURE_2D);
        }

        // initialize depth renderbuffer
        glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depth_rb);
        glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT,
                                 GL_DEPTH_COMPONENT24, 512, 512);

        // setup framebuffers, sharing depth
        for (int i=0; i<N; i++) {
          glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb_array[i]);
          glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
                                    GL_COLOR_ATTACHMENT0_EXT,
                                    GL_TEXTURE_2D, color_tex_array[i], 0);
          glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
                                       GL_DEPTH_ATTACHMENT_EXT,
                                       GL_RENDERBUFFER_EXT, 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++) {
              glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb_array[i]);
              <draw to texture i>
            }

            glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);

            // automatically generate mipmaps
            for (int i=0; i<N; i++) {
              glBindTexture(GL_TEXTURE_2D, color_tex_array[i]);
              glGenerateMipmapEXT(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.

        glGenFramebuffersEXT(1, &fb);
        glGenTextures(1, &color_tex);
        glGenRenderbuffersEXT(1, &depth_rb);

        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 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);
        glGenerateMipmapEXT(GL_TEXTURE_2D);
        glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
                                  GL_COLOR_ATTACHMENT0_EXT,
                                  GL_TEXTURE_2D, color_tex, 0);

        // initialize depth renderbuffer
        glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depth_rb);
        glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT,
                                 GL_DEPTH_COMPONENT24, 512, 512);
        glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
                                     GL_DEPTH_ATTACHMENT_EXT,
                                     GL_RENDERBUFFER_EXT, depth_rb);

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

        loop {
            glBindTexture(GL_TEXTURE_2D, 0);

            glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);
            glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
                                      GL_COLOR_ATTACHMENT0_EXT,
                                      GL_TEXTURE_2D, color_tex, 0);
            glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
                                         GL_DEPTH_ATTACHMENT_EXT,
                                         GL_RENDERBUFFER_EXT, depth_rb);

            <draw to the base level of the color texture>

            // custom-generate successive mipmap levels
            glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
                                         GL_DEPTH_ATTACHMENT_EXT,
                                         GL_RENDERBUFFER_EXT, 0);
            glBindTexture(GL_TEXTURE_2D, color_tex);
            foreach (level > 0, in order of increasing values of level) {
                glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
                                          GL_COLOR_ATTACHMENT0_EXT,
                                          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);

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


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

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

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

                CreateFramebufferAttachableImage();

                AttachFramebufferAttachableImageToFramebuffer();
            }

            status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
            switch(status)
            {
                case GL_FRAMEBUFFER_COMPLETE_EXT:
                    success = true;
                    done = true;
                    break;

                case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
                    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
        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);

        // Set up depth_tex for render-to-texture
        glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
                                  GL_DEPTH_ATTACHMENT_EXT,
                                  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
        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 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
        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);
        glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
                                  GL_COLOR_ATTACHMENT0_EXT,
                                  GL_TEXTURE_2D, color_texA, 0);
        glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
                                  GL_COLOR_ATTACHMENT1_EXT,
                                  GL_TEXTURE_2D, color_texB, 0);
        glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
                                     GL_DEPTH_ATTACHMENT_EXT,
                                     GL_RENDERBUFFER_EXT, depth_rb);

        // Enable both attachments as draw buffers
        GLenum drawbuffers = {GL_COLOR_ATTACHMENT0_EXT,
                              GL_COLOR_ATTACHMENT1_EXT};
        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
        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 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>

Issues

    (1)  We obviously won't call this "ARB_compromise_buffers", so
         what name should we use?

            RESOLUTION: resolved, EXT_framebuffer_object

            Possibilities considered include:
                EXT_framebuffer
                EXT_framebuffer_object
                EXT_renderable_buffers
                EXT_renderbuffer
                EXT_superbuffers (hah!)
                EXT_renderable_image
                EXT_render_image

            The lead candidates were EXT_renderable_image and
            EXT_framebuffer_object Since this extension introduced both
            new concepts into OpenGL, this was a bit of a toss up.
            EXT_framebuffer_object was chosen based on a weak precedent
            given by EXT_texture_object and ARB_vertex_buffer_object

    (2)  Many developers complain about the OpenGL/glX/WGL/agl pbuffer
         API, which they use both to do "render to texture" and to do
         general offscreen (non-windowed) accelerated rendering.  This
         extension is intended to subsume, some and perhaps all of, the
         functionality currently handled by pbuffers.  Should this
         extension (initially?) support only render-to-texture or should
         it try to provide an OpenGL API to fully replace the pbuffer
         API?

            RESOLUTION:  This extension should fully replace the pbuffer API.

            The implication of this decision is that this API should provide
            a way to support rendering to offscreen buffers that are not
            textures.

    (3)  As a consequence of issue (2), this extension adds the concept of
         share-able, non-texturable renderable entitites that can be
         used as color buffers, depth buffers, stencil buffers, etc.
         The OpenGL spec refers to these entities as "logical buffers".
         What should this spec call them?

            RESOLUTION: "renderbuffer", (one word)

            We could just call them "logical buffers", but is there a
            better name?

            The group considered:
            logical buffer  - possible, kind of general
            render buffer   - clear, (one word or two?)
            renderable      - clear, but may conflict with glx "drawable"
            drawable        - confusing: glx "drawable" == gl "framebuffer"
            render surface  - possible
            render target   - possible
            image buffer    - may get confused with Tex"Image"
            image           - may get confused with Tex"Image"
            surface buffer  - too verbose?
            surface         - too general
            others???

            The group felt "render buffer " (or possibly "renderbuffer")
            provides for the clearest expression of the purpose for
            these buffers.

            We finally decided on "renderbuffer" because we didn't want
            to use "render" as an adjective to describe a generic
            buffer, but rather decided to coin a new compound word to
            describe this concept.

    (4)  How should the specification refer to the group of
         various types of objects that can be attached to the framebuffer
         attachment points?

            RESOLUTION:  The specification will use the phrase
            "framebuffer-attachable images" to mean the 2D array of
            pixels (image) of a "renderbuffer", a "texture", or any
            other items that could be attached to a framebuffer.

                Options considered include:
                  "render target"
                  "renderable image"
                  "framebuffer-attachable

            Initially, we chose the phrase "render target" for this but
            felt it didn't accurately capture the concept of a 2D array
            of pixels that was simultaneously useable as the storage of
            a texture object and the destination of rendering.

            We then tried to borrow the "image" language of OpenGL which
            describes texture's pixel arrays as "images" and we chose
            the term "renderable image".

            However, in the end, we felt that the salient characteristic
            of these images was that we could attach them to a
            framebuffer and settled on the term "framebuffer-attachable
            image".

    (5)  How should the specification refer to the places in a framebuffer
         that can hold a framebuffer-attachable image?

            RESOLUTION: This state is called an "attachment point" of
            the framebuffer.

            "attachment points" will be be used to describe the
            framebuffer state that holds a connection to a given
            framebuffer-attachable image (a renderbuffer image or a
            texture image). The framebuffer attachment points include
            the framebuffer's color buffers, stencil buffer, depth
            buffer, and aux buffer.

            The word "attach" is being used to refer to connecting one
            object to another.  "bind" refers to connecting an object to
            the context state.  A texture image can be attached to a
            framebuffer object, but a framebuffer object is bound into
            the context state vector.

    (6)  This extension adds the concept of collections of "logical
         buffers", to replace the window-system provided collection
         (drawable, or window) of logical buffers.  What should we call
         these?

            RESOLUTION:  "framebuffer"

            For the "collection of logical buffers" object, the group
            considered the names: "framebuffer", "renderTarget",
            "drawable".  We chose "framebuffer" since this is consistent
            with how the OpenGL specification already uses the word
            framebuffer.

    (7)  This extension introduces two new object types into the OpenGL:
         renderbuffer objects and framebuffer objects.  For handling
         these objects, there are two main object manipulation
         methodology precedents to choose from:

             1) "texture/program/vbo" object model:
                     app-supplied int handles,
                     Gen/is/Bind/Delete functions

             2) "GLSL" object model:
                     driver-supplied GLhandle handles,
                     Create/Delete/Attach, etc

         Which methodology should this extension use for each new object?

             RESOLUTION: Use Option (1), "texture" object methodology,
             for both "renderbuffer" objects and framebuffer objects.

             This is consistent with the June, 2004 ARB meeting vote to
             use the "texture" object methodlogy as the default object
             methodology.

    (8)  Do we need separate framebuffer objects?

            RESOLUTION: yes.

            The framebuffer object is an object to encapsulate the state
            of the framebuffer and the collection of
            framebuffer-attachable images attached to the logical buffer
            attachment points.  A question was raised early on about
            whether we should have separate, shareable framebuffer
            objects or we should fold a single framebuffer "object"
            state vector into the context.

            We decided to leave framebuffer objects in the API, with the
            understanding that we could easily remove them from the API
            and the spec later if a convincing case was argued for
            removing it.

            There are several reasons why framebuffer objects were
            introduced:

              FB1. It can be "expensive" (for some definition of
                   expensive) to validate the framebuffer and all its
                   attached objects.  There is a desire to be able to
                   easily recognize that a particular state. combination
                   has been seen and validated previously.

              FB2. There is some subset of GL context state which only
                   makes sense in its relationship to the current
                   framebuffer and attached images (red bits, green
                   bits, blue bits, etc, presence or absence of aux
                   buffers or depth buffers, current value of draw
                   buffer(s), read buffer, etc. etc).  It would be nice
                   if this state "tracked" changes to the current
                   framebuffer configuration by being part of the
                   framebuffer object state.

              FB3. For a while, we considered adding "intrinsic" or
                   "implicit" buffer storage to the framebuffer.  This
                   would be used for buffers that were either hidden
                   from the user, like the multisample buffer, or
                   perhaps needed to be explicitly formatted by the
                   driver.  If we did have this kind of "intrinsic"
                   storage, then framebuffers would be a lot like
                   textures and would have the same kinds of pressures
                   to minimize vram, sharing storage across objects and
                   contexts as textures did.  In fact, they would be
                   similar to cube map texture objects which had 6
                   attached face images, or mipmaped textures which had
                   a set of mipmap level images.  In the end we decided
                   not to use intrinsic buffers, - see issue (13) - but
                   we might decide to add them back in the future.  For
                   instance, one option for supporting multisampling is
                   to use an implicit multisample buffer.

              FB4. We realized that most of the "hard" issues introduced
                   by this extension were completely orthogonal to the
                   presence or absence of framebuffer objects.  All of
                   the same issues apply regardless of whether there is
                   a single non-default framebuffer as part of the
                   context or multiple framebuffer objects.  These
                   issues about attaching, (binding) objects,
                   reformatting attached (or bound) images via
                   TexImage/RenderbufferStorage, pixel format
                   combinations, framebuffer completeness, and the
                   relationship between a non-"default" framebuffer and
                   the legacy window sytem framebuffer and pixel format
                   all come in to play either way.  So there is actually
                   little implementation or conceptual cost incurred by
                   the introduction of these framebuffer objects.

            There were also a few reasons why we considered *not* adding
            framebuffer objects:

              NoFB1. In the absence of "intrinsic" buffers, framebuffer
                     objects only really consist of the attachment
                     state.  It is convenient to encapsulate this state
                     into an object, but one could ask if it's any more
                     convenient than say a "blend state" object or a
                     "texture unit attachment state" object, which to
                     date, we have chosen not to add into OpenGL.

              NoFB2. As a "state-only" object, there's a question about
                     how much state should be included - at least the
                     attachment state should be included, but what about
                     draw buffers state, what about the viewport state,
                     what about other state?  Since drawing the line is
                     hard, we questioned whether we needed these
                     objects.

              NoFB3. Some amount of the functionality of the framebuffer
                     objects could be implemented by the application
                     with the appropriate use of display lists.

            In weighing (FB1), expense of validating framebuffer state,
            versus (NoFB1), not wanting to introduce "state only"
            objects, we realized that framebuffer validation is more
            expensive than the blend state (for which there is no object
            in GL) and less expensive than a fragment program (for which
            there is an object in GL).  While it's not exactly clear
            precisely where on the spectrum of "expense" the framebuffer
            validation lies, we decided that it may be expensive enough
            to justify creating a new object type.  So we retained
            framebuffer objects in the API now, with the understanding
            that if we change our minds it's easier to rip them out
            later than it is to add them back in later.

    (9)  Should the routine which allocates a renderbuffer accept an
         image to initialize the buffer, analogous to how TexImage
         works?

            RESOLUTION: no, it should allocate uninitialized storage

            We could have allowed a renderbuffer "image" specification
            routine, but this would essentially serve the same purpose
            as a combined "allocate renderbuffer followed by DrawPixels"
            routine so we decided it was extraneous.  The primary
            purpose of these buffers is to store rendered output anyway,
            so there was not sufficient demand to support an optimized
            path for data initialization. See related issue (10).

    (10) What should we call the routine that allocates storage for the
         renderbuffer?  This routine would be the moral equivalent of
         glTexImage.

            RESOLUTION: RenderbufferStorage()

            Options included:
                RenderbufferStorage()
                RenderbufferImage()
                others???

            This is really a function of how we resolve issue (9).

            RenderbufferImage would be appropriate if the allocation
            routine could take an image to initialize the renderbuffer.

            RenderbufferStorage would be more appropriate if the
            allocation routine does not take an image.

            Since the group decided supporting an "initialization" image
            for a "renderbuffer" was too much overlapping functionality
            with DrawPixels, RenderbufferStorage was chosen.

    (11) The routine(s) which attach a texture to a framebuffer
         attachment point need to describe which image in the texture
         they are using, i.e., which cube map face, mipmap level, or 3D
         texture z-slice/depthoffset/image.  Should we have one routine
         that handles all of these with some arguments ignored for
         specific texture types/targets?  Or should we have a parallel
         set of routines for 1D/2D/3D, like TexImage does?

             RESOLUTION: Option (b) 3 routines for texture, 1 for
             renderbuffer

                Originally, we chose option (b) for reasons of
                similarity to glTexImage1D/2D/3D.  For TexImage2D and
                FramebufferTexture2D, the texture target was used to
                select a face on a cube map texture object.  Since
                glTexImage1D/3D used TEXTURE_1D/TEXTURE_3D texture
                targets, we did the same for FramebufferTexture1D/3D. We
                also included the texture target in case it was needed
                for future expandability.

                However, some felt uncomfortable with this resolution
                since it adds 3 framebuffer attachment calls for
                textures, so we reopened the issue.

                Originally we just considered options (a) and (b).  We
                then reconsidered a few additional flavors: (c), (d),
                and (e)

             Options include:

             a) one routine with arguments that are sometimes "ignored"

                For instance <image> is ignored for non-3D textures
                and <face> is ignored for non-cube maps, etc.

                This gives us:

                void FramebufferTexture(enum target, enum attachment,
                                        uint texture,
                                        uint level, enum face, uint image);

             b) routines for 1D/2D/3D, use FramebufferTexture2D for 2D,
                Cube, Rectangle

                Requires use of a texture target to distinguish cube map
                faces on FramebufferTexture2D

                Includes "redundant" texture target for 1D/3D variants
                for consistency and precedent with TexImage1D/3D.

                This gives us:

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

            c) same as (b) but add a dedicated routine for Cubemaps

               Question: since we added a Cubemap version, do we need a
               Rectangle variant as well?

                This gives us:

                void FramebufferTexture1D(enum target, enum attachment,
                                          enum textarget, uint texture, uint level);
                void FramebufferTexture2D(enum target, enum attachment,
                                          enum textarget, uint texture, uint level);
                void FramebufferTextureCubemap(enum target, enum attachment,
                                          enum textarget, uint texture, uint level);
                void FramebufferTexture3D(enum target, enum attachment,
                                          enum textarget, uint texture, uint level, uint image);


            d) same as (c) but with no texture target parameter

               Question: since we added a Cubemap version, do we need a
               Rectangle variant as well?

                This gives us:

                void FramebufferTexture1D(enum target, enum attachment,
                                          uint texture, uint level);
                void FramebufferTexture2D(enum target, enum attachment,
                                          uint texture, uint level);
                void FramebufferTextureCubemap(enum target, enum attachment,
                                               uint texture, enum face, uint level);
                void FramebufferTexture3D(enum target, enum attachment,
                                          uint texture, uint level, uint image);


             e) one FramebufferTexture routine with additional arguments
                passed in via another routine.

                There are no "ignored" arguments in this routine.

                The arguments which would be "ignored" by this function
                are passed in as selector state by a separate function.
                These could be specified as a FramebufferParameter
                (implying that they are stored as framebuffer state), or
                as a piece of context state that is copied into the
                framebuffer attachment point at FramebufferTexture time.
                Of the two, context state is much more desirable since
                ARB_render_texture made the mistake of putting the
                selection state in the pbuffer, and this has real
                usability issues for multicontext applications.

                This gives us (two routines)

                void FramebufferTexture(enum target, enum attachment,
                                        uint texture, uint level);
                and

                void FramebufferParameter(enum target, enum pname, uint param);
                    where pname can be one of
                        GL_{attachment}_TEXTURE_CUBEMAP_FACE
                        GL_{attachment}_TEXTURE_3D_IMAGE
                    and param represents the cube map face or z-slice image.

                Also, option (e) raises 2 questions:

                1. Since the rest of the selection state would come in
                   through another function, we have to ask when can
                   these selector state variables be changed?

                   We had previously decided that we want to pass
                   selection state in atomically with the attachment
                   request.  To be consistent with this earlier
                   decision, this would imply that these variables could
                   not be changed dynamically but would be "snapshotted"
                   into the framebuffer attachment point at at
                   FramebufferTexture time.  This snapshot could be
                   thought of as similar to the way ActiveTexture works.
                   This is also similar to the snapshot of the
                   transformed raster pos vertex that occurs at
                   glRasterPos time.  It is a copy of one piece of state
                   into another piece of state, not just a "switch" than
                   can be updated later that indicates where other state
                   should be stored.

                2. Is the rationale to consolidate FramebufferTexture
                   from 3 routines to 1 also a reason to consolidate
                   FramebufferTexture and FramebufferRenderbuffer into a
                   single attachment routine?  I.e., should there just
                   be one routine called FramebufferAttachableImage()?

                   If we did this, then we could also move <level> out
                   of the argument list and rename the function to,
                   perhaps, FramebufferAttach.

                       void FramebufferAttach(enum target, enum attachment,
                                              enum objectType, uint name);
                       and we'd need to create another enum for
                       FramebufferParameter
                           GL_{attachment}_TEXTURE_LEVEL

                       or, avoiding the use of verbs in the function
                       name, perhaps:

                       void FramebufferAttachableImage(enum target, enum attachment,
                                                       enum objectType, uint name);


            Rationale:

            (a) was discarded because it was not very extensible in the
            event we need to add additional texture selection state in
            the future (for instance, what if we add TEXTURE_4D
            targets?)

            (c) and (d) were discarded because the introduction of a
            special cubemap routine was undesirable since we were
            considering issue in an attempt to *reduce* the number of
            entry points.  Additionally, (d) was discarded because it
            was felt the texture targets were still required.

            (e) was discarded because the intent was that attachment
            (and the consequent framebuffer validation) was a
            "heavy-weight" operation.  By using a separate routine to
            set part of the attachment state, developers may be
            incorrectly encouraged to assume some attachment state could
            be changed more easily than others.  It was felt it wasn't
            worth this possible misunderstanding just to save some
            function entry points.

            In the end, it was determined that (b) was the lesser of two
            (five?) evils.  (b) also has precedent in the specification
            of texture images via gl{Copy}TexImage.  Finally, (b) is
            pretty clearly extensible to new attachment routines for
            future object types.


    (12) Do we need a "format group" or "format restriction" API?

            RESOLUTION: Yes, but put it in a separate extension for
                        reasons of schedule.

            This extension introduces the ability to construct a
            collection of logical buffers using images of various
            formats into a framebuffer in a very flexible manner.  It is
            by design more flexible than used to be possible to do by
            querying for available pixel formats in the window-system
            glX/WGL/agl API's.  As a result, it is possible to construct
            a framebuffer that is actually not supportable by the
            implementation and the reasons for the configuration being
            unsupportable are entirely implementation dependent.

            This is why we originally added the CheckFramebufferStatus
            API.  So that the application at least has the ability to
            determine that a particular, otherwise legal, configuration
            of framebuffer attachments actually will not work on this
            implementation.

            However, this extension does not provide any very helpful
            mechanism to find out why things are not supported or what
            to do to reconfigure the attachments into a supported
            configuration.

            This is a very difficult problem to solve.  glX/WGL/agl
            solved this problem by allowing the application to specify a
            request for a configuration and letting implementation
            provide a "best match".  Additionally, glX and WGL also
            allow for the enumeration of all possible supported
            configurations.

            Various schemes like these were considered but they were all
            quite complicated (possibly as complicated as the windowing
            system API's we are trying to replace).  Consequently, we
            decided to investigate some additional approaches.

            One of these approaches is to specify "allocation and usage"
            hints prior to the routines which allocate buffers
            (TexImage/RenderbufferStorage) that will somehow indicate an
            intended configuration and then let the implementation use
            this additional information when selecting internal formats
            for textures and renderbuffers.  The GL already has the
            freedom to pick any internal format it wants for textures
            and renderbuffers (subject to invariance requirements), and
            so we would like to leverage this freedom and influence the
            choice with an additional channel of information.

            One example, though not the only one, is some API to let the
            application specify it would like to be able to use a color
            buffer, depth, and stencil buffer.  The implementation would
            take advantage of this information when allocating textures
            and renderbuffers and only choose internal formats for
            color, depth, and stencil textures and renderbuffers that
            could be guaranteed to be used together.  For instance, the
            user could call:

                FormatRestriction(GL_COLOR | GL_DEPTH | STENCIL);

            or perhaps

                FormatRestriction(GL_32_BITS_COLOR_DEPTH_STENCIL);

            and then when the user called TexImage with a color buffer,
            the GL would only pick color formats that could definitely
            be used with depth and stencil buffers.  The effect of this
            API would be to "restrict" the avaible choices to the GL to
            the subset of compatible formats.  In this way, the
            possibility of encountering an implementation-dependent
            reason for failing "framebuffer completeness" would be
            greatly reduced or perhaps entirely eliminated.

            In any event, specifying this "FormatRestriction" API was
            going to take additional time and we wished to get this base
            EXT_framebuffer_object specification done and shipping as
            soon as possible.  So we agreed to defer this "format
            restriction" API specification to a later extension, with
            the intent to develop this API or some other solution to
            this problem as soon as possible.

    (13) Do we need intrinsic buffers in addition to renderbuffers?

            RESOLUTION: no

            When intrinsic buffers were initially proposed, the format
            and dimensions of an intrinsic buffer could mutate in order
            to provide compatibility with the other images attached to a
            framebuffer object.  After much debate and a series of
            votes, intrinsic buffers had lost both of those properties.
            (See issue 36.)  In the end the working group decided that
            the crippled form of intrinsic buffers do not provide enough
            added value to justify their existence.

    (14) Is it necessary to require that all the logical buffers of a
         framebuffer object have the same dimensions?

            RESOLUTION: Yes.  Matching dimensions are required for
            simplicity.  If the dimensions do not match, the framebuffer
            object will not be "framebuffer complete".

            It could be useful to use a single large depth buffer when
            rendering to many textures of several different sizes.  This
            is something that could be added later by a layered
            extension that relaxes the matching dimension restriction.
            Supporting heterogeneous sized logical buffers requires
            defining where in a larger buffer the smaller results are
            written, and deciding what guarantees can be made and what
            should be left undefined.

    (15) What happens when TexImage or CopyTexImage is called on a
         texture image that is attached as an image of the
         currently bound framebuffer object?

            RESOLUTION: resolved, {Copy}TexImage will redefine the
            texture image, which can affect the completeness of the
            framebuffer to which it is attached, and possibly cause the
            currently bound framebuffer to start failing the framebuffer
            completeness test.

            As far as {Copy}TexImage (or RenderbufferStorage) are
            concerned, there is nothing "special" about a texture image
            (or renderbuffer) attached to a framebuffer object. Attempts
            to redefine attached images in this manner should succeed.
            However, if the redefined image is no longer appropriate for
            the relevant attachment point in the framebuffer it is
            attached to, then it's possible the framebuffer may start
            failing the framebuffer completeness test.

            Another option that was considered involved having TexImage
            and CopyTexImage result in INVALID_OPERATION and do nothing
            when the target texture is bound for render-to-texture. This
            idea was rejected because, in the multicontext case, one
            context could change the attachments of a shared framebuffer
            and cause another context to suddenly start generating
            errors on {Copy}TexImage calls.  This extension has tried to
            avoid introducing asynchronous generation of gl errors.

            Still another option that was considered was "orphaning" the
            old texture memory such that it could still be used as a
            framebuffer attachment but the texture would get newly
            allocated storage.  However, this implied a side-ways copy
            of the texture object memory or the image for its continued
            use as a framebuffer-attachable image, and was therefore
            rejected.

            For the purposes of comparison, consider that
            ARB_render_texture faced a similar question and resolved it
            by implicitly unbinding the texture from the pbuffer when
            TexImage is called.

    (16) What happens when TexImage or CopyTexImage is called on a
         texture object that is attached as an image of a
         framebuffer object that is not bound to the current context?

            RESOLUTION: resolved, {Copy}TexImage will redefine the
            texture image, which can affect the completeness of the
            framebuffer object to which it is attached.  When the
            framebuffer object is bound to the context, it may start
            failing the framebuffer completeness test.  If the
            framebuffer object is bound in another context at the time
            {Copy}TexImage is called, then the framebuffer object may
            start failing the framebuffer completeness test in the other
            context.

            The rationale for this decision is the same as for issue
            (15).

            However, since in this case the relevant framebuffer is not
            current, there is no guarantee that this framebuffer
            revalidation or invalidation will happen until the next time
            the framebuffer is bound to a context.

            The texture (or renderbuffer) state is changed immediately,
            regardless of whether the texture image (or renderbuffer) is
            attached to a framebuffer object.  However, a context other
            than the one issuing the {Copy}TexImage operation might not
            notice the state change until after it has (re)bound the
            framebuffer object or reattached the texture image.

            This is intended to be similar to what happens in the
            multicontext case when the state of a shared texture object
            is changed by another context.  There is no guarantee that
            texture state change will be visible in the current context
            until the current context binds the texture object again.

    (17) Why is render to vertex array missing?

            RESOLUTION: Render to vertex array is separate functionality
            from render to logical buffer or render to texture.  RTVA
            can be added as a separate extension.  The framework is
            general enough to support more than one way of adding RTVA,
            without deciding today on the details of a particular RTVA
            implementation.

            One idea is to define a way to interpret a vertex array or
            buffer object, which is inherently byte-oriented linear, as
            a framebuffer, which is inherently component-oriented and
            dimensioned, and then call FramebufferArrayEXT like this:

            FramebufferArrayEXT(FRAMEBUFFER_EXT, COLOR, buffer_obj);

            Another idea is to define a general way to interpret a
            component-oriented dimensioned image, such as a texture or a
            color buffer, as a byte-oriented vertex stream.  Using this
            approach one would render vertex attributes to a
            renderbuffer, to a texture image, or to an AUX buffer, and
            then use the image data directly as a vertex array.

            There is controversy over which RTVA method(s) should be
            supported.  One goal of EXT_framebuffer_object is to ship
            render-to-texture and render-to-logical-buffer functionality
            today while leaving the door open to add one or more RTVA
            solutions in the future.

    (18) What function should perform the action of attaching a texture
         image to a framebuffer for rendering purposes?

            RESOLUTION: The new FramebufferTexture*EXT functions perform
            this action.

            Options that were considered include overloading
            BindTexture, using a FramebufferParameter function, and
            adding a new function.

            BindTexture is problematic because it creates a new texture
            object with default state if the name is previously unused,
            but the default state has no dimensions, dimensionality, or
            format.

            One reason that FramebufferTexture*EXT was well-received is
            because it sets, in one atomic operation, all framebuffer
            attachment state for both texture image and renderbuffer
            type of attachments.  Given the polymorphic nature of
            framebuffer-attachable images, this guarantees that all
            framebuffer attachment state is in a consistent
            configuration, without having to define confusing precedent
            rules between competing (texture image and renderbuffer)
            pieces of framebuffer attachment state, or having to create
            enables (either a tri-state enable or separate enables again
            with precedence) to select texture image or renderbuffer
            attachment state as the "active" set of state.

            This decision also makes it simpler to specify how a
            framebuffer-attachable image is detached from a
            framebuffer--it would be confusing if detaching a texture
            image resulted in *attaching* a renderbuffer simply because
            texture image attachment state takes precedence over
            renderbuffer image attachment state.

    (19) What should happen if the texture argument given to
         FramebufferTextureEXT is an unused texture name?  And
         similarly, what should happen if the renderbuffer argument
         given to FramebufferRenderbufferEXT is an unused renderbuffer
         name?

            RESOLUTION:  resolved, (a) this is an error.

            Options included:

                a) throw an error at Framebuffer{Texture|Renderbuffer}

                b) texture/renderbuffer is created just like
                   Bind{Texture|Renderbuffer}

                c) no error, but the framebuffer cannot be "framebuffer
                   complete" until a texture/renderbuffer by that name
                   has been created and satisfies the rules of
                   framebuffer completeness.

            This is interesting because on the one hand we might like to
            adopt the model that we simply catch all the invalid state
            combinations when determining framebuffer completeness,
            i.e., option (c).  This has a certain consistency but then
            what does it mean to call FramebufferTexture{1D|2D|3D} when
            the target of the texture name is not yet known?  How should
            the other arguments to those calls be validated?

            Option (b) was rejected as it would introduce a second way
            to create a texture/renderbuffer object.  I.e., both
            BindTexture and FramebufferTexture would create the texture
            object.

            Since there are "target aware" FramebufferTexture{1D|2D|3D}
            calls, the app already has to know the target prior to
            calling FramebufferTexture.  Also, the texture target of a
            given object is immutable once set.  An app can not set it
            and then change it later so this is really just an issue
            with the order in which they call the relevant functions.
            Consequently, requiring that the user call BindTexture prior
            to calling  FramebufferTexture does not seem to be a burden.
            So this should be an error, since it's probably a mistake on
            the user's part in the first place.

    (20) What should happen if the texture argument given to
         FramebufferTextureEXT is the name of an existing texture
         object, but the texture has no texture image (i.e., TexImage
         has never been called)?  Similarly what should happen if the
         renderbuffer argument given to FramebufferRenderbufferEXT is
         the name of an existing renderbuffer, but the named
         renderbuffer has no storage (i.e., RenderbufferStorage has
         never been called?)

            RESOLUTION: resolved, option (c) - no error, but the
            framebuffer object cannot be "framebuffer complete" until
            the state of the texture image satisfies the rules of
            framebuffer completeness.

            Same options as issue (19), these include:

                a) throw an error at Framebuffer{Texture|Renderbuffer}

                b) texture/renderbuffer is created just like
                   Bind{Texture|Renderbuffer}

                c) no error, but the framebuffer cannot be "framebuffer
                   complete" until the texture image or renderbuffer
                   satisfies the rules of framebuffer completeness.

            This is an issue because you could be attempting to attach a
            texture (or renderbuffer) to a framebuffer attachment point
            prior to the application having called TexImage (or
            RenderbufferStorage) to define the width/height/format of
            the framebuffer-attachable image.

            At first, this seems similar to issue (19), so we could
            throw an error in this case too.  It is different for two
            reasons however.  First, there are default values for the
            texture object and renderbuffer object state.  Second, the
            values of the width/height/format/etc for the texture object
            are mutable, unlike the texture target of the texture
            object.  There is really no difference between the case
            where GL uses the default values for an object, and the case
            where the user explictly set the state equivalent to the
            default values using TexImage (or RenderbufferStorage).
            Because this state is mutable, it must be tested anyway when
            framebuffer completeness is determined.

            Therefore, we simply defer the check for whether the
            texture/renderbuffer state is appropriate for the
            framebuffer attachment point until determination of
            framebuffer completeness.  If the state is not valid, then
            the framebuffer will not be complete, regardless of whether
            or not TexImage/RenderbufferStorage has been used to create
            storage for the texture level (renderbuffer).

    (21) What happens when DeleteTextures is called on a texture that is
         attached to a framebuffer object?  Similarly, what happens when
         DeleteRenderbuffers is called on a renderbuffer that is
         attached to a framebuffer object?

            RESOLUTION: resolved, see issue (77)

    (22) How do you detach a texture or renderbuffer from a framebuffer
         object?  Should we use two routines or create a detach routine?

            RESOLUTION: resolved, 2 routines

            If the user calls either FramebufferTexture with a zero
            texture name, or FramebufferRenderbuffer with a zero
            renderbuffer name, then the it as if nothing is attached to
            the specified attachment point.

            There was a concern that having two routines be able to set
            the framebuffer attachment state to "none" was confusing.
            However, the idea is simply that for any object that can be
            attached to a framebuffer, there should be a routine that
            can set up the attachment and return the framebuffer to the
            default "nothing attached" state.

            The implication here is that the default state for
            framebuffer attachments is:
                attachment object type = GL_NONE, and
                attached object name   = 0

    (23) Should it be legal for the framebuffer state to pass through
         invalid configurations?  (I.e., depth and color buffer sizes
         don't match, etc)

            RESOLUTION: resolved, "yes"

            It's easier for the application if the render target state
            is allowed to pass through invalid configurations when
            transitioning between two valid configurations.  A
            consistency check is defined to determine if a configuration
            is valid.

            As long as everything is valid at render time, transient
            invalid states are allowed.

    (24) What happens when you try to draw to a framebuffer that
         is not "framebuffer complete"?

            RESOLUTION: resolved, rendering is disabled, and an error is
            generated.  See issue (64) as this issue is essentially a
            duplicate of that one.

    (25) What should happen on a query of framebuffer state while the
         framebuffer is invalid?  For instance, what does a query of
         RED_BITS return if the currently bound framebuffer is not
         "framebuffer complete"?

            RESOLUTION: resolved, there's no issue here.  Attempts to
            query bit depths should return the "real" answers.

            For instance, if there's no color buffer attached to the
            framebuffer attachment point, then attempts to return
            RED_BITS could return zero.  If there is a color-renderable
            image attached, then RED_BITS would return whatever the
            RED_BITS are, regardless of the valid/invalid state of the
            framebuffer.

            Other options include returning some kind of magic value or
            generating an error if the framebuffer is invalid.  However,
            any "magic value" would simply be a duplicated query for the
            framebuffer completeness status.  Also, returning an error
            would be problematic because another context can make a
            framebuffer invalid and we have been trying to avoid any API
            in which one context can cause another context to start
            generating errors asynchronously.

    (26) What happens when you try to read (e.g. ReadPixels) from a
         framebuffer that is not "framebuffer complete"?  Reads cannot
         be "disabled" or "ignored" in the same way that rendering can.

            RESOLUTION: resolved, generate a GL error.  See issue (65).

            Originally this was resolved as "undefined pixels are
            generated, but no error"

            Initially, generating an error was rejected for a few
            reasons.  First, it is asymmetric with the behavior for
            drawing - when the framebuffer is not complete, drawing is
            disabled.  We would like to be consistent here.  Second,
            there are no other cases where ReadPixels or
            CopyTex{Sub}Image will generate an error based on the state
            of the framebuffer and we didn't want to introduce one.
            Third, there is already a pixel ownership requirement in
            order to get defined results back from reading the
            framebuffer, so if we simply behave as if incomplete
            framebuffer fails ths pixel ownership test, then we can
            leverage that already specified behavior for reading the
            framebuffer.

            For these reasons, we initially choose to have reads from an
            incomplete framebuffer return undefined pixel values and not
            generate a GL error.

            However, once we subsequntly resolved issue (64) to say that
            rendering with an incomplete framebuffer generates an error,
            we decided again for reasons of symmetry that reading from
            an incomplete framebuffer should also generate an error.
            (And most likely the same error.)

            So in the end, we decided that reads (e.g., ReadPixels and
            CopyTex{Sub}Image) in this case would result in an error to
            be named in issue (65).

            See also related issue (73), describing ReadPixels of color
            data from a complete framebuffer while READ_BUFFER is NONE.

    (27) What happens when you query the number of bits per channel
         (e.g., DEPTH_BITS) prior to the consistency check being run
         when intrinsic buffers are in use, since implementations are
         allowed to select a number of bits for an intrinsic buffer at
         consistency check time to give a better chance of a consistent
         state being reached?

            RESOLUTION: This is not an issue since we don't have
            intrinsic buffers, see issue (13).  We are keeping this
            issue in the issues list just in case we ever go back and
            add something like this to a future API.

            If we would have retained the intrinsic buffer api (i.e.,
            glFramebufferStorage) or if some future API adds it back in,
            then one possible resolution of this problem would have been
            to simply say that a query of the number of bits prior to
            the consistency check being run will produce an answer that
            is subject to change.

            This is preferable to some other possible resolutions that
            have been discussed (e.g., having the query cause a
            validation to occur implicitly, thereby "baking" in the
            answer) because it is the one least likely to introduce
            unexpected side-effects to an operation as seemingly
            innocuous as a query.

            A possible variant of this proposed resolution would have
            been to have the query return a number of bits that is
            guaranteed to be less than or equal to the actual number of
            bits that will eventually be used.  This may or may not be a
            useful guarantee.  We could have also had the query return 0
            or -1 as a signal that the framebuffer is incomplete.

            Again, this is all moot since we decided against this style
            of intrinsic buffers in this extension.

    (28) What should the <image> parameter to FramebufferTexture3DEXT
         actually be called?

            RESOLUTION: resolved, "zoffset"

           This parameter could have been called <image> or <slice>.
           <depth> or <zoffset> might also be appropriate.  The reason
           the answer here is non-obvious is that normally 3D textures
           are specified all at once, not one 2D "slice" at a time
           (TexImage3D takes one big array that represents all three
           dimensions at once, for example), and because texture
           coordinates for TEXTURE_3D targets are normalized
           floating-point numbers, just as they are with TEXTURE_2D
           targets, not integer indices.

           The GL uses the term "image" to mean "slice" in a few
           instances.  For example, pixel unpack parameters
           UNPACK_SKIP_IMAGE and UNPACK_IMAGE_HEIGHT describe state
           related to the "slices" a 3d texture.

           However, in some ways the act of rendering into a texture is
           most similar to CopyTexSubImage3D, which also redefines a
           texture's contents (but never its format or dimensions) based
           on the contents of the framebuffer.  The "zoffset" parameter
           to CopyTexSubImage selects a particular 2D image (depth
           "slice") of a 3-dimensional texture.  "zoffset" is a
           coordinate, and the parameter to FramebufferTexture3DEXT is
           also a coordinate.  "Image" typically refers to an array of
           pixels.

           We already use the term "image" throughout this extension to
           talk about 2d arrays of pixels beyond their use in 3D
           textures.  It is a little confusing to overload "image" to
           also mean Z coordinate in FramebufferTexture3DEXT.

           For the sum of these reasons, we decided "zoffset" is a
           better name than "image", for the parameter to
           FramebufferTexture3DEXT.

    (29) Should GenerateMipmap functionality be included in this
         extension or put in it's own extension?

            RESOLUTION: resolved, yes, include this functionality

            It is arguably useful separately, i.e., without all this
            machinery.  However, it's also kind of required here to have
            some kind of way to deal with the interaction with
            SGIS_generate_mipmap.  Probably we should just include it
            here.  (maybe also a separate extension?)

            It's easier to define when automatic mipmap generation
            happens for a traditional non-rendered texture than it is
            for a texture that is modified by rendering-to-texture.  If
            GENERATE_MIPMAP were to cause a rendered-texture's mipmaps
            to be automatically generated, presumably generation would
            occur when either the texture is detached from the
            framebuffer or when the framebuffer is unbound.  If neither
            of these events occur, should automatic mipmap generation
            also occur when the texture is bound to a texture unit (of
            same or different context?)

            It's believed the recommended way of achieving maximum
            performance using this extension is to make all attachments
            during initialization, and then not change attachments in
            the steady state.  This reasoning is, after all, a major
            reason for introducing framebuffer objects.  If an
            application does not detach textures from framebuffers, then
            what event triggers mipmap generation?  An explicit
            GenerateMipmap works well here.

            Would the base level have to actually be modified in order
            for mipmap generation to occur?  How should "modified" be
            defined?

            If the application rendered to each level of the texture
            before detaching the texture or unbinding the framebuffer,
            would automatic mipmap generation happen anyway?  (This
            implies the application needs to set GENERATE_MIPMAP to
            FALSE before rendering to the texture, but maybe that's OK.)

            Historical background: One reason for introducing
            GenerateMipmap in the context of the original uber_buffers
            proposal was that uber_buffers lacked a Begin-time
            consistency check, but instead prevented the framebuffer
            from ever getting into an inconsistent state (once
            validated).  Operations such as TexImage that can change the
            dimensions and format of a tetxture's levels were disallowed
            when the texture was attached to a framebuffer.  Since
            automatic mipmap generation can change the dimensions and
            format of a texture's levels, that meant that automatic
            mipmap generation could not be performed in some cases, but
            there was no good way to communicate this error to the
            application.  Hence there really was a need for a separate
            GenerateMipmap function.  This restriction does not apply
            to the current API because the semantics of an incomplete
            framebuffer are different now.  Nevertheless, we decided to
            retain this manual mipmap generation as part of this
            extension.

    (30) Do the calls to deal with renderbuffers need a target
         parameter?  It seems unlikely this will be used for anything.

            RESOLUTION: resolved, yes

            Whether we call it a "target" or not, there is *some* piece
            of state in the context to hold the current renderbuffer
            binding.  This is required so that we can call routines like
            RenderbufferStorage and {Get}RenderbufferParameter() without
            passing in an object name.  It is also possible we may
            decide to use the renderbuffer target parameter to
            distinguish between multisample and non multisample buffers.
            Given those reasons, the precedent of texture objects, and
            the possibility we may come up with some other renderbuffer
            target types in the future, it seems prudent and not all
            that costly to just include the target type now.

    (31) What should happen if you call FramebufferTexture{1D|2D|3D}
         with a texture name of zero?

            RESOLUTION:  This will detach the image from the specified
            attachment point in the currently bound framebuffer object.

            For reference, this reason this is problematic because there
            is not really a "texture object zero"

            Texture name zero does not define an object but defines
            context state (one texture named zero, per target, per
            context).  The textures referred to by the name zero are
            never shared across contexts.  So the behavior of
            framebuffer objects shared by multiple contexts where each
            is attached to the context's texture named zero seems odd at
            best, and confusing at worst.  As such, it was decided to
            not allow a framebuffer to attach to texture named zero.

            Another option would have been to make this an error.  If we
            had done this, then we would need a specific function to
            detach a texture from an attachment point.  That is, we
            would have needed to create something like a dedicated
            DetachFramebufferAttachableImage() entry point.

    (32) Should there be a renderbuffer object with the name of zero?

            RESOLUTION:  NO.

            By way of symmetry with textures, renderbuffer zero, if it
            existed, would not be an object.  It would be a
            non-shareable piece of the context state.  There would be
            one renderbuffer named zero per target per context.

            If we can't share renderbuffer name zero, then also by way
            of symmetry with textures, we would not want to support
            attaching renderbuffer name zero to a framebuffer.

            So, if it can't be used as a rendering destination, then a
            renderbuffer name zero would seem to serve no purpose as a
            state container.

            However, we'd like to retain the use of name zero in certain
            routines with special semantics, particularly for detaching
            non-zero renderbuffer objects from the framebuffer and
            context.  See issue (33).

            On implication of this decision is that state
            setting/getting routines that operate on the currently bound
            renderbuffer should throw a GL error if no renderbuffer is
            bound/attached.  A similar choice was made in the
            ARB_vertex_buffer_objects specification which also had
            special semantics for object zero.

            Also note, another option considered was making object zero
            a full fledged, shareable object just like the non-zero
            object names.  This was rejected as being too different from
            texture/program vbo's/etc., possibly leading to confusion.

    (33) What should happen if you call FramebufferRenderbuffer or
         BindRenderbuffer with a renderbuffer name of zero?

            RESOLUTION:   This will detach the image from the
            specified attachment point in the currently bound
            framebuffer object.

            This is resolved exactly the same way as issue (31) was
            resolved for textures, and for the same reasons.

            Similarly, calling BindRenderbuffer with a name of zero will
            unbind the currently bound renderbuffer from the context.

    (34) Should there be a way to query a framebuffer object for its
         attached texture and/or renderbuffers?  If so, how, and
         what should be the query result when attached textures or
         renderbuffers have been deleted?

            RESOLUTION: resolved, yes

            In general, OpenGL lets you query settable state, so
            we allow this.
            To see what this query should look like, see related
            issue (51)

            This issue also raises the question about what values should
            be returned for attached objects if the named objects have
            since been deleted.  This can happen if the textures were
            attached to non-currently bound framebuffers or attached to
            framebuffers in other contexts.  Three possible solutions
            include:

                a) Don't support this query.

                b) Return zero if no texture has ever been attached.
                   Return zero if the attached texture has been deleted.

                c) Return zero if no texture has ever been attached.
                   Return the name of the texture that was attached even
                   though it has been deleted.

                Option (a) was rejected as we would like settable state
                to be queriable.

                So, for this extension originally we choose option (c).
                However, we have since decided, in issue (21), that
                DeleteTexture and DeleteRenderbuffer will first detach
                the texture/renderbuffer from any attached framebuffer
                objects *in this context*.  In principle, the
                application can't tell the difference between the
                texture getting deleted now or later, so whether the
                texture is actually detached from the current
                framebuffer now and other framebuffers when they are
                bound, or the texture is actually detached from all
                framebuffers at once is moot.  In practice, this means
                that options (b) and (c) are essentially
                indistinguishable for a single context case.

                However, it's worth noting that if the texture is
                deleted and attached to a framebuffer which is current
                in another context, the standard rules about undefined
                behavior of state modifcations of shared objects in
                other contexts will still applye.

                This means that the texture may or may not be detached
                (and thus deleted) from that other context's current
                framebuffer until the next BindFramebuffer (or
                FramebufferTexture/FramebufferRenderbuffer?) in the
                other context.

    (35) Earlier proposals included a way to create some memory and then
         attach it to a texture object.  Should this extension include
         this feature?

            RESOLUTION:  no.

            This was considered when this extension was intended
            to be a more general purpose memory manager.  Since this
            extension has been retasked to focus in on render-to-X
            functionality, this feature was not necessary.

    (36) Earlier proposals had renderable memory constructs which could
         change internal format or dimensions to meet intra-framebuffer
         compatibiltiy requirements of individual vendors' hardware
         platforms.  Should this extension have these kind of malleable
         format objects?

            RESOLUTION: no.

            Such malleability leads to invariance problems when formats
            change.  For example, if bits per pixel is decreased then
            increased back to the original value, some precision is
            lost.

            Some IHVs wanted to require format conversion of existing
            contents in all cases where the format changes.  This sort
            of invariance would be an acceptable side-effect.  The
            suggestion was to think of the action of rendering to a
            texture as an extended non-atomic TexImage call.  TexImage
            is allowed to change the format of an existing texture
            image.  It was claimed that such intrinsic buffers are more
            convenient in many applicaitons than are the explicitly
            managed renderbuffers.

            Other IHVs expressed a strong opinion against implicit
            format conversions, but instead wanted to invalidate the
            buffer's contents whenever the format changed.  It was
            difficult to define the set of operations that might cause
            the format to change, so it was difficult to define when the
            contents could become invalidated.  If the contents were
            invalidated by a format change, the API under consideration
            made it cumbersome for the application to detect and handle
            this condition.  In the end, under the buffer content
            invalidation approach, application code would not be any
            better off than if the appliation instead used the explicit
            renderbuffers.  For the type of intrinsic buffers that could
            not change format and dimensions dynamically, the claim that
            intrinsic buffers were more convenient than renderbuffers
            was no longer true.

            The working group voted for the latter: no implicit format
            changes.  Instead the format would be immutable once it is
            known.

            A secondary issue is the question: are the buffer contents
            invalidated when the dimensions change, are the contents
            scaled, or are the contents are clipped/padded (with some
            sort of gravity).  This issue could be avoided by requiring
            explicit, rather than implicit, resize of intrinsic buffers.

            The working group voted for no implicit change in the
            dimensions of intrinsic buffers, and finally for the removal
            of intrinsic buffers altogether.

    (37) In order to abstract hardware dependent compatibility
         requirements, this API introduces a function called
         CheckFramebufferStatus to check for compatibility prior to
         rendering.  CheckFramebufferStatus returns a value which
         indicates whether or not the framebuffer object is "framebuffer
         complete", and framebuffer completeness depends in part on
         hardware dependent constraints.  The hardware dependent aspect
         represents a new concept in OpenGL.  Therefore, should an app
         be required to call this function to help "enforce" the notion
         that apps should be on the lookout for failure?

            RESOLUTION: no.  Calling CheckFramebufferStatus is not
            required.

            The group considered requiring a call to
            CheckFramebufferStatus after changing framebuffer state or
            attachment points in order to "enable" rendering.  It was
            hoped that requiring a call to CheckFramebufferStatus would
            push developers to write code which is more platform
            independent.  Ultimately though, since the API can't require
            applications to actually observe and deal with a validation
            failure, that it was not worth it to make this function call
            required.  There was also feedback from some developers that
            requiring this call would be cumbersome and undesirable.

            Note, however, that the framebuffer is effectively validated
            implicitly at every rendering (and reading) entry point.
            These include glBegin, gl{Multi}Draw{Arrays|Elements},
            gl{Draw|Copy|Read}Pixels, glCopyPixels, glReadPixels,
            glCopyTex{Sub}Image, etc.

            Applications are strongly advised to test framebuffer
            completeness with CheckFramebufferStatus after setting up or
            changing the configuration of a framebuffer object, and to
            handle the possible failure cases with a fallback plan that
            selects a different set of internal formats of attached
            images.  See usage example 6.  Section 4.4.4.2 lists the
            operations that can cause the framebuffer's status to
            change.

            In addition, a "format group" API, has been proposed as a
            means of programmatically determining a set of internal
            formats that are guaranteed to be compatible with respect to
            framebuffer completeness.  This API would be specified in a
            layered extension as suggested in issue (12)

    (38) Do we need to support multiple render targets, i.e.,
         ARB_draw_buffers?

            RESOLUTION: Yes.

            ARB_draw_buffers is going to be part of OpenGL 2.0 so we'd
            better support it.

    (39) How should we support ARB_draw_buffers?

            RESOLUTION: refactored into the following issues:
                        (53), (54), (55), (56), and (57)

    (40) (How) should we support accum buffers?

            RESOLUTION: defer this until (shortly) after this extension.

            Accum buffers appears to be very simple to specify and
            implement.  Basically, we would need to add a new internal
            ACCUM format that can be passed to RenderbufferStorage.  We
            would also need to add an ACCUM attachment point in the
            framebuffer that could be used to point to one of these
            ACCUM format renderbuffers.  A new ACCUM format is needed
            because the ACCUM buffer is defined by GL to be signed
            floating point value, unlike other internal formats.

            Also note, the above solution is the exact same one we are
            using for STENCIL buffers as well (i.e., an internal format
            enum and an attachment point).

            We could also decide if this new ACCUM internal format can
            be used with textures in addition to renderbuffers, for
            creating images that can be attached to the accum buffer
            attachment point.

            Supporting accum was deferred for this extension, primarily
            for time-to-market reasons, and as it was not critical for
            most render-to-texture applications.  However, we intend to
            work on some kind of "EXT_accum_renderbuffer" extension
            shortly.

            Since this was deferred, we need to define what happens when
            you call the various Accum operations on a non-default
            framebuffer object.  We considered adding spec language that
            would generate an error on Accum operations.  However, it
            seems like we can simply leverage whatever legacy behavior
            is currently defined for when the pixel format has no accum
            buffer.  This is the case in this extension as we have
            defined no way to attach or enable an accum buffer.  Chapter
            4 on page 188 already says that "If there is no accumulation
            buffer, or if the GL is in color index mode, Accum generates
            the error INVALID OPERATION", so we don't actually need any
            additional language of our own.

    (41) (How) should we support multisample buffers?

            RESOLUTION: defer this until (shortly) after this extension.

            Supporting multisample was deferred for this extension,
            primarily for time-to-market reasons and because it's not
            entirely clear what is the "best" API for exposing
            multisample.  However, we intend to work on some kind of
            "EXT_multisample_renderbuffer" extension shortly.

            Since this feature was deferred, we need to define what
            happens when you try to enable multisample on a non-default
            framebuffer object.  For now we need some way to *not* do
            multisampling.  This can either be that we set SAMPLES 1 and
            SAMPLE_BUFFERS to 0, or we say that
            Enable/Disable(MULTISAMPLE) is ignored.  This is actually
            related to issue (62) - should SAMPLE_BUFFERS change when
            using a non-default framebuffer or when attachments change?
            When/if we define and export "EXT_multisample_renderbuffer"
            extension, this state will again have significance.

            A discussion of how we might support this feature follows:

            There are several considerations here: First, we'd like
            something simple to specify, implement, and use.  Second,
            we'd like to not delay this extension's approval,
            implementation or adoption for this particular feature.
            Third, we are trying to replace pbuffer functionality, which
            does support multisampling (at least in principle), so we'd
            like to not take a step backward in functionality if
            possible.

            However, this extension is *not* trying to "improve" the
            traditional multisample support.  If we do anything, we will
            simply expose the existing multisample buffer semantics
            without causing undue implementation burden.

            Finally, if an implementation is currently taking short-cuts
            to GL's traditional "per-pixel-resolve" multisample
            semantics, we'd like for this extension to continue to allow
            the exact same short-cuts (to whatever extent the core GL
            spec does or does not allow those short-cuts).  If someone
            later decides to go an revamp multisampling support in
            general, they can update this extension at the same time.

            Given the above, it appears that the options include:

              A) Don't support it.  In other words, you can't use
                 mulitsampling and EXT_framebuffer_object.  The
                 multisample state is either ignored, or causes the
                 framebuffer to not be complete, or generates some kind
                 of error.

              B) Create a separate multisample renderbuffer that can be
                 attached to a new framebuffer attachment point.

                 The reason that we might need a separate
                 RESOLUTION_BUFFER is that all renderable color buffer
                 formats might not be usable for multisampling on all
                 implementations.

                 Also, this option would allow multiple framebuffers to
                 share the storage for multisample buffers under the
                 control of the application.

                 Depth sample buffers and stencil sample buffers
                 wouldn't necessarily need resolution buffers, but that
                 could be added by some future extension.

                 This option has several variants:

                   B1) Create MULTISAMPLE and/or RESOLUTION_BUFFER
                       internal formats for renderbuffer objects that
                       can be used with RenderbufferStorage.  The
                       samples buffer and the resolution buffer would be
                       allocated and attached to the framebuffer
                       separately.  Having them be separate allows the
                       samples to be deleted after rendering if desired.

                       One issue with this option is that somehow you'd
                       need to specify the number of samples maybe using
                       glFramebufferParameter or
                       glRenderbufferParameter.

                   B2) Perhaps, instead of using a single internal
                       format called MULTISAMPLE, use a set of internal
                       formats like MULTISAMPLE_1_SAMPLE,
                       MULTISAMPLE_2_SAMPLE, MULTISAMPLE_4_SAMPLE, etc.
                       This is problematic for supporting depth/stencil
                       multisampling unless we want an explosion of
                       color/depth/stencil multisample internal formats.
                       It's also problematic if MRT draw buffers need to
                       be multisampled because we'd need a number of
                       enums able to support 1 to N draw buffers times
                       the number of sample patterns we support.

                   B3) Have RenderbufferStorage always take a number of
                       samples.  We could do this if option (B2) is
                       insufficient due to the need to support DEPTH or
                       STENCIL multisampling, which we probably will.
                       We would then allow the internal format to choose
                       DEPTH, STENCIL, or RGBA/etc.  This is clean but
                       it means that the user would always need to
                       specify a number of samples even when the value
                       is "1".

                   B4) Pass in a variable length argument list to the
                       renderbuffer allocation routine, and some of the
                       arguments would indicate intended usage
                       (COLOR/DEPTH/MULTISAMPLE) others would indicate
                       internal format (RGBA/DEPTH24) and others would
                       indicate number of samples.  This is how
                       EXT_compromise_buffers dealt with this problem,
                       though people didn't seem to like this variable
                       length argument list.  EXT_render_target didn't
                       deal with this problem so doesn't offer any
                       guidance here.

                   B5) Create a new RENDERBUFFER_MULTISAMPLE
                       renderbuffer target type and a corresponding
                       allocation routine, perhaps called
                       RenderbufferMultisampleStorage().  This is
                       analogous to how textures have their own
                       allocation routine per target type
                       (TexImage1D/2D/3D, etc).

                       With this option, we could preclude
                       non-multisample targets from being attached to
                       non-multisample attachment points as well.

                   B6-B10) Any of the above options can be implemented
                           with either a single monolithic mulitsample
                           buffer that contains the samples for all draw
                           buffers, depth and stencil and a single
                           attachment point, *OR* with independent
                           multisample buffers for each draw buffer and
                           depth and stencil and independent attachment
                           points for each.

              C) Use some kind of "behind the scenes" mulitsample buffer.

                 This option also has several variants:

                   C1) An "implicit" multisample buffer that is simply a
                       property of the framebuffer object.  Each
                       framebuffer object could have its own multisample
                       buffer(s).  Multisampling would be enabled with
                       some kind of FramebufferParameter call.  This
                       implies that each framebuffer has memory
                       allocated with it.  It further implies that the
                       contents of the multisample buffer are
                       framebuffer state and are thus retained with the
                       framebuffer object.

                   C2) We don't say anything except that we say the
                       value of the glEnable(MULTISAMPLE) is still
                       respected and we render as directed.  This is
                       similar to (C1) but we don't go so far as to say
                       that the multisample buffer(s) is/are retained
                       per framebuffer object.  In other words, a call
                       to BindFramebuffer() and changes to framebuffer
                       attachments may or may not retain multisample
                       buffer contents.  Valid implmentations of this
                       would include a multisample buffer per
                       framebuffer or one per context.

              D) something else (hopefully simpler?)

    (42) What set of framebuffer targets should the initial extension
         support?

            RESOLUTION: resolved, (D) single target

            Basic possibilities include:

            (A) DRAW_AND_READ_FRAMEBUFFER_EXT

            (B) DRAW_FRAMEBUFFER_EXT
                READ_FRAMEBUFFER_EXT

            (C) DRAW_FRAMEBUFFER_EXT
                READ_FRAMEBUFFER_EXT
                DRAW_AND_READ_FRAMEBUFFER_EXT

            (D) FRAMEBUFFER_EXT

            The fundamental question is: must framebuffer binding points
            mimic the expressiveness of the window-system function
            MakeContextCurrent, which is described in the glX spec and
            the ARB_make_current_read extension?

            It was not immediately clear how to specify the distinction
            between a READ and a DRAW framebuffer in the context of the
            existing read/draw buffer semantics, given that this
            extension relaxes the "compatibility" requirement between
            read and draw drawables.  How would the value of RED_BITS
            for the read framebuffer be queried if it is different than
            the value of RED_BITS for the draw framebuffer?  What
            exactly is the set of implementation dependent state (see
            the "Implementation Dependent *" state tables in chapter 6)
            that can differ between read and draw framebuffer objects?

            When using MakeContextCurrent, the context's and drawable's
            FBconfig (or pixel format) must be "compatible" or else the
            results are implementation dependent.  But
            EXT_framebuffer_object cannot afford to swing such a large
            "undefined" stick, because it is more likely that
            framebuffer objects are incompatible in this sense, and
            because the "pixel format compatility" of a framebuffer
            object is dynamic--by changing attachments or redefining the
            internal format of an attached texture image.

            The value added by ARB_make_current_read through
            MakeContextCurrent is less relevant to
            EXT_framebuffer_object.  EXT_framebuffer_object enables
            rendering to a texture, and textures are objects with a
            clearly defined mechanism for use as the source of a pixel
            copy: rather than using CopyPixels to move pixels from the
            READ_BUFFER to the DRAW_BUFFER(s), an application can simply
            use the source data as a texture and then draw a
            screen-aligned textured quad to the framebuffer.

            Additionally, adding separate DRAW and READ bindings in the
            future is pretty straightforward.  One solution would be to
            say that FRAMEBUFFER_EXT is the DRAW framebuffer, and name
            the new READ framebuffer FRAMEBUFFER_READ_EXT.  Add a new
            BindFramebuffer-like function which takes two framebuffer
            names--one for DRAW and one for READ.  The current
            BindFramebuffer function binds a single object to both
            FRAMEBUFFER_EXT and FRAMEBUFFER_READ_EXT.

            So, we defer the additional targets until need has been
            proven, and go with the simpler option (D) for now.

    (43) In order for a framebuffer object to be "framebuffer complete",
         must all textures attached to the framebuffer be mipmap
         complete (or mipmap cube complete if cubemap texture)?

            RESOLUTION:  resolved, no

            The reason this is a consideration is that some
            architectures require framebuffer-attachable images to be
            located in graphics memory when rendered to, and it may be
            more convenient to allocate and store a texture in graphics
            memory only if the texture is mipmap (cube) complete--i.e.,
            the size and format of all levels are consistent in the
            normal sense of texture compeleteness.

            However, since framebuffer attachment points only really
            deal with single images of a texture level, it seems
            excessive to require the state of the other levels of a
            texture to affect the validty of the framebuffer object
            itself.

            Addtionally, the same difficulties around "incomplete"
            textures already apply to traditional CopyTexSubImage, and
            we have been trying to make the render-to-texture semantics
            similar to CopyTexSubImage.

            Therefore, we chose not to treat render to texture any
            differently than CopyTexSubImage and do not require that the
            attached texture is mipmap (cube) complete.

    (44) What should happen if a texture that is currently bound to the
         context is also used as an image attached to the
         currently bound framebuffer?  In other words, what happens if a
         texture is used as both a source for texturing and a
         destination for rendering?

            RESOLUTION: resolved, (b2) - results are undefined because
            the framebuffer is not "framebuffer complete".

            Originally this was resolved as causing framebuffer to fail
            the completeness test--i.e., rendering would be disabled (b1)

            As background, the reason this is an issue in the first
            place is that simultaneously reading from, and writing to,
            the same texture image is likely to be problematic on
            multiple vendors' hardware without paying performance
            penalties for excessive synchronization and/or data copying.

            There are, however, certain cases where this functionality
            would arguably be useful, supportable, and well-defined.  In
            particular, we can consider the case of custom mipmap
            generation using one level's image as source data to render
            into other levels of the same texture.

            So, at a minimum, we would like to support rendering to a
            currently bound texture object if the source texture object
            has the BASE_LEVEL and MAX_LEVEL texture parameters set such
            that the level being used as a framebuffer-attachable image
            is excluded from texture fetches.

            This was our original rationale:

             a1) is problematic because one context could modify the
                 base/max level on a shared texture causing another
                 context which is using the texture as a destination to
                 throw an error.  This idea was rejected as it
                 essentially meant that the error would need to be
                 thrown at render timer which people found unacceptable.

             b1) has the same kind of multicontext behavior but no
                 error.  One context can cause a framebuffer shared in
                 another context to become invalid, but this is already
                 true and can happen for a variety of reasons if the
                 participating framebuffer-attachable images and/or
                 framebuffer attachments are modified by either context.

                 At the time, we also considered the following
                 questions: should the specification require the
                 framebuffer to fail the framebuffer completeness test?
                 Or is the framebuffer simply "allowed" to not be
                 complete in this case?  The latter choice would imply
                 that the framebuffer might still be considered
                 "framebuffer complete" on some implementations.  See
                 issue (46)

             c1) is the easiest to specify and has an advantage that
                 some implementations may be relying on this behavior
                 already.  However, this was rejected as it is the least
                 portable of the three options.

            We originally chose option (b1), though we considered that
            later on, individual hardware vendors may offer layered
            extensions that change this "framebuffer completeness"
            failure into a success with either defined or undefined
            rendering behavior.

            However, this issue was re-opened becaues the subsequent
            resolution of issue (66) was that there should be no
            "context-dependent" reasons for framebuffer incompleteness.
            If we had stuck with option (b1), then we would be making
            the framebuffer completeness predicated on a piece of
            context state (the current texture binding).  Consider the
            case where texture T is attached to a framebuffer.  Then
            this would have meant that a framebuffer could be complete
            in one context (that didn't have texture T bound as a
            texture) and incomplete in another context (that did have
            texture T bound).

            When reconsidering this issue, we realized that we would not
            throw an error at Begin time without disabling rendering, so
            we really only considered the following revised set of
            options:

                 a2) throw an error and disable rendering, but don't
                     affect framebuffer completeness
                 b2) the behavior is undefined

            The issue was resolved the second time as:
                 b2) Undefined behavior

            Another option that was briefly considered was to make this
            another type of error (unrelated to trying to render with an
            incomplete framebuffer).  However, part of the rationale for
            throwing an error at glBegin time when trying to render with
            an incomplete framebuffer was that if you already have to
            test for framebuffer completeness, then throwing an error is
            no additional implementation burden.  Yet, since it was
            decided that the "texture-from-destination" condition is not
            part of framebuffer completeness - issue (66) - then it is
            an additional burden to perform the
            "texture-from-destination" check just so that an error can
            be generated.  The concern was some implementations might
            not need to check for this case at all and we didn't want to
            burdern those implementations with an additional Begin-time
            error check.

            Also, for what it's worth, if we had left the
            "texture-from-destination" case in the framebuffer
            completeness test then any language describing how
            framebuffer completeness is affected when a currently bound
            texture is used as both source and destination needs to be
            explicit that the texture has to be currently bound *and*
            enabled.  For instance, consider the case where a user has a
            cubemap texture object name N bound to unit X and a 2D
            texture object name M also bound to unit X.  What if the
            user would like to use the 2D texture M as a source while
            rendering to the faces of the cubemap texture N?  We would
            like to support this scenario, so the language about a
            currently bound texture object would have needed to take the
            target into account.  And to make matters more interesting,
            this means we would have needed to take texture enables and
            fragment shaders into account in this decision.  In the end,
            we decided that "context-state" would not affect the
            defintion of framebuffer completeness we avoided this
            complexity (or at least moved it out of the framebuffer
            completeness test).

    (45) Are framebuffer configurations with no color attachments allowed?

            RESOLUTION: resolved, yes

            The reason this is an issue is that the GL spec assumes
            there is always a color buffer.  If a framebuffer with no
            images attached to any of the color buffer attachment points
            can be "framebuffer complete", then the core GL spec will
            need to be modified to relax the assumption that a color
            buffer always exists.

            However, since one of the possible likely uses of this
            extnesion is to support depth texture rendering and stencil
            rendering for shadowing techniques, it seems like requiring
            an unused "dummy" color buffer in some cases is both
            inconvenient and a waste of memory.

            Therefore, framebuffers do not require color attachments to
            be valid.  Perhaps though we should require that a
            framebuffer with *no* attachments is invalid.

            It also should be stated that attempting to render without
            the "appropriate" buffers attached needs to be defined.  For
            instance, presumably, for depth rendering with no depth
            buffer attached, the depth test is disabled, as it is in
            traditional GL.

    (46) In the framebuffer completeness criteria, this extension
         introduces the idea that rendering can fail for implementation
         dependent reasons.  Framebuffer completeness also considers
         implementation *independent* reasons for failure.

         Do we need to make special distinction between the cases where
         a framebuffer is not complete because of implementation
         dependent or because of implementation indepenent reasons?

            RESOLUTION: resolved, yes, though this is really tied into
            how we resolve the minimum requirements for supporting this
            extension.  See issue (61)

            Examples where a framebuffer may be incomplete on some
            implementations but not others include:
                - 16 bit z-buffer used with 8 bit stencil buffer
                - 32 bit color buffer with 16 bit depth buffer
                - others?

            Examples where framebuffer MUST be incomplete on all
            implementations include:

                - color-renderable image attached to a non-color
                  attachment point

                - depth-renderable image attached to a non-depth
                  attachment point

                - stencil-renderable image attached to a non-stencil
                  attachment point

                - all images attached to a framebuffer do not have the
                  same dimensions

                - multiple render targets of different bit depths

                - texture image attached to the framebuffer is part of a
                  currently bound and enabled texture and the image is
                  within the range of mipmap levels that can be fetched
                  by rendering.

           To make this determination we need to describe the criteria
           we should use to determine whether a framebuffer *can* or
           *must* be incomplete.

           The arguments for putting state vectors into the "can" fail
           case is that a later extension can come along and simply
           relax those portions of the framebuffer completeness
           definiton with no additional API.  State vectors classified
           as "must" fail cases would at least require the later
           extension to add an additional enable to start passing.

    (47) Certain state-modification operations can cause a change to the
         validated state of a framebufffer.  (I.e., can make a
         framebuffer that was complete become incomplete, or
         vice-versa).  Do we want to list exactly which
         state-modification routines can cause this to happen?  If so
         what is the list?

            RESOLUTION: resolved, the answer is: yes we want to
            delineate exactly which routines can cause validation state
            changes.

            Currently any routine which changes any of the following
            state can potentially cause framebuffer completness to
            change:

                framebuffer state
                state changes to attached objects
                currently bound fragment program
                texture enable state

            The list of operations that can cause framebuffer a change
            to framebuffer completeness are spelled out in section
            4.4.4.2.

    (48) What information should be returned from
         CheckFramebufferStatusEXT()?

            New RESOLUTION: resolved: 8 possible enum values, see issue
            (55)

            Previous RESOLUTION: resolved, return one of three enumerated values:
                1. GL_FRAMEBUFFER_COMPLETE_EXT
                2. GL_FRAMEBUFFER_UNSUPPORTED_EXT
                3. GL_FRAMEBUFFER_INCOMPLETE_EXT
            where the three values mean the following:
                1. framebuffer is complete and supported
                2. framebuffer is not supported for implementation *dependent*   reason
                3. framebuffer is incomplete for    implementation *independent* reason

            We considered the following two sets of enums:
                Set 1:
                    GL_FRAMEBUFFER_COMPLETE_EXT
                    GL_FRAMEBUFFER_NOT_COMPLETE_EXT
                    GL_FRAMEBUFFER_NOT_SUPPORTED_EXT

                Set 2:
                    GL_FRAMEBUFFER_COMPLETE_EXT
                    GL_FRAMEBUFFER_INCOMPLETE_EXT
                    GL_FRAMEBUFFER_UNSUPPORTED_EXT

            New resolution is Set 2.

            NOTE: In order to fully resolve issue (55), we expanded this set
            of enums to identify all of the implementation-independent
            causes for a failure of the framebuffer completeness test.

            Originally, we had decided to have a query where the
            query returns one of three possible values

            One possible set of names that could be returned included:
                FRAMEBUFFER_COMPLETE, and
                FRAMEBUFFER_HW_DEPENDENT, and
                FRAMEBUFFER_HW_INDEPENDENT

            How much information we return from CheckFramebufferStatus
            is a function of how we expect the return value to be used.
            A framebuffer object that is not complete for implementation
            *indepednent* reasons is really an indication of a
            programming error (like mismatched sizes) and should only
            occur during development phase of an application.  The
            correct response to this failure is to modify the
            application to fix the bug.  After application development,
            a framebuffer object that is not complete for implementation
            *dependent* reasons is possible.  However, it's not yet
            clear whether we can easily characterize these reasons for
            failure in a programmatic fashion that would really offer
            the application enough information to do something different
            at runtime.  Perhaps a human readable info log, intended
            just as an application debugging aid, would be more
            appropriate.

            We also considered whether we needed two separate queries:
            One that queried whether the framebuffer was complete
            according to the spec, and one that queried whether the
            framebuffer was supported.  This was a little problematic as
            it might not be possible to answer the
            "IsFramebufferSupported" query until the framebuffer was
            complete.  A possible solution would have been to return
            UNKNOWN from the "IsFramebufferSupported" query until the
            "IsFramebufferComplete" query returned TRUE.

            In any event, we decided a single query was a simpler
            solution.

            In addition, the proposed "format group / format
            restriction" API (see issue 12) should make the
            implementation-dependent framebuffer incomplete case much
            less likely (and perhaps impossible) to occur.

            Note that if a framebuffer's state violates more than one of
            the framebuffer completeness rules described in section
            4.4.4.2, then it is undefined which of the enumerated value
            corresponding to one of the violated rules will be returned
            by CheckFramebufferStatusEXT.  Since the initial state of a
            framebuffer violates multiple rules from section 4.4.4.2,
            it is therefore undefined exactly which value is returned if
            CheckFramebufferStatusEXT is called while bound to a newly
            created framebuffer object.

    (49) When this extension is used in conjunction with MRT (multiple
         render targets), it would naively be possible to create a
         framebuffer that had different color bit depths/formats for
         various color attachment points.  Should this be allowed?

            RESOLUTION: resolved, no, not in this extension.
            A soon to follow extension may add this feature.

            This feature could be supported by simply not requiring that
            all of the FRAMEBUFFER_COLOR_ATTACHMENTn images share the
            same internal format.  We decided against doing so, however.

            ARB_draw_buffers and OpenGL-2.0 do not provide any mechanism
            to support rendering to multiple color buffers of different
            formats.  Consequently, we chose not to extend OpenGL in
            this manner as part of the EXT_framebuffer_object extension.

            Presumably, a future layered extension could easily add this
            feature.  There are some open questions about exactly how
            this might work.  For instance, what should a query of
            RED_BITS return if the attached color-renderable images have
            different formats?  In any event, we leave the details of
            rendering to differently formatted MRT for a future
            extension to define.

    (50) This extension introduces the concept of attaching one GL
         object (texture, renderbuffer) to another GL object
         (framebuffer).  In many ways this situation is analogous to a
         previously poorly specified situation where a GL object could
         be attached to multiple contexts and the issues this raises
         with deletion and state propogation are similar.  Several
         issues resolutions have been predicated on the assumption that
         as we specify this container/member relationship, the
         generation of GL errors should never be triggered in one
         context based on the asychronous actions of another context.
         Is this a valid premise?

         In other words, should we be using the prevention of
         asynchronously generated GL errors as a design constraint?

            RESOLUTION: resolved, no.

            We didn't officially decide on this as a design constraint.
            However, we essentially decided it by proxy.  We decided in
            issue (26) and (66) that an incomplete framebuffer can cause
            GL errors on rendering or reading the framebuffer.
            Consequently, this means a framebuffer shared by two
            contexts can be made incomplete by either context, and
            therefore each context can effectively cause the other
            context to start generating errors asynchronously.

            We would expect that the state of framebuffer completness,
            like all the state of all shared objects, is not
            "guaranteed" to show up in another context until that
            context makes an "atomic" request to the server (like a
            BindFramebuffer for instance).  Until that point, it is
            undefined whether the state change will show up in the other
            context, just like any state change made on a shared texture
            object.

    (51) What api should we use to query the attachments of
         the currently bound framebuffer?

            RESOLUTION: resolved, (b)

            This is an issue because the relevant state
            for a specific attachment point is a function
            of the type of object attached to that that attachment point.
            The attachment point state needs to select a
            an image from an object which may have
            a collection of images, for instance
            the faces of a cube map texture.

            This introduces a kind of "polymorphism" into the
            framebuffer attachment point that is problematic
            for queries.

            We have a few options:

            a) Some kind of single atomic query that
               returns a variable number of values in an array:

               GetFramebufferParameteriv(enum target,
                                         enum pname,
                                         int* params);
                    where
                    <target> = a framebuffer target
                    <pname> = {attachment_point}

                    Upon success "params" will contain an array of
                    values where

                    params[0] = {NONE | TEXTURE | RENDERBUFFER}

                    if params[0] == TEXTURE then
                        params[1] = texture object name
                        params[2] = level
                        params[3] = face
                        params[4] = image
                    else if params[0] = RENDERBUFFER then
                        params[1] = renderbuffer name

                    Elements of the params array not explicitly defined
                    above will have undefined values.

               One problem with (a) is that we would potentially also
               need a query to identify how many state variables will
               come back in this query.  Consider the case where in the
               future we add a new attachable object type that needs
               more selections tate or even add new selection state to
               existing object types.  Applications coded to expect a
               maximum of n values returned today may break in the
               future unless they have a way to dynamically learn how
               many attachment state params will come back from the
               query.


            b) individual queries for all the possible attachment
               state values.

               We create a new routine to add a new <attachment>
               argument, otherwise we'd have an explosion of
               permutations of attachment points and possible attachment
               selection state values

               This could look like

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

                    where
                    <target> = a framebuffer target
                    <attachment> = {attachment_point}
                    <pname> = one of
                        FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT
                        FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT
                        FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT
                        FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT
                        FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT

                    Upon success, param will be filled out as follows:

                    if pname is FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT,
                    then param will contain one of:
                        { NONE | TEXTURE | RENDERBUFFER },

                    else if pname is
                    FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT, and
                    FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT = TEXTURE,
                    then param will contain:
                        { name of attached texture }

                    else if pname is
                    FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT, and
                    FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT =
                    RENDERBUFFER, then param will contain:
                        { renderbuffer object name }

                    else if pname is
                    FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT, and
                    FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT = TEXTURE,
                    then param will contain:
                        { selected mipmap level of attached texture }

                    else if pname is
                    FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT,
                    and FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT =
                    TEXTURE, then param will contain:
                        { selected face of attached cube map texture }
                        { 0 if texture target is not TEXTURE_CUBE_MAP }

                    else if pname is
                    FRAMEBUFFER_ATTACHMENT_TEXTURE_ZOFFSET_EXT, and
                    FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT = TEXTURE,
                    then param will contain:
                        { selected z-slice/image of attached 3D texture }
                        { 0 if texture is not 3-dimensional }

                    otherwise, param will contain the value 0.


               One problem with option (b) is that it is a little
               heavy-handed as every piece of state needs its own query
               and enum

            Given the above choices, and the problems of extending option
            (a) in the future, (b) is probably the better of the two
            choices.  It really only adds a few enums, and though it does
            require an independent function call to obtain each piece of
            state, this is well-precedented behavior throughout GL.

    (52) Should manual mimpap generation via GenerateMipmap apply to
         textures regardless of whether they are attached to framebuffer
         objects?  Should automatic mimpap generation apply to all
         textures regardless of whether they are attached to framebuffer
         objects?

            RESOLUTION: resolved, (a) - both apply to both.

         This is an issue because the introduction of GenerateMipmap is
         intended both to address long standing complaints about the
         existing "automatic" mipmap generation API and to provide a
         clear trigger for render to texture API's to know when to do
         the mipmap generation.

         These API's could be considered completely orthogonally.  It's
         clear how they could interoperate.  The question is should they
         interoperate, or should one supercede the other?

         There are a couple of ways to address this issue:

            a) "automatic" mipmap generation applies always and is
                triggered by any gl{Copy}Tex{Sub}Image call if
                GENERATE_MIPMAP is set to TRUE.  "Manual" mipmap
                generation applies always and is triggered by a call to
                GenerateMipmap

            b) "automatic" mipmap generation applies only
               to textures which are not attached to framebuffer
               objects, calls to GenerateMipmap on "unattached" textures
               are ignored.

               "manual" mipmap generation applies only to textures which
               are attached to framebuffer objects, the value of
               GENERATE_MIPMAP for "attached" textures is ignored

           c) Like option (b), but allow GenerateMipmap to
              apply to all textures and only let automatic mipmap
              generation apply to "non-attached" textures.

           d) Create an enable or other piece of state
              to toggle between allowing automatic and allowing manual
              generation.

        We disregarded (d) because it's not clear why an application
        that had the freedom to set this new enable bit wouldn't
        simply just turn off the legacy automatic mimpap generation
        to start with.

        Of the remaining choices, (a) is the most "orthogonal".  The
        intent of adding GenerateMipmap is to provide a cleaner and
        saner interface to mipmap generation that we would encourage
        developers to use over the automatic method.  Given that, it
        seems like restricting the "manual" generation to certain
        cases doesn't serve that goal, so we wish to allow its use
        on any textures, attached or not.

    (53) When supporting ARB_draw_buffers, do we need the level of
         indirection between fragment color outputs and attached
         mages provided in that API?

            RESOLUTION: yes

            ARB_draw_buffers allows the user to set up an "indirection
            table" between the fragment color outputs ("result.color[n]"
            in ARB_fragment_program, and "gl_FragData[n]" in GLSL) and
            the attached draw buffers (FRONT, BACK, LEFT, RIGHT, etc).

            Since EXT_framebuffer_object is creating new non-visible
            framebuffer objects for which the legacy attachment points
            may not be appropriate, we could consider naming the
            attachment points by numerical index (COLOR0 ... COLORn) in
            which case we could consider dropping this level of
            indirection and allowing the fragment shader to output
            directly into the numerically specified COLOR0 attachment
            point with no indirection.

            However, this indirection is deemed to be useful becaues it
            allows the application to redirect the fragment color
            outputs without changing either the fragment shader itself
            or the current framebuffer attachments, both of which are
            believed to be heavier-weight state change operations than
            simply changing the indirection table via glDrawBuffers..

            Therefore, we elect to retain this level of indirection.
            This leaves open the question of what to call the attachment
            points.  See issue (54).

    (54) What should we name the logical buffer attachment points,
         bearing in mind the relationship to ARB_draw_buffers?

            RESOLUTION: resolved, option (E), which is a modified
            version of (C).  Specifically, we use the names
            COLOR_ATTACHMENT0_EXT through COLOR_ATTACHMENTn_EXT,
            DEPTH_ATTACHMENT_EXT, and STENCIL_ATTACHMENT_EXT (and any
            future attachment points also get the ATTACHMENT suffix).

            The reason this is an issue is that prior to
            EXT_framebuffer_object, the names of the various color
            logical buffer "attachment points" were heavily influenced
            by their intended usage in a graphical window-system.
            Logical buffers for BACK and FRONT_LEFT make sense in the
            context of double buffering and stereo presentation, but
            their use in off-screen rendering situations is
            anachronistic at best and perhaps even confusing.

            There are several options:

            Option (A): stick with the "legacy" names

                This would have us use all of the legacy names which are
                used to identify a single buffer: FRONT_LEFT,
                FRONT_RIGHT, BACK_LEFT, BACK_RIGHT, and AUX0..AUXn.

                This option would require no change to DrawBuffersARB().

            Option (B): AUXn names

                If we wish to avoid using the legacy names, one option
                is to re-use another numerically named set of color
                buffers, the AUX buffers, and only allow framebuffer
                objects to support AUX0..AUXn attachment points.

                This has the advantage of being easy to specify, and
                numerically delimit, but is a little strange as
                framebuffer objects could conceivably support the same
                number of AUX buffers as the implementation supports
                multiple render targets.  This would have the awkward
                consequence of allowing framebuffer objects to support
                more AUX buffers than the default framebuffer could
                support via the pixel format selection mechanism.

                This option would require no specific change to
                DrawBuffers but might require non-default framebuffers
                to support more AUX buffers than the default framebuffer
                controlled by the window-system pixel format.

            Option (C): COLORn names

                Another option is to rename the color buffer attachment
                points for application-created framebuffer objects to
                COLOR0..COLORn.  This has the advantage of avoiding the
                legacy window-centric names, and avoiding the confusion
                with AUX buffers.  When considered in conjunction with
                the decision in issue (53) to support a level of
                indirection when using ARB_draw_buffers, however, the
                user of the names COLOR0..COLORn may be confusing.  For
                instance, if an ARB fragment program contains color
                output to "result.color[3]", it will not necessarily
                output to COLOR3.  It will actually write to the buffer
                specified by DrawBuffersARB for DRAW_BUFFER3 which may
                or may not be COLOR3.

                This option would require an update to DrawBuffers to
                accept the new COLOR0..COLORn values as valid draw
                buffers and would require a change to DrawBuffers to
                disallow the "legacy" names.  Or at the very least we
                would need some language to describe what happens if the
                DrawBuffers are using the legacy names when the
                currently bound framebuffer is not the default window
                system framebuffer.

            Option (D): DATAn names

                Yet another option is to call these attachment points
                DATA0..DATAn.  This is the same as option (C) but uses
                the word DATA instead of COLOR.  This has the advantage
                of avoiding the above problems with COLOR0..COLORN, but
                introduces a similar conflict with GLSL which uses the
                "gl_FragData[n]" name for its output.  Additionally,
                since we only support multiple render targets for color
                logical buffers, it may be that using the word DATA is
                considered too abstract/general.

            Option (E): add ATTACHMENT to *ALL* names

                In order to avoid the confusion of option (C) and (D),
                we can choose to be more verbose.  We can add the word
                _ATTACHMENT to distinguish these enums from the color
                outputs of a fragment program or fragment shader.  For
                symmetry we also add _ATTACHMENT to the DEPTH and
                STENCIL (and any other to-be-added) attachment points.

                Similar to (C) and (D), this option requires an update
                to DrawBuffers to at least accept the new enum values.
                We could choose to make it illegal to specify the legacy
                values for non-default framebuffers as well.  This is
                essentially covered by issue (55).

            Here is an pseudo-code example using option (E):

                // Assume presence of color renderbuffers
                // with names 1000, 2000, 3000, 4000

                GLuint db[4] =
                    { COLOR_ATTACHMENT4, COLOR_ATTACHMENT7,
                      COLOR_ATTACHMENT1, COLOR_ATTACHMENT2 };

                glDrawBuffers(4, db);

                glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,   COLOR_ATTACHMENT4,
                                             GL_RENDERBUFFER_EXT, 1000);

                glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,   COLOR_ATTACHMENT7,
                                             GL_RENDERBUFFER_EXT, 2000);

                glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,   COLOR_ATTACHMENT1,
                                             GL_RENDERBUFFER_EXT, 3000);

                glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,   COLOR_ATTACHMENT2,
                                             GL_RENDERBUFFER_EXT, 4000);

                Then in ARB_fragment_program
                    result.color[0] writes to COLOR_ATTACHMENT4  (i.e., renderbuffer 1000)
                    result.color[1] writes to COLOR_ATTACHMENT7  (i.e., renderbuffer 2000)
                    result.color[2] writes to COLOR_ATTACHMENT1  (i.e., renderbuffer 3000)
                    result.color[3] writes to COLOR_ATTACHMENT2  (i.e., renderbuffer 4000)

                And in ARB_fragment_shader
                    gl_FragData[0]  writes to COLOR_ATTACHMENT4  (i.e., renderbuffer 1000)
                    gl_FragData[1]  writes to COLOR_ATTACHMENT7  (i.e., renderbuffer 2000)
                    gl_FragData[2]  writes to COLOR_ATTACHMENT1  (i.e., renderbuffer 3000)
                    gl_FragData[3]  writes to COLOR_ATTACHMENT2  (i.e., renderbuffer 4000)


            See also issue (57) for discussion on querying the number of
            available color buffers.

    (55) What should happen if the current DRAW_BUFFER(s) point to a
         non-existent logical buffer?  Likewise for READ_BUFFER.

            RESOLUTION: resolved

                partial resolution #1: DrawBuffer(s)/ReadBuffer throws
                an error if the buffer does not "exist" for all
                framebuffers (default and non-default).

                    Should it be an error to call drawBuffer on a
                    non-default framebuffer if named buffer does not
                    exist?

                        Resolved: yes

                partial resolution #2: The test for having a valid draw
                and read buffer should be part of framebuffer
                completeness test.

                    Should be part of completeness test and should all 5
                    indpenent reasons add 5 enums?

                        Resolved: yes

                partial resolution #3: we should create an enum for
                each implementation independent reason for failing
                the framebuffer completeness test of section 4.4.4.1

                    Current names (could change...)
                        FRAMEBUFFER_COMPLETE_EXT
                        FRAMEBUFFER_INCOMPLETE_ATTACHMENTS_EXT
                        FRAMEBUFFER_INCOMPLETE_IMAGES_EXT
                        FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT
                        FRAMEBUFFER_INCOMPLETE_FORMATS_EXT
                        FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT
                        FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT
                        FRAMEBUFFER_UNSUPPORTED_EXT

                        NOTE: as per resolution of issue (78)
                        FRAMEBUFFER_INCOMPLETE_ATTACHMENTS_EXT
                        became
                        FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT
                        and
                        FRAMEBUFFER_INCOMPLETE_IMAGES_EXT
                        was dropped.

            This issue is intertwined with issue (56), which discusses
            whether the DRAW_BUFFER and READ_BUFFER are context or
            framebuffer object state.

            First, some background: If DRAW_BUFFER state is part of the
            context state vector rather than the framebuffer object
            state vector (see issue 56), then there are three ways to
            cause DRAW_BUFFER to reference a color buffer attachment
            point that "does not exist" in the currently bound
            framebuffer.  If DRAW_BUFFER is part of the framebuffer
            object state vector, then (A) still applies but (B) and (C)
            do not.

              A) The first case is by detaching, from the currently
                 bound framebuffer object, the image that is attached to
                 attachment point named by the value of DRAW_BUFFER.  If
                 an image is attached to COLOR_ATTACHMENTn_EXT in the
                 current framebuffer object and DRAW_BUFFER is set to
                 COLOR_ATTACHMENTn_EXT, and then the application
                 detaches the image from COLOR_ATTACHMENTn_EXT, then
                 DRAW_BUFFER will end up specifying a buffer that "does
                 not exist" in the currently bound framebuffer object.

                 There is no analogue to this case in OpenGL prior to
                 EXT_framebuffer_object.  Before this extension, the
                 pixel format or fbconfig of a window or pbuffer is
                 immutable once one of these drawables has been created.
                 By design, framebuffer objects (which essentially
                 represent a new type of drawable) have mutable "pixel
                 formats".

              B) The second case is by binding between two user-created
                 framebuffer objects, where the two framebuffer objects
                 do not have images attached to the same set of color
                 attachment points.  If an image is attached to
                 COLOR_ATTACHMENTn_EXT in the current framebuffer object
                 and DRAW_BUFFER is set to COLOR_ATTACHMENTn_EXT, and
                 then the user binds to a new framebuffer for which
                 there is no image attached to COLOR_ATTACHMENTn_EXT,
                 then DRAW_BUFFER will end up specifying a buffer that
                 "does not exist" in the newly bound framebuffer object.

                 This is morally equivalent to calling MakeCurrent to
                 bind a context to a different drawable (window or
                 pbuffer) which does not have bitplanes for the color
                 buffer named by the context's value of DRAW_BUFFER.
                 For example, MakeCurrent to a double-buffered window,
                 set DRAW_BUFFER to BACK, then MakeCurrent to a
                 single-buffered window.

              C) The third case is by binding between the default
                 framebuffer and a user-created framebuffer object.  The
                 attachment points of a user-created framebuffer object
                 are named COLOR_ATTACHMENTn_EXT, DEPTH_ATTACHMENT_EXT,
                 STENCIL_ATTACHMENT_EXT, etc.  These are also the legal
                 values of DRAW_BUFFER when a user-created framebuffer
                 object is bound.  The default framebuffer, on the other
                 hand, does not use the _ATTACHMENT names but instead
                 uses names such as FRONT_LEFT, BACK_RIGHT, and AUXn as
                 legal DRAW_BUFFER values.  Because the two sets of
                 names do not overlap, no value of DRAW_BUFFER is valid
                 for both the default framebuffer and a user-created
                 framebuffer object.

                 This is somewhat equivalent to case (B), except that in
                 case (C) there is a guarantee that DRAW_BUFFER will
                 become invalid, whereas in case (B) it is only
                 _possible_ that DRAW_BUFFER will become invalid.

            The very problem of invalid DRAW and READ buffers was
            already a feature of OpenGL (and the window-system APIs)
            before the introduction of the EXT_framebuffer_object
            extension.  The GLX specification specifically addresses
            what happens when MakeCurrent is used to bind a context to a
            different drawable (window or pbuffer) which does not
            possess one of the color buffers referenced by the context's
            current values of DRAW_BUFFER and READ_BUFFER.  GLX
            addresses this by saying that no GL error is generated, but
            invalid DRAW_BUFFER behaves as if DRAW_BUFFER were NONE, and
            reads produce undefined results when READ_BUFFER is invalid.

            Now, back to the question of how EXT_framebuffer_object
            should handle the situation when a framebuffer object is
            bound and DRAW_BUFFER or READ_BUFFER is not valid while
            bound to a user-created framebuffer object.

            Obviously one option is to resolve the issue the same way is
            handled by MakeCurrent in the GLX spec.  Invalid DRAW_BUFFER
            acts as if DRAW_BUFFER were NONE, and invalid READ_BUFFER
            causes read operations to generate undefined results.

            A second option is to modify the framebuffer completeness
            test to fail if the current DRAW_BUFFER or READ_BUFFER
            reference an attachment point to which no image is attached.
            This solution would also result in no rendering being
            performed, but would also generate a GL error when rendering
            is attempted while in this state, as determined by issue
            (64).  When rendering to a framebuffer object, invalid
            DRAW_BUFFER would cause generation of GL errors; but when
            rendering to a window, invalid DRAW_BUFFER would not cause
            generation of GL errors.

            Consider also that, because of the resolution of issue (66),
            depending on how issue (56) is decided, failing the
            framebuffer completeness test due to a "non-existent"
            DRAW_BUFFER or READ_BUFFER may not be a viable option,
            because the framebuffer completeness test is not allowed to
            examine context state.

            Additionally, there are two sub-issues that fall out of this
            issue:

                sub-issue 1: Error at DrawBuffer call time or not?
                sub-issue 2: DRAW_BUFFER in or out of completeness test?

            [sub-issue 1]:  First, what should be the behavior of
            DrawBuffer(s) and ReadBuffer if the specified buffer does
            not exist at the time DrawBuffer(s) or ReadBuffer is called?

            For default framebuffer (window-system drawables), an error
            is currently thrown.  We can not (or do not wish to) change
            this legacy behavior of window-system supplied drawables.
            Consequently, we must resolve several questions here:

            For instance:

                - Should we do the same thing (error at DrawBuffer time)
                  for user framebuffer objects?

                - Is this decision influenced by the fact that
                  user-created framebuffer objects can change their
                  attachments one buffer at a time while window-system
                  supplied drawables can not (i.e., must change all
                  attachments atomically)?

                - Also, on other places in this API, such as assembling
                  a framebuffer from framebuffer-attachable images, we
                  have allowed the system to move through "invalid"
                  states without generating an error as long as the
                  system was back in a "valid" state by rendering time
                  (or "validation" time).  Should we adhere to that
                  principle here, or is this case different somehow?

                - Do we wish to retain the legacy window-system
                  DrawBuffer(s) behavior for application-created
                  framebuffer objects for the sake of maintaining
                  consistency?  i.e., Does the benefit of treating
                  default and non-default framebuffers consistently
                  outweigh the earlier decision to delay validation of
                  "invalid" states?

                - Both resolutions are examples of "state combination"
                  errors where an error may or may not be generated
                  depending on the order state-changing function calls
                  are made.  For instance, in the legacy behavior
                  DrawBuffers does or does not throw an error on user
                  framebuffer objects depending on when you call
                  DrawBuffer relative to when you made your image
                  attachments.  On the other hand, if we decided to not
                  throw an error at DrawBuffer time for user framebuffer
                  objects, then DrawBuffer does or does not throw an
                  error depending on whether one is bound to a default
                  or non-default framebuffer.  Is one of these "state
                  combination" errors better or worse than the other?

            [sub-issue 2]: Should having a DRAW_BUFFER that names a
            non-existent buffer cause the framebuffer completeness test
            to fail?

            Since image attachments can be changed after
            DrawBuffer(s) is called, even if we throw an error at
            Drawbuffer(s) time, we still must decide how to handle
            having an invalid DRAW_BUFFER at render (or "validation")
            time.  Our options include failing the completeness test,
            (thus disabling rendering and generating an error at render
            time) or just behaving as if DRAW_BUFFER is NONE (thus
            disabling rendering but generating no error at render time).

            If the answer is "fail completeness test", then since
            currently framebuffer completeness can only be affected by
            framebuffer state, then one of two things has to happen:
            Either the drawbuffer state must be framebuffer object
            state, or we have to revisit our decision that framebuffer
            completeness is solely a property of the framebuffer state
            and can not be affected by "per context" state.

            If the answer is "do not fail completeness test", then the
            practical consequence of this decision is that having an
            invalid DRAW_BUFFER behaves as if DRAW_BUFFER is NONE, and
            no error is generated at render time.  Also, in this case,
            DRAW-BUFFER state can be either per-context or
            per-framebuffer object state without violating any
            previously decided issues.

    (56) Should the value of DRAW_BUFFER, the corresponding draw buffers
         indirection table for ARB_draw_buffers, and the value of
         READ_BUFFER, be part of the context state vector or part of the
         the framebuffer object state vector?

            RESOLUTION: resolved, per-framebuffer object

            This issue is intertwined with issue (55), which discusses
            what happens when the DRAW_BUFFER or READ_BUFFER references
            a color buffer that "does not exist" in the current
            framebuffer.

            Please first read the "First, some background" section of
            issue (55), which could be, but is not, replicated here.
            Note that depending on how issue (56) is decided, cases (B)
            and (C) from issue (55) might become moot.  Specifically, if
            the DRAW_BUFFER and READ_BUFFER state are added to the
            framebuffer object state vector, then neither case (B) nor
            case (C) remains relevant.  Only case (A) would continue to
            be an issue.

            The discussion over this issue centered around the following
            areas:

             i) There must be a unique per-context value of DRAW_BUFFER
                for the default window-system-provided framebuffer.

                In GL, before EXT_framebuffer_object, the DRAW_BUFFER
                was considered context state because:

                1) When two contexts are rendering to the same drawable,
                   each context can use a different value of
                   DRAW_BUFFER.

                2) When MakeCurrent alternately binds a single context
                   to each of two different drawables, after MakeCurrent
                   DRAW_BUFFER retains the value it had immediately
                   before calling MakeCurrent.  This is true even if the
                   last time the context was bound to a given drawable,
                   DRAW_BUFFER had a different value than it does when
                   that drawable is next bound to the context.

                Therefore, a per-context value of DRAW_BUFFER must
                exist, and must be in effect when the
                FRAMEBUFFER_BINDING_EXT is zero.

                Two ways of satisfying this requirement that we have
                considered include:

                A) DRAW_BUFFER is part of the context state vector, but
                   is not part of the framebuffer object state vector.

                B) Every framebuffer, including the per-context default
                   window-system-provided framebuffer, has its own value
                   for DRAW_BUFFER.

            ii) MakeCurrent vs. BindFramebuffer

                As described above, the context state vector must
                contain a value for DRAW_BUFFER that applies to the
                default window-system-provided framebuffer, which is
                used after a call to BindFramebuffer(0).  When
                MakeCurrent is used to bind the context to a different
                drawable (window or pbuffer), the context's value of
                DRAW_BUFFER remains unchanged.  In other words, the
                choice of drawable does not affect the value of
                DRAW_BUFFER.

                An application-created framebuffer object is another
                type of drawable.  When the framebuffer binding is
                changed via BindFramebuffer, issue (56) speaks to the
                way in which DRAW_BUFFER is or is not updated.  If
                DRAW_BUFFER is part of the context state vector, then
                DRAW_BUFFER remains unchanged after calling
                BindFramebuffer, just like it remains unchanged after
                calling MakeCurrent.  On the other hand, if DRAW_BUFFER
                is part of the framebuffer object state vector, then
                after calling BindFramebuffer DRAW_BUFFER may change
                along with the rest of the per-framebuffer state (i.e.,
                the image attachments).

                By defining DRAW_BUFFER as context state, the behavior
                of BindFramebuffer and MakeCurrent are similar, with
                respect to their effect on the value of DRAW_BUFFER.

                On the other hand, by defining DRAW_BUFFER as
                framebuffer object state, then BindFramebuffer and
                MakeCurrent differ in their impact on the value of
                DRAW_BUFFER.

           iii) Multiple contexts and shared framebuffer objects

                If DRAW_BUFFER is part of the framebuffer object state
                vector, then a single value of DRAW_BUFFER, like all of
                the framebuffer object state, will be shared by any
                context bound to a given framebuffer object.  This can
                be considered either a feature or a restriction
                depending on whether or not it is desirable for multiple
                contexts to be able to share a single the value of
                DRAW_BUFFER.

                Note that WGL_ARB_pbuffer plus WGL_ARB_render_texture
                API has limitations due to the fact that the texture
                image selection state is stored in the pbuffer drawable.
                For example, that API does not support six different
                contexts (in six different threads) simultaneously
                rendering to the six faces of a cube map pbuffer.  It
                offers no way to share the images without also sharing
                the pbuffer, and the pbuffer contains a single set of
                texture image selection state.

                EXT_framebuffer_object differs from ARB_render_texture,
                however, however, in that EXT_framebuffer_object allows
                the same images of a texture to be attached to multiple
                framebuffer objects.  Consequently, the above cubemap
                example can be implemented in EXT_framebuffer_object in
                one or two ways, depending on the resolution of issue
                (56):

                1) Create six framebuffer objects.  Attach a different
                   face of a cubemap texture to each of the six
                   framebuffer objects.  Each of the six contexts binds
                   to a unique framebuffer object.  Technically, this
                   option is available whether DRAW_BUFFER is context or
                   framebuffer state.  However, if it is context state,
                   then there is no reason to create six framebuffer
                   objects since the value of the DRAW_BUFFER will
                   already be unique per context.

                2) On the other hand, if DRAW_BUFFER is defined as
                   context state, then a second option is available.
                   Using a single framebuffer object, attach each face
                   of the cube map texture to a different attachment
                   point in the framebuffer object.  Each of the six
                   contexts binds to the same framebuffer object, but
                   each context uses a different value of DRAW_BUFFER.

            iv) Frequency of DrawBuffer calls:

                Whether DRAW_BUFFER is part of context or framebuffer
                state will have an effect on how often one must call
                DrawBuffer after modifying framebuffer state.

                If DRAW_BUFFER is part of the context state vector, then
                DRAW_BUFFER is guaranteed to become invalid after
                calling BindFramebuffer to switch between the default
                framebuffer and a user-created framebuffer object [i.e.,
                this is case (C) in issue (55)].  DRAW_BUFFER may become
                invalid after switching between two user-created
                framebuffer objects if the framebuffer objects do not
                have images attached to the same set of color attachment
                points.  When DRAW_BUFFER is invalid, it is necessary to
                call DrawBuffer to set DRAW_BUFFER to a valid value or
                else rendering is disabled.

                If, on the other hand, DRAW_BUFFER is part of the
                framebuffer object state vector, then it should never be
                necessary to call DrawBuffer after calling
                BindFramebuffer.  DRAW_BUFFER would only become invalid
                if an image was detached from the framebuffer, or if
                MakeCurrent bound the default framebuffer to a drawable
                with a different set of color buffers.  (The latter was
                possible prior to this extension.)

                Note that there are several state-modifying routines
                that may also need to get called after a framebuffer
                state change, like Viewport, Scissor, etc.  We are not
                proposing that these other routines be part of
                framebuffer state.  One could think of DrawBuffer as
                being similar to these other routines which you may also
                need to call when you bind between framebuffer objects.
                On the other hand, some have questioned whether an
                invalid DRAW_BUFFER is really in the same class of
                problems as an out-of-bounds viewport or scissor
                because: 1) an invalid viewport or scissor never
                generates a GL error, and 2) prior to the
                EXT_framebuffer_object extension an invalid DRAW_BUFFER
                would generate INVALID_ENUM inside DrawBuffer.

             v) Effect on framebuffer completeness test:

                By resolution of issue (66), if the draw buffer is
                context state, then the fact that the draw buffer names
                a non-existent buffer can not affect the result of the
                framebuffer completeness test.  Note that this still
                could be considered a "do not render" case, but would
                separate from the framebuffer completeness test.

                If the draw buffer(s) and read buffer are part of the
                framebuffer object state then having a draw or read
                buffer name a non-existent buffer can (if we choose) be
                part of the framebuffer (in)completeness test.

                Note, by resolution of issue (64), failing the
                framebuffer completeness test causes a GL error to be
                generated when draw or read operations are attempted.
                Prior to EXT_framebuffer_object, it was already possible
                to have an invalid value of DRAW_BUFFER if a call to
                MakeCurrent bound the context to a drawable that did not
                contain a color buffer corresponding to the context's
                value of DRAW_BUFFER.  However, no GL error would be
                generated if DRAW_BUFFER obtained an invalid value
                through this method.

            vi) Draw buffer(s) error behavior:

                Prior to the EXT_framebuffer_object extension, it was an
                error to call DrawBuffer or ReadBuffer with a value that
                did not correspond to one of the logical color buffers
                of the currently bound drawable (window or pbuffer).
                Although it was not possible to set DRAW_BUFFER to an
                invalid value by calling DrawBuffer, it was actually
                possible for DRAW_BUFFER to have an invalid value after
                a call to MakeCurrent, as describe in issue (55).

                It has not been decided yet whether
                EXT_framebuffer_object will relax the requirement that
                the argument to DrawBuffer references a color buffer
                that "exists" in the currently drawable.

                In working group discussions, there was a perception
                that such an error during DrawBuffer can be generated
                only if DRAW_BUFFER is part of the framebuffer object
                state vector.  Then when the default framebuffer (window
                or pbuffer) is current, the legal values of the argument
                to DrawBuffer would be determined by the pixel format or
                fbconfig.  When a user-created framebuffer object is
                current, the legal values of DrawBuffer would either be
                any of the COLOR_ATTACHMENTn_EXT names or only the names
                of attachment points to which an image is presently
                attached.

                However, given the precedent set by MakeCurrent and
                DRAW_BUFFER, it seems reasonable to retain the
                preexisting requirement that the argument to DrawBuffer
                names a buffer that "exists" in the current drawable.
                In other words, there already exists precedent that says
                it is OK for DrawBuffer to generate an error in all the
                cases described in the preceeding paragraph, even if
                DRAW_BUFFER is defined as part of the context state
                vector.

    (57) Should we have a query to define the maximum number of
         attachable color buffers (to support ARB_draw_buffers)?

            RESOLUTION: yes, MAX_COLOR_ATTACHMENTS.

            Currently an application can query the GL for the maximum
            number of supported AUX buffers.  An application can also
            query for MAX_DRAW_BUFFERS_ARB in the ARB_draw_buffers
            extension.  Given that we have named the color logical
            buffer attachment points, COLOR_ATTACHMENT0_EXT through
            COLOR_ATTACHMENTn_EXT, it seems natural that we should have
            a query to find the maximum value "n".

            One thought was that we might be able to use
            MAX_DRAW_BUFFERS_ARB to store this value, but that value
            really describes the maximum number of colors that can be
            simultaneously output which is not the same thing as the
            number of buffers which can be attached and then selected
            among using DrawBuffersARB().

            This question is related to issue (54), which covers the
            names of the user-created framebuffer object color
            attachment points.  Using the names COLOR_ATTACHMENT0_EXT
            through COLOR_ATTACHMENTn_EXT rather than the legacy color
            buffer attachment names (FRONT_LEFT et. al.) for
            user-created framebuffer objects has an advantage that the
            number of color buffer attachment points could be queried
            independent of the number of AUX buffers and existence of
            front/back & left/right color buffers as specified in the
            pixelformat.  The number of available offscreen attachment
            points really should be independent of the properties of the
            current drawable's pixelformat, especially since MakeCurrent
            can bind a context to a drawable with a different
            pixelformat and thus different set of color buffers.

            One implication of this query is that the value of
            MAX_COLOR_ATTACHMENTS_EXT is possibly still dependent on the
            context/pixel format but independent of the currently bound
            framebuffer.  In other words, MAX_COLOR_ATTACHMENTS_EXT can
            not change simply because the user called BindFramebuffer().
            Or can it?  See issue (62)

    (58) What should we do about rendering to textures with borders?
         (besides attempt to fervently wish them out of existence, I mean)

            RESOLUTION: resolved, borders are fully supported

                Should we allow rendering to textures with borders at
                all?
                    Resolved: yes

                If we allow this, can you render to the border pixels?
                    Resolved: yes

            The reason this is an issue is that (a) everyone hates
            supporting borders, and (b) it's not clear what it means to
            render to a texture with borders.

            To disallow rendering to a texture image with non-zero
            border size, we could add a test for non-zero border size to
            the definition framebuffer completeness.  This might be
            preferrable to an error at FramebufferTexture, since the
            user could always redefine the texture to have borders after
            attachment, and so the framebuffer completeness test is
            necessary anyway.

            However, since borders do exist today and we are not
            planning to rip them out of OpenGL everywhere else, we
            decided to support them.  It seemed odd that you could still
            specify borders via TexImage but not render into the same
            texture so we leave them supported.  Note that it's quite
            possible that implementations which don't support borders
            may continue to either not support them or fall to software
            rasterization.

            If someday we decide to disallow borders in general, they
            will be disallowed from this extension as well.

            One additional note: section 3.8.2, page 137, of the OpenGL
            1.5 specification, states that {Copy}TexSubImage uses
            negative offsets to refer to border texels.  We choose not
            to do this because negative window-coordinates are
            undefined.  (NOTE: Are negative window coordinates actually
            undefined?  Or are they just not commonly used in practice?)

    (59) Should we support named bit depths for stencil renderbuffers?

            RESOLUTION: resolved, yes, choose 4 common formats.

            We intend to support using renderbuffers to store stencil
            data.  This means we need to consider what kind of "internal
            format" request we provide for stencil formatted
            renderbuffers.

            We choose to allow a "named" format request for the internal
            format.  This is essentially equivalent to the named
            internal format request of the TexImage calls.  It is merely
            a request and the driver will attempt to satisfy it as best
            as possible but may approximate the requested format with
            another format.  Additionally, this request is subject to
            the same invariance constraints as the texture internal
            format requests.

            For the initial extension we choose the following four sized
            internal formats, as well as the base internal format
            STENCIL_INDEX:

                STENCIL_INDEX1_EXT
                STENCIL_INDEX4_EXT
                STENCIL_INDEX8_EXT
                STENCIL_INDEX16_EXT

    (60) If depth buffer is disabled when a user-created framebuffer
         object is bound and an image is attached to GL_DEPTH, does the
         depth buffer factor into framebuffer validity determination or
         is the depth buffer ignored?  Similar for other types of
         logical buffers.

            RESOLUTION: resolved, consider all attached images when
            determining framebuffer completeness, even if the images are
            "irrelevant" based on the state of the framebuffer.

            The main reason to consider not paying attention to certain
            images (i.e., ignoring the image attached to the depth
            buffer when depth test is disabled) would be developer
            convenience.  The developer wouldn't need to explicitly
            detach a buffer, but could set the state to ignore it
            (disable depth test, or disable color mask, reset draw
            buffer, etc).

            However, this raises the possibility that by simply changing
            this other state (depth test, stencil test, color mask, etc)
            the query for framebuffer completeness could change values.
            This was deemed undesirable.  We'd like to be able to
            minimize the amount of state changes that can cause the
            framebuffer completeness query to change.

            Another strange effect of ignoring "irrelevant" images when
            considering framebuffer completeness is that we could get an
            undesirable interaction between draw buffer and the pixel
            format for the framebuffer.  A framebuffer is considered
            incomplete if the color buffers do not all have the same
            internal format.  But, consider the following case:

                - an application attaches a floating point
                  color-renderable image to COLOR_ATTACHMENT1, and

                - the application attaches a fixed point
                  color-renderable image to COLOR_ATTACHMENT2 and

                - the application sets the DRAW_BUFFER to
                  COLOR_ATTACHMENT1, then

            If we ignored the attached images not pointed to by
            DRAW_BUFFER(s} when evalutating framebuffer completeness, we
            could consider this framebuffer complete.  This framebuffer
            would use floating point rendering.  Now, if the application
            simply changes the DRAW_BUFFER to COLOR-ATTACHMENT2, then we
            would also say the framebuffer is complete but now the
            framebuffer would be using fixed point rendering.  We didn't
            want to allow a change to DRAW_BUFFER to effectively change
            the pixel format.  On the other hand if we always considered
            all attached images, then in this case described above, the
            framebuffer would always be incomplete while the formats of
            the color-renderable images were inconsistent.

            To avoid the above complications, we choose to have
            framebuffer completeness queries consider all attached
            buffers, regardless of whether they would be "used"
            according to the current state vector or not.

    (61) What are the "minimum requirements" to support this extension?

            RESOLUTION: resolved, language added to end of 4.4.4.2

            For instance, is it a requirement that there must be at
            least one renderable color, depth, and stencil format that
            can all work together?  is it a requirement that you must be
            able to render to *any* "color-renderable" texture format?

            Since this extension specifically pulling in functionality
            that used to be in the domain of the window sytem, we would
            like to use as a starting point for our requrirements, the
            language from the GLX 1.3 spec, page 15, which lists the
            minimum requirements langauge for a conformant GLX
            implementation.

            Questions to answer:

                - is the GLX spec a good starting point?

                - do we want the same requirements as the GLX spec?

                - do we want stronger requirements than the GLX spec?

                - do we want some kind of requirement that states that
                  to support this extension, there must be at least one
                  "gl conformant" framebuffer configuration that can be
                  constructed on a given implementation?  If so, how do
                  we phrase this?

            Anyway, the GLX spec states:

                "Servers are required to export at least one GLXFBConfig
                that supports RGBA rendering to windows and passes
                OpenGL conformance (i.e., the GLX RENDER TYPE attribute
                must have the GLX RGBA BIT set, the GLX DRAWABLE TYPE
                attribute must have the GLX WINDOW BIT set and the GLX
                CONFIG CAVEAT attribute must not be set to GLX NON
                CONFORMANT CONFIG).  This GLXFBConfig must have at least
                one color buffer, a stencil buffer of at least 1 bit, a
                depth buffer of at least 12 bits, and an accumulation
                buffer; auxiliary buffers are optional, and the alpha
                buffer may have 0 bits.  The color buffer size for this
                GLXFBConfig must be as large as that of the deepest
                TrueColor, DirectColor, PseudoColor, or StaticColor
                visual supported on framebuffer level zero (the main
                image planes), and this confguration must be available
                on framebuffer level zero."

            So if we did a direct translation of these requirements into
            our spec, we'd end up with something approximately like the
            following:

                Although GL defines a wide variety of internal formats
                for textures and renderbuffers, some implementations may
                not support particular combinations of internal formats
                for the images attached to the framebuffer.  For a
                framebuffer with these unsupported combinations of
                internal formats, calls to CheckFramebufferStatusEXT()
                will return FRAMEBUFFER_UNSUPPORTED_EXT.

                There must exist, however, at least one combinations of
                internal formats for the images attached to the
                framebuffer for which CheckFramebufferStatusEXT() will
                *not* return FRAMEBUFFER_UNSUPPORTED_EXT.

                Specifically, implementations are required to support at
                least one set of internal formats for the images
                attached to a framebuffer such that

                    - the image attached to the color buffer supports
                      RGBA rendering, and

                    - the image attached to the color buffer has at
                      least as many bits as the deepest visual supported
                      by the window-system, although the alpha buffer
                      can have 0 bits, and

                    - the image attached to the depth buffer has at
                      least 12 bits, and

                    - the image attached to the stencil buffer has at
                      least 1 bit, and

                    - rendering to this framebuffer passes OpenGL
                      conformance."

            However, it looks like no one is seriously using the
            NON_CONFORMANT_CONFIG bit under GLX or AGL, and on WGL,
            there is no such bit, so we'd like to "assume" conformance
            and drop the last clause.  Additionally, we'd like to just
            piggy back on the existing requirements without duplicating
            them here so we will simplify this language to leave out the
            last paragraph and list of clauses altogether.

            We do wish to retain the notion that there must be some
            configuration for which FRAMEBUFFER_UNSUPPORTED_EXT is not
            returned.

    (62) Exactly which, if any, queriable state can change after a call
         to BindFramebuffer and/or a change in framebuffer attachments?

            RESOLUTION: resolved, at the Sept. 2004 ARB meeting we
            resolved in principle that there is a small subset of
            "framebuffer-related" state that can change.  We just need
            to define exactly the subset.  The current subset as listed
            in section 4.4.5 is below:

                AUX_BUFFERS
                MAX_DRAW_BUFFERS
                MAX_COLOR_ATTACHMENTS
                RGBA_MODE
                INDEX_MODE
                DOUBLEBUFFER
                STEREO
                SAMPLE_BUFFERS
                SAMPLES
                {RED|GREEN|BLUE|ALPHA}_BITS
                DEPTH_BITS
                STENCIL_BITS
                ACCUM_{RED|GREEN|BLUE|ALPHA}_BITS

            The reason this is an issue is that traditionally there are
            some GL context state queries that are dependent on pixel
            format and window-system state.  For instance, doing a
            GetIntegerv of DEPTH_BITS returns the bit depth of the
            window-system allocated depth buffer which is a function of
            the pixel format.  If DEPTH_BITS is zero, this means that no
            depth buffer was present in the pixel format.  Other context
            state queries like MAX_DRAW_BUFFERS, MAX_ACCUM_BUFFERS,
            SAMPLES, etc are all possibly functions of the current pixel
            format, and have traditionally been constant over the
            lifetime of a given context.

            However, this extension specifically subsumes some of the
            operations and state of the window-system pixel format
            mechanism.  So an obvious question is: what should these
            queries return for things like DEPTH_BITS and
            MAX_DRAW_BUFFERS when using a non-default framebuffer
            object?

            If we allow these queries to return a value that is a
            function of the current framebuffer object, then a
            consequence is that the values returned by these queries can
            change after a call to BindFramebuffer and/or a change in
            the attachments of the currently bound framebuffer object.

            This may be desirable: for instance, a user may rightly
            expect that querying RED_BITS returns the red bits of the
            currently attached color buffer(s).  But is the user also
            expecting that MAX_DRAW_BUFFERS might change?  What about
            SAMPLES or SAMPLE_BUFFERS?  What about
            MAX_COLOR_ATTACHMENTS?

            Consider that in developing ARB_draw_buffers it was stated
            that some implementations might want to set MAX_DRAW_BUFFERS
            to 1 for pixel formats that also supported multisampling.
            This would allow implementations to control which
            capabilities they exported.  What facilities do we have for
            this in this extension - can MAX_DRAW_BUFFERS change if we
            supported multisampling on a non-default framebuffer object?

            Fundamentally, all of the state in table 6.28-6.31 of the
            OpenGL 1.5 spec (the MAX_* queries) can in theory change as
            the result of the pixel format changing.  Since this
            extension does an effective pixel format change, what if any
            of this state can/should be allowed to change when
            framebuffer attachments are changed?

    (63) Should we change ValidateFramebuffer into an explicit
         enum-based query for framebuffer completeness?

            RESOLUTION: resolved, separate API function rather than a
            Get query, to emphasize the "on-demand" state examination.

            We did choose a different name for ValidateFramebuffer().
            In issue (67) we decided to rename this function
            CheckFramebufferStatus().

            For reference the reason this is an issue is that, as
            originally described, ValidateFramebuffer (now called
            CheckFramebufferStatus) served three purposes:

            First, it forced an "on-demand" examination of the current
            framebuffer state (including framebuffer attachment state)
            and the state of the attached images.  On some
            implementations this examination might be expensive, and
            therefore there was a desire to control exactly when the
            operation would occur.

            Second, because of the implementation dependent reasons that
            a framebuffer might be considered not complete,
            ValidateFramebuffer served as a query for an application to
            determine at run-time if a seemingly compatible combination
            of attached images is actually incompatible on the current
            GL implementation.

            Third, ValidateFramebuffer was more than just a query.  It
            was a function that would set a piece of framebuffer state
            that "enabled" rendering if the framebuffer was determined
            to be complete.  After certain changes to framebuffer state,
            or in the initial default state, unless ValidateFramebuffer
            was called prior to rendering, and unless framebuffer
            validation "passed", rendering would be disabled.

            However, now that it is no longer required to call
            ValidateFramebuffer prior to rendering, ValidateFramebuffer
            doesn't really set any state.  The third reason is no longer
            pertinent.

            This leaves us with the first and second reasons.  The first
            reason in particular seems to be driven by convenience.  It
            is convenient to be able to control when this operation
            happens, but it is arguably also convenient to be able to
            force the examination/validation of a wide variety of other
            pieces of GL state, yet we don't have specific on-demand
            "ValidateTexture" or "ValidateBlendState" routines.  In
            addition, on some implementations framebuffer validation may
            be less expensive than originally thought.

            So if we ignore the first reason for a moment, we are left
            the second reason for ValidateFramebuffer - a query of the
            framebuffer completeness.  We do wish to retain this query
            somehow, so we could choose to leave it in its current form,
            or we could choose to make it look like other more
            traditional queries, i.e., some kind of GetInteger,
            GetFramebuffer, or GetFramebufferParameter call.

            If we feel like the first reason is still valid, we could
            also choose to retain a ValidateFramebuffer call to get the
            "on-demand" state examination and still choose to make
            separate query for the framebuffer completeness.

            Either way, if we decide to make an enum-based query we need
            to choose the form.  We could choose to use GetInteger and
            query for COMPLETENESS.  (If we do this, we'd need a
            "per-target" variant of the enum, i.e.,
            FRAMEBUFFER_COMPLETE, and if a read framebuffer target is
            added later, READ_FRAMEBUFFER_COMPLETE would need to be
            added as well.)  This would be similar to how texture
            bindings are queried on a per target basis as in
            GetIntegerv(TEXTURE_BINDING_2D, &param).  Another option is
            to add a target-aware query routine, i.e.,
            GetFramebufferiv(FRAMEBUFFER, COMPLETE, &param); this is
            similar to what the ARB vertex/fragment program API's did to
            query per-target state like PROGRAM_NATIVE_INSTRUCTIONS_ARB.

    (64) Should it be a GL error to attempt to render with an incomplete
         framebuffer?

            RESOLUTION: resolved, "YES"

            In looking at other GL resources that can be considered
            "incomplete" for rendering, there were two precedents to
            draw on here: (a) textures and (b) programs/shaders.

            a) For textures, the GL behaves as if the incomplete
            resource is simply not available.  That is, if an
            application attempts to render with an incomplete texture,
            then the GL behaves as if texturing is simply disabled.  No
            error is thrown.

            b) For ARB_vertex_program and ARB_fragment_program, and GLSL
            shaders, if a program or shader is invalid, then the GL
            throws an error at "Begin" time.

            Originally, we choose style (a): treat an incomplete
            framebuffer similar to a "pixel ownership test failure".
            This means that no fragments are generated, reads of the
            framebuffer generate undefined pixels, and no error is
            thrown.

            [NOTE: Technically, according to the GL spec, the fate of
            rendered fragments that fail the pixel ownership test is
            left up to the window-system and is therefore implementation
            dependent.  A better way to handle this is to mimic
            make_current_read's language "as if DRAW_BUFFER is NONE"]

            However, since the a query of framebuffer completeness can
            only answer the question "is the framebuffer complete right
            now?", but doesn't indicate whether the application may have
            attempted to render with an incomplete framebuffer earlier,
            we decided to throw an error in this case as an aid to the
            developer.  Throwing an error has an advantage in that the
            error state is retained, like all GL errors until the user
            calls GetError().

            Another option that was considered was to extend the
            framebuffer completeness query to indicate that the
            framebuffer is complete now, but was incomplete during
            earlier rendering.  The downside of this option was that
            then there would then be two return values for the query
            that would mean "framebuffer complete right now".  So in the
            end, we simply decided to leverage the existing GetError
            semantics to capture this "sticky" error behavior.

            One additional concern was that gl errors are traditionally
            only used to indicate programming errors on the part of the
            application, but the framebuffer completeness test may have
            failed simply because of implementation dependencies through
            no fault of the application.  We decided to adopt the notion
            is that it is an error to attempt to render with an
            incomplete framebuffer, on all implementations, and so it
            actually *is* a programming error if an application does not
            attempt to deal with an incomplete framebuffer prior to
            rendering.

    (65) If it is an error to render to or read from an incomplete
         framebuffer, should we use INVALID_OPERATION or create a new
         error?

            RESOLUTION: resolved, INVALID_FRAMEBUFFER_OPERATION_EXT

            We resolved to create a new error at the September ARB
            meeting and then resolved the name of the error within
            the work group.

                We agreed that if we throw an error here, we'd like a
                new error enum, particularly because the error may have
                been triggered by a framebuffer which is incomplete for
                implementation dependent reasons.

                Some options for the new error name which were discussed:

                    OPERATION_ON_INCOMPLETE_FRAMEBUFFER
                    INCOMPLETE_FRAMEBUFFER
                    IMPLEMENTATION_DEPENDENT_FAILURE
                    INVALID_FRAMEBUFFER
                    INVALID_FRAMEBUFFER_OPERATION

    (66) There are several issues related to how we treat DrawBuffer(s)
         and other context state with respect to framebuffer
         completeness.  We'd like a self-consistent model here and this
         may affect the resolution of issue (8), (44), (55), and (56).

            RESOLUTION: resolved, (d) - no context state in framebuffer
            completeness test, but context state can affect whether
            rendering takes place, does not take place, or is undefined.
            Note option (d) required us to revisit issue (44).

            The first question we had to answer was:

                Is it desireable that "framebuffer completeness" be
                purely a property of the set of framebuffer state (which
                includes the state of the images attached to the
                framebuffer)?  Or can a framebuffer's completeness
                depend on "non-framebuffer" context state as well?

            For instance, there are currently two pieces of context
            state that can affect framebuffer completeness: texture
            binding state and draw buffer state.

            First, in issue (44), we decided that attaching an image of
            a currently bound and enabled texture to a framebuffer can
            cause a framebuffer to be incomplete.  The texture binding
            is context state and there are pieces of the texture object
            state (base level, max level) that can also affect the
            determination of framebuffer completeness.  (Additionally if
            we add render-to-vertex-array functionality later, we might
            expect to have a framebuffer completeness requirement that
            examines the state of the currently bound vertex array.)

            One way to avoid this context dependency is to revisit issue
            (44) and say that this "texture-from-destination" case
            simply generates undefined rendering but does not affect
            framebuffer completeness.  This would replace the "expressly
            disabled" rendering and framebuffer incompleteness with
            "undefined rendering", but would also let implementations
            avoid checking context state during the validation of the
            framebuffer state.

            The second piece of context state that might cause
            framebuffer validation failures is the draw buffer(s) and/or
            read buffer state.  It has been suggested in issue (55) that
            if the draw buffers specify attachment points with no
            attached images, then the framebuffer might be considered
            incomplete.  If we choose to do this, then we would have
            context state influencing framebuffer completeness state.
            However, if we resolve issue (56) to say that the draw
            buffer state is part of the framebuffer object state, then
            the draw buffer is no longer context state and this
            particular dependency of framebuffer completeness on context
            state goes away.

            The above discussion leaves us with several self-consistent,
            but different sets of decisions:

                (a) Remove context dependencies from framebuffer
                    completeness.

                    To do this we would:

                    - Move draw buffer state from context into
                      framebuffer: issue (56)

                    - Make "texture-from-destination" undefined instead
                      of a reason for framebuffer incompleteness: issue
                      (44)

                    - Presumably, if we created a render-to-vertex-array
                      extension layered on this one, we would likely
                      also make rendering into the currently bound
                      vertex array undefined as well.

                    With option (a), we can say that having draw buffer
                    set to an non-existent buffer is a reason for
                    framebuffer incompleteness and there are no context
                    dependencies.  This would resolve issue (55).

                (b) Allow context dependencies in framebuffer
                    completeness.

                    Essentially this means that the result of a query of
                    framebuffer completeness is dependent on the context
                    making the query - or put another way, the
                    framebuffer completeness state is context state not
                    framebuffer state.

                    If we choose this option (b), then we are esentially
                    free to resolve issues (44), (55), and (56)
                    however we want.  In other words:

                        - draw buffer can be either context or
                          framebuffer state: issue (56)

                        - "texture-from-destination" can be either
                          undefined or a reason for framebuffer
                          incompleteness

                        - draw buffer specifying a non-existent buffer
                          can be a reason for framebuffer incompleteness
                          or could result in undefined behavior: issue
                          (55)

                (c) Remove the framebuffer object and make the
                    framebuffer state part of the context.

                    This option redefines the issue by not making a
                    distinction between framebuffer "object" state and
                    "context" state, therefore framebuffer completeness
                    depends only on "context" state because all of the
                    "framebuffer" state is now "context" state.

                    This would mean that there is now a subset of state
                    in the context that can be considered the
                    "framebuffer state" of the context.  This is the set
                    of state that would presumably be pushed/popped
                    under a theoretical FRAMEBUFFER_BIT for
                    PushAttrib().

                    Regardless of whether there is a framebuffer object,
                    framebuffer completeness may or may not still depend
                    on pieces of other "context" state that are not part
                    of subset of context state related to the
                    "non-default" framebuffer (for instance, texture
                    bindings and/or draw buffer state).

                    If we choose this option (c),

                        - we remove the framebuffer object: issue (8)
                          This means:

                            - removing gen/is/bind/delete framebuffer
                              object

                            - moving the attachment state into the
                              context

                            - creating new context bind points for
                              framebuffer attachments and creating new
                              BindFramebufferAttachableImage calls or
                              using the FramebufferTexture() calls to do
                              context binds of framebuffer-attachable
                              images

                        - we decide whether there is a single set of
                          draw/read buffer context state or a 2nd set of
                          draw/read buffer context state to be used for
                          "non-default" framebuffer objects.  Either way
                          it's "context" state but we need to know if we
                          have one set of state or two.  This is a
                          variation on issue (56).

                        - as in option (b), "texture-from-destination"
                          can be either undefined or a reason for
                          framebuffer incompleteness

                        - as in option (b), a draw buffer specifying a
                          non-existent buffer can either be a reason for
                          framebuffer incompleteness or could result in
                          undefined behavior: issue (55)

                        - all the framebuffer attachments become context
                          state

                        - we add a framebuffer enable/disable bit to use
                          to distinguish between the "default" and
                          "non-default" framebuffer

                (d) Create a new category of reasons that you can't use
                    a framebuffer for rendering in a specific context,
                    but that are not part of the test for "framebuffer
                    completeness"

                    Essentially, this is a kind of hybrid of options (a)
                    and (b).  There are no context dependent reasons for
                    framebuffer incompleteness, but at the same time
                    there are some additional context-dependent
                    constraints on using a framebuffer.  In other words,
                    a framebuffer can be complete but still not suitable
                    for rendering by a given context.

                    This creates two categories of tests that can be
                    used to disable rendering - the set of
                    context-independent test that are used to determine
                    framebuffer completeness, and the set of tests that
                    are context-dependent and not used to determine
                    framebuffer completeness.

                    An open question is: should we add a separate query
                    for this second set of context-dependent tests
                    and/or a "meta-query" that would cover both sets.
                    This "meta-query" would return "true" if and only if
                    the framebuffer is complete *and* it can be used in
                    this context.

                    Note that while the "is framebuffer complete" query
                    is required by the fact that a framebuffer can be
                    incomplete because of implementation dependent
                    reasons, the second query of the context-dependent
                    test results and the "meta query" are primarily
                    debugging aids, though perhaps convenient ones.

                    The framebuffer completeness query is analogous to
                    asking if a texture is "mipmap complete".  The
                    question, "can I render into my framebuffer", is
                    analgous to asking the question, "is texturing
                    enabled."  A bound texture may be "complete", but
                    texturing can still be disabled due to an
                    unfortunate combination of non-texture-object
                    context state.  Option (d) is basically saying the
                    same thing of framebuffer objects.

                    To implement option (d), we'd do the following:

                    - If draw buffer is defined as "context state" it
                      can not affect framebuffer completeness, but if
                      draw buffer is defined as framebuffer state it
                      might affect framebuffer completeness.  See issues
                      (55) and (56).

                    - Make "texture-from-destination" undefined instead
                      of a reason for framebuffer incompleteness: issue
                      (44).  Technically, this could still be an error
                      unrelated to framebuffer completeness, but we are
                      trying to avoid creating a precedent for arbitrary
                      "errors at begin time".  When this case was
                      included in the "framebuffer completeness"
                      validation, the additional cost of generating the
                      error was free.  But if this
                      "texture-from-destination" case is not part of
                      framebuffer completeness, then it is an additional
                      cost at begin time to detect this in order to flag
                      an error (and/or disable rendering).  To avoid
                      this cost, we would make this undefined.

                    - Presumably, if we later create a
                      render-to-vertex-array extension layered on this
                      one, we would likely also choose the same
                      resolution for rendering into the currently bound
                      vertex array as we choose for the currently bound
                      texture.

    (67) In issue (63) we decided we want to use a dedicated API
         function to test framebuffer completeness.  We might want to
         change the name of "ValidateFramebuffer" however.  If so, what
         name should we use?

            RESOLUTION: resolved, CheckFramebufferStatus()

            One reason we decided to retain an explicit API function
            instead of just using a GetInteger style query is to
            emphasis the "on-demand" state examination that takes place
            when making this query.

            However, some were uncomfortable with the name
            ValidateFramebuffer for this purpose.  Some felt that it
            implied a requirement to call the function, and others felt
            it was too similar in name to the GLSL function
            ValidateProgram which served a related but slightly
            different purpose.  So we chose a new name.

            Some options we considered:
                ValidateFramebufferCompleteness()
                CheckFramebufferCompleteness()
                CheckFramebufferStatus()
                IsFramebufferComplete()

    (68) Exactly which levels should by generated by GenerateMipmapEXT?

            RESOLUTION: resolved, from TEXTURE_BASE_LEVEL+1 through q

            Automatic mipmap generation via GENERATE_MIPMAP generates
            from TEXTURE_BASE_LEVEL+1 through p, which is the 1x1 level.
            However, applications frequently don't want to waste
            computation generating past q, which is the min of
            TEXTURE_MAX_LEVEL and p.  The only recourse is to accept the
            performance hit or to not use GENERATE_MIPMAP.

            Arguably GENERATE_MIPMAP should have been specified to
            generate only through q.  We have the opportunity to "fix"
            this problem by "correctly" specifying the new function
            GenerateMipmapEXT to generate only from TEXTURE_BASE_LEVEL+1
            through q.

            As the specification of GenerateMipmapEXT is currently
            written, GenerateMipmapEXT only generates levels
            TEXTURE_BASE_LEVEL+1 through q.

    (69) What should we call the framebuffer objects to distinguish
         them from the default framebuffer?

            RESOLUTION: resolved, "application-created"

            Currently we call these "application-created" framebuffers
            Some places in the spec have also referred these as
            "GL-allocated" framebuffers.  Whichever term we use, we
            should use it consistently.

            Some terms we considered:

                "application-created" framebuffers
                "application-allocated" framebuffers
                "non-default" framebuffers
                "GL-created" framebuffers
                "GL-allocated" framebuffers
                "dynamically-created" framebuffers
                etc.

            The GL spec already talks about "creating" textures, not
            "allocating" them, so "*-created" seems like a better
            choice.

            It's a bit of a toss-up between "GL-created" and
            "application-created".  Technically, the "GL" really creates
            and manages these objects but it only does so at the request
            of the application.  Going with "application-created" for
            now.

    (70) With which, if any, attribute bit does the framebuffer binding
         push and pop?  The same question applies to the current
         renderbuffer?

             RESOLUTION: resolved, don't push/pop framebuffer binding
             bit for now.  If desired, we may add this in the ARB/core
             update of this spec.

        There are a few precedents to choose from.

        The ARB_vertex/fragment_program extensions chose to *not*
        push/pop the current program object binding.  It's not clear if
        this was intentional or which existing attribute bit was
        appropriate to use or if there was a desire to not create a new
        attribute bit.

        ARB_vertex_buffer_object buffer objects and GL core texture
        objects do push/pop the bindings with the existing VERTEX_ARRAY
        and TEXTURE bits respectively.  In addition, the texture enables
        are push/pop'ed with the TEXTURE bit.

        If we do wish to push/pop the FRAMEBUFFER_BINDING_EXT state we
        probably need a new FRAMEBUFFER bit.

        We could also consider adding a RENDERBUFFER_BIT to cover the
        current renderbuffer binding or allow this renderbuffer binding
        to push/pop with the FRAMEBUFFER bit.  However, it's less clear
        that push/pop'ing the renderbuffer binding is useful since the
        renderbuffer binding is not used for rendering.  The
        renderbuffer binding is only used to set the current
        renderbuffer for renderbuffer storage allocation and queries.

        Also, there are a related set of questions about how much state
        should push/pop with a new FRAMEBUFFER bit.  Should we push/pop
        all of the framebuffer object state in addition to the current
        binding?  Similar to the way vertex array's can be attached to
        VBO's, use of VBO, framebuffers can be attached to other GL
        objects.  The TEXTURE_BIT covers both per object (min/mag
        filter) and per context (texture environment and enable) state.
        It's not clear if this is useful or desirable to have per-object
        state push/pop.  With the addition of object semantics, it seems
        like the need for push/pop of object state is reduced.

        In the end, since we'd need to create a new bit anyway, we
        decided to defer adding push/pop semantics until we understand
        the implementation ramifications better.  If we decide to create
        the bit later on in the ARB or Core revision of this extension,
        we can add it in a backward-compatible fashion.

    (71) Should we spell out precisely which rendering and reading
         routines can cause us to generate an error at the time the
         rendering or reading functions are called?

             RESOLUTION: resolved, keep the same language as ARB
             vertex/fragment program and GLSL for now, with the
             addtitions relevant for reading the framebuffer, but
             recommend the ARB look at this when doing the next core GL
             spec revision.

        Currently GL has a few cases that can cause errors at render
        time.  Specifically, attempting to render with a mapped vertex
        buffer object, an invalid low-level vertex or fragment program,
        or an invalid GLSL program object all generate errors at "Begin"
        time.

        This extension adds a new error at "begin" time.  Attempting to
        render with an "incomplete" framebuffer generates
        INVALID_FRAMEBUFFER_OPERATION_EXT.  In addition, this extension
        adds the same error at "read" time if the application tries to
        read from an "incomplete" framebuffer.

        The ARB vertex program, ARB fragment program, and GLSL extension
        specs state that an app which tries to use an "invalid" object
        can generate errors when Begin, RasterPos, or any command that
        performs an explicit Begin is called.

        This extension has adopted similar language.  So the question
        asked by this issue is: do we need ot be more explicit.

        There are some ambiguities.  For instance, it is an error to
        write pixels using an "implicit Begin" operation like DrawArrays
        if the current vertex program is invalid, but it is not an error
        to do an Accum operation which also writes pixels to the
        framebuffer.

        This issue applies to all of these extensions.

        Options include:

            - listing all routines which can render or read from the
              framebuffer and stating that they can cause an error if
              the framebuffer is incomplete, solving the problem for
              this extension only.

            - adding to the GL core a table of "routines that read
              pixels" and "routines that write pixels" and referencing
              those tables in the language for each of these extensions.

        Because each extension is doing something a little different,
        it's not even clear if the second option is a viable option.
        It's possible each extension would need its own list of routines
        which can generate errors anyway.

        Basically, this is a larger problem than this
        EXT_framebuffer_object extension.  For now, we choose to use the
        same (vague-ish) language adopted by the
        ARB_vertex/fragment_program and GLSL extnesions.

        We do recommend, however, that the ARB address this issue in the
        next GL core revision.

    (72)  Should the framebuffer completeness test include a clause that
          says "at least one color attachment" has been made?  Or "at
          least one attachment of any type"?  Or is the framebuffer
          still complete when there are no attachments at all?

            RESOLUTION: resolved, a framebuffer must have at least one
            color-renderable, depth-renderable, or stencil-renderable
            image attached to be complete.

            While a framebuffer with only depth, or only color
            attachments seems plausible, we couldn't come up with a
            sensible use for a framebuffer with no attachments at all,
            so the assumption is that this is an unintended error on the
            part of the application.  Therefore, we choose to make it
            part of the framebuffer completeness test.

            We could make this its own clause in the framebuffer
            completeness test.  If we choose to do so, we should
            probably come up with a new FRAMEBUFFER_INCOMPLETE_* to
            conform to our previous practice of keeping one enum per
            clause.

            However, since this is really related to the attachment
            state, we could just piggy back this on the first clause and
            same all the attachment points must be "attachment complete"
            and there must be at least one color, depth, or stencil
            buffer attached.

            If we choose this latter option, we can continue to use the
            FRAMEBUFFER_INCOMPLETE_ATTACHMENT enum to cover this case.

    (73) This clause from framebuffer completeness (before it was
         reworded, see below):

           * The value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT must
             not be NONE for any color attachment point named by
             READ_BUFFER.

         basically requires at least one color attachment is non-NULL.
         But this is not what we want.  So what should we do?

            RESOLUTION: resolved, (4a) READ_BUFFER can be NONE

         The reason is: READ_BUFFER is not allowed to be NONE, which in
         turn means to be framebuffer complete, READ_BUFFER must be
         COLOR_ATTACHMENTn_EXT for some n which has an image attached.
         However, we don't wish to preclude a no-color framebuffer.
         What should we do?

            Options include:

                4a) Allow READ_BUFFER of NONE, reads of color from the
                    framebuffer when read buffer is none, generate error
                    INVALID_OPERATION

                4b) Generate an error when a read operation (ReadPixels,
                    CopyPixels, etc) is attempted while the color
                    attachment point referenced by the READ_BUFFER does
                    not have an attached image.

                4c) Reverse earlier decision to allow complete
                    framebuffer not to have any color attachments.
                    Instead, require at least one color attachment.
                    READ_BUFFER must point to a valid color attachment
                    or else the framebuffer object is incomplete.

        (4c) seems to require the user attach a color buffer just to be
        able to read the depth buffer of a depth-only framebuffer.

        (4b) seems to suffer from the same problem (unless we move the
        "valid read buffer" test out of the completeness test).

        Of these choices, (4a) seems to be the most palatable.  We
        choose the allow the value of READ_BUFFER to be NONE, but reads
        of color buffers when READ_BUFFER is NONE will generate an
        error, in order to be consistent with the decision in issues
        (26) and (65).

        Note: that clause was eventually reworded to say:

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

    (74) What should CheckFramebufferStatusEXT return if
         FRAMEBUFFER_BINDING_EXT is zero?

         Secondary question: what should CheckFramebufferStatusEXT
         return if there is an error?

             RESOLUTION: resolved, default fb returns COMPLETE always,
             and CheckFramebufferStatusEXT returns
             FRAMEBUFFER_STATUS_ERROR if there is an error (bad target)

            This goes to a larger question of whether all framebuffers
            including the default window-system-provided framebuffer
            have a "completeness" state, or if "completeness" is only a
            property which applies to application-created framebuffers.

            For the case where the current FRAMEBUFFER_BINDING_EXT is
            zero, options include:

                - CheckFramebufferStatusEXT returns an error when
                  FRAMEBUFFER_BINDING_EXT is zero.

                - CheckFramebufferStatusEXT always returns
                  FRAMEBUFFER_COMPLETE_EXT when FRAMEBUFFER_BINDING_EXT
                  is zero.

            For the case CheckFramebufferStatusEXT generates an error,
            options include:

                - reworking CheckFramebufferStatus into a "get" style
                  routine that returns a value (or not) in an input
                  parameter like GetIntegerv

                - returning a known value like NONE or 0

                - returning undefined results

    (75) How are state values for the stencil index write mask and
         stencil reference value affected by this extension?

            RESOLUTION:
                a) index write mask is stored as 32 bit value, default
                   is all 1's, and
                b) reference value is not clamped on specification but
                   rather is clamped on use and query, and
                c) we need to add the stencil reference value
                   to the state table that lists the state values that
                   might change after a framebuffer state change

            The reason this is an issue is that the current GL
            specification indicates that the stencil index write mask
            and the stencil reference value are masked/clamped according
            to the number of stencil bitplanes.  However, in this
            extension the number of stencil bitplanes can now change
            dynamically as the image attached to the framebuffer is
            changed.

            For instance, if these values are clamped/masked according
            to the bitdepth of the currently attached stencil buffer,
            what should happen if the user later attaches a stencil
            buffer of a different bit depth?  Must the stencil reference
            value or index write mask be respecified?

            For the index write mask: we decide to treat this value as
            "all 1's" as the current specification allows, but further
            define the number of 1's to be 32 (the minimum width of an
            integer in GL), and a likely maximum stencil bitdpeth for
            the forseeable future.  This should retain backward
            compatbility and still handle the case where the bitdepth of
            the stencil buffer can change dynamically.

            For the stencil reference value, we decide to treat this
            state similar to way various clamped colors are treated in
            the ARB floating point pixel extensions.  Specifically, the
            state values are clamped against the current logical buffer
            bitdepths as they are used for rendering and queried, but
            are not clamped on specification.  This means that these
            state values do not need to be respecified just because the
            logical buffer bit depth changes, and retains backward
            compatibility to the behavior prior to this extension.

            We will update the appropriate sections of the specification
            to describe this behavior.

    (76) Currently framebuffer objects are shared, should we make them
         not shared across contexts?

            RESOLUTION: yes, framebuffers are shared like display lists
            and textures are shared.

            Initially it was suggested that some complicated
            multi-context semantics might be avoided if if the namespace
            for framebuffer objects were not shared across contexts.
            Specifically, some members of the group felt that by not
            sharing framebuffer objects, we could avoid the situation
            where:

                a) one context can change the draw buffer of a
                   framebuffer object in use by another context.

                b) one context can change the attachments of a
                   framebuffer object which may be in use by another
                   context.

            However, after some discussion, we realized that even if we
            didn't share framebuffer objects, there were still
            interactions similar to those listed above because the
            underlying images could still be shared.  Consequently, one
            context could still affect the completeness and attachments
            of the framebuffers in another context by modifying or
            deleting the framebuffer-attachable images shared by both
            contexts.

            So in the end, we decided to retain the share-ability of
            framebuffer objects rather than introduce an asymmetry with
            other GL objects like textures.

            ADDITIONAL COMMENTS:

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

    (77) If the application deletes an object and that object contains
         an image which is attached to a framebuffer object, exactly
         when and how is the image detached from the framebuffer?

            RESOLUTION: resolved, option (1): images are detached from
            the currently bound framebuffer on delete, but images remain
            attached to any non-bound framebuffers.

            This is issue is somewhat related to the multi-context
            object-sharing discussion currently going on in the ARB.

            This extension presupposes that framebuffer attachments
            represent a reference to the attached image (or more
            correctly - a reference to the object containing the
            attached image).  Since having a reference to an object
            affects when the object (and/or its name) is deleted, object
            deletion semantics are tied into the notion when the state
            describing these references is modified.  In other words,
            the semantics of when objects are deleted are affected by
            the details concerning when a change to the framebuffer
            attachment state takes place.

            Prior to the EXT_framebuffer_object and GLSL extensions, the
            only way in which an object not currently bound to this GL
            context could be modified, was when the object was modified
            by another GL context.

            Both the EXT_framebuffer_object and GLSL extensions allow an
            object (texture, renderbuffer, shader) to be attached to a
            "container" object (framebuffer, program).  With the
            introduction of "attachment", an object could be bound to
            the context at more than one binding point.  For example, a
            texture can be bound to TEXTURE_2D_BINDING, and it can also
            be indirectly bound through the FRAMEBUFFER_BINDING if it is
            attached to the framebuffer object bound to the
            FRAMEBUFFER_BINDING.

            Furthermore, a texture can be attached (by reference) to a
            framebuffer object that is not bound to any context, while
            at the same time the texture *is* bound to context's
            TEXTURE_2D_BINDING.  Because the texture state is a part of
            the framebuffer object's state, it is now possible for
            modification of a texture through TEXTURE_2D_BINDING to
            cause modification of a framebuffer object, even though the
            framebuffer object is not bound to any context at the time
            it is modified.

            One conceptual model for dealing with this situation is to
            treat attachment similar to bind, but instead of binding to
            a context, you are "binding" to another object.  For the
            purposes of managing object references, object lifetimes,
            state propogation semantics, etc., these attachments can be
            considered to be "just like" a bind operation.  [A "bind"
            and an "attach" are not exactly equivalent, however; see
            issue (82) for a further discussion on Bind vs. Attach.]

            If we agree on the above conceptual model, then we may wish
            to look to the multi-context situation for guidance on how
            to treat state changes to non-currently-bound framebuffer
            objects.

            Unfortunately, the multi-context semantics are poorly
            defined by OpenGL.  If we decide to use them as a guide, we
            should at least define what they are and this is why the
            larger ARB is looking at this issue now.

            For EXT_framebuffer_object, there are three choices for
            behavior.  In each case, we defer to the larger ARB the
            details about when an object name is available for reuse.
            For the purposes of this discussion, we are looking only at
            state changes governing the attachments.  The three choices
            are listed below:

              For the sake of concrete simplicity, this discussion
              speaks to the images of a texture object; but it applies
              equally to the image of a renderbuffer object.

              If you delete a texture object while one of the texture's
              images is attached to a framebuffer object (or multiple
              framebuffer objects), then:

              (1) The image is automatically detached from the currently
                  bound framebuffer object only.

                  If the image is also attached to any other framebuffer
                  objects, then the image is NOT automatically detached
                  from those.

                  The application is responsible for manually detaching
                  images from the other framebuffer objects, by
                  rebinding each framebuffer in turn and performing an
                  explicit detach operation.

                  Until the application manually detaches the image from
                  the other framebuffers, those framebuffers continue to
                  use the image for rendering.  The other framebuffer
                  objects have a reference to the image until the image
                  has been detached from them.  In this way, attachment
                  behaves as if the image was "bound to the framebuffer
                  object".

              (2) The image is automatically detached from the currently
                  bound framebuffer object.  Also during DeleteTexture,
                  the image is automatically detached from any other
                  framebuffer object to which it is attached; however,
                  the image is not guaranteed to be detached from the
                  other framebuffer objects until the next time those
                  framebuffer objects are bound via BindFramebufferEXT.

                  Similar to option (1), in order to "really" delete the
                  object, the application is responsible for rebinding
                  all the framebuffer objects to which the deleted image
                  was attached.  However, unlike option (1), the
                  application need not actually perform an explicit
                  detach operation.  The application can merely bind the
                  framebuffer.

                  Until the application actually rebinds the framebuffer
                  the images are not actually detached and deleted.  The
                  other framebuffer objects continue to hold a reference
                  (like a binding) to the image until the next time the
                  framebuffer objects are bound.

              (3) The image is automatically detached from all
                  framebuffers objects during DeleteTextures, including
                  the currently bound framebuffer as well as any other
                  framebuffers to which the image is attached.

                  The application need not explicitly bind to, and
                  detach the image from, any framebuffer that is not
                  bound at the time DeleteTextures was called.

                  Because the framebuffer object has a reference to the
                  texture object, and the texture object's state is
                  considered part of the framebuffer object's state,
                  this resolution implies that DeleteTextures may
                  modifiy the state of a framebuffer object that is not
                  the currently bound object.

            With reference to the object-sharing discussion that is
            going on in the ARB right now, for (a)-style
            implementations, options (2) and (3) are indistinguishable.
            However, for (b)-style implementations, implementing (3)
            would require textures to store a list of all attached
            framebuffers while (2) would not.

            Options (2) and (3) essentially treat the currently-bound
            and non-currently-bound framebuffers the same--i.e.,
            deleting the image (ultimately) detaches it from all
            framebuffer.  This may be desirable as a convenience to the
            application.

            On the other hand, Option (1) treats the currently bound
            framebuffer special, in that deletions are performed
            automatically much like textures are unbound automatically
            from the current context's binding points, but they are not
            unbound automatically from other contexts' binding points.
            Also, Option (1) leaves the application in control of when
            the images are detached, which also may be desirable.

            We choose option (1) because it is the simplest, and it also
            does not unduly burden implementations regardless of their
            choice of (a) versus (b) object-sharing model.

            If an implementation has the (a)-style object sharing model,
            then the fact that images remain attached to non-bound
            objects has no affect on when the object name may be
            re-used.  If the implementation has a (b)-style
            object-sharing model, then the outstanding attachments will
            delay re-use of the object name until the image has been
            detached.  Regardless of whether the ARB chooses (a) or (b)
            behavior, or even if the ARB chooses to leave this behavior
            undefined, we can "piggy-back" on the name-reuse semantics
            they decide.

            Also, option (1) means that if the application deletes a
            texture while one of the texture's images is attached to a
            framebuffer object that is not bound, then the application
            may continue to render into the image after the framebuffer
            is bound again, regardless of the (a) vs. (b) choice.

            Finally, note that if a context deletes an object containing
            an image attached to the currently bound framebuffer, then
            we first detach the image from the bound framebuffer.  This
            means that the state change to the framebuffer (the detach
            operation) is guaranteed to be picked up by any other
            context the next time the framebuffer is bound in one of the
            other contexts.

    (78) Should we collapse the notions of "framebuffer-attachable image
         completeness" and "framebuffer attachment completeness" into a
         single type of completeness (probably retaining the name
         "framebuffer attachment completeness"

            RESOLUTION: resolved, yes, eliminate "framebuffer-attachable
            image completeness" and add a "non-zero-area" requirement to
            the "framebuffer attachement completeness" test.

            Originally this extension had several layers of which
            affected framebuffer completness.  They were:

                - framebuffer-attachable image completeness
                    * image has non-zero width/height/depth
                    * image has color, depth, or stencil format
                    * image is not from a proxy texture

                - framebuffer attachment completeness
                    * attached image is textures/renderbuffer
                    * attached image is from existing object
                    * attached image has format appropriate
                      for attachment point (depth buffer
                      has depth format, etc)

                - framebuffer completeness
                    * all attachment points are "attachment complete"
                    * all images are "framebuffer-attachable image complete"
                    * all color buffers have same format
                    * draw buffer is attached
                    * read buffer is attached
                    * framebuffer format combination is supported

            However, upon further reflection of the
            "framebuffer-attachable image completeness" tests, we
            realized that

                a) the requirement that the renderble image is not a
                   "proxy" texture was already covered by the fact that
                   it's illegal to attach a proxy texture to a
                   framebuffer, and

                b) the requirement that the format be color, depth, or
                   stencil is essentially already covered by the
                   "framebuffer attachment completeness" test
                   requirement that the format is appropriate for the
                   attachment point.

            This left only the "non-zero-area" test, so we decided to
            fold this requirement into the "framebuffer attachement
            completeness" test and eliminate the concept of
            "framebuffer-attachable image completeness".  This decision
            required the elimination of one of the
            FRAMEBUFFER_INCOMPLETE_* enums as they correspond to the
            conditions in the "framebuffer completeness" test of section
            4.4.4

    (79) Should the internal format chosen by GL for a texture (or
         renderbuffer) be invariant with respect to the state of the
         current framebuffer and its attached images?

            RESOLUTION: yes, the choice of internal format must be
            invariant with respect to framebuffer state changes.

            This means that the GL must choose texture internal format
            based only on the arguments to TexImage and ignore the
            current framebuffer state in this selection process.

            Similarly, the GL must choose renderbuffer internal format
            based only on the arguments to RenderbufferStorage and
            ignore the current framebuffer state in this selection
            process.

            This issue is a variant of issue (62).  The OpenGL 2.0
            specification (p.152, paragraph 4) states that:

                 "A GL implementation may vary its allocation of
                 internal component resolution or compressed internal
                 format based on any TexImage3D, TexImage2D (see below),
                 or TexImage1D (see below) parameter (except target),
                 but the allocation and chosen compressed image format
                 must not be a function of any other state and cannot be
                 changed once they are established."

            Consider that prior to this extension, some implementations
            may have considered the the bitdepths of the logical buffers
            of the framebuffer or the bitdepth of the display when
            choosing an internal format for textures.  Since, in
            practice, these bitdepths typically were immutable for the
            lifetime of a GL context, the invariance requirements were
            met.

            With the introduction of EXT_framebuffer_object, however,
            the logical buffer bitdepths can change over the lifetime of
            the context.  So this issue examines whether or not
            framebuffer state is allowed to affect texture internal
            format selection.

            After some discussion, we felt it was too problematic to
            introduce this type of invariance.  So this extension makes
            no modifications to the invariance language, and adds
            similar invariance language applicable to renderbuffer
            objects.  As long as the app provides the same arguments to
            TexImage{1D|2D|3D} or RenderbufferStorage, then the GL must
            always choose the same internal format.

            Note, however, that the GL is not required to provide the
            same internal format resolution for renderbuffers as it does
            for textures.

    (80) Should attachment routines be display-list'able?

            RESOLUTION: no, in fact none of the routines introduced in
            this extension are included in display lists.

            Initially, we were just considering whether or not the
            framebuffer attachement routines should be included in
            display lists.  The rationale for not including them was
            that since query routines can not be in display lists, and
            well-behaved apps should call the query routine
            CheckFramebufferStatusEXT() after calling making changes to
            framebuffer attachments, it was not possible to write a
            well-behaved app that uses display lists to build up and use
            a framebuffer.  So, one possible solution was to simply
            disallow from display lists the routines that change change
            the result of CheckFramebufferStatusEXT().

            However, we realized on further consideration that other
            routines which can affect the results of
            CheckFramebufferStatusEXT are already allowed in display
            lists.  Namely, the routines which affect textures (TexImage
            and friends).  So, disallowing the attachment routines is a
            partial solution at best.

            We also looked for various precedents and found some mixed
            results:

                - VBO bind operations are not display-list'able, but
                  this is primarily because the VBO bindings are
                  considered client-state

                - texture bindings are display-list'able

            In the end, though we decided to not include the routines
            introduced by this extension in display lists for reasons of
            simplicity more than anything else.

            It's possible we may need to add support for display lists
            back in during promotion of this extension if we determine
            that it is needed later, but for now, we leave this out.

    (81) How should PushAttrib and PopAttrib work with this extension?

            RESOLUTION: mostly deferred for now, may revisit later

            This extension introduces no new push/pop attrib bits to
            cover the state introduced by this extension (for instance
            there is no FRAMEBUFFER_BIT).  So the only real question to
            answer is what effect should Push/Pop attrib have on any
            existing state as it relates to this extension.

            In particular, how should Push/PopAttrib of the
            COLOR_BUFFER_BIT which covers the DRAW_BUFFER and
            READ_BUFFER state interact with this extension?  Does the
            COLOR_BUFFER_BIT affect the per-object DRAW_BUFFER and
            READ_BUFFER state?

            Currently, the answer is yes.  PushAttrib(COLOR_BUFFER_BIT)
            saves the DRAW_BUFFER value of the currently bound
            framebuffer object.  If the app later calls PopAttrib() this
            saved value will be restored even if the framebuffer bound
            at the time PopAttrib is called is different from the
            framebuffer bound at the time PushAttrib was called.

            In other words, one are considering whether or not it is
            strange that PushAttrib(COLOR_BUFFER_BIT) affects a piece of
            per-object state.  Note that this is somewhat similar to the
            way that a PushAttrib(TEXTURE_BIT) can save off
            per-texture-object state and a later call to PopAttrib can
            restore that per-object state even if the texture bound at
            PopAttrib time has since been changed/ deleted/modified in
            some way.

            There are some differences with the texture analogy though.
            Namely, the TEXTURE_BIT does include the texture bindings so
            at least the texture object binding is restored in
            conjunction with the per-texture-object state.  Also, some
            may consider the fact that the TEXTURE_BIT affects
            per-texture-object state more intuitive than the fact that
            the COLOR_BUFFER_BIT affects per-framebuffer-object state.

            Also, there is a larger discussion going on in the ARB right
            now about whether PushAttrib/PopAttrib save references to
            existing bound objects or only the state values which name
            an existing bound object.

            For now, we have deferred further discussion of the
            PushAttrib/PopAttrib semantics in this extension until the
            larger issues are cleared up.

    (82) What is the relationship between a "binding" and an
         "attachment"?

            RESOLUTION: resolved, the concept of attachment is described
            below, though final implications will be affected by larger
            ARB discussions about object sharing and multiple context
            semantics.

                "Attaching" is 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 principle,
                we treat "A" as if it is <implicitly> bound to "C".

                The larger ARB is currently attempting to more clearly
                define the mutliple context semantics as they relate to
                object sharing and binding.  The final implications for
                EXT_framebuffer_object may not be clear until those
                discussions are resolved.  This extension may need an
                update once those issues are addressed.

    (83) We use a non-zero framebuffer binding to enable the use of this
         extension.  Should we instead consider using an explicit
         enable?

            RESOLVED: no, retain the "non-zero-binding means enable"
            semantics.

            Currently we enable the use of an application-created
            framebuffer by binding a non-zero framebuffer object to
            FRAMEBUFFER_EXT binding point.  If the framebuffer binding
            is zero, then the extension is disabled (i.e., we use the
            window-system-provided framebuffer).

            It might be cleaner to be able to say things like, "when
            FRAMEBUFFER_OBJECT is enabled", rather than "when the
            framebuffer binding is not zero", and add an explicit
            enable.  Doing so would also allow changing framebuffer
            object attachments while FBO is disabled, which might result
            in the driver doing less validation while the application is
            setting up framebuffer objects.  It would also provide a
            cleaner way to explain that the permitted DRAW_BUFFER and
            READ_BUFFER values change when the extension is
            enabled/disabled.

            There are a few object model precedents to choose from:
            Textures and ARB Vertex and Framgment Program extensions use
            the explicit enable state.  However, Vertex Buffer Objects,
            Pixel Buffer Objects, and GLSL Vertex and Fragment shaders
            use a non-zero-binding to enable the use of those features.

            If we used an explicit enable, then we could allow creation
            of an object named zero.  Precedent dictates that an object
            named zero is never shared in the context share group.  All
            other framebuffer objects are shared across the share group.
            It might be cleaner to disallow creation of an object named
            zero anyway.

            Since binding to zero disables the extension, one way to
            think about this is that there is an object named zero which
            is managed through MakeCurrent, MakeContextCurrent, and the
            window manager.  All other objects are managed through
            FramebufferTexture, FramebufferRenderbuffer, and the
            operations that define/modify texture and renderbuffer
            images.  When looked at in this light, lack of an explicit
            enable is not as strange.

    (84) Do we need to add any language to describe the y-orientation of
         framebuffer-attachable images?  Specifically, what coordinate
         system is used by images attached to the framebuffer?

            Resolution: unresolved

            GL defines the rendering origin at the lower-left corner.
            Yet, because of the differences between orientation storage
            of textures and images, pbuffer rendering is often
            implemented using a "y-inverted" coordinate system.  Is this
            y-inversion exposed in the API?

            Is the origin in the lower-left?  Upper-left?  Do we need to
            say anything about this at all, or is it already covered by
            existing GL language?

            Currently there is place-holder text in section 4.4.2.3

            The intent of this specification is simply to mirror the
            y-orientation issues of the pbuffer style render to texture
            API's.  What's unclear is whether this requires any new
            language in this specification or not.

    (85) Explain what happens when the FBO has a different width/height
         from the window?

            An FBO takes on the width/height of its attachments.  This
            width/height can be different than the width/height of the
            window (of framebuffer "zero").

            In such cases, after calling BindFramebuffer, it is the
            application's responsibility to set the glViewport and the
            glScissor (if necessary) to match that of the new
            framebuffer binding.

            Some background: The default viewport for a context is
            defined by the dimensions of the window to which the context
            is first made current.  When the window is resized, or when
            the context is bound to a different window, the viewport
            does not change automatically.  It has always been the
            application's responsibility to set the viewport after one
            of these events.  FBO is no different; after BindFramebuffer
            it is the application's responsibility to set the viewport
            if the new framebuffer binding has a different width/height
            than the old binding..

    (86) Are any one- or two- component formats color-renderable?

            Presently none of the one- or two- component texture formats
            defined in unextended OpenGL is color-renderable.  The R
            and RG float formats defined by the NV_float_buffer
            extension are color-renderable.

            Although an early draft of the FBO specification permitted
            rendering into alpha, luminance, and intensity formats, this
            this capability was pulled when it was realized that it was
            under-specified exactly how rendering into these formats
            would work.  (specifically, how R/G/B/A map to I/L/A)

            To resolve this we seem to have two options:

            A) Add new R and RG formats like NV_float_buffer did.

            B) For the existing one- and two- component formats, define
               the mapping from RGBA components to ILA components.

            The superbuffers group has informally decided that option A
            is preferable.

    (87) What happens if a single image is attached more than once to a
         framebuffer object?

         RESOLVED: The value written to the pixel is undefined.

         There used to be a rule in section 4.4.4.2 that resulted in
         FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT if a single
         image was attached more than once to a framebuffer object.

             FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT   0x8CD8

             * A single image is not attached more than once to the
               framebuffer object.

               { FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT }

         This rule was removed in version #117 of the
         EXT_framebuffer_object specification after discussion at the
         September 2005 ARB meeting.  The rule essentially required an
         O(n*lg(n)) search.  Some implementations would not need to do that
         search if the completeness rules did not require it.  Instead,
         language was added to section 4.10 which says the values
         written to the framebuffer are undefined when this rule is
         violated.

Revision History
    #123, October 6, 2016: Jon Leech
        - Remove STENCIL_REF from list of state moved to become framebuffer
          dependent (Bug 8422).
    #122, May 3, 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)
    #121, 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).
    #120, April 22, 2008: Jeremy Sandmel & Jon Leech
        - Update errors section so detaching renderbuffers and textures
          using object name zero is not an error.
    #119, February 13, 2007: Jon Leech
        - Corrected typos in 'GenerateMipmap'.
    #118, April 5, 2006:  jjuliano
        - Improve language related to which formats are
          color-renderable, and describe format conversions when reading
          from and writing to the framebuffer.  Lays groundwork for
          making additional formats color-renderable.
        - Add section 4.4.6.
        - Selecting same attachment multiple times via DRAW_BUFFERs
          writes undefined value to the buffer.
        - Clarify effect of framebuffer completeness on values of state
          table 9.nnn.
        - Describe interaction with NV_float_buffer and
          NV_texture_shader.
    #117, September 26, 2005:  jjuliano
        - Remove FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT.
        - Add language to section 4.10 explaining that duplicate
          attachments result in undefined behavior
        - Add issue (87) to discuss the change.
        - List EXT_packed_depth_stencil as affecting this extension.

    #116, September 16, 2005:  jjuliano
        - Add example (8) demonstrating FBO + ARB_draw_buffers.
        - Add issue (85) discussing window and FBO of different sizes.
        - Add issue (86) about one- and two- component texture formats.
        - State that OpenGL 1.1 is required.

    #115, July 25, 2005:  jjuliano
        - Improve wording around ReadPixels of color data while
          READ_BUFFER is NONE. (INVALID_OPERATION).  Clarify that it is
          legal to read depth/stencil while READ_BUFFER is NONE.
        - In section 4.4.4.2 (Framebuffer Completeness), clarify that
          READ_BUFFER can be NONE, and if NONE then framebuffer
          completeness does not require a color attachment.

    #114, June 16, 2005:  jjuliano
        - Eliminate the name STENCIL_INDEX_EXT.  The name STENCIL_INDEX
          is already defined in the core specification.
        - Add some missing errors to the errors section.
        - Add _ARB suffix to TEXTURE_RECTANGLE, and describe interactions
          with ARB_texture_rectangle.
        - In errors section, say that it is an error if cube map texture
          passed to GenerateMipmapEXT is not cube complete.

    #113, May 27, 2005:  jsandmel, jjuliano, chris niederauer, alex eddy, barthold lichtenbelt
        - improved langage and added some tables (10.nnn and 11.nnn) in
          another attempt to clarify the DrawBuffer(s)/ReadBuffer error
          semantics
        - added additional errors to the summary at the end
        - fixed typo in FramebufferTexture3D where <zoffset> was
          compared against MAX_3D_TEXTURE_SIZE and should have been
          compared against (MAX_3D_TEXTURE_SIZE - 1).
        - note that issue (21) is a duplicate of issue (77) and
          mark issue (21)'s resolution with a reference to issue (77)
        - the resolution of issue (75) indicated that STENCIL_REF is now
          dependent on the current framebuffer state, but STENCIL_REF
          was inadvertantly left off of table 9.nnn
        - fixed the bullet item in section 4.4.1 that stated that when bound to
          an application-created framebufer, the value of SAMPLES is 1.
          it should have said 0.
        - added missing queries of renderbuffer bit depths that were
          inadvertantly left out of the spec.

    #112, April 28, 2005:  jsandmel, jjuliano, chris niederauer
        - updated contributors list
        - Improve language pertaining to "render to texture source" loop.
        - Fixed typo where CheckFramebufferStatusEXT was accidentally
          listed twice in additions to chapter 5's list of
          non-display-listed commands
        - fixed typo in prototype conventions
        - as per workgroup meeting decision on April 4, 2005,
          DrawBuffer(s) and ReadBuffer no longer generate an error when
          specifying an attachment point for which there is no image
          attached.  The rationale is that the user can always attach
          (or detach) after DrawBuffer(s)/ReadBuffer is called anyway.
          We retain the test in CheckFramebufferStatusEXT that makes
          sure the buffers are attached prior to rendering, however.
        - as per workgroup email list discussions April 20, 2005, added
          BindFramebuffer/BindRenderbuffer to the list of
          display-listable functions.  They were inadvertantly left off
          the list.  Adding them back to be consistent with resolution
          of issue (80).
        - added missing language to FramebufferTexture discussion to
          correct section where we compared width/height/level values to
          MAX_TEXTURE_SIZE instead of MAX_CUBE_MAP_TEXTURE_SIZE for cube
          maps attached to framebuffer.
        - as per workgroup meeting decision on April 26, 2005,
          CheckFramebufferStatusEXT will generate an error if called
          within a Begin/End pair, since it is (intentionally) not
          listed in the exclusion list for functions that can be called
          within Begin/End in section 2.6.3
        - as per workgroup meeting decision on April 26, 2005, since
          section 2.6.3 states that routines that return a value should
          return 0 if the routine generates an error,
          CheckFramebufferStatusEXT should return zero and not
          FRAMEBUFFER_STATUS_ERROR_EXT.  Since we don't need
          FRAMEBUFFER_STATUS_ERROR_EXT anymore, we are removing this
          enum from the spec.
        - added missing error language to spec body and fixed incorrect
          language in "Errors" section to clarify that specifying enums
          to DrawBuffer(s) and ReadBuffer that are NEVER legal is an
          INVALID_ENUM, while specifying values that only illegal
          because of the current framebuffer binding are an
          INVALID_OPERATION.
        - Fix minor typos in DrawBuffer(s) and ReadBuffer definitions.

    #111, February 28, 2005:  jjuliano, jsandmel
        - Add example 7 illustrating "depth-only" framebuffer object.

    #110, February 28, 2005:  jsandmel, jjuliano, brian paul
        - no functional changes
        - integrated Brian Paul's fixes for typos and noted
          that invalid operation is generated if the <textarget>
          and type of texture don't match in FramebufferTexture
        - default internalformat for renderbuffer is RGBA not "1" since
          "1" is not a legal internalformat for renderbuffers
        - note that the unsinged base internal formats of RGB, RGBA,
          DEPTH_COMPONENT, and STENCIL_INDEX are legal internal formats
          for renderbuffers.  They were intended to be legal all along
          but the language indicated otherwise.

    #109, January 31, 2005:  jsandmel, jjuliano
        - added language to issue (48) to indidcate that
          CheckFramebufferStatus will return an undefined result for a
          framebuffer in the intial state since a framebuffer in the
          initial state violates multiple completeness rules

    #108, January 31, 2005:  jjuliano
        - fix typos pointed out by various people (thanks)

    #107, January 17, 2005:  jjuliano, jsandmel
        - fix resolution of issue (28) to say "zoffset", not "image"
        - more cleanup of issue resolutions

    #106, January 17, 2005:  jjuliano
        - per working group decision, clean up issue resolutions
        - minor whitespace and punctuation cleanup

    #105, January 17, 2005:  jjuliano
        - add XXX documenting "undefined-ness" of rendering
          vs. texturing
        - minor language clarification and typo fix

    #104, January 14, 2005:  jjuliano, jsandmel
        - white space clean up (plus a few capitalizations)
        - no functional changes in this revision

    #103, January 14, 2005:  jjuliano, jsandmel, barthold lichtenbelt, jon leech
        - add missing "NONE" case to DrawBuffer language
        - permit ReadBuffer(NONE) for application-created framebuffers
        - spec body: actually state that DrawPixels, ReadPixels,
          CopyPixels, and derivatives of CopyPixels all generate
          INVALID_FRAMEBUFFER_OPERATION_EXT if called while framebuffer
          is not complete
        - clarify error semantics for DrawBuffer(s) when there is no
          image attached to the framebuffer attachment point named by
          DrawBuffer(s)
        - improve error language regarding the <level> parameter of
          FramebufferTexture
        - State that table 4.nnn is part of the per-framebuffer-object
          state vector
        - Delete dangling references to table 3.nnn
        - In section 4.4.4.2, adjust wording to understand that
          DeleteTextures deletes an object, not image
        - Convert some left-over window-system-* to
          window-system-provided
        - Adjust some whitespace and punctuation
        - renumbered tables to remove the hole now that the old table of
          CheckFramebufferStatus enums has been deleted.
        - incorporate remainder of barthold's edits removing more
          "framebuffer-attachble" references from the issues list
        - moved comment describing the purpose of the
          CheckFramebufferStatus enums in the framebuffer completeness
          test closer to their initial use in the spec.
        - Eliminate two XXX comments that addressed by this revision

    #102, January 13, 2005:  jjuliano, jsandmel, barthold lichtenbelt, jon leech
        - replacement of "renderable image" with "framebuffer-attachable
          image"
        - removed lots of (now redundant) instances of
          "framebuffer-attachable"
        - streamlined the grammar in several places to account for
          "framebuffer-attachable" change
        - incorporated outstanding edits from barthold's review of #73
          and #98
        - made FramebufferTexture and FramebufferRenderbuffer use "uint"
          for texture and renderbuffer names for consistency with
          Gen/Is/Bind/Delete.  For some reason, in revision #77 we
          had incorrectly changed these from uint to ints.
        - renamed FRAMEBUFFER_INCOMPLETE_MULTIPLE_ATTACHMENT to
          FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT
        - fixed DeleteTextures and DeleteRenderbuffers language to
          reflect resolution of issue (77), by adding forward reference
          to the section that describes attachment (that already had
          that right language).
        - fixed the different language in FramebufferRenderbuffer and
          FramebufferTexture that described the state when binding a
          zero object (dropped the reference to object type of NONE
          since that *is* the default and it already said the state was
          set to default values)
        - reworked section 4.4.2 overview to simplify intro to
          attaching images to framebuffers
        - reworded intro to section 4.4.2.1 Renderbuffer Objects
        - fixed several instances of "render buffer" to "renderbuffer"
        - replaced language in framebuffer attachment routines that
          bounded the upper value of <level> to use the parallel
          language from page 185 of the OpenGL 2.0 spec.
        - simplified first clause of framebuffer compelteness test to
          just require at least one image attached to framebuffer
        - reordered CheckFramebufferStatusEXT section and moved
          description of FRAMEBUFFER_UNSUPPORTED_EXT to be part of
          framebuffer completeness section description
        - deleted table 3.nnn which lsted the return values of
          CheckFramebufferStatusEXT since this info is already included
          in the framebuffer completeness test itself and was really
          just a duplicate copy in table form.
        - added several errors which were missing from the error summary
          at the end of the spec

    #101, January 12, 2005:  jjuliano, jsandmel
        - Clarify language related to BindRenderbuffer(<target>, 0)
        - Small grammatical change related to object vs. object's image.

    #100, January 11, 2005:  jsandmel, jjuliano
        - added new enums and clauses to framebuffer completeness test
          to catch mutliple and missing attachements
        - reshuffled existing enums to account for new enums
        - clarified issue (84) it indicate that the intent is to mimic
          the pbuffer orientation style

    #99, January 11, 2005:  jsandmel, jjuliano
        - use more expelict language mapping window coordinates to
          texture image texels at the end of section 4.4.2.3
        - fixed typos
        - coalesced interactions with AGL/GLX/WGL with interactions with
          WGL/GLX_make_current_read extensions
        - addressed and removed some more remaining XXX comments
        - added note to issue (58) saying that {Copy}TexSubImage
          uses negative offsets to address border texels
        - added issue (84) - do we need any language describing
          orientation of renderable images?  (I.e., are they y-inverted?)

    #98, January 7, 2005:  jsandmel
        - remove more outstanding XXX comments
        - updated section 4.4 to better define applicatino-created and
          window-system-provided framebuffers in the overview of
          framebuffer objects
        - further clarifications to issue (49) concerning MRT support
        - removed stale XXX comment from issue (75) about stencil mask
          language

    #97, January 7, 2005:  jjuliano
        - Resolve some XXX comments, by adding missing spec language and
          clarifying existing spec language.

    #96, January 6, 2005:  jjuliano, ian romanick
        - renumbered sections to reflect earlier removal of the section
          on renderable image completeness.
        - fixed prototype of CheckFramebufferStatusEXT in spec (bool->enum)

    #95, January 6, 2005:  jsandmel, jjuliano
        - added missing change notes from #94
        - fixed more typos
        - updated issue (48) - it had been resolved already but need
          some updated some language from the resolution to reflect our
          final decision
        - marked issue (55) as resolved (it had been resolved a while
          ago but was left as unresolved)
        - resolved issue (82) - bind vs. attach.  final spec
          implications may get updated when we resolved the larger ARB
          discussions over multicontext behavior and object sharing

    #94, January 4, 2005:  jjuliano
        - language clarification and word smithing.
        - note that rendering to the border of a texture uses
          an origin within the border texels
        - updated comments in sample code for clarity
        - updated issue (16) to clarify how CopyTexImage possibly
          affects framebuffer completeness, and simplified remaining
          language
        - updated issue (77) to better capture the effects of
          deleting attached renderable images
        - updated issue (79) to better capture the invariance of
          renderable image internal format selection
        - added additional clarifications to issue (83) to describe how
          an explicit enable/disable API would work


    #93, December 23, 2004:  jsandmel
        - improved stencil ref value clamping language yet again to
          indicate that queries are clamped
        - moved old XXX comment about an explicit enable into a new
          resolved issue (83)
        - removed a condition of framebuffer attachment completness
          concerning the legality of the LEVEL param which I
          overzealously added in revision #92
        - resolved issue (77) - images are detached from current
          framebuffer only, user must do manual detachment for
          non current framebuffers
        - clarified issue (79) to note that GL need not choose the same
          format for both renderbuffers and textures as the text seemed
          to imply before.
        - clarified issue (16) to note that state changes to non-bound
          framebuffers are somewhat similar to state changes made by
          another context to shared objects (possibly) bound by this
          context.
        - clarified resolution of issues (15) and (16) which talk about
          how {Copy}TexImage into textures affect the framebuffers to
          which textures are attached.

    #92, December 23, 2004:  jsandmel
        - updated "Dependencies" section to add descriptions for
          interactions with other extensions
        - fixed a stale reference to "accum" in overview
        - improved language in overview that seemed to imply that
          this extension required a data copy to do render to texture
        - removed stale XXX comment about framebuffer sharing since
          issue (76) is resolved
        - added proposed language for "attach" definition in glossary
        - removed stale glossary entry for "renderable image completeness"
          now that issue (78) is resolved
        - Updated chapter 2 to use proposed language changes describing
          interactions with the framebuffer in the context of this
          extension.
        - clarified that GenerateMipmap only requires cubemap textures
          to be cubemap complete
        - removed unnecessary reference to proxy texture in GenerateMipmap
        - clarified language about stencil ref value clamping
        - removed various other stale XXX comments
        - added note that RENDERBUFFER_BINDING_EXT can be queried
        - included alternate beahviors in language influenced by issue
          (77)
        - defined the error that occurs on FramebufferTexture when
          a level is specified that is too big
        - added requirement to framebuffer attachment completeness
          that FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT must be
          less than q for symmetry with the requirement that the
          z-offset is smaller than the depth of the texture
        - added section numbers to state tables
        - indicated there are no attribute bits for the state tables
        - added proposed language for issue (82)
        - added proposed language for issue (77)

    #91, December 22, 2004:  jsandmel
        - added updated stencil language to reflect resolution of
          issue (75) - stencil ref value and writemask clamping
        - added language to section 4.4.2.1 indicating that internal
          format selection for renderbuffers follows the same invariance
          rules as textures
        - updated framebuffer completeness language to reflect resolution
          of sissue (78)
        - added test to framebuffer attachment completeness indicating
          that the z-offset identifying an image within a 3D texture must
          be less than the texture's depth
        - added routines to list of non-display-list'able routines
          as per resolution of issue (80)
        - deleted note about OpenGL ES in issue (76)
        - cleaned up the proposed language for issue (77) based on
          feedback from Jeff Juliano

    #90, December 22, 2004:  jsandmel
        - removed plural from FRAMEBUFFER_INCOMPLETE_ATTACHMENT[S]
        - added FRAMEBUFFER_STATUS_ERROR_EXT to enumerants list
        - resolved issue (78) - collapsing "renderable image
          completeness" test and removed FRAMEBUFFER_INCOMPLETE_IMAGES
          enum as per meeting Dec. 21, 2004
        - fixed up some typos
        - wrote up and resolved issue (76) - framebuffers are shared
          like textures as per meeting Dec. 21, 2004
        - wrote up issue (77) - detachment on deletion
        - wrote up and resolved issue (79) - textures are invariant
          with respect to framebuffer state
        - wrote up and resolved issue (80) - no routines in this
          extension are display-list'able
        - wrote up and deferred issue (81) - push/pop attrib
        - added issue (82) - bind vs. attach defintions

    #89, December 16, 2004:  jjuliano, jsandmel, ian romanick
        - added glx protocol for this extension
        - added issue (75) - stencil ref value and write mask state
        - added issue (76) - sharing framebuffer objects
        - added issue (77) - deletes affect on detaching images
        - added issue (78) - collapsing "completeness" tests

    #88, December 06, 2004:  jjuliano, jsandmel
        - revised examples again for clarity, added example (6) to show
          one way to handle CheckFramebufferStatusEXT

    #87, December 03, 2004:  jjuliano, jsandmel
        - incorporated language edit feedback from john rosasco
        - changed a few instances of "rendering to texture" to "render
          to texture"
        - added XXX notes about sections that still need cleanup
        - clarified definition of renderbuffer and its image in overview
        - clarified comparison of MakeCurrent and BindFramebuffer in
          overview
        - fixed misc typos
        - renamed TEXTURE_ZOFFSET to TEXTURE_3D_ZOFFSET for consistency
          with TEXTURE_CUBE_MAP_FACE
        - added note to update section 2.1 to talk about configuring
          framebuffer (need forward reference to chapeter 4).
        - changed several instances "the GL is using ... framebuffer" to
          "the GL is bound to ... framebuffer"
        - changed several instances of "When [A], if [B], [C]" into "If
          [A] and [B], then [C]"

    #86, December 02, 2004:  jon leech
        - assigned "real" enum values
        - fixed some minor typos

    #85, December 01, 2004:  jjuliano, jsandmel
        - Improve error checking in examples
        - whitespace cleanup

    #84, December 01, 2004:  jjuliano
        - DrawBuffer(s) while bound to user-created framebuffer object
          generates an error if the named color attachment does not have
          have anything attached to it when DrawBuffer is invoked.
        - Likewise for ReadBuffer.

    #83, November 30, 2004:  jjuliano
        - improve wording of issue (28) - zoffset vs image of a
          3-dimensional texture
        - update examples to use the new attach target enums, and
          to check framebuffer status

    #82, November 30, 2004:  jsandmel
        - renumbered tables to start with 1.nnn instead of 2.nnn
        - resolved issue (74) - return value of CheckFramebufferStatus()
        - re-opened and re-resolved issue (28) - zoffset vs image of a
          3d texture
        - fixed reference of CopyTexImage to CopyTexSubImage in intro
        - added 16 enums for COLOR_ATTACHMENTn_EXT as per meeting
          november 29, 2004
        - clarified language about number of attachment points in
          description of BindFramebufferEXT().

    #81, November 30, 2004:  jsandmel
        - re-added *-renderable clause to "renderable image completeness"
          test.
        - clarified language in intro that describes selecting an
          image from a texture
        - fixed a few more typos

    #80, November 30, 2004:  jjuliano
        - Improve definition of CheckFramebufferStatusEXT.
          FRAMEBUFFER_STATUS_ERROR_EXT is returned if <target> is
          invalid.  Framebuffer zero always produces
          FRAMEBUFFER_COMPLETE_EXT.
        - Rename 3D_IMAGE to ZOFFSET.  More consistent with
          CopyTex(Sub)Image.
        - In definition of GetFramebufferAttachmentParameterivEXT,
          explain that zero is returned when face or zoffset is queried,
          but texture is not cube map or 3-dimensional, resp.  This
          matches the informal description in issue (51).
        - Eliminate table 1.nnn, and modify references to instead
          reference table 6.nnn.  I have not renumbered all the tables
          yet, so that the diffs are more obvious.  Renumbering can
          happen in the next change.
        - Eliminate *-renderable clause from Renderable Image
          Completeness.  This is already covered under Framebuffer
          Attachment Completeness.
        - For each clause in Framebuffer Completeness, add references to
          specific error generated when that clause is violated.

    #79, November 23, 2004:  jsandmel, jjuliano
        - more typos fixed
        - added placeholder enumeration of all tables so that every
          table was not named XXX.XXX.  They are now named M.nnn where M
          is incremented sequentially for each table.
        - stated that order of return of CheckFramebufferStatus enums is
          "implementatino-dependent" instead of "undefined"
        - added state table for framebuffer object state (as opposed to
          table of framebuffer attachment point state), added
          DRAW_BUFFERi and READ_BUFFER state to this table.

    #78, November 22, 2004:  jsandmel
        - re-opened and re-resolved issue (4) - renamed
          "renderable-images" to "framebuffer-attachable images"
        - resolved issue (70) - defer support of framebuffer binding
          push/pop semantics

    #77, November 22, 2004:  jsandmel, jjuliano
        - fixed up typos and address other issues found by Barthold
        - changed errors of GetFramebufferAttachmentParameterivEXT
          to be INVALID_ENUM instead of INVALID_VALUE where appropriate
        - added missing INVALID_ENUM GetRenderbufferParameterivEXT error
          case to list of errors
        - dropped framebuffer status state from state table (The reason
          is: technically this is not state queriable with a standard
          Get call and doesn't really need to be stored, an
          implementation could calculate this result on the fly in
          principle.)
        - added issue (74) - what does it mean to call
          CheckFramebufferStatusEXT on framebuffer zero (default
          framebuffer) and what if CheckFramebufferStatusEXT generates
          an error?
        - cleaned up a bunch more "window-system-provided" references
        - changed a bunch of "bit plane" references --> "bitplane"
        - more updates to glossary section (not complete yet)
        - Added boolean return values to IsRenderbuffer and
          IsFramebuffer prototypes
        - Changed object id's in FramebufferTexture* and
          FramebufferRenderbuffer from uint to int to be consistent with
          texture routines.
        - changed typo in Get*Parameter routines: "param" --> "params"
        - added missing COLOR_ATTACHMENTn_EXT enums to new tokens list
        - clarified difference and similarities between automatic and
          manual mipmap generation in section 3.8.8
        - added lots of missing EXT's
        - clarified use of <textarget> in FramebufferTexture when
          <texture> is zero and <renderbuffer> target in
          FramebufferRenderbuffer when <renderbuffer> is zero.
          (<textarget> and <renderbuffertarget> are ignored in this case>
        - added a sentence defining that order of return for enums in
          CheckFramebufferStatusEXT is undefined if multiple clauses of
          framebuffer completeness test fail

    #76, November 19, 2004:  jsandmel
        - as per group meeting Nov. 19, 2004, rename "render buffer" to
          "renderbuffer".  This is the only substantive change in this
          revision.  Unfortunately, this had a lot of white-space
          collateral damage.  Also, this reopens and closes issue (3).

    #75, November 18, 2004:  jsandmel
        - added missing enums to New Tokens section
        - clarified wgl/agl/glx language additions section to note that
          the window-system draw/read drawables are ignored when bound
          to an application-created framebuffer object
        - resolved issue (69) - "application-create" framebuffers
        - added more description of issue (70) - push/pop binding bits?
        - resolved issue (71) - defining which draw/reading routines can
          throw errors
        - resolve issue (72) - require at least one color, depth, or
          stencil attachment
        - resolved issue (73) - allow READ_BUFFER to be none so
          user can read from a non-color buffer in a framebuffer
          with no color attachments
        - added section on ReadBuffer whose absence had unfortunately
          gone unnoticed until now.
        - added missing "initial state" language for draw buffer to
          section 4.2
        - cleaned up several references to FRAMEBUFFER_EXT that should
          have been either "the target FRAMEBUFFER_EXT" or
          "FRAMEBUFFER_BINDING_EXT"

    #74, November 18, 2004:  jsandmel, jjuliano
        - fixed up typos found by Ian Romanick
        - changed several instances of "GL-allocated framebuffer" to
          "application-created framebuffer" for consistency.
          NOTE: However, we might want to pick a new term for these
          everywhere.  Added issue (69) for this.
        - added a MAX_RENDERBUFFER_SIZE_EXT implementation constant
          to catch errors to RenderbufferStorageEXT.
        - added issue (70), (71), (72), (73) for issues found
          by Jeff

    #73, November 15, 2004:  jsandmel
        - split out CheckFramebufferStatus enums as per work group
          meeting November 15, 2004
        - added note to self to go back and clean up issue (48)

    #72, November 15, 2004:  jsandmel
        - added "valid draw/read buffer" test to framebuffer
          completeness test as per resolution of issue (55) as per
          meeting on November 11, 2004.
        - added new enums to CheckFramebufferStatus for each of the
          implementation-independent failure cases as per resolution of
          issue (55) as per meeting on November 11, 2004.
          (these may be placeholder names for now)
        - added additional partial resolutions to issue (55) as
          per meeting on November 11, 2004
        - added XXX note to update state tables with whatever the
          final final resolution of the DRAW_BUFFER location is.

    #71, November 9, 2004:  jsandmel
        - cleaned up contributors list
        - resolved issue (61) on minimum requirements as per work group
          meeting on November 6, 2004
        - added partial resolution and additional description to
          issue (55) as per meeting on November 8, 2004

    #70, November 2, 2004:  jsandmel, jjuliano
        - clarified opening language of chapter 4 to name non-visible
          buffers
        - improved language about when the number of bits in a bitplane
          can change
        - removed "SUBPIXEL_BITS" from table of state that can change
          on framebuffer state change as per working group
          meeting November 1, 2004 and marked issue (62) as resolved
        - marked issue (56) - draw buffer state location as framebuffer
          object state as per working group meeting November 1, 2004

    #69, November 1, 2004:  jsandmel
        - added placeholder "min requirements" text to issue (61)
        - marked issue (68) as resolved since it was resolved during
          week of Oct 18, 2004.
        - incorporated feedback from Brian Paul on various typos,
          prototype mismatches, missing "EXT"s, and missing
          IsRenderbuffer language (to chapter 6)
        - added missing IsFramebufferLanguage to chapter 6

    #68, October 29, 2004:  jjuliano, jsandmel
        - additional clarifications to opening of chapter 4
        - various other minor word substitutions

    #67, October 28, 2004:  jjuliano
        - additional clarifications to issue (56)

    #66, October 27, 2004:  jsandmel
        - added most (all?) of the necessary state tables to the end of
          the spec (also removed old state table notation)
        - made references to the state tables as 6.3XX until we know the
          final table numbering
        - fleshed out the language of the intro to chapter 4 describing
          the color logical buffers and attachable color buffers
        - at the beginning of chapter 4, modified core spec language to
          note that the bitplane depths are no longer fixed
        - moved XXX note about invariance to end of start of chapter 4
        - slightly reworded description of FRAMEBUFFER_UNSUPPORTED_EXT
        - moved table of "framebuffer dependent state variables"
          from spec body into state tables at end of spec
        - added most (all?) of the known errors to the "Errors"
          section of the spec.

    #65, October 25, 2004:  jsandmel
        - changes to resolve issue (67) - ValidateFramebuffer is now
          called CheckFramebufferStatus().
        - updated section 4.2.1 to include DrawBuffers (plural) language
          from OpenGL 2.0 spec.  Note: we either need to update whole
          spec to be based on OpenGL 2.0 spec, or else revise the
          DrawBuffer(s) language to refer to the ARB_draw_buffers
          extension sepc language.
        - added (possibly temp) reference to errors on ReadPixels when
          using an incomplete framebuffer
        - added note to section 4.4.1 that describes pixel ownership
          test success when using application-created framebuffers
        - added table of enum values returned from
          CheckFramebufferStatus() as per resolution of issue (48)
        - resolved issue (65) - name of error on incomplete framebuffer
          operations
        - clarified that issue (24) is really a duplicate of (64).
        - resolved issue (48)
        - added note to write up issue (61) language for review

    #64, October 19, 2004:  jsandmel, jjuliano
        - more rewording and clarifications of issue (56)

    #63, October 15, 2004:  jjuliano
        - more rewording and clarifications of issue (55) and (56)

    #62, October 14, 2004:  jsandmel
        - more rewording and clarifications of issue (55) and (56)

    #61, October 13, 2004:  jjuliano
        - Dramatically reword issues (55) and (56).
        - Add issue (68) addressing which levels are generated by
          GenerateMipmapEXT

    #60, October 11, 2004:  jsandmel
        - revised write up of issue (56) to capture recent work group
          discussions about draw buffer state location
        - resolved issue (48) as per work group meeting Oct. 11, 2004

    #59, October 11, 2004:  jjuliano
        - added note about possibly wanting to have explicit enable for
          framebuffer objects instead of using zero in section 4.2.1
        - cleaned up list of differences between framebuffer object and
          default framebuffer
        - separated out attach/detach cases in list of diffs between
          default framebuffer and framebuffer objects
        - added reminder note about invariance clause modifications
          for section 4.4.5
        - added reminder note about modifications for wgl spec
        - cleaned up language in issue (26) about reading from
          incomplete framebuffer
        - clarified resolution of issue (44) - texture from destination
        - replaced various instances of framebuffer "invalid" with
          framebuffer "incomplete"
        - other misc. typos, white space clean up

    #58, October 8, 2004:  jsandmel, jjuliano
        - reopened and resolved issue (26) - incomplete framebuffer
          read is an error?
        - reopened, updated, and resolved issue (44) - "texture from
          destination" is undefined
        - marked issue (50) as resolved, since it basically was
        - updated and resolved issue (64) - incomplete framebuffer
          rendering is an error?
        - tentatively resolved issue (65) - name of error when
          trying to use an incomplete error
        - resolved issue (66) - clarified what state can
          cause framebuffer incompleteness
        - created issue (67) - name of ValidateFramebuffer
        - implemented preliminary draw buffer language in section 4.2.1
        - added more language in section 4.4.1 to describe differences
          between window-system and application-created framebuffers
        - updated "texture-from-destination" language in section 4.4.3
          to reflect new resolution of issue (44).
        - removed clause describing "texture from destination"
          constraints from framebuffer completeness test in section
          4.4.4.1 to reflect resolution of issue (44).
        - added list of operations which can change framebuffer
          completeness to section 4.4.4.2
        - Added language to section 4.4.4.3 indicating that rendering to
          or reading from an incomplete framebuffer is an error, as per
          resolution of issue (64) and (26)
        - Added more description of implementation dependent state which
          can change in section 4.4.5 and refer to framebuffer
          completeness section in 4.4.4.2 to identify when this state
          can change
        - added MAX_COLOR_ATTACHMENTS to list of state variables that
          might change if framebuffer state changes
        - added error conditions to queries when framebuffer zero or
          renderbuffer zero is bound (since there is no framebuffer
          zero or renderbuffer zero).
        - added placeholder for Additions to the AGL/GLX/WGL
          Specifications
        - fixed up misc. typos and whitespace

    #57, October 1, 2004:  jjuliano
        - added additional discussion in issue (66)
        - fixed up misc. typos and whitespace

    #56, September 29, 2004:  jsandmel
        - added additional option (d) to issue (66) as per our work
          group discussions on Sept 30, 2004.

    #55, September 29, 2004:  jsandmel
        - added meta-issue (66) which deals with framebuffer
          completeness dependencies on the context state.
        - added section 4.4.5 about state variables which may change if
          framebuffer state changes.
        - dropped some redundant exposition in issue (55)
        - resolved issue (60) and wrote up the description of the issue
        - removed ACCUM_FORMAT from list of new enums per resolution of
          issue (40)

    #54, September 27, 2004:  jsandmel
        - added issue (64) - error to render with incomplete framebuffer?
        - added issue (65) - what should the error be?
        - added note to ask if we need to reopen (26) about reading
          from invalid framebuffer in light of resolution of (64).

    #53, September 17, 2004:  jsandmel
        - updated "attach" definition in glossary
        - fixed up some minor typos, whitespace issues
        - in issue (15)/(16) indicate tex state changes can affect
          framebuffer completeness, not just cause it to fail (they
          might cause it to succeed).
        - add clarification about the type of intrinsic buffers that
          were removed in issue (36)
        - updated language describing use of ACCUM format for textures
          in issue (40)
        - reworded reference to "billboarding" in issue (42)
        - clarified the draw buffer(s) issue (55) to indicate
          possible problems even after DrawBuffer(s) is called.
        - pacified some of the language surrounding issue (63) and the
          rationale for using ValidateFramebuffer or a GetInteger style
          query.

    #52, September 17, 2004:  jjuliano
        - edits based on review of a subset of the issues section
        - edits to the diffs from version #51
        - added note to overview comparing render-to-texture to
          CopyTexImage
        - added "attach" term to glossary section
        - replaced ARB's with EXT's in issue (1)
        - distinguished between bind and attach in isuse (5)
        - various replacements of "texture" with "texture image"
        - various replacements of "framebufer (in)valid" language with
          framebuffer (in)completeness language
        - added additional rationale to issue (18) about framebuffer
          renderable image attachment
        - clarified issue (27) that the resolution is no error is
          generated
        - added note to issue (40) that we might want to use ACCUM
          format for textures
        - added description of complications with having draw and read
          framebuffer targets in issue (42)
        - added additional language describing issue (63) concerning the
          reasons for using ValidateFramebuffer versus the reasons for
          using an explicit query API for framebuffer completeness.

    #51, September 16, 2004:  jsandmel
        - resolved issue (26) - reading from incomplete framebuffer
        - clarified issue (55) - draw buffer set to non-existent buffer
        - added issue (63) - should we make ValidateFramebuffer a query?
        - marked issue (46) as resolved, since there's not much left to
          do except resolve the minimum requirements issue (61).

    #50, September 16, 2004:  jjuliano
        - edits based on version #49 diffs, as well as...
        - replace uses of "fail ValidateFramebuffer" with references to
          "framebuffer completeness"
        - reformat whitespace of some very long and very indented issues
        - remove "MERGE from some other proposed API" comments

    #49, September 16, 2004:  jsandmel
        - added DeleteTexture and DeleteRenderbuffers spec language to
          describe detaching from framebuffers first
        - added place holders in various places to correspond
          with lots of resolved issues
        - added stencil S format table
        - renamed section 4.4.3
        - clarified framebuffer attachment and renderable image
          requirements for completeness
        - added requirement to completeness to have all
          color attachments with the same format
        - added  missing write ups for various issues (8), (9), (12)
        - in issue (40), clarified that accum language from 1.5 spec
          already covers the error behavior we need to defer accum support
        - in issue (41), clarified multisample language from 1.5 could
          cover the behavior we need to defer multisample support if we
          set SAMPLE_BUFFERS to 0 for non-default framebuffers

    #48, September 15, 2004:  jjuliano
        - edits based on review of chapter 4.

    #47, September 15, 2004:  jjuliano
        - edits based on review of all sections except for chapter 4,
          Issues.
        - clarified, reordered overview
        - added missing enums for framebuffer attachment point state
          queries to list of new enums
        - indicated that GenerateMipmap will only generate
          levels base through q instead of base through p

    #46, September 15, 2004:  jjuliano
        - move issues section to end of document.
          (issues section accounts for >50% of the document!)

    #45, September 13, 2004:  jsandmel, jjuliano
        - typos and white space updates
        - clarified language about the framebuffer object bound to <target>
          in section 4.4.4.2
        - clarified isssue (62) on which state can change and when

    #44, September 13, 2004:  jsandmel
        - resolved issue (40) accum buffers - deferred per group
          decision
        - resolved issue (41) multisample buffers - deferred per group
          decision
        - resolved issue (57) maximum attachable color buffers query per
          group decision
        - opened issue (62) which queries can change state after
          BindFramebuffer

    #43, September 13, 2004:  jsandmel, jjuliano
        - typos, cleanup
        - fixed up use of COLOR/AUX/DATAN to use lower n as GL spec.
        - clarified definitions of color/depth renderable
        - indicate renderable images don't have to be attached to be
          "renderable image complete"
        - replaced requirement on texture images that they simply need
          non-zero dimensions instead of saying they have been "defined"
          already

    #42, September 13, 2004:  jsandmel
        - updated Framebuffer validation language
        - added "complete" terms to glossary in overview

    #41, September 9, 2004:  jjuliano
        - re-add and rewrite section 4.4.4 on "Framebuffer
          Validation"

    #40, September 9, 2004:  jsandmel
        - fixed extra "GL" typos noted by Brian Paul
        - resolved issue (54) - color attachment names
        - resolved issue (58) - textures with borders
        - resolved issue (59) - stencil formats
        - added issue (61) - minimum requirements

    #39, September 9, 2004:  jsandmel, jjuliano
        - misc. typos and white space fixed

    #38, September 8, 2004:  jsandmel, jjuliano
        - clarifed section 4.4.3 to indicate that if mipmapping
          disabled, the framebuffer texture attachment rules are
          slightly different.
        - fleshed out multisample buffer support options for
          issue (41) after more discussions

    #37, September 8, 2004:  jsandmel
        - renamed attachment enums again to add FRAMEBUFFER_ on the
          front to further qualify their namespace.
        - updated table of attachment point state to include default
          values
        - added language to "Texturing From an Attached Renderable
          Image" (section 4.4.3)

    #36, September 8, 2004:  jjuliano
        - update chapter 3 language on mipmap generation
        - modify example 5 to not use depth buffer when
          custom-generating mipmap
        - add issue 60 on whether or not disabled depth attachment
          factors into framebuffer validity determination

    #35, September 7, 2004:  jsandmel
        - updated chapter 6 language on querying renderbuffer and
          framebuffer attachment state.
        - made references to "id 0" into "name zero" for easier
          searching and consistency with core GL spec
        - renamed the enums for framebuffer attachment state to add
          "ATTACHMENT" to each to qualify the name space of the enums.
          These might not be the final names.

    #34, September 7, 2004:  jsandmel, jjuliano
        - further clarified framebuffer attachment language
        - specify that attachment routines set "rest" of
          attachment state to default values

    #33, September 7, 2004:  jsandmel
        - added examples to issue (54) about framebuffer attachment names

    #32, September 7, 2004:  jsandmel
        - further clarified framebuffer attachment language

    #31, September 3, 2004:  jsandmel
        - added issue (58) about texture borders
        - added issue (59) about stencil internal formats
        - updated new tokens section to reflect recent issue resolutions
        - added attachment state table to section 4.4.2
        - added langauge describing renderbuffer and texture attachment
          routines

    #30, September 3, 2004:  jjuliano
        - more typos and white space cleanup
        - issue (46): make it clear that validation failure occurs
          because of a mismatch in dimensions, rather than size
        - clarified language on draw buffer error semantics in issue
          (55)
        - included more language describing issue (57) about querying
          for max number of attachable drawbuffers.

    #29, September 2, 2004:  jsandmel, jjuliano
        - typos fixed and whitespace clean up
        - factored issue (39) on ARB_draw_buffers into separate
          issues (53), (54), (55), (56), (57)
        - fleshed out issue (40) - on ACCUM buffers, tentatively
          we will support this if there is time
        - made a few ValidationFailures in isseu (46) more
          explicit
        - added issue (53) - indirection for ARB_draw_buffers?
        - added issue (54) - name of color attachment points?
        - added issue (55) - error behavior for DRAW_BUFFER
        - added issue (56) - is DRAW_BUFFER context state or framebuffer
          state?

    #28, September 2, 2004:  jsandmel
        - Improve language describing framebuffer and renderbuffer
          objects

    #27, August 26, 2004:  jsandmel, jjuliano
        - re-resolved issue (11) - we use 3 framebuffer attachment
          routines for textures, 1 for renderbuffers, also cleaned up
          the rationale language for this choice
        - resolved issue (30) - renderbuffer state routines take a target
        - resolved issue (42) - we use a single framebuffer target enum
        - resolved issue (43) - incomplete attached textures will
          not cause ValidateFramebuffer failures
        - resolved issue (45) - framebuffers with no color buffer attached
          will be allowed
        - deferred and expanded issue (48) - what info should
          ValidateFramebuffer return.
        - resolved issue (51) - use individual queries for attachment
          state
        - resolve issue (52) - auto and manual mipmap generation
          can peacefully coexist
        - deleted obsolete mipmap generation language from spec text
          as this needs to be reworked anyway

    #26, August 26, 2004:  jsandmel
        - corrected some depth_offset --> image terms, since that
          is the current resolution of issue (28), unless we reopen it.
        - clean up issue (11) language
        - moved query of attachments api sub issue from (34) to
          its own issue (51)
        - removed obsolete note on issue (44)
        - fleshed out another alternative attachment query API in issue
          (51)
        - created issue (52) on when auto/manual mip generation applies
        - began more spec language edits to mip generation and framebuffer
          object definition (this may be throwaway language depending
          on the resolution of some outstanding issues)

    #25, August 24, 2004:  jjuliano
        - Fill in chapter 4.
        - Replace some references to "logical buffer" with
          "renderbuffer".
        - Modification to issue (44).
        - Incorporate feedback from Eric Werness: improvements to
          examples.
        - Incorporate feedback from Jason Allen: issue (42) option D
          (GL_FRAMEBUFFER_EXT), and removal of FramebufferBuf.

    #24, August 23, 2004:  jjuliano
        - First stab at text for additions to chapters 2, 3, and 5.
        - Fill in examples 1-5.
        - Add description of GetFramebufferBufferParametervEXT to
          chapter 6.
        - Add EXT suffix in some places it was missing.

    #23, August 20, 2004:  jjuliano
        - fix minor typos
        - added additional comments regarding reopened issue (11)
        - changed some references from z-slice to depth offset

    #22, August 19, 2004:  jsandmel
        - reopened and expanded the options for issue (11) about one vs
          many FramebufferTexture attachment routines
        - clarified issue (16) does not imply that texture/renderbuffer
          state updates are delayed on attached renderable images
        - clarified issue (21) to not specifically imply that a call
          to BindFramebuffer is required to delete a renderable image
          attached to a framebuffer.
        - resolved issue (28) "slices" are now referred to as "images"
        - resolved issue (29) - GenerateMipmap is included in this
          extension
        - added and resolved issue (49) - MRT of different formats are
          not supported
        - added issue (50) - meta issue about whether async generation
          of GL errors should be avoided in this api.

    #21, August 19, 2004:  jsandmel
        - incorporated feedback from Barthold (typos fixed)
        - incorporated feedback from Barthold (ARB_compromise_buffers->EXT_framebuffer_object)
        - incorporated feedback from Barthold (slice->image)
        - incorporated feedback from Barthold (other ARB->EXT changes)

    #20, August 19, 2004:  jjuliano
        - fill in issue (13) and (36) - intrinsic buffers

    #19, August 18, 2004:  jjuliano
        - fixed minor typos in issue (15)
        - further clarified design rationale in issue (16)

    #18, August 18, 2004:  jjuliano, jsandmel
        - cleaned up  language for issues (15) and (16)

    #17, August 18, 2004: jsandmel
        - cleaned up stale references to ARB_compromise_buffers.
        - resolved issues (1) - extension name
        - resolved issues (15) - {Copy}TexImage behavior on current framebuffer
        - resolved issues (16) - {Copy}TexImage behavior on non-current framebuffer
        - (re)resolved issues (21) - Delete object behavior on attached objects
        - resolved issues (22) - 1 or 2 detach objects routines
        - resolved issues (25) - query on invalid framebuffers
        - cleaned up issue (34) language on attachment query API

    #16, August 18, 2004: jsandmel
        - renamed EXT_framebuffer_object as per group decision

    #15, August 8, 2004: jsandmel
        - fixed minor typos found by jeff
        - expanded discussion on issue (20) to distinguish
          width/height/format of texture is mutable unlike texture
          target as suggested by jeff

    #14, August 5, 2004: jsandmel
        - In several issues, make sure ask the same questions about
          renderbuffers when we are talking about textures.  We want to
          resolve these issues symmetrically in almost all cases.
        - resolved issue (19) about unused texture/renderbuffer names
        - resolved issue (20) about attaching default state objects to
          framebuffers
        - resolved issue (21) about deleting attached texture/renderbuffer
          objects
        - fixed typo indicating when issue (33) was resolved
        - resolved issue (34) about querying framebuffer objects
          for attachments
        - resolved issue (44) about using a texture object as a source
          texture and destination renderable image
        - resolved issue (47) about delineating exactly which state
          modifying routines can cause framebuffer revalidation
        - added issue (48) about the returned information from
          ValidateFramebuffer().

    #13, August 3, 2004: jsandmel
        - added related issue in issue (44) - we need to consider
          texture objects bound to different targets on the same unit
          not just currently bound texture, when calculating
          source/destionation circuits.
        - in issue (44), option (b), indicate a possibly variant is
          to allow but not require ValidateFramebuffer to fail
        - cleaned up the "must fail" and "can fail" cases in
          issue (46).
        - added issue (47) - do we need to list exactly which
          state modification routines can cause ValidateFramebuffer
          to change its answer?

    #12, August 3, 2004: jsandmel
        - added issue about when validation failures "can" occur vs. "must"
          occur.

    #11, August 2, 2004: jsandmel
        - removed non-contact emails from contributor list
        - "methodology" -> "model" in issue (7)
        - resolved issues (31,32,33), there is no renderbuffer name zero,
          and binding/attaching to it simply unbinds/detaches the previously
          bound/attached object.
        - added issue (44) about using the same texture object as both
          a source and destination
        - added issue (45) about scenarios where having no renderable
          image attached to the color buffer attachment point might be
          acceptable

    #10, July 30, 2004: jjuliano
        - flesh out details of issue (29) about GenerateMipmap
        - add issue (43) about mipmap cube complete textures and
          framebuffer consistency check.

    #9, July 30, 2004: jsandmel
        - renumbered issues to account for remaval and addition of issues
        - dropped issue [used to be (14)] as it was a duplicate of issue
          [now (38)] about support for multiple render targets.
        - added issue (32) about  whether and how to support a
          renderbuffer with the name zero (is it an object?)

    #8, July 30, 2004: jjuliano
        - tightened up language in overview regarding use of renderable
          images
        - clarified in overview that window and framebuffer can
          have different formats
        - fixed various typos, grammar, spelling errors
        - indicated we should drop issue (14) about MRT, same as issue (37)
        - indicate -1 is one option for return value on nonsense queries
          of non-validated framebuffer state

    #7, July 29, 2004: jsandmel
        - add some more terms to the glossary list
        - white space and various grammar clean ups (minor)
        - note that we need resolution on the switch from
          "render target" to "renderable image"
        - cleaned up language for issue (31) and (32)

    #6, July 29, 2004: jsandmel
        - reworked, clarified, streamlined overview section to read better
        - cleaned up some white space problems

    #5, July 29, 2004: jsandmel
        - fixed bad numbering in issues list

    #4, July 29, 2004: jsandmel
        - cleaned up issues after incorporating feedback

    #3, July 28, 2004: jsandmel
        - began merging render target and compromise buffers issues lists
        - added contributors from EXT_render_target list
        - added some extension dependencies
        - borrowed overview from EXT_render_target, reworded to
          make more appropriate for differences with this spec
        - added placeholders for sample code
        - resolved a few issues here
        - removed intrinsic buffers per group decision july 26,2004
        - retained framebuffer objects per group decision july 26,2004
        - made FramebufferTexture into 3 functions per group decision july 26, 2004

    #2, July 22, 2004: jsandmel
        - removed all old EXT-compromise_buffer language, but
          some of this will get reformed and added back in
        - removed example temporarily, again this will get reformed and
          added back in.
        - LogicalBuffer renamed to "Renderbuffer"
        - began fleshing out issues list

    #1, July 22, 2004: jsandmel
        - very first revision
        - derived from EXT_compromise_buffers but really a mishmash of
          all the proposals under discussion
