| 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. |