blob: ba551d2573aff4822eedba7985329e4e35546b04 [file] [log] [blame]
Name
ANGLE_multiple_render_targets
Name Strings
GL_ANGLE_multiple_render_targets
Contributors
Contributors to GL_NV_draw_buffers
Contributors to GL_NV_fbo_color_attachments
Contributors to the OpenGL ES 2.0 specification
Contributors to the OpenGLSL ES 1.0.17 specification
Contributors to the OpenGL ES 3.0 specification
Nicolas Capens, TransGaming Inc.
Daniel Koch, TransGaming Inc.
Alastair Patrick, Google Inc.
Kenneth Russell, Google Inc.
Members of the WebGL working group
Contact
Daniel Koch <daniel> <at> <transgaming> <dot> <com>
Status
Incomplete -- do not implement!
Version
Last Modified Date: January 23, 2013
Revision: #6
Number
TBD
Dependencies
OpenGL ES 2.0 is required.
The extension is written against the OpenGL ES 2.0 specification.
ANGLE_framebuffer_blit affects the definition of this extension.
APPLE_framebuffer_multisample affects the definitin of this extension.
Overview
This extension increases the number of available framebuffer object
color attachment points, extends OpenGL ES 2.0 to allow multiple output
colors, and provides a mechanism for directing those outputs to
multiple color buffers.
This extension is similar to the combination of the GL_NV_draw_buffers
and GL_NV_fbo_color_attachments extensions, but imposes certain
restrictions informed by the OpenGL ES 3.0 API.
New Procedures and Functions
void DrawBuffersANGLE(sizei n, const enum *bufs);
New Tokens
Accepted by the <pname> parameter of GetIntegerv:
MAX_COLOR_ATTACHMENTS_ANGLE 0x8CDF
Accepted by the <pname> parameters of GetIntegerv and GetFloatv:
MAX_DRAW_BUFFERS_ANGLE 0x8824
DRAW_BUFFER0_ANGLE 0x8825
DRAW_BUFFER1_ANGLE 0x8826
DRAW_BUFFER2_ANGLE 0x8827
DRAW_BUFFER3_ANGLE 0x8828
DRAW_BUFFER4_ANGLE 0x8829
DRAW_BUFFER5_ANGLE 0x882A
DRAW_BUFFER6_ANGLE 0x882B
DRAW_BUFFER7_ANGLE 0x882C
DRAW_BUFFER8_ANGLE 0x882D
DRAW_BUFFER9_ANGLE 0x882E
DRAW_BUFFER10_ANGLE 0x882F
DRAW_BUFFER11_ANGLE 0x8830
DRAW_BUFFER12_ANGLE 0x8831
DRAW_BUFFER13_ANGLE 0x8832
DRAW_BUFFER14_ANGLE 0x8833
DRAW_BUFFER15_ANGLE 0x8834
Accepted by the <attachment> parameter of FramebufferRenderbuffer,
FramebufferTexture2D and GetFramebufferAttachmentParameteriv, and by
the <bufs> parameter of DrawBuffersANGLE:
COLOR_ATTACHMENT0_ANGLE 0x8CE0
COLOR_ATTACHMENT1_ANGLE 0x8CE1
COLOR_ATTACHMENT2_ANGLE 0x8CE2
COLOR_ATTACHMENT3_ANGLE 0x8CE3
COLOR_ATTACHMENT4_ANGLE 0x8CE4
COLOR_ATTACHMENT5_ANGLE 0x8CE5
COLOR_ATTACHMENT6_ANGLE 0x8CE6
COLOR_ATTACHMENT7_ANGLE 0x8CE7
COLOR_ATTACHMENT8_ANGLE 0x8CE8
COLOR_ATTACHMENT9_ANGLE 0x8CE9
COLOR_ATTACHMENT10_ANGLE 0x8CEA
COLOR_ATTACHMENT11_ANGLE 0x8CEB
COLOR_ATTACHMENT12_ANGLE 0x8CEC
COLOR_ATTACHMENT13_ANGLE 0x8CED
COLOR_ATTACHMENT14_ANGLE 0x8CEE
COLOR_ATTACHMENT15_ANGLE 0x8CEF
The COLOR_ATTACHMENT0_ANGLE constant is equal to the
COLOR_ATTACHMENT0 constant.
Each COLOR_ATTACHMENT<i>_ANGLE adheres to COLOR_ATTACHMENT<i>_ANGLE
= COLOR_ATTACHMENT0_ANGLE + <i>.
Changes to Chapter 3 of the OpenGL ES 2.0 Specification (Rasterization)
Section 3.2, (Multisampling). Replace the second paragraph:
An additional buffer, called the multisample buffer, is added to the
window system-provided framebuffer. Pixel sample values, including
color, depth, and stencil values, are stored in this buffer. Samples
contain separate color values for each fragment color. When the
window system-provided framebuffer includes a multisample buffer, it
does not include depth or stencil buffers, even if the multisample
buffer does not store depth or stencil values. Color buffers do
coexist with the multisample buffer, however.
Section 3.8.2, (Shader Execution) Replace subsection "Shader
Outputs":
The OpenGL ES Shading Language specification describes the values
that may be output by a fragment shader. These are gl_FragColor and
gl_FragData[n]. The final fragment color values or the final
fragment data values written by a fragment shader are clamped to the
range [0, 1] and then converted to fixed-point as described in
section 2.1.2 for framebuffer color components.
Writing to gl_FragColor specifies the fragment color (color number
zero) that will be used by subsequent stages of the pipeline.
Writing to gl_FragData[n] specifies the value of fragment color
number n. Any colors, or color components, associated with a
fragment that are not written by the fragment shader are undefined.
A fragment shader may not statically assign values to both
gl_FragColor and gl_FragData. In this case, a compile or link error
will result. A shader statically assigns a value to a variable if,
after preprocessing, it contains a statement that would write to the
variable, whether or not run-time flow of control will cause that
statement to be executed.
Changes to Chapter 4 of the OpenGL ES 2.0 Specification (Per-Fragment
Operations and the Frame Buffer)
Modify the overview of Chapter 4 and replace the sentences
of the fifth paragraph which read:
"The name of the color buffer of an application-created framebuffer
object is COLOR_ATTACHMENT0. The names of the depth and stencil buffers
are DEPTH_ATTACHMENT and STENCIL_ATTACHMENT."
With the following:
"A framebuffer object has an array of color buffer attachment points,
numbered zero through <n>, a depth buffer attachment point, and a
stencil buffer attachment point."
Insert Table 4.3 to Section 4.2.1 (and renumber subsequent tables):
Symbolic Constant Meaning
----------------- ---------------------
NONE No buffer
COLOR_ATTACHMENT<i>_ANGLE (see caption) Output fragment color to image
attached at color attachment
point i
Table 4.3: Arguments to DrawBuffersANGLE when the context is bound to a
framebuffer object, and the buffers they indicate. <i> in
COLOR_ATTACHMENT<i>_ANGLE may range from zero to the value of
MAX_COLOR_ATTACHMENTS_ANGLE minus one.
Replace Section 4.2.1, "Selecting a Buffer for Writing" with the following:
"By default, color values are written into the front buffer for
single buffered surfaces or into the back buffer for back buffered
surfaces as determined when making the context current. To control
the color buffer into which each of the fragment color values is
written, DrawBuffersANGLE is used.
The command
void DrawBuffersANGLE(sizei n, const enum *bufs);
defines the draw buffers to which all fragment colors are written.
<n> specifies the number of buffers in <bufs>. <bufs> is a pointer
to an array of symbolic constants specifying the buffer to which
each fragment color is written.
Each buffer listed in <bufs> must be BACK, NONE, or one of the
values from table 4.3. Further, acceptable values for the constants
in <bufs> depend on whether the GL is using the default framebuffer
(i.e., DRAW_FRAMEBUFFER_BINDING is zero), or a framebuffer object
(i.e., DRAW_FRAMEBUFFER_BINDING is non-zero). For more information
about framebuffer objects, see section 4.4.
If the GL is bound to the default framebuffer, then <n> must be 1
and the constant must be BACK or NONE. When draw buffer zero is
BACK, color values are written into the sole buffer for single-
buffered contexts, or into the back buffer for double-buffered
contexts. If DrawBuffersANGLE is supplied with a constant other than
BACK and NONE, the error INVALID_OPERATION is generated.
If the GL is bound to a draw framebuffer object, then each of the
constants must be one of the values listed in table 4.3.
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. The
number of draw buffers supported can be queried by calling
GetIntegerv with the symbolic constant MAX_DRAW_BUFFERS_ANGLE. An
INVALID_VALUE error is generated if <n> is greater than
MAX_DRAW_BUFFERS_ANGLE.
If the GL is bound to a draw framebuffer object, the <i>th buffer listed
in <bufs> must be COLOR_ATTACHMENT<i>_ANGLE or NONE. Specifying a
buffer out of order, BACK, or COLOR_ATTACHMENT<m>_ANGLE where <m> is
greater than or equal to the value of MAX_COLOR_ATTACHMENTS_ANGLE,
will generate the error INVALID_OPERATION.
If a fragment shader writes to "gl_FragColor", DrawBuffersANGLE
specifies the draw buffer, if any, into which the color written to
"gl_FragColor" is written. If a fragment shader writes to
"gl_FragData", DrawBuffersANGLE specifies a set of draw buffers
into which each of the multiple output colors defined by these
variables 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.
Indicating a buffer or buffers using DrawBuffersANGLE causes
subsequent pixel color value writes to affect the indicated
buffers. If the GL is bound to a draw framebuffer object and a draw
buffer selects an attachment that has no image attached, then that
fragment color is not written.
Specifying NONE as the draw buffer for a fragment color will inhibit
that fragment color from being written.
The state required to handle color buffer selection for each
framebuffer is an integer for each supported fragment color. For the
default framebuffer, in the initial state the draw buffer for
fragment color zero is BACK if there is a default framebuffer
associated with the context, otherwise NONE. For framebuffer
objects, in the initial state the draw buffer for fragment color
zero is COLOR_ATTACHMENT0_ANGLE.
For both the default framebuffer and framebuffer objects, the
initial state of draw buffers for fragment colors other than zero is
NONE.
The value of the draw buffer selected for fragment color <i> can be
queried by calling GetIntegerv with the symbolic constant
DRAW_BUFFER<i>_ANGLE."
Replace the second paragraph of Section 4.4.1 (Binding and Managing
Framebuffer Objects) with the following:
"The namespace for framebuffer objects is the unsigned integers, with
zero reserved by OpenGL ES to refer to the default framebuffer. A
framebuffer object is created by binding an unused name to the
target FRAMEBUFFER, DRAW_FRAMEBUFFER, or READ_FRAMEBUFFER. The binding
is effected by calling
void BindFramebuffer(enum target, uint framebuffer);
with <target> set the desired framebuffer target and <framebuffer> set
to the unused name. The resulting framebuffer object is a new state
vector. There is a number of color attachment points, plus one each
for the depth and stencil attachment points. The number of color attachment
points is equal to the value of MAX_COLOR_ATTACHMENTS_ANGLE."
Replace the third item in the bulleted list in Section 4.4.1 (Binding
and Managing Framebuffer Objects) with the following:
" * The only color buffer bitplanes are the ones defined by the
framebuffer attachments points named COLOR_ATTACHMENT0_ANGLE through
COLOR_ATTACHMENT<n>_ANGLE."
Modify Section 4.4.3 (Renderbuffer Objects) in the
"Attaching Renderbuffer Images to a Framebuffer" subsection as follows:
Insert the following table:
Name of attachment
---------------------------------------
COLOR_ATTACHMENT<i>_ANGLE (see caption)
DEPTH_ATTACHMENT
STENCIL_ATTACHMENT
Table 4.x: Framebuffer attachment points. <i> in COLOR_ATTACHMENT<i>_ANGLE
may range from zero to the value of MAX_COLOR_ATTACHMENTS_ANGLE minus 1.
Modify the third sentence of the paragraph following the definition of
FramebufferRenderbuffer to be as follows:
"<attachment> should be set to one of the attachment points of the
framebuffer listed in Table 4.x."
Modify Section 4.4.3 (Renderbuffer Objects) in the "Attaching Texture
Images to a Framebuffer" subsection as follows:
Modify the last sentence of the paragraph following the definition of
FramebufferTexture2D to be as follows:
"<attachment> must be one of the attachment points of the framebuffer
listed in Table 4.x."
Modify Section 4.4.5 (Framebuffer Completeness) and replace the 3rd
item in the bulleted list in the "Framebuffer Attachment Completeness"
subsection with the following:
" * If <attachment> is COLOR_ATTACHMENT<i>_ANGLE, then <image> must
have a color-renderable internal format."
Changes to Chapter 6 of the OpenGL ES 2.0 Specification (State and
State Requests)
In section 6.1.3 (Enumerated Queries) modify the third sentence in
the definition of GetFramebufferAttachmentParameteriv to be as follows:
"<attachment> must be one of the attachment points of the framebuffer
listed in Table 4.x."
Changes to Chapter 3 of the OpenGL ES Shading Language 1.0.17 Specification (Basics)
Add a new section:
3.4.1 GL_ANGLE_multiple_render_targets Extension
To use the GL_ANGLE_multiple_render_targets extension in a shader it
must be enabled using the #extension directive.
The shading language preprocessor #define
GL_ANGLE_multiple_render_targets will be defined to 1, if the
GL_ANGLE_multiple_render_targets extension is supported.
Dependencies on ANGLE_framebuffer_blit and APPLE_framebuffer_multisample:
If neither ANGLE_framebuffer_blit nor APPLE_framebuffer_multisample are
supported, then all references to "draw framebuffers" should be replaced
with references to "framebuffers". References to DRAW_FRAMEBUFFER_BINDING
should be replaced with references to FRAMEBUFFER_BINDING. References to
DRAW_FRAMEBUFFER and READ_FRAMEBUFFER should be removed.
If ANGLE_framebuffer_blit is supported, DRAW_FRAMEBUFFER_BINDING, DRAW_FRAMEBUFFER
and READ_FRAMEBUFFER all refer to corresponding _ANGLE suffixed names
(they have the same token values).
If APPLE_framebuffer_multisample is supported, DRAW_FRAMEBUFFER_BINDING,
DRAW_FRAMEBUFFER and READ_FRAMEBUFFER all refer to the corresponding _APPLE
suffixed names (they have the same token values).
Errors
The INVALID_OPERATION error is generated if DrawBuffersANGLE is called
when the default framebuffer is bound and any of the following conditions
hold:
- <n> is greater than 1 and less than MAX_DRAW_BUFFERS_ANGLE,
- <bufs> contains a value other than BACK or NONE.
The INVALID_OPERATION error is generated if DrawBuffersANGLE is called
when bound to a draw framebuffer object and any of the following
conditions hold:
- the <i>th value in <bufs> is not COLOR_ATTACHMENT<i>_ANGLE or NONE.
The INVALID_VALUE error is generated if DrawBuffersANGLE is called
with a value of <n> which is greater than MAX_DRAW_BUFFERS_ANGLE.
The INVALID_ENUM error is generated by FramebufferRenderbuffer if
the <attachment> parameter is not one of the values listed in Table 4.x.
The INVALID_ENUM error is generated by FramebufferTexture2D if
the <attachment> parameter is not one of the values listed in Table 4.x.
The INVALID_ENUM error is generated by GetFramebufferAttachmentParameteriv
if the <attachment> parameter is not one of the values listed in Table 4.x.
New State
Add Table 6.X Framebuffer (State per framebuffer object):
State Type Get Command Initial Value Description
--------------- ---- ------------ ------------- -----------
DRAW_BUFFER<i>_ANGLE Z10* GetIntegerv see 4.2.1 Draw buffer selected
for fragment color i
Add to Table 6.18 (Implementation Dependent Values)
Get value Type Get Cmnd Minimum Value Description Sec.
------------------------ ---- ----------- ------------- ----------- -----
MAX_DRAW_BUFFERS_ANGLE Z+ GetIntegerv 1 Maximum number of 4.2.1
active draw buffers
MAX_COLOR_ATTACHMENTS_ANGLE Z+ GetIntegerv 1 Number of framebuffer 4.4.1
color attachment points
Issues
See ARB_draw_buffers for relevant issues.
1) Differences from NV_draw_buffers + NV_fbo_color_attachments?
- adds interactions with blit_framebuffer and separate draw/read binding points
- MAX limits are global instead of per-fbo (see Issue 2)
- no broadcast from gl_FragColor (see Issue 3)
- can be used to with default framebuffer to set NONE/BACK (see Issue 4)
2) Should the MAX_DRAW_BUFFERS_ANGLE and MAX_COLOR_ATTACHMENTS_ANGLE limits
be per-framebuffer values or implementation dependent constants?
DISCUSSION: In ARB_draw_buffers this was per-context (see Issue 2).
EXT_framebuffer_object (and subsequently ARB_framebuffer_object, and GL 3.0
through GL 4.2) made these queries framebuffer-dependent.
However in GL 4.3 and GLES 3.0, these limits were changed from
framebuffer-dependent state to implementation-dependent state after
much discussion (Bug 7990).
NV_draw_buffers has MAX_DRAW_BUFFERS listed as per-framebuffer state,
but NV_fbo_color_attachments has MAX_COLOR_ATTACHMENTS as an
implementation-dependent constant.
This is relevant because some implementations are not able to support
multisampling in conjuction with multiple color attachments. If the
query is per-framebuffer, they can report a maximum of one attachment
when there are multisampled attachments, but a higher limit when only
single-sampled attachments are present.
RESOLVED. Make this global context state as this is most consistent
with GLES 3.0 and updated GL drivers. Unfortunately this means that a
D3D9-based implementation of this extension is not possible since D3D9
does not support multisampled MRTs. Perhaps such an implementation could
report FBO incomplete in this situation, but that seems less than desirable.
3) Should we support broadcast from gl_FragColor to all gl_FragData[x]
or should it be synonymous with gl_FragData[0]?
DISCUSSION: With NV_draw_buffers, writing to gl_FragColor writes to all
the enabled draw buffers (ie broadcast). In OpenGL ES 3.0 when using
ESSL 1.0, gl_FragColor is equivalent to writing a single output to
gl_FragData[0] and multiple outputs are not possible. When using ESSL 3.0,
only user-defined out variables may be used.
If broadcast is supported, some implementations may have to replace
writes to gl_FragColor with replicated writes to all possible gl_FragData
locations when this extension is enabled.
RESOLVED: Broadcast from gl_FragColor to all enabledMRT buffers is not
supported. A shader author must write gl_FragData[x] if they want to use MRT
4) Should we allow DrawBuffersANGLE to be called when the default FBO is bound?
DISCUSSION: NV_draw_buffers specifies that DrawBuffersNV errors with
INVALID_OPERATION when the default FBO is bound. OpenGL ES 3.0 allows
DrawBuffers to toggle between BACK and NONE on the default FBO.
An implementation that does not natively support disabling the drawbuffer
on the default FBO could emulate this by disabling color writes.
RESOLVED: Allow DrawBuffersANGLE to be called for the default FBO. This
is more forward looking and is compatible with ES 3.0.
5) What are the requirements on the color attachment sizes and formats?
RESOLVED: ES 2.0 requires that all color buffers attached to application-
created framebuffer objects must have the same number of bitplanes
(Chapter 4 overview p91). ES 2.0 also requires that all attached images
have the same width and height (Section 4.4.5 Framebuffer Completeness).
This extension does not lift those requirements, and failing to meet
them will result in an incomplete FBO.
Revision History
01/23/2013 dgkoch add resolutions to issues 2-4.
add issue 5.
Add Table 4.x and update various explicit
references to COLOR_ATTACHMENT0.
Add errors.
11/13/2012 dgkoch add revision history
add text from updated ES 3.0 spec
add issues for discussion
10/16/2012 kbr update name string
10/16/2012 kbr remove restrition requiring draw buffer 0 to be non-NULL
10/12/2012 kbr remove references to GetDoublev and ReadBuffer
10/11/2012 kbr initial draft extension