Name

    ARB_framebuffer_sRGB

Name Strings

    GL_ARB_framebuffer_sRGB
    GLX_ARB_framebuffer_sRGB
    WGL_ARB_framebuffer_sRGB

Contributors

    Herb (Charles) Kuta, Quantum3D
    Alain Bouchard, Matrox
    Brian Paul, Tungsten Graphics
    Daniel Vogel, Epic Games
    Eric Werness, NVIDIA
    Kiril Vidimce, Pixar
    Mark J. Kilgard, NVIDIA
    Pat Brown, NVIDIA
    Yanjun Zhang, S3 Graphics
    Jeremy Sandmel, Apple
    Jon Leech

Contact

    Mark J. Kilgard, NVIDIA Corporation (mjk 'at' nvidia.com)

Notice

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

Status

    Approved by the ARB on July 11, 2008

Version

    Date: August 11, 2008
    Revision: 1.2

Number

    ARB Extension #46

Dependencies

    OpenGL 1.1 is required

    This extension is written against the OpenGL 2.0 (September 7,
    2004) specification.

    WGL_EXT_extensions_string is required for WGL support.

    WGL_EXT_pixel_format is required for WGL support.

    ARB_color_buffer_float interacts with this extension.

    ARB_framebuffer_object is required.

    EXT_texture_sRGB interacts with this extension.

    ARB_draw_buffers interacts with this extension.

Overview

    Conventionally, OpenGL assumes framebuffer color components are stored
    in a linear color space.  In particular, framebuffer blending is a
    linear operation.

    The sRGB color space is based on typical (non-linear) monitor
    characteristics expected in a dimly lit office.  It has been
    standardized by the International Electrotechnical Commission (IEC)
    as IEC 61966-2-1. The sRGB color space roughly corresponds to 2.2
    gamma correction.

    This extension adds a framebuffer capability for sRGB framebuffer
    update and blending.  When blending is disabled but the new sRGB
    updated mode is enabled (assume the framebuffer supports the
    capability), high-precision linear color component values for red,
    green, and blue generated by fragment coloring are encoded for sRGB
    prior to being written into the framebuffer.  When blending is enabled
    along with the new sRGB update mode, red, green, and blue framebuffer
    color components are treated as sRGB values that are converted to
    linear color values, blended with the high-precision color values
    generated by fragment coloring, and then the blend result is encoded
    for sRGB just prior to being written into the framebuffer.

    The primary motivation for this extension is that it allows OpenGL
    applications to render into a framebuffer that is scanned to a monitor
    configured to assume framebuffer color values are sRGB encoded.
    This assumption is roughly true of most PC monitors with default
    gamma correction.  This allows applications to achieve faithful
    color reproduction for OpenGL rendering without adjusting the
    monitor's gamma correction.

New Procedures and Functions

    None

New Tokens

    Accepted by the <attribList> parameter of glXChooseVisual, and by
    the <attrib> parameter of glXGetConfig:

        GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB             0x20B2

    Accepted by the <piAttributes> parameter of
    wglGetPixelFormatAttribivEXT, wglGetPixelFormatAttribfvEXT, and
    the <piAttribIList> and <pfAttribIList> of wglChoosePixelFormatEXT:

        WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB             0x20A9

    Accepted by the <cap> parameter of Enable, Disable, and IsEnabled,
    and by the <pname> parameter of GetBooleanv, GetIntegerv, GetFloatv,
    and GetDoublev:

        FRAMEBUFFER_SRGB                             0x8DB9

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

    None

Additions to Chapter 3 of the 2.0 Specification (Rasterization)

    None

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

    DELETE the following sentence from section 4.1.8 (Blending) because
    it is moved to the new "sRGB Conversion" section:

    "Each of these floating-point values is clamped to [0,1] and
    converted back to a fixed-point value in the manner described in
    section 2.14.9."

    If ARB_color_buffer_float is supported, the following paragraph
    is modified to eliminate the fixed-point clamping and conversion
    because this behavior is moved to the new "sRGB Conversion" section.

    "If the color buffer is fixed-point, the components of the source
    and destination values and blend factors are clamped to [0, 1]
    prior to evaluating the blend equation, the components of the
    blending result are clamped to [0,1] and converted to fixed-
    point values in the manner described in section 2.14.9. If the
    color buffer is floating-point, no clamping occurs.  The
    resulting four values are sent to the next operation."

    The modified ARB_color_buffer_float paragraph should read:

    "If the color buffer is fixed-point, the components of the source
    and destination values and blend factors are clamped to [0, 1]
    prior to evaluating the blend equation.  If the color buffer is
    floating-point, no clamping occurs.  The resulting four values are
    sent to the next operation."

    Replace the following sentence:

    "Destination (framebuffer) components are taken to be fixed-point
    values represented according to the scheme in section 2.14.9 (Final
    Color Processing), as are source (fragment) components."

    with the following sentences:

    "Destination (framebuffer) components are taken to be fixed-point
    values represented according to the scheme in section 2.14.9 (Final
    Color Processing).  If FRAMEBUFFER_SRGB is enabled and the value
    of FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING for the framebuffer
    attachment corresponding to the destination buffer is SRGB (see
    section 6.1.3), the R
    G, and B destination color values (after conversion from fixed-point
    to floating-point) are considered to be encoded for the sRGB color
    space and hence need to be linearized prior to their use in blending.
    Each R, G, and B component is linearized by some approximation of
    the following:

            {  cs / 12.92,                 cs <= 0.04045
       cl = {
            {  ((cs + 0.055)/1.055)^2.4,   cs >  0.04045

    where cs is the component value prior to linearization and cl is
    the result.  Otherwise if FRAMEBUFFER_SRGB is disabled, or the
    value of FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING is not SRGB, no
    linearization is performed.

    The resulting linearized R, G, and B and unmodified A values are
    recombined as the destination color used in blending computations.


    ADD new section 4.1.X "sRGB Conversion" after section 4.1.8 (Blending)
    and before section 4.1.9 (Dithering).  With this new section added,
    understand the "next operation" referred to in the section 4.1.8
    (Blending) to now be "sRGB Conversion" (instead of "Dithering").

    "If FRAMEBUFFER_SRGB is enabled and the value of
    FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING for the framebuffer attachment
    corresponding to the destination buffer is SRGB (see section 6.1.3),
    the R, G, and B values after blending are converted into the non-linear
    sRGB color space by some approximation of the following:

             {  0.0,                          0         <= cl
             {  12.92 * c,                    0         <  cl < 0.0031308
        cs = {  1.055 * cl^0.41666 - 0.055,   0.0031308 <= cl < 1
             {  1.0,                                       cl >= 1

    where cl is the R, G, or B element and cs is the result
    (effectively converted into an sRGB color space).

    If FRAMEBUFFER_SRGB is disabled or the value of
    FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING is not SRGB, then

        cs = cl

    The resulting cs values for R, G, and B and the unmodified A form a
    new RGBA color value. If the color
    buffer is fixed-point, the components of this RGBA color value are
    clamped to [0,1] and then converted to a fixed-point value in the
    manner described in section 2.14.9.  The resulting four values are
    sent to the subsequent dithering operation."

Additions to Chapter 5 of the 2.0 Specification (Special Functions)

    None

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

    None

Additions to the OpenGL Shading Language specification

    None

Additions to the GLX Specification

    None

Dependencies on ARB_color_buffer_float

    If ARB_color_buffer_float is not supported, ignore the edits to
    ARB_color_buffer_float language.

Dependencies on EXT_texture_sRGB and ARB_framebuffer_object

    If EXT_texture_sRGB and ARB_framebuffer_object are both supported, the
    implementation should set the value of
    FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING to LINEAR when
    rendering to a color texture that is not one of the EXT_texture_sRGB
    introduced internal formats. An implementation can determine whether
    or not it will set the value of
    FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING to SRGB for the
    EXT_texture_sRGB introduced internal formats.  Implementations are
    encouraged to allow sRGB update and blending when rendering to sRGB
    textures using ARB_framebuffer_object but this is not required.
    In any case, FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING should indicate
    whether or not sRGB update and blending is supported.

Dependencies on ARB_draw_buffers, EXT_texture_sRGB, and ARB_framebuffer_object

    If ARB_draw_buffers, EXT_texture_sRGB, and ARB_framebuffer_object
    are supported and an application attempts to render to a set of
    color buffers where some but not all of the color buffers are SRGB
    capable, sRGB update and blending only apply to the color buffers
    that are actually sRGB-capable.

GLX Protocol

    None.

Errors

    Relaxation of INVALID_ENUM errors
    ---------------------------------

    Enable, Disable, IsEnabled, GetBooleanv, GetIntegerv, GetFloatv,
    and GetDoublev now accept FRAMEBUFFER_SRGB as allowed in the "New
    Tokens" section.

New State

    Add to table 6.20 (Pixel Operations)

    Get Value         Type  Get Command  Initial Value  Description      Sec.   Attribute
    ----------------  ----  -----------  -------------  ---------------  -----  -------------------
    FRAMEBUFFER_SRGB  B     IsEnabled    False          sRGB update and  4.1.X  color-buffer/enable
                                                        blending enable

New Implementation Dependent State

    None

Issues

    1)  What should this extension be called?

        RESOLVED: ARB_framebuffer_sRGB.

        The "ARB_framebuffer" part indicates the extension is in
        the framebuffer domain and "sRGB" indicates the extension is
        adding a set of sRGB formats.  This mimics the naming of the
        EXT_texture_sRGB extension that adds sRGB texture formats.

        The mixed-case spelling of sRGB is the established usage so
        "_sRGB" is preferred to "_srgb".  The "s" stands for standard
        (color space).

        For token names, we use "SRGB" since token names are uniformly
        capitalized.

    2)  Should alpha be sRGB encoded?

        RESOLVED:  No.  Alpha remains linear.

        A rationale for this resolution is found in Alvy Ray's "Should
        Alpha Be Nonlinear If RGB Is?" Tech Memo 17 (December 14, 1998).
        See: ftp://ftp.alvyray.com/Acrobat/17_Nonln.pdf

    3)  Should the ability to support sRGB framebuffer update and blending
        be an attribute of the framebuffer?

        RESOLVED:  Yes.  It should be a capability of some pixel formats
        (mostly likely just RGB8 and RGBA8) that says sRGB blending can
        be enabled.

        This allows an implementation to simply mark the existing RGB8
        and RGBA8 pixel formats as supporting sRGB blending and then
        just provide the functionality for sRGB update and blending for
        such formats.

        sRGB support for floating-point formats makes little sense
        (because floating-point already provide a non-linear distribution
        of precision and typically have considerably more precision
        than 8-bit fixed-point framebuffer components allow) and would
        be expensive to support.

        Requiring sRGB support for all fixed-point buffers means that
        support for 16-bit components or very small 5-bit or 6-bit
        components would require special sRGB conversion hardware.
        Typically sRGB is well-suited for 8-bit fixed-point components
        so we do not want this extension to require expensive tables
        for other component sizes that are unlikely to ever be used.
        Implementations could support sRGB conversion for any color
        framebuffer format but implementations are not required to
        (honestly nor are implementations like to support sRGB on anything
        but 8-bit fixed-point color formats).

    4)  Should there be an enable for sRGB update and blending?

        RESOLVED:  Yes, and it is disabled by default.  The enable only
        applies if a destination buffer's pixel format is capable
        of sRGB update and blending.  Otherwise, the enable is silently
        ignored (similar to how the multisample enables are ignored when
        the pixel format lacks multisample supports).

    5)  How is sRGB blending done?

        RESOLVED:  Blending is a linear operation so should be performed
        on values in linear spaces.  sRGB-encoded values are in a
        non-linear space so sRGB blending should convert sRGB-encoded
        values from the framebuffer to linear values, blend, and then
        sRGB-encode the result to store it in the framebuffer.

        The destination color RGB components are each converted
        from sRGB to a linear value.  Blending is then performed.
        The source color and constant color are simply assumed to be
        treated as linear color components.  Then the result of blending
        is converted to an sRGB encoding and stored in the framebuffer.

    6) What happens if GL_FRAMEBUFFER_SRGB is enabled (and
        GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING is GL_SRGB), but
        GL_BLEND is not enabled?

        RESOLVED: The color result from fragment coloring (the source
        color) is converted to an sRGB encoding and stored in the
        framebuffer.

    7)  How are multiple render targets handled?

        RESOLVED: Render targets that are not sRGB-capable ignore the
        state of the GL_FRAMEBUFFER_SRGB enable for sRGB update and
        blending. Note that unlike EXT_framebuffer_sRGB, the
        sRGB-capable query may be performed on a per-color-attachment
        basis.

    8)  Should sRGB framebuffer support affect the pixel path?

        RESOLVED:  No.

        sRGB conversion only applies to color reads for blending and
        color writes.  Color reads for glReadPixels, glCopyPixels,
        or glAccum have no sRGB conversion applied.

        For pixel path operations, an application could use pixel maps
        or color tables to perform an sRGB-to-linear conversion with
        these lookup tables.

    9)  Can luminance (single color component) framebuffer formats
        support sRGB blending?

        RESOLVED:  Yes, if an implementation chooses to advertise such
        a format and set the sRGB attribute for the format too.

        Implementations are not obliged to provide such formats.

    10) Should all component sizes be supported for sRGB components or
        just 8-bit?

        RESOLVED:  This is at the implementation's discretion since
        the implementation decides what pixel formats such support sRGB
        update and blending.

        It likely implementations will only provide sRGB-capable
        framebuffer configurations for configurations with 8-bit
        components.

    11) What must be specified as far as how do you convert to and from
        sRGB and linear RGB color spaces?

        RESOLVED:  The specification language needs to only supply the
        linear RGB to sRGB conversion (see section 4.9.X above).

        The sRGB to linear RGB conversion is documented in the
        EXT_texture_sRGB specification.

        For completeness, the accepted linear RGB to sRGB conversion
        (the inverse of the function specified in section 3.8.x) is as
        follows:

        Given a linear RGB component, cl, convert it to an sRGB component,
        cs, in the range [0,1], with this pseudo-code:

            if (isnan(cl)) {
                /* Map IEEE-754 Not-a-number to zero. */
                cs = 0.0;
            } else if (cl > 1.0) {
                cs = 1.0;
            } else if (cl < 0.0) {
                cs = 0.0;
            } else if (cl < 0.0031308) {
                cs = 12.92 * cl;
            } else {
                cs = 1.055 * pow(cl, 0.41666) - 0.055;
            }

         The NaN behavior in the pseudo-code is recommended but not
         specified in the actual specification language.

         sRGB components are typically stored as unsigned 8-bit
         fixed-point values.  If cs is computed with the above
         pseudo-code, cs can be converted to a [0,255] integer with this
         formula:

            csi = floor(255.0 * cs + 0.5)

    12) Does this extension guarantee images rendered with sRGB textures
        will "look good" when output to a device supporting an sRGB
        color space?

        RESOLVED:  No.

        Whether the displayed framebuffer is displayed to a monitor that
        faithfully reproduces the sRGB color space is beyond the scope
        of this extension.  This involves the gamma correction and color
        calibration of the physical display device.

    13) How does this extension interact with ARB_framebuffer_object?

        RESOLVED: ARB_framebuffer_object is required to provide the
        GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING query used to determine
        if the color texture image is capable of sRGB rendering.

        This query should be LINEAR for all texture internal formats
        other than sRGB internal formats such as those introduced by
        EXT_texture_sRGB. Implementations of this extension must be able
        to support sRGB update and blending of sRGB textures.

    14) How is the constant blend color handled for sRGB framebuffers?

        RESOLVED:  The constant blend color is specified as four
        floating-point values.  Given that the texture border color can
        be specified at such high precision, it is always treated as a
        linear RGBA value.

    15) How does glCopyTex[Sub]Image work with sRGB?  Suppose we're
        rendering to a floating point pbuffer or framebuffer object and
        do CopyTexImage.  Are the linear framebuffer values converted
        to sRGB during the copy?

        RESOLVED:  No, linear framebuffer values will NOT be automatically
        converted to the sRGB encoding during the copy.  If such a
        conversion is desired, as explained in issue 12, the red, green,
        and blue pixel map functionality can be used to implement a
        linear-to-sRGB encoding translation.

    16) Should this extension explicitly specify the particular
        sRGB-to-linear and linear-to-sRGB conversions it uses?

        RESOLVED:  The conversions are explicitly specified but
        allowance for approximations is provided.  The expectation is
        that the implementation is likely to use a table to implement the
        conversions the conversion is necessarily then an approximation.

    17) How does this extension interact with multisampling?

        RESOLVED:  There are no explicit interactions.  However, arguably
        if the color samples for multisampling are sRGB encoded, the
        samples should be linearized before being "resolved" for display
        and then recoverted to sRGB if the output device expects sRGB
        encoded color components.

        This is really a video scan-out issue and beyond the scope
        of this extension which is focused on the rendering issues.
        However some implementation advice is provided:

        The implementation sufficiently aware of the gamma correction
        configured for the display device could decide to perform an
        sRGB-correct multisample resolve.  Whether this occurs or not
        could be determined by a control panel setting or inferred by
        the application's use of this extension.

    18) Why is the sRGB framebuffer GL_FRAMEBUFFER_SRGB enable
        disabled by default?

        RESOLVED:  This extension could have a boolean
        sRGB-versus-non-sRGB pixel format configuration mode that
        determined whether or not sRGB framebuffer update and blending
        occurs.  The problem with this approach is 1) it creates may more
        pixel formation configurations because sRGB and non-sRGB versions
        of lots of existing configurations must be advertised, and 2)
        applicaitons unaware of sRGB might unknowingly select an sRGB
        configuration and then generate over-bright rendering.

        It seems more appropriate to have a capability for sRGB
        framebuffer update and blending that is disabled by default.
        This allows existing RGB8 and RGBA8 framebuffer configurations
        to be marked as sRGB capable (so no additional configurations
        need be enumerated).  Applications that desire sRGB rendering
        should identify an sRGB-capable framebuffer configuration and
        then enable sRGB rendering.

        This is different from how EXT_texture_sRGB handles sRGB support
        for texture formats.  In the EXT_texture_sRGB extension, textures
        are either sRGB or non-sRGB and there is no texture parameter
        to switch textures between the two modes.  This makes sense for
        EXT_texture_sRGB because it allows implementations to fake sRGB
        textures with higher-precision linear textures that simply convert
        sRGB-encoded texels to sufficiently precise linear RGB values.

        Texture formats also don't have the problem enumerated pixel
        format descriptions have where a naive application could stumble
        upon an sRGB-capable pixel format.  sRGB textures require
        explicit use of one of the new EXT_texture_sRGB-introduced
        internal formats.

    19) How does sRGB and this extension interact with digital video
        output standards, in particular DVI?

        RESOLVED:  The DVI 1.0 specification recommends "as a default
        position that digital moniotrs of all types support a color
        transfer function similar to analog CRT monitors (gamma=2.2)
        which makes up the majority of the compute display market." This
        means DVI output devices should benefit from blending in the
        sRGB color space just like analog monitors.

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

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

        This does not apply to the GLX and WGL elements of this
        extension, since those elements are not part of a new core GLX
        or WGL release yet.

    21) Where's the specification language for the GLX and WGL pixel
        format selection interface?

        TO BE DONE. The {GLX,WGL}_FRAMEBUFFER_SRGB_CAPABLE_ARB pixel
        format attributes are used to select default framebuffers which
        are sRGB-capable in the fairly obvious way, but this language
        was missing in the original EXT_framebuffer_sRGB and needs to be
        added here.

Revision History

        Rev.    Date    Author    Changes
        ----  --------  --------  -------------------------------------
         1.2  08/11/08  jleech    Use per-FBO-attachment state for
                                  sRGB-capable queries, rather then the
                                  EXT's single boolean query for the
                                  entire framebuffer.
         1.1  08/08/08  jleech    Remove ARB suffixes.
           1  10/21/06  barthold  Added revision history
         0.4  10/20/06  mjk       Added issue 19
         0.3            mjk       Internal spec development.

