Name

    ARB_shader_precision

Name Strings

    GL_ARB_shader_precision

Contact

    John Kessenich ( john.kessenich 'at' intel.com )

Contributors

    Bill Licea-Kane, AMD
    Chris Dodd, Nvidia
    Jeff Bolz, Nvidia
    Pat Brown, Nvidia
    Piers Daniell, Nvidia
    Ian Romanick, Intel
    Daniel Koch, Transgaming
    Frank ??, Qualcomm
    Jeremy Sandmel, Apple
    Jeff Daniels
    Greg Roth, Nvidia

Notice

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

Status

    Complete. Approved by the ARB on June 9, 2010.
    Approved by the Khronos Board of Promoters on July 23, 2010.

Version

    Last Modified Date: 2010-04-29
    Author Revision: 6.0
    $Date$ $Revision$

Number

    ARB Extension #98

Dependencies

    This extension is written against OpenGL 4.0.

    OpenGL 4.0 is required.

Overview

    This extension more clearly restricts the precision requirements of 
    implementations of the GLSL specification.  These include precision of 
    arithmetic operations (operators '+', '/', ...), transcendentals (log, exp, 
    pow, reciprocal sqrt, ...), when NaNs (not a number) and INFs (infinities) will
    be supported and generated, and denorm flushing behavior.  Trigonometric 
    built-ins and some other categories of built-ins are not addressed.

IP Status

    No known IP claims.

New Procedures and Functions

    None.

New Types

    None.

New Tokens

    None, unless we add switches.

Additions to the OpenGL Shading Language 4.00 Specification

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

      #extension GL_ARB_shader_precision : <behavior>

    where <behavior> is as specified in section 3.3.

    A new preprocessor #define is added to the OpenGL Shading Language:

      #define GL_ARB_shader_precision 1

Changes to Section 4.1.4 Floats

    Keep the first two sentences of the second paragraph:

    As an input value to one of the processing units, a single-precision or double- 
    precision floating-point variable is expected to match the corresponding IEEE 
    754 floating-point definition for precision and dynamic range.  Floating-point 
    variables within a shader are also encoded according to the IEEE 754 
    specification for single-precision floating-point values....

    Remove the remainder of the paragraph:

    ...However, it is not 
    required that the precision of internal processing match the IEEE 754 floating-
    point specification for floating-point operations, but the guidelines for 
    precision established by the OpenGL Graphics System Specification must be met. 
    Similarly, treatment of conditions such as divide by 0 may lead to an 
    unspecified result, but in no case should such a condition lead to the 
    interruption or termination of processing.  Generally, there are no signaling 
    NaNs, and operating on NaNs (Not a Number) or infs (positive or negative 
    infinities) gives undefined results.

    replacing it with the following:

    ...See section 4.5.1 Range and Precision for more details on precision and
    usage of NaNs (Not a Number) and Infs (positive or negative infinities).

Add to Section 4.5.1 Range and Precision

    The precision of stored single and double precision floating-point variables is 
    defined by the IEEE 754 standard for 32-bit and 64-bit floating-point numbers.  
    This includes support for NaNs (Not a Number) and Infs (positive or negative 
    infinities).

    The following rules apply to both single and double precision operations:  
    Dividing by 0 results in the appropriately signed IEEE Inf.  Any denormalized 
    value input into a shader or potentially generated by an operation in a shader 
    can be flushed to 0.  In general, correct signedness of 0 is not required.  The 
    rounding mode cannot be set and is undefined.  Support for signaling NaNs is 
    not required and exceptions are never raised.  Operations and built-in functions 
    that operate on a NaN are not required to return a NaN as the result.

    Precisions are expressed in terms of maximum relative error in units of ULP 
    (units in the last place).

    For single precision operations

            Operation                       Precision

        a+b, a-b, a*b              correctly rounded
        <, =<, ==, >, >=           correct result
        a/b, 1.0/b                 <= 2.5 ULP
        a*b+c                      correctly rounded single operation or
                                   sequence of two correctly rounded operations
        fma()                      same as a*b+c
        pow                        <= 16 ULP
        exp, exp2                  <= 3 ULP
        log, log2                  <= 3 ULP
        sqrt                       <= 3 ULP
        inversesqrt                <= 2 ULP
        conversions                correctly rounded
   
    Built-in functions defined in the specification with an equation built from the 
    above operations inherit the above errors.  These include, for example, the 
    geometric functions, the common functions, and many of the matrix functions.  
    Built-in functions not listed above and not defined as equations of the above 
    have undefined precision.  These include, for example, the trigonometric 
    functions and determinant.
        
    Double precision operations:

        TBD.

Changes to Section 8.3 Common Functions

    In the table for intBitsToFloat, uintBitsToFloat, and packDouble2x32, change

    If an inf or NaN is passed in, it will not signal, and the resulting floating 
    point value is unspecified.

    To

    If an inf or NaN is passed in, it will not signal, and the resulting floating 
    point value will be a NaN.

Issues

1.  Operations like fma(), pow(), etc. might not be as precise as specified.  To 
keep backward compatibility, this implies vendors finding out what precisions they do 
have.  Possibly also either new built-ins or modes are needed to access 
hardware's ability to deliver the more precise versions of what is found.

2.  The specification is currently lacking in edge case behavior.  How much of this 
should refer to existing IEEE and language specifications versus be reproduced 
here?

Revision History

    Revision 1, johnk, 2010-04-29
      - Working Draft

    Revision 2, johnk, 2010-05-06
      - Don't require operations on NaNs to return NaNs.
      - Change from EXT to ARB.

