blob: 4a9bed217a1cb08d087346b4b3a8a07be800ac0d [file] [log] [blame]
Erik Dahlströmea7a2122014-11-17 16:15:57 +01001Name
2
3 EXT_shader_framebuffer_fetch
4
5Name Strings
6
7 GL_EXT_shader_framebuffer_fetch
8
9Contact
10
11 Benj Lipchak, Apple (lipchak 'at' apple.com)
12
13Status
14
15 Complete
16
17Version
18
19 Last Modified Date: May 28, 2013
20 Author Revision: 4
21
22Number
23
24 OpenGL ES Extension #122
25
26Dependencies
27
28 OpenGL ES 2.0 is required.
29
30 This specification is written against the OpenGL ES 2.0.24 specification.
31 This extension is written against the OpenGL ES Shading Language 1.0.17
32 specification.
33
34 OpenGL ES 3.0 affects the definition of this extension.
35
36Overview
37
38 Conventional OpenGL blending provides a configurable series of operations
39 that can be used to combine the output values from a fragment shader with
40 the values already in the framebuffer. While these operations are
41 suitable for basic image compositing, other compositing operations or
42 operations that treat fragment output as something other than a color
43 (normals, for instance) may not be expressible without multiple passes or
44 render-to-texture operations.
45
46 This extension provides a mechanism whereby a fragment shader may read
47 existing framebuffer data as input. This can be used to implement
48 compositing operations that would have been inconvenient or impossible with
49 fixed-function blending. It can also be used to apply a function to the
50 framebuffer color, by writing a shader which uses the existing framebuffer
51 color as its only input.
52
53Issues
54
55 1. How is framebuffer data treated during multisample rendering?
56
57 RESOLVED: Reading the value of gl_LastFragData produces a different
58 result for each sample. This implies that all or part of the shader be run
59 once for each sample. Input values to the shader from existing variables
60 in GLSL ES remain identical across samples.
61
62 2. How does the use of gl_LastFragData interact with fragment discard?
63
64 RESOLVED: Hardware may not necessarily support discarding on sample
65 granularity. Therefore, three options were considered for this
66 functionality:
67
68 A) Allow discard based on variables calculated using the framebuffer
69 color when multisample rasterization is disabled, but disallow
70 discard in this manner when multisample rasterization is enabled.
71
72 B) Restrict usage of the framebuffer color until it is known whether
73 or not the pixel will be discarded.
74
75 C) Allow undefined results for fragment shaders that discard on a
76 per-sample basis on hardware that doesn't support it.
77
78 This extension has chosen option C. Restricting orthogonality of fragment
79 shaders between single-sample and multisample rendering is undesirable, as
80 is restricting usage of the framebuffer color, which can generally only be
81 done with detailed flow-control analysis.
82
83 3. What is the precision of gl_LastFragData in practice?
84
85 RESOLVED: Three options were considered for this functionality:
86
87 A) gl_LastFragData is always mediump.
88
89 B) gl_LastFragData takes the precision most closely matching the
90 actual storage format of the framebuffer.
91
92 C) Allow redeclaration of gl_LastFragData in order to change its
93 precision.
94
95 This extension has chosen option C. A fixed precision per option A
96 increases the likelihood of redundant conversion operations in the shader,
97 and option B does not provide for clear behavior with regard to the
98 precision of intermediate results from calculations using the
99 framebuffer color.
100
101 4. How does this extension iteract with conventional blending?
102
103 RESOLVED: There is no interaction. The two remain orthogonal. The rest
104 of the pipeline continues as usual after the fragment shader stage.
105
106
107 5. How does this extension work in ES 3.0?
108
109 RESOLVED: Differently than in ES 2.0.
110
111 The built-in fragment outputs of ES 2.0 are replaced in #version 300 es
112 shaders by user-declared outputs, to accomodate integer and MRT
113 framebuffers. Three options were considered:
114
115 A) Add built-ins similar to gl_LastFragData.
116
117 B) Add a layout to mark user-declared fragment outputs as having
118 defined content on entry to fragment shader.
119
120 C) Allow marking user-declared fragment outputs as "inout".
121
122 This extension has chosen option C. Adding built-ins per option A is
123 unwieldy for MRT framebuffers with mixed attachment types and precisions.
124 Options B and C are semantically identical, but C requires fewer
125 modifications to the specification and to user shaders. Note that the
126 inout qualifier is not allowed for re-declaring existing fragment outputs
127 such as gl_FragDepth.
128
129New Procedures and Functions
130
131 None
132
133New Tokens
134
135 Accepted by the <pname> parameter of GetBooleanv, GetIntegerv, GetFloatv,
136 and GetDoublev:
137
138 FRAGMENT_SHADER_DISCARDS_SAMPLES_EXT 0x8A52
139
140New Builtin Variables
141
142 mediump vec4 gl_LastFragData[gl_MaxDrawBuffers]
143
144Changes to the OpenGL ES 2.0.24 Specification, Chapter 3
145
146 Remove the last sentence of Paragraph 2 of Section 3.8.1, page 84 ("These
147 built-in varying variables include [...]" and add:
148
149 These built-in varying variables include the fragment's position, eye z
150 coordinate, and front-facing flag, as well as the last data or color value
151 written to the framebuffer. When the value of SAMPLE_BUFFERS is 1 and the
152 current framebuffer color is accessed in the fragment shader, the fragment
153 shader will be invoked separately for each covered sample and a separate
154 value for the previous framebuffer color will be provided for each sample."
155
156 Add a new subsection to section 3.8.2, page 87 ("Shader Execution"):
157
158 "Discard
159
160 Fragment shaders may conditionally abandon operations using the discard
161 keyword. However, the ability of hardware to support abandoning operations
162 on a single sample when the shader is invoked once for each covered sample
163 is implementation-dependent. This capability can be determined by calling
164 GetBooleanv with the symbolic constant
165 FRAGMENT_SHADER_DISCARDS_SAMPLES_EXT. If FALSE is returned, results from
166 shaders which discard based on per-sample logic are undefined."
167
168Changes to the OpenGL ES 2.0.24 Specification, Chapter 4
169
170 Replace first element of Figure 4.1, page 90 ("Fragment + Associated Data"):
171
172 "Fragment (or sample) + Associated Data"
173
174New Implementation Dependent State
175
176 Add to table 6.19 (Implementation Dependent Values (cont.)):
177
178 Get Value Type Get Command Minimum Value Description Section
179 --------- ---- ----------- ------------- -------------- -------
180 FRAGMENT_SHADER_DISCARDS_SAMPLES_EXT B GetBooleanv - Samples may be 3.8.2
181 discarded
182 individually
183
184Changes to the OpenGL ES Shading Language 1.0.17 Specification, Chapter 3
185
186 Remove Paragraph 2 of section 3.8, page 17, Identifiers ("Identifiers
187 starting with "gl_" are reserved [...]") and add:
188
189 "Identifiers starting with "gl_" are reserved for use by OpenGL ES, and
190 may not be declared in a shader as either a variable or a function.
191 However, as noted in the specification, certain predeclared "gl_" names
192 are allowed to be redeclared in a shader for the specific purpose of
193 changing their precision qualifier."
194
195Changes to the OpenGL ES Shading Language 1.0.17 Specification, Chapter 7
196
197 Add after the last sentence of Paragraph 2 of Section 7.2, page 60,
198 Fragment Shader Special Variables ("These variables may be written to
199 more [...]"):
200
201 "... To access the existing framebuffer values (e.g., to implement a
202 complex blend operation inside the shader), fragment shaders should use
203 the read-only input array gl_LastFragData. gl_LastFragData returns the
204 value written by the most recent fragment at the same position.
205
206 Access to gl_LastFragData is optional, and must be enabled by
207
208 #extension GL_EXT_shader_framebuffer_fetch : <behavior>
209
210 Where <behavior> is as specified in section 3.3.
211
212 By default, gl_LastFragData is declared with the mediump precision
213 qualifier. This can be changed by redeclaring the corresponding variables
214 with the desired precision qualifier.
215
216 Redeclarations are done as follows
217
218 // Redeclaration that changes nothing is allowed
219 mediump vec4 gl_LastFragData[gl_MaxDrawBuffers];
220
221 // All the following are allowed redeclaration that change behavior
222 lowp vec4 gl_LastFragData[gl_MaxDrawBuffers];
223 highp vec4 gl_LastFragData[gl_MaxDrawBuffers];
224
225 Redeclarations must not otherwise alter the declared type or array size of
226 gl_LastFragData."
227
228Changes to the OpenGL ES Shading Language 3.00.3 Specification, Chapter 4
229
230 Modify Paragraph 2 of section 4.3.6:
231 "Except in the fragment stage, there is not an inout storage qualifier at
232 global scope for declaring a single variable name as both input and output
233 [...]"
234
235 Modify Paragraph 5 of section 4.3.6:
236 "Fragment outputs output per-fragment data and are declared using the out
237 or inout storage qualifier. It is an error to use centroid out or centroid
238 inout in a fragment shader [...]" and append new paragraph:
239
240 "Upon entry to the fragment shader, fragment outputs declared as inout will
241 contain the value written by the most recent fragment at the same position.
242 This behavior, and the ability to use the inout qualifier at global scope
243 in a fragment shader, is optional and must be enabled by
244
245 #extension GL_EXT_shader_framebuffer_fetch : <behavior>
246
247 Where <behavior> is as specified in section 3.4."
248
249Interactions with OES_standard_derivatives
250
251 Results from shaders which use the built-in derivative functions dFdx,
252 dFdy, and fwidth on variables calculated using the current framebuffer
253 color are undefined.
254
255Revision History
256
257 Version 4, 2013/05/28 - Added ES3 interaction as requested in Bug 10236
258 Version 3, 2012/09/24 - Remove obsolete issue 3 about derivatives
259 Version 2, 2012/06/21 - Fix MULTISAMPLE enabled -> SAMPLE_BUFFERS = 1,
260 recast from APPLE to multivendor EXT, clarify that
261 gl_LastFragData reflects value written by previous
262 pixel at same coordinates.
263 Version 1, 2012/06/01 - Conversion from ARB_sync to APPLE_sync for ES.