blob: 8ef024018e29ac27a548e1df4619715247c091eb [file] [log] [blame]
Name
EXT_multiview_draw_buffers
Name Strings
GL_EXT_multiview_draw_buffers
Contributors
Acorn Pooley, NVIDIA
Greg Roth, NVIDIA
Maurice Ribble, Qualcomm
Contact
Greg Roth (groth 'at' nvidia.com)
Version
Version 3, Sept 03, 2011
Number
OpenGL ES Extension #125
Status
Complete
Dependencies
Written against the OpenGL ES 2.0 Specification
NV_draw_buffers affects the definition of this extension.
OpenGL ES 3.0 affects the definition of this extension.
Overview
This extension allows selecting among draw buffers as the
rendering target. This may be among multiple primary buffers
pertaining to platform-specific stereoscopic or multiview displays
or among offscreen framebuffer object color attachments.
To remove any artificial limitations imposed on the number of
possible buffers, draw buffers are identified not as individual
enums, but as pairs of values consisting of an enum representing
buffer locations such as COLOR_ATTACHMENT_EXT or MULTIVIEW_EXT,
and an integer representing an identifying index of buffers of this
location. These (location, index) pairs are used to specify draw
buffer targets using a new DrawBuffersIndexedEXT call.
Rendering to buffers of location MULTIVIEW_EXT associated with the
context allows rendering to multiview buffers created by EGL using
EGL_EXT_multiview_window for stereoscopic displays.
Rendering to COLOR_ATTACHMENT_EXT buffers allows implementations to
increase the number of potential color attachments indefinitely to
renderbuffers and textures.
This extension allows the traditional quad buffer stereoscopic
rendering method that has proven effective by indicating a left or
right draw buffer and rendering to each accordingly, but is also
dynamic enough to handle an arbitrary number of color buffer targets
all using the same shader. This grants the user maximum flexibility
as well as a familiar interface.
New Procedures and Functions
void ReadBufferIndexedEXT(enum src, int index);
void DrawBuffersIndexedEXT(int n, const enum *location,
const int *indices);
void GetIntegeri_vEXT(enum target, uint index, int *data);
New Tokens
Accepted by the <location> parameter of DrawBuffersIndexedEXT:
COLOR_ATTACHMENT_EXT 0x90F0
MULTIVIEW_EXT 0x90F1
Accepted by the <target> parameter of GetIntegeri_EXT:
DRAW_BUFFER_EXT 0x0C01
READ_BUFFER_EXT 0x0C02
Accepted by the <target> parameter of GetInteger:
MAX_MULTIVIEW_BUFFERS_EXT 0x90F2
Changes to Chapter 4 of the OpenGL ES 2.0 Specification (Per-Fragment
Operations and the Frame Buffer)
Modify section 4.2.1, "Selecting a Buffer for Writing"
Change first paragraph to:
By default, color values are written into the front buffer for
single buffered contexts or into the back buffer for back buffered
contexts as determined when creating the GL context. To control
the color buffer into which each of the fragment color values is
written, DrawBuffersNV or DrawBuffersIndexedEXT is used.
Add to the end of 4.2.1:
The command
void DrawBuffersIndexedEXT(sizei n, const enum *locations,
const int *indices);
defines the draw buffers to which all fragment colors are written.
<n> specifies the number of values in <locations> and <indices>.
<locations> is a pointer to an array of symbolic constants
specifying the location of the draw buffer. <indices> is a pointer
to an array of integer values specifying the index of the draw
buffer. Together <locations> and <indices> specify the draw buffer
to which each fragment color is written.
Each constant in <locations> must be MULTIVIEW_EXT, COLOR_-
ATTACHMENT_EXT, or NONE. Otherwise, an INVALID_ENUM error is
generated. Further, acceptable values for the constants in
<locations> depend on whether the GL is using the default
framebuffer (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 each of the
location constants must be MULTIVIEW_EXT or NONE.
If the GL is bound to a framebuffer object, then each of the
location constants must be COLOR_ATTACHMENT_EXT or NONE.
Where the constant in <locations> is MULTIVIEW_EXT, the
corresponding value in <indices> must be a value from 0 through
MAX_MULTIVIEW_BUFFERS_EXT. Where the constant in <locations> is
COLOR_ATTACHMENT_EXT, the value in <indices> must be a value from 0
through MAX_COLOR_ATTACHMENTS_NV. Otherwise, an INVALID_OPERATION
error is generated. Where the constant in <locations> is NONE, the
value in <indices> is ignored.
For monoscopic rendering, the only available view is index 0. For
stereoscopic rendering, view index 0 corresponds to the left buffer
and view index 1 corresponds to the right buffer.
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.
Except for where the constant in <locations> is NONE, a buffer may
not be specified more than once by the arrays pointed to by
<locations> and <indices>. Specifying a buffer more than once will
result in the error INVALID_OPERATION.
If a fragment shader writes to "gl_FragColor", DrawBuffersIndexedEXT
specifies a set of draw buffers into which the color written to
"gl_FragColor" is written. If a fragment shader writes to
gl_FragData, DrawBuffersIndexedEXT 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 DrawBuffersIndexedEXT causes
subsequent pixel color value writes to affect the indicated
buffers. If more than one color buffer is selected for drawing,
blending is computed and applied independently for each buffer.
Specifying NONE in the <locations> array for a fragment color will
inhibit that fragment color from being written to any buffer.
Monoscopic surfaces include only left buffers, while stereoscopic
surfaces include a left and a right buffer, and multiview surfaces
include more than 1 buffer (a stereoscopic surface is a multiview
surface with 2 buffers). The type of surface is selected at EGL
surface initialization.
The state required to handle color buffer selection is two integers
for each supported fragment color for each framebuffer or
framebuffer object. For the default framebuffer, the initial state
of the draw buffer location for fragment color zero is MULTIVIEW_EXT
and the index is 0. For framebuffer objects, the initial state of
the draw buffer location for fragment color zero is COLOR_-
ATTACHMENT_EXT and the index is 0. The initial state of draw buffers
for fragment colors other than zero is NONE.
The color buffer location and index to which fragment colors are
written for an output color index <i> can be queried by calling
GetIntegeri_vEXT with <target> DRAW_BUFFER_EXT and index
<i>. This returns a pair of values representing the draw buffer
location and index. The number of multiview buffers available to a
GL context can be queried by calling GetIntegerv with <target>
MAX_MULTIVIEW_BUFFERS_EXT.
Section 4.3.1 (Reading Pixels), subsection "Obtaining Pixels from
the Framebuffer" add:
For color formats, the read buffer from which values are obtained is
one of the color buffers; the selection of color buffer is
controlled with ReadBufferIndexedEXT.
The command
void ReadBufferIndexedEXT(enum location, int index);
takes a symbolic constant and integer pair to select the color
buffer from which color values are obtained. <location> must be one
of MULTIVIEW_EXT, COLOR_ATTACHMENT_EXT, or NONE. Otherwise, an
INVALID_ENUM error is generated. If <location> is MULTIVIEW_EXT,
<index> must be a value from 0 through MAX_MULTIVIEW_BUFFERS_EXT.
If <location> is COLOR_ATTACHMENT_EXT, <index> must be a value from
0 through MAX_COLOR_ATTACHMENTS_NV. Otherwise, an INVALID_OPERATION
error is generated. If <location> is NONE, <index> is ignored.
The acceptable values for <location> depend on whether the GL is
using the default framebuffer (i.e. FRAMEBUFFER_BINDING is zero), or
a framebuffer object (i.e. FRAMEBUFFER_BINDING is non-zero). For
more information about framebuffer objects, see section 4.4.
If the object bound to FRAMEBUFFER_BINDING is not framebuffer
complete (as defined in section 4.4.5), then ReadPixels generates
the error INVALID_FRAMEBUFFER_OPERATION. If <location> is a constant
that is neither legal for the default framebuffer, nor legal for a
framebuffer object, then the error INVALID_ENUM results.
When FRAMEBUFFER_BINDING is zero, i.e. the default framebuffer,
<location> must be MULTIVIEW_EXT or NONE. If the buffer indicated by
<index> is missing, the error INVALID_OPERATION is generated. For
the default framebuffer, the initial setting for READ_BUFFER_EXT is
<location> of MULTIVIEW_EXT and <index> of zero.
When the GL is using a framebuffer object, <location> must be NONE
or COLOR_ATTACHMENT_EXT. Specifying COLOR_ATTACHMENT_EXT enables
reading from the image attached to the framebuffer at COLOR_-
ATTACHMENT<index>_NV. For framebuffer objects, the initial setting
for READ_BUFFER_EXT is <location> of COLOR_ATTACHMENT_EXT and
<index> of zero.
ReadPixels generates an INVALID_OPERATION error if it attempts to
select a color buffer while READ_BUFFER_EXT is none.
Changes to chapter 6
Add to section 6.1.1, "Simple Queries" before description of
IsEnabled:
Indexed simple state variables are queried with the command
void GetIntegeri_vEXT(enum target, uint index, int* data);
<target> is the name of the indexed state and <index> is the
index of the particular element being queried. <data> is a
pointer to a scalar or array of the indicated type in which
to place the returned data. An INVALID_VALUE error is generated
if <index> is outside the valid range for the indexed state
<target>.
Changes to Chapter 3 of the OpenGL Shading Language 1.0 Specification
(Basics)
Add a new section:
3.4.1 GL_EXT_multiview_draw_buffers Extension
To use the GL_EXT_multiview_draw_buffers extension in a shader it
must be enabled using the #extension directive.
The shading language preprocessor #define GL_EXT_multiview_draw_-
buffers will be defined to 1, if the GL_EXT_multiview_draw_buffers
extension is supported.
Dependencies on NV_draw_buffers:
If NV_draw_buffers is not supported and OpenGL ES 3 is, add to the
description of DrawBuffersIndexedEXT:
The <i>th index listed in <indices> must be <i> or NONE.
Specifying a buffer out of order will generate the error
INVALID_OPERATION.
If neither NV_draw_buffers nor OpenGL ES 3 is supported, all
references to DrawBuffersNV and color attachments are removed. The
following is substituted for the above changes to Chapter 4 (Per-
Fragment Operations and the Frame Buffer):
Change section 4.2.1, "Selecting a Buffer for Writing"
Change first paragraph to:
By default, color values are written into the front buffer for
single buffered contexts or into the back buffer for back buffered
contexts as determined when creating the GL context. To control
the color buffer into which each of the fragment color values is
written, DrawBuffersIndexedEXT is used.
Add to the end of 4.2.1:
The command
void DrawBuffersIndexedEXT(sizei n, const enum *locations,
const int *indices);
defines the draw buffers to which all fragment colors are written.
<n> specifies the number of values in <locations> and <indices>.
<locations> is a pointer to an array of symbolic constants
specifying the location of the draw buffer. <indices> is a pointer
to an array of integer values specifying the index of the draw
buffer. Together <locations> and <indices> specify the draw buffer
to which each fragment color is written.
Each constant in <locations> must be MULTIVIEW_EXT or NONE.
Otherwise, an INVALID_ENUM error is generated.
DrawBuffersIndexedEXT generates an INVALID_OPERATION error if the GL
is bound to a framebuffer object.
Where the constant in <locations> is MULTIVIEW_EXT, the
corresponding value in <indices> must be a value from 0 through
MAX_MULTIVIEW_BUFFERS_EXT. Otherwise, an INVALID_OPERATION error is
generated. Where the constant in <locations> is NONE, the value
in <indices> is ignored.
An INVALID_VALUE error is generated if <n> is not 1.
For monoscopic rendering, the only available view is index 0. For
stereoscopic rendering, view index 0 is left and view index 1 is
right.
If a fragment shader writes to "gl_FragColor" or "gl_FragData[0]",
DrawBuffersIndexedEXT specifies a set of draw buffers into which the
output color is written. If a fragment shader writes to neither
gl_FragColor nor gl_FragData[0], the values of the fragment colors
following shader execution are undefined, and may differ for each
fragment color.
Indicating a buffer using DrawBuffersIndexedEXT causes subsequent
pixel color value writes to affect the indicated buffer.
Specifying NONE in the <locations> array for a fragment color will
inhibit that fragment color from being written to any buffer.
Monoscopic surfaces include only left buffers, while stereoscopic
surfaces include a left and a right buffer, and multiview surfaces
include more than 1 buffer (a stereoscopic surface is a multiview
surface with 2 buffers). The type of surface is selected at EGL
surface initialization.
The state required to handle color buffer selection is two integers
for the fragment color output for each framebuffer or framebuffer
object. For the default framebuffer, the initial state of the draw
buffer location for fragment color zero is MULTIVIEW_EXT and the
index is 0. For framebuffer objects, the initial state of the draw
buffer location for fragment color zero is COLOR_ATTACHMENT_EXT and
the index is 0.
The color buffer location and index to which fragment colors are
written can be queried by calling GetIntegeri_vEXT with <target>
DRAW_BUFFER_EXT and index 0. This returns a pair of values
representing the draw buffer location and index. The number of
multiview buffers available to a GL context can be queried by
calling GetIntegerv with <target> MAX_MULTIVIEW_BUFFERS_EXT.
The command
void ReadBufferIndexedEXT(enum location, int index);
takes a symbolic constant and integer pair to select the color
buffer from which color values are obtained. <location> must be
MULTIVIEW_EXT or NONE. Otherwise, an INVALID_ENUM error is
generated. If <location> is MULTIVIEW_EXT, <index> must be a value
from 0 through MAX_MULTIVIEW_BUFFERS_EXT. Otherwise, an
INVALID_OPERATION error is generated. If <location> is NONE, the
<index> is ignored.
When FRAMEBUFFER_BINDING is zero, i.e. the default framebuffer,
<location> must be MULTIVIEW_EXT or NONE. If the buffer indicated by
<index> is missing, the error INVALID_OPERATION is generated. For
the default framebuffer, the initial setting for READ_BUFFER_EXT is
<location> of MULTIVIEW_EXT and <index> of zero.
ReadBufferIndexedEXT generates an INVALID_OPERATION error if the GL
is bound to a framebuffer object.
ReadPixels generates an INVALID_OPERATION error if it attempts to
select a color buffer while READ_BUFFER_EXT is none.
New State
Add the new Table 6.X "Framebuffer (State per framebuffer object)" :
State Type Get Command Initial Description
--------------- ----- --------------- ------- -----------
DRAW_BUFFER_EXT nxZ+ GetIntegeri_vEXT See 4.2.1 Multiview draw buffer
location and index
selected for the
specified color output
READ_BUFFER_EXT nxZ+ GetInteger See 4.3.1 Read source buffer
location and index
Add the new Table 6.X "Framebuffer Dependent Values" :
State Type Get Command Min Value Description
--------------- ----- --------------- --------- -----------
MAX_MULTIVIEW_BUFFERS_EXT Z+ GetIntegerv 1 Number of multiview
draw buffers
Issues
1. What should this extension be called?
RESOLVED: multiview_draw_buffers. Multiview has come to be the
standard term to refer to stereoscopic and beyond buffer rendering
and this approach centers around the traditional usage of
a drawbuffers call to specify the buffer(s) to render to.
2. How should draw buffer bindings be queried?
RESOLVED: A new indexed integer query function called
glGetIntegeri_vEXT. This extension adds an indexed binding for draw
buffers so it follows that an indexed query should be used to
retrieve the state that it sets. The name glGetIntegeri_vEXT is
chosen as it was in desktop GL to clarify the 'i' suffix
indicating an indexed call as opposed to 'i' indicating an integer
variant of a call accepting parameters of various types.
3. Should the <location> parameter of DrawBuffersIndexedEXT be removed?
RESOLVED: No. It is useful when draw_buffers is supported.
Revision History
Version 4, 25 Sept 2012 Clean up overview. Fix a few typographical
errors.
Version 3, 03 Sept 2011 EXTify. Remove ALL broadcast.
Add interactions for ES3 and non-
draw_buffers cases
Version 2, 02 Aug 2011 Responses to feedback.
Version 1, 14 April 2011 First draft.