blob: aa272667c07b01637dd0ef3287b5b070a18d75b3 [file] [log] [blame]
Name Strings
Graham Sellers, AMD
Mark Young, AMD
Nick Haemel, AMD
Pierre Boudier, AMD
Mais Alnasser, AMD
Jeff Bolz, NVIDIA
Pat Brown, NVIDIA
Ian Stewart, NVIDIA
Mark Kilgard, NVIDIA
Graham Sellers, AMD (graham.sellers 'at'
Copyright (c) 2010-2013 The Khronos Group Inc. Copyright terms at
Specification Update Policy
Khronos-approved extension specifications are updated in response to
issues and bugs prioritized by the Khronos OpenGL Working Group. For
extensions which have been promoted to a core Specification, fixes will
first appear in the latest version of that core Specification, and will
eventually be backported to the extension document. This policy is
described in more detail at
Complete. Approved by the ARB at the 2010/01/22 F2F meeting.
Approved by the Khronos Board of Promoters on March 10, 2010.
Last Modified Date: 05/22/2015
Author Revision: 13
ARB Extension #78
OpenGL 1.0 is required.
The ARB_fragment_shader extension is required.
The EXT_gpu_shader4 extension is required.
The EXT_blend_func_separate extension interacts with this extension.
The ARB_draw_buffers extension trivially affects the definition of this
The ARB_draw_buffers_blend extension affects the definition of this
This extension is written against the OpenGL 3.2 Specification (Compatibility Profile)
Traditional OpenGL includes fixed-function blending that combines source
colors with the existing content of a render buffer in a variety of ways.
A number of extensions have enhanced this functionality by adding further
sources of blending weights and methods to combine them. However, the inputs
to the fixed-function blending units are constrained to a source color (as
output from fragment shading), destination color (as the current content
of the frame buffer) or constants that may be used in their place.
This extension adds new blending functions whereby a fragment shader may
output two colors, one of which is treated as the source color, and the
other used as a blending factor for either source or destination colors.
Furthermore, this extension increases orthogonality by allowing the
SRC_ALPHA_SATURATE function to be used as the destination weight.
IP Status
No known IP claims.
New Procedures and Functions
void BindFragDataLocationIndexed(uint program, uint colorNumber,
uint index, const char * name);
int GetFragDataIndex(uint program, const char * name);
New Tokens
Accepted by the <src> and <dst> parameters of BlendFunc and
BlendFunci, and by the <srcRGB>, <dstRGB>, <srcAlpha> and <dstAlpha>
parameters of BlendFuncSeparate and BlendFuncSeparatei:
Accepted by the <pname> parameter of GetBooleanv, GetIntegerv, GetFloatv
and GetDoublev:
Additions to Chapter 2 of the OpenGL 3.2 Specification (Compatibility Profile) (OpenGL Operation)
Additions to Chapter 3 of the OpenGL 3.2 Specification (Compatibility Profile) (Rasterization)
Modify the "Shader Outputs" subsection of Section 3.12.2, Shader Execution
Modify the text on p.297 beginning "The binding of a user-defined varying
out variable to a fragment..."
The binding of a user-defined varying out variable to a fragment color number
can be specified explicitly. The command
void BindFragDataLocationIndexed(uint program, uint colorNumber, uint index, const char * name);
specifies that the varying out variable name in <program> should be bound to
fragment color <colorNumber> when the program is next linked. <index> may be
zero or one to specify that the color be used as either the first or second
color input to the blend equation, respectively, as described in Section 4.1.8.
If <name> was bound previously, its assigned binding is replaced with
colorNumber. <name> must be a null-terminated string. The error INVALID_VALUE
is generated if <colorNumber> is equal or greater than MAX_DRAW_BUFFERS and
<index> is zero, or if <colorNumber> is equal or greater than
MAX_DUAL_SOURCE_DRAW_BUFFERS and <index> is greater than or equal to one.
The command
void BindFragDataLocation(uint program, uint colorNumber, const char * name)
is equivalent to calling BindFragDataLocationIndexed with the same values
for <program>, <colorNumber> and <name>, and with <index> set to zero.
When a program is linked, any varying out variables without a binding
specified through BindFragDataLocationIndexed or BindFragDataLocation will
automatically be bound to fragment colors and indices by the GL. All such
assignments will use color indices of zero. Such bindings can be queried
using the commands GetFragDataLocation and GetFragDataIndex. Output
binding assignments will cause LinkProgram to fail:
* if the number of active outputs is greater than the value of
* if the program has an active output assigned to a location greater
than or equal to the value of MAX_DUAL_SOURCE_DRAW_BUFFERS and has an
active output assigned an index greater than or equal to one;
* if more than one varying out variable is bound to the same number and
index; or
* if the explicit binding assignments do not leave enough space for the
linker to automatically assign a location for a varying out array,
which requires multiple contiguous locations.
BindFragDataLocationIndexed may be issued before any shader objects are
attached to a program object. Hence it is allowed to bind any name (except a
name starting with gl_) to a color number and index, including a name that
is never used as a varying out variable in any fragment shader object.
Assigned bindings for variables that do not exist are ignored.
Add to the last paragraph on p.279
The command
int GetFragDataIndex(uint program, const char * name);
returns the index of the fragment color to which the variable <name> was bound
when the program object <program> was last linked. If program has not been
successfully linked, the error INVALID_OPERATION is generated. If name is not
a varying out variable, or if an error occurs, -1 will be returned.
Additions to Chapter 4 of the OpenGL 3.2 Specification (Compatibility Profile) (Per-Fragment Operations
and the Framebuffer)
Modify the first paragraph of the Blending Functions subsection of Section
4.1.8 Blending (p. 292) as follows:
The weighting factors used by the blend equation are determined by the blend
functions. There are four possible sources for weighting factors. These are
the constant color (Rc, Gc, Bc, Ac) (see BlendColor, p. 211), the first
source color (Rs0, Gs0, Bs0, As0), the second source color
(Rs1, Gs1, Bs1, As1), and the destination color (the existing content of the
draw buffer). Additionally the special constants ZERO and ONE are
available as weighting factors. Blend functions are specified ...
Modify Table 4.2 (p. 213) as follows
RGB Blend Factors Alpha Blend Factors
Value (Sr, Sg, Sb) or (Dr, Dg, Db) Sa or Da
----- ---------------------------- -------------------
ZERO (0, 0, 0) 0
ONE (1, 1, 1) 1
SRC_COLOR (Rs0, Gs0, Bs0) As0
ONE_MINUS_SRC_COLOR (1, 1, 1) - (Rs0, Gs0, Bs0) 1 - As0
DST_COLOR (Rd, Gd, Bd) Ad
ONE_MINUS_DST_COLOR (1, 1, 1) - (Rd, Gd, Bd) 1 - Ad
SRC_ALPHA (As0, As0, As0) As0
ONE_MINUS_SRC_ALPHA (1, 1, 1) - (As0, As0, As0) 1 - As0
DST_ALPHA (Ad, Ad, Ad) Ad
ONE_MINUS_DST_ALPHA (1, 1, 1) - (Ad, Ad, Ad) 1 - Ad
ONE_MINUS_CONSTANT_COLOR (1, 1, 1) - (Rc, Gc, Bc) 1 - Ac
ONE_MINUS_CONSTANT_ALPHA (1, 1, 1) - (Ac, Ac, Ac) 1 - Ac
SRC_ALPHA_SATURATE (f, f, f) 1 (Now allowed for dst)
SRC1_COLOR (Rs1, Gs1, Bs1) As1 New
ONE_MINUS_SRC1_COLOR (1, 1, 1) - (Rs1, Gs1, Bs1) 1 - As1 New
SRC1_ALPHA (As1, As1, As1) As1 New
ONE_MINUS_SRC1_ALPHA (1, 1, 1) - (As1, As1, As1) 1 - As1 New
Remove Footnote 1 from Table 4.2.
Add the following subsections to Section 4.1.8 Blending, at the end of the
description of Blend Function (p. 294)
Dual Source Blending and Multiple Draw Buffers
Blend functions that require the second color input, <Rs1, Gs1, Bs1, As1>
ONE_MINUS_SRC1_ALPHA) may consume hardware resources that could
otherwise be used for rendering to multiple draw buffers. Therefore, the
number of draw buffers that can be attached to a frame buffer may be lower
when using dual-source blending.
The maximum number of draw buffers that may be attached to a single frame
buffer when using dual-source blending functions is implementation dependent
and can be queried by calling GetIntegerv with the symbolic constant
using dual-source blending, MAX_DUAL_SOURCE_DRAW_BUFFERS should be used
in place of MAX_DRAW_BUFFERS to determine the maximum number of draw
buffers that may be attached to a single frame buffer. The value of
MAX_DUAL_SOURCE_DRAW_BUFFERS must be at least 1. If the value of
MAX_DUAL_SOURCE_DRAW_BUFFERS is 1, then dual-source blending and
multiple draw buffers cannot be used simultaneously.
If either blend function is set to one of the second source factors
ONE_MINUS_SRC1_ALPHA) for any draw buffer and any draw buffers equal to
or greater than the value of MAX_DUAL_SOURCE_DRAW_BUFFERS have values other than NONE,
the error INVALID_OPERATION is generated by Begin, or any procedure that
implicitly calls Begin.
Generation of Second Color Source for Blending
There is no way to generate the second source color using the fixed-function
fragment pipeline. Rendering using any of the blend functions that consume
the second input color (SRC1_COLOR, ONE_MINUS_SRC1_COLOR,
SRC1_ALPHA or ONE_MINUS_SRC1_ALPHA) using fixed function will produce
undefined results. To produce input for the second source color, a shader
must be used.
When using a GLSL fragment shader with dual-source blending functions,
the color output varyings are bound to the first and second inputs of a
draw buffer using BindFragDataLocationIndexed as described in the "Shader
Outputs" subsection of Section 3.12.2. Data written to the first of these outputs
becomes the first source color input to the blender (corresponding to
SRC_COLOR and SRC_ALPHA). Data written to the second of these outputs
generates the second source color input to the blender (corresponding to
If the second color input to the blender is not written in the shader, or if
no output is bound to the second input of a blender, the result of the blending
operation is not defined.
Other shading languages may define similar methods for producing the first
and second color inputs to blending equations.
Additions to Chapter 5 of the OpenGL 3.2 Specification (Compatibility Profile) (Special
Additions to Chapter 6 of the OpenGL 3.2 Specification (Compatibility Profile) (State and
State Requests)
Dependencies on ARB_fragment_shader
If ARB_fragment_shader is not supported then references to
ARB_fragment_shader in section 4.1.8 and elsewhere in this document should
be removed. In this case, there is no way to generate the second color input
to the blending equation unless a further extension to another shading
language is defined and used.
Dependencies on ARB_draw_buffers
Using dual-source blending functions may consume additional outputs from
hardware shading units and therefore can reduce the number of draw buffers
that may be attached to a single frame buffer when dual-source blending
functions are enabled. In this case, the value of
MAX_DUAL_SOURCE_DRAW_BUFFERS may be less than the value of
MAX_DRAW_BUFFERS. If ARB_draw_buffers is not supported then the value of
MAX_DUAL_SOURCE_DRAW_BUFFERS will be 1. Furthermore, the discussion
in the subsection entitled "Dual Source Blending and Multiple Draw Buffers"
may be discarded.
Dependencies on EXT_blend_func_separate
If EXT_blend_func_separate is not supported, remove references to
BlendFuncSeparate. Also, remove any references to BLEND_SRC_ALPHA and
BLEND_DST_ALPHA, and replace references to BLEND_SRC_RGB and BLEND_DST_RGB
with BLEND_SRC and BLEND_DST, respectively. In this case, the new blend
functions may only be enabled via the BlendFunc procedure.
Dependencies on ARB_draw_buffers_blend
If ARB_draw_buffers_blend is not supported, all references to BlendFunci
and BlendFuncSeparatei should be removed. In this case, the blend
functions for all attached draw buffers will be the same.
Interactions with NV_gpu_program5
If NV_gpu_program5 is supported, fragment result bindings
"result.color[n].primary" and "result.color[n].secondary" can be used to
specify the <n>th color outputs for index 0 and 1, respectively.
Additions to the AGL/GLX/WGL Specifications
GLX Protocol
The error INVALID_OPERATION is generated by Begin or any procedure that
implicitly calls Begin if any draw buffer has a blend function requiring the
second color input (SRC1_COLOR, ONE_MINUS_SRC1_COLOR, SRC1_ALPHA or
ONE_MINUS_SRC1_ALPHA), and a framebuffer is bound that has more than
the value of MAX_DUAL_SOURCE_DRAW_BUFFERS-1 active color attachments.
New State
Table 6.21 (p. 286)
Get Value Type Get Command Initial Value Description Sec Attribute
------------------------ ---- ------------ ------------- ------------------- ----- ---------
BLEND_SRC_RGB Z19 GetIntegerv ONE Blending source RGB 4.1.8 color-buffer
BLEND_SRC_ALPHA Z19 GetIntegerv ONE Blending source A 4.1.8 color-buffer
BLEND_DST_RGB Z19 GetIntegerv ZERO Blending dest. RGB 4.1.8 color-buffer
BLEND_DST_ALPHA Z19 GetIntegerv ZERO Blending dest. A 4.1.8 color-buffer
NOTE: The only change is that Z14 and Z15 change to Z19 for the existing blend
function state. No new state is actually added to the OpenGL Specification.
New Implementation Dependent State
Get Value Type Get Command Minimum Value Description Sec. Attribute
--------- ---- ----------- ------------- ------------------- ----- ---------
MAX_DUAL_SOURCE_DRAW_BUFFERS Z+ GetIntegerv 1 Maximum number of 4.1.8 -
active draw buffers
when using dual-source
Example Use Cases
There are several potential uses for this functionality. A first example
is in the implementation of sub-pixel accurate font rendering algorithms.
Given a known layout of pixel elements (red, green and blue components),
coverage may be calculated independently for each element and passed
to the blender in the second source color as a per-channel opacity. To use
this mode, use the following blend functions:
As a second example, consider a partially reflective colored glass window.
It will attenuate light passing through it, and reflect some of the light
that strikes it. Using an appropriate combination of functions, this effect
may be simulated in a single pass using only fixed-function blending
hardware. In this case, the following blend functions may be used:
1) Should the new tokens be SRC1_COLOR and SRC2_COLOR (1-based), or
RESOLVED: Indices in OpenGL are generally zero based. These follow
2) What happens when rendering using a dual-source blend function using
RESOLVED: There is no reasonable way to generate the second source color
for blending using fixed-function fragment processing. However, as it is
possible to set the blend function and then enable a shader, there isn't
really a clean way to report an error. Therefore, we allow it, but leave
the result undefined.
2a) Can't we use an existing output from fixed function, like back color,
to make this work?
DISCUSSION: We could relabel things. For example, make the front color
be the first input to blending and the back color the second input. This
kind of thing would come at the cost of lost fixed function capability,
possible ambiguity and added complexity in the fixed function
specification. The new functionality in this extension is most useful
when reading data from multiple textures or other complex sources that
would just be too complex to express with fixed function processing.
For these reasons, rendering through dual-source blending functions using
the fixed function pipeline is not supported and will produce undefined
2b) Then why write this against OpenGL 2.1 which includes fixed-function?
Why not write against OpenGL 3.x that only supports shaders anyway?
DISCUSSION: Because this extension adds functionality to existing
extensions and those are written against OpenGL 2.1. Furthermore, the
functionality described here does not rely on any core feature provided
by OpenGL 3.x and can be easily built upon and used in implementations of
OpenGL 2.1 or earlier versions of the OpenGL Specification.
RESOLVED: Updated to stand against OpenGL 3.2, but kept the fixed function
issues in the spec.
3) Why is this not orthogonal and interoperable with ARB_draw_buffers?
RESOLVED: This is functionality that has existed in hardware for some
time and been made available via other graphics APIs. In some hardware
and APIs, the second color input from the shader is actually what would
have been written to draw buffer 1. This is the functionality that is
guaranteed to be universally supported. This extension does not preclude
use with multiple draw buffers except exclusion through implementation
defined limits. If future hardware supports multiple color outputs
simultaneously to multiple draw buffers, it can simply advertise higher
4) Can we not add an implementation state query to find out if it's
available with multiple draw buffers?
the same value as MAX_DRAW_BUFFERS then the functions are orthogonal.
If this returns 1, then they cannot be used together. If it returns some
value between 1 and MAX_DRAW_BUFFERS, then dual-source blending
may consume some additional hardware routing resources, but can be used
with multiple draw buffers provided the MAX_DUAL_SOURCE_DRAW_BUFFERS
limit is not exceeded.
5) Should there also be a Link error if the fragment shader uses both an
index=1 output below MAX and an index=0 output greater than or equal to
MAX? The quoted begin-time error leaves open the possibility of an app
doing something like BindFragDataLocationIndexed(colorNumber=0, index=0)
+ (colorNumber=0, index=1) + (colorNumber=1, index=0), then rendering
without using the src1 blend functions. If an implementation aliases
index=1 onto other index=0 outputs, then it wouldn't be able to handle
that case.
DISCUSSION: The begin time error language states '... if any draw buffer
has a blend function requiring the second color input ...'. This means
that the outputs can be bound to non-zero indices, but if the blend
function does not consume that output, no error will be generated. In
theory, an implementation could ignore output bound to color=0, index=1
in this case and operate as if it were not there. However, it makes no
sense for the linker to accept such a configuration of outputs because
the underlying hardware may not be able to support it. Therefore, we can
generate a link time error, thus eliminating this begin-time check and
potentially improving run-time performance.
Revision History
Rev. Date Author Changes
---- -------- -------- -----------------------------------------
13 05/22/2015 mjk Fix misspellings
12 02/05/2010 istewart Add interactions with NV_gpu_program5.
11 01/26/2010 pbrown Assign enum values.
10 01/14/2010 pbrown Add spec language allowing for a link error if
explicit output bindings don't leave enough
space for array outputs. Clarify that any
automatic assignments for fragment outputs
will use color index zero.
9 12/10/2009 Jon Leech Fix typos in blending equation table, remove
ARB suffixes for core 3.3 inclusion, clean
up "GL_TOKEN" vs. "the value of GL_TOKEN".
8 11/19/2009 gsellers Remove SRC0_COLOR etc. enums, use old ones
instead. Use previously defined value for
SRC1_ALPHA. Update text to match.
7 10/26/2009 gsellers Change BindFragDataLocationIndexedARB to take a
numerical index instead of an enum. Clarify
behavior in several places. Add issue 5.
6 10/20/2009 gsellers Update to diff to OpenGL 3.2 (Compatibility) spec.
Add BindFragDataLocationIndexedARB and
GetFragDataIndexARB. Remove idea of making shader
outputs arrays. Define Begin time error when
blend func is SRC1_* for FBO with >=
5 05/21/2009 gsellers Clarify meaning of MAX_DUAL_SOURCE_BUFFERS_ARB.
Clarify the (lack of) interaction with fixed
function fragment processing and further
justify lack of support (Issues 2a and 2b).
Clarify modification to state.
4 05/19/2009 gsellers Allow simultaneous use of ARB_draw_buffers with
this extension;
Document interaction with ARB_draw_buffers_blend.
3 05/19/2009 gsellers Remove access via gl_FragData, replace with user
defined output varyings.
2 05/15/2009 gsellers Minor cleanup. Add usage examples.
1 05/14/2009 gsellers Initial draft