blob: 4a9bed217a1cb08d087346b4b3a8a07be800ac0d [file] [log] [blame]
Name
EXT_shader_framebuffer_fetch
Name Strings
GL_EXT_shader_framebuffer_fetch
Contact
Benj Lipchak, Apple (lipchak 'at' apple.com)
Status
Complete
Version
Last Modified Date: May 28, 2013
Author Revision: 4
Number
OpenGL ES Extension #122
Dependencies
OpenGL ES 2.0 is required.
This specification is written against the OpenGL ES 2.0.24 specification.
This extension is written against the OpenGL ES Shading Language 1.0.17
specification.
OpenGL ES 3.0 affects the definition of this extension.
Overview
Conventional OpenGL blending provides a configurable series of operations
that can be used to combine the output values from a fragment shader with
the values already in the framebuffer. While these operations are
suitable for basic image compositing, other compositing operations or
operations that treat fragment output as something other than a color
(normals, for instance) may not be expressible without multiple passes or
render-to-texture operations.
This extension provides a mechanism whereby a fragment shader may read
existing framebuffer data as input. This can be used to implement
compositing operations that would have been inconvenient or impossible with
fixed-function blending. It can also be used to apply a function to the
framebuffer color, by writing a shader which uses the existing framebuffer
color as its only input.
Issues
1. How is framebuffer data treated during multisample rendering?
RESOLVED: Reading the value of gl_LastFragData produces a different
result for each sample. This implies that all or part of the shader be run
once for each sample. Input values to the shader from existing variables
in GLSL ES remain identical across samples.
2. How does the use of gl_LastFragData interact with fragment discard?
RESOLVED: Hardware may not necessarily support discarding on sample
granularity. Therefore, three options were considered for this
functionality:
A) Allow discard based on variables calculated using the framebuffer
color when multisample rasterization is disabled, but disallow
discard in this manner when multisample rasterization is enabled.
B) Restrict usage of the framebuffer color until it is known whether
or not the pixel will be discarded.
C) Allow undefined results for fragment shaders that discard on a
per-sample basis on hardware that doesn't support it.
This extension has chosen option C. Restricting orthogonality of fragment
shaders between single-sample and multisample rendering is undesirable, as
is restricting usage of the framebuffer color, which can generally only be
done with detailed flow-control analysis.
3. What is the precision of gl_LastFragData in practice?
RESOLVED: Three options were considered for this functionality:
A) gl_LastFragData is always mediump.
B) gl_LastFragData takes the precision most closely matching the
actual storage format of the framebuffer.
C) Allow redeclaration of gl_LastFragData in order to change its
precision.
This extension has chosen option C. A fixed precision per option A
increases the likelihood of redundant conversion operations in the shader,
and option B does not provide for clear behavior with regard to the
precision of intermediate results from calculations using the
framebuffer color.
4. How does this extension iteract with conventional blending?
RESOLVED: There is no interaction. The two remain orthogonal. The rest
of the pipeline continues as usual after the fragment shader stage.
5. How does this extension work in ES 3.0?
RESOLVED: Differently than in ES 2.0.
The built-in fragment outputs of ES 2.0 are replaced in #version 300 es
shaders by user-declared outputs, to accomodate integer and MRT
framebuffers. Three options were considered:
A) Add built-ins similar to gl_LastFragData.
B) Add a layout to mark user-declared fragment outputs as having
defined content on entry to fragment shader.
C) Allow marking user-declared fragment outputs as "inout".
This extension has chosen option C. Adding built-ins per option A is
unwieldy for MRT framebuffers with mixed attachment types and precisions.
Options B and C are semantically identical, but C requires fewer
modifications to the specification and to user shaders. Note that the
inout qualifier is not allowed for re-declaring existing fragment outputs
such as gl_FragDepth.
New Procedures and Functions
None
New Tokens
Accepted by the <pname> parameter of GetBooleanv, GetIntegerv, GetFloatv,
and GetDoublev:
FRAGMENT_SHADER_DISCARDS_SAMPLES_EXT 0x8A52
New Builtin Variables
mediump vec4 gl_LastFragData[gl_MaxDrawBuffers]
Changes to the OpenGL ES 2.0.24 Specification, Chapter 3
Remove the last sentence of Paragraph 2 of Section 3.8.1, page 84 ("These
built-in varying variables include [...]" and add:
These built-in varying variables include the fragment's position, eye z
coordinate, and front-facing flag, as well as the last data or color value
written to the framebuffer. When the value of SAMPLE_BUFFERS is 1 and the
current framebuffer color is accessed in the fragment shader, the fragment
shader will be invoked separately for each covered sample and a separate
value for the previous framebuffer color will be provided for each sample."
Add a new subsection to section 3.8.2, page 87 ("Shader Execution"):
"Discard
Fragment shaders may conditionally abandon operations using the discard
keyword. However, the ability of hardware to support abandoning operations
on a single sample when the shader is invoked once for each covered sample
is implementation-dependent. This capability can be determined by calling
GetBooleanv with the symbolic constant
FRAGMENT_SHADER_DISCARDS_SAMPLES_EXT. If FALSE is returned, results from
shaders which discard based on per-sample logic are undefined."
Changes to the OpenGL ES 2.0.24 Specification, Chapter 4
Replace first element of Figure 4.1, page 90 ("Fragment + Associated Data"):
"Fragment (or sample) + Associated Data"
New Implementation Dependent State
Add to table 6.19 (Implementation Dependent Values (cont.)):
Get Value Type Get Command Minimum Value Description Section
--------- ---- ----------- ------------- -------------- -------
FRAGMENT_SHADER_DISCARDS_SAMPLES_EXT B GetBooleanv - Samples may be 3.8.2
discarded
individually
Changes to the OpenGL ES Shading Language 1.0.17 Specification, Chapter 3
Remove Paragraph 2 of section 3.8, page 17, Identifiers ("Identifiers
starting with "gl_" are reserved [...]") and add:
"Identifiers starting with "gl_" are reserved for use by OpenGL ES, and
may not be declared in a shader as either a variable or a function.
However, as noted in the specification, certain predeclared "gl_" names
are allowed to be redeclared in a shader for the specific purpose of
changing their precision qualifier."
Changes to the OpenGL ES Shading Language 1.0.17 Specification, Chapter 7
Add after the last sentence of Paragraph 2 of Section 7.2, page 60,
Fragment Shader Special Variables ("These variables may be written to
more [...]"):
"... To access the existing framebuffer values (e.g., to implement a
complex blend operation inside the shader), fragment shaders should use
the read-only input array gl_LastFragData. gl_LastFragData returns the
value written by the most recent fragment at the same position.
Access to gl_LastFragData is optional, and must be enabled by
#extension GL_EXT_shader_framebuffer_fetch : <behavior>
Where <behavior> is as specified in section 3.3.
By default, gl_LastFragData is declared with the mediump precision
qualifier. This can be changed by redeclaring the corresponding variables
with the desired precision qualifier.
Redeclarations are done as follows
// Redeclaration that changes nothing is allowed
mediump vec4 gl_LastFragData[gl_MaxDrawBuffers];
// All the following are allowed redeclaration that change behavior
lowp vec4 gl_LastFragData[gl_MaxDrawBuffers];
highp vec4 gl_LastFragData[gl_MaxDrawBuffers];
Redeclarations must not otherwise alter the declared type or array size of
gl_LastFragData."
Changes to the OpenGL ES Shading Language 3.00.3 Specification, Chapter 4
Modify Paragraph 2 of section 4.3.6:
"Except in the fragment stage, there is not an inout storage qualifier at
global scope for declaring a single variable name as both input and output
[...]"
Modify Paragraph 5 of section 4.3.6:
"Fragment outputs output per-fragment data and are declared using the out
or inout storage qualifier. It is an error to use centroid out or centroid
inout in a fragment shader [...]" and append new paragraph:
"Upon entry to the fragment shader, fragment outputs declared as inout will
contain the value written by the most recent fragment at the same position.
This behavior, and the ability to use the inout qualifier at global scope
in a fragment shader, is optional and must be enabled by
#extension GL_EXT_shader_framebuffer_fetch : <behavior>
Where <behavior> is as specified in section 3.4."
Interactions with OES_standard_derivatives
Results from shaders which use the built-in derivative functions dFdx,
dFdy, and fwidth on variables calculated using the current framebuffer
color are undefined.
Revision History
Version 4, 2013/05/28 - Added ES3 interaction as requested in Bug 10236
Version 3, 2012/09/24 - Remove obsolete issue 3 about derivatives
Version 2, 2012/06/21 - Fix MULTISAMPLE enabled -> SAMPLE_BUFFERS = 1,
recast from APPLE to multivendor EXT, clarify that
gl_LastFragData reflects value written by previous
pixel at same coordinates.
Version 1, 2012/06/01 - Conversion from ARB_sync to APPLE_sync for ES.