remove unused413 stuff, glDrawBuffersARB uses that slot now
[mesa.git] / src / mesa / shader / slang_fragment_builtin.gc
1
2 //
3 // TODO:
4 // - implement texture1D, texture2D, texture3D, textureCube,
5 // - implement shadow1D, shadow2D,
6 // - implement dFdx, dFdy,
7 //
8
9 //
10 // From Shader Spec, ver. 1.051
11 //
12 // The output of the fragment shader goes on to be processed by the fixed function operations at
13 // the back end of the OpenGL pipeline. Fragment shaders interface with the back end of the OpenGL
14 // pipeline using the built-in variables gl_FragColor and gl_FragDepth, or by executing the discard
15 // keyword.
16 //
17 // These variables may be written more than once within a fragment shader. If so, the last value
18 // assigned is the one used in the subsequent fixed function pipeline. The values written to these
19 // variables may be read back after writing them. Reading from these variables before writing them
20 // results in an undefined value. The fixed functionality computed depth for a fragment may be
21 // obtained by reading gl_FragCoord.z, described below.
22 //
23 // Writing to gl_FragColor specifies the fragment color that will be used by the subsequent fixed
24 // functionality pipeline. If subsequent fixed functionality consumes fragment color and an
25 // execution of a fragment shader does not write a value to gl_FragColor then the fragment color
26 // consumed is undefined.
27 //
28 // If the frame buffer is configured as a color index buffer then behavior is undefined when using
29 // a fragment shader.
30 //
31 // Writing to gl_FragDepth will establish the depth value for the fragment being processed. If
32 // depth buffering is enabled, and a shader does not write gl_FragDepth, then the fixed function
33 // value for depth will be used as the fragment\92s depth value. If a shader statically assigns
34 // a value to gl_FragDepth, and there is an execution path through the shader that does not set
35 // gl_FragDepth, then the value of the fragment\92s depth may be undefined for some executions of
36 // the shader. That is, if a shader statically writes gl_FragDepth, then it is responsible for
37 // always writing it. There is also no guarantee that a shader can compute the same depth value
38 // as the fixed function value; an implementation will provide invariant results within shaders
39 // computing depth with the same source-level expression, but invariance is not provided between
40 // shaders and fixed functionality.
41 //
42 // Writes to gl_FragColor and gl_FragDepth need not be clamped within a shader. The fixed
43 // functionality pipeline following the fragment shader will clamp these values.
44 //
45 // If a shader executes the discard keyword, the fragment is discarded, and the values of
46 // gl_FragDepth and gl_FragColor become irrelevant.
47 //
48 // The variable gl_FragCoord is available as a read-only variable from within fragment shaders
49 // and it holds the window relative coordinates x, y, z, and 1/w values for the fragment. This
50 // value is the result of the fixed functionality that interpolates primitives after vertex
51 // processing to generate fragments. The z component is the depth value that would be used for
52 // the fragment\92s depth if a shader contained no writes to gl_FragDepth. This is useful for
53 // invariance if a shader conditionally computes gl_FragDepth but otherwise wants the fixed
54 // functionality fragment depth.
55 //
56 // The fragment shader has access to the read-only built-in variable gl_FrontFacing whose value
57 // is true if the fragment belongs to a front-facing primitive. One use of this is to emulate
58 // two-sided lighting by selecting one of two colors calculated by the vertex shader.
59 //
60 // The built-in variables that are accessible from a fragment shader are intrinsically given types
61 // as follows:
62 //
63
64 vec4 gl_FragCoord;
65 bool gl_FrontFacing;
66 vec4 gl_FragColor;
67 float gl_FragDepth;
68
69 //
70 // However, they do not behave like variables with no qualifier; their behavior is as described
71 // above. These built-in variables have global scope.
72 //
73
74 //
75 // Unlike user-defined varying variables, the built-in varying variables don\92t have a strict
76 // one-to-one correspondence between the vertex language and the fragment language. Two sets are
77 // provided, one for each language. Their relationship is described below.
78 //
79 // The following varying variables are available to read from in a fragment shader. The gl_Color
80 // and gl_SecondaryColor names are the same names as attributes passed to the vertex shader.
81 // However, there is no name conflict, because attributes are visible only in vertex shaders
82 // and the following are only visible in a fragment shader.
83 //
84
85 varying vec4 gl_Color;
86 varying vec4 gl_SecondaryColor;
87 varying vec4 gl_TexCoord[]; // at most will be gl_MaxTextureCoordsARB
88 varying float gl_FogFragCoord;
89
90 //
91 // The values in gl_Color and gl_SecondaryColor will be derived automatically by the system from
92 // gl_FrontColor, gl_BackColor, gl_FrontSecondaryColor, and gl_BackSecondaryColor based on which
93 // face is visible. If fixed functionality is used for vertex processing, then gl_FogFragCoord will
94 // either be the z-coordinate of the fragment in eye space, or the interpolation of the fog
95 // coordinate, as described in section 3.10 of the OpenGL 1.4 Specification. The gl_TexCoord[]
96 // values are the interpolated gl_TexCoord[] values from a vertex shader or the texture coordinates
97 // of any fixed pipeline based vertex functionality.
98 //
99 // Indices to the fragment shader gl_TexCoord array are as described above in the vertex shader
100 // text.
101 //
102
103 //
104 // The OpenGL Shading Language defines an assortment of built-in convenience functions for scalar
105 // and vector operations. Many of these built-in functions can be used in more than one type
106 // of shader, but some are intended to provide a direct mapping to hardware and so are available
107 // only for a specific type of shader.
108 //
109 // The built-in functions basically fall into three categories:
110 //
111 // \95 They expose some necessary hardware functionality in a convenient way such as accessing
112 // a texture map. There is no way in the language for these functions to be emulated by a shader.
113 //
114 // \95 They represent a trivial operation (clamp, mix, etc.) that is very simple for the user
115 // to write, but they are very common and may have direct hardware support. It is a very hard
116 // problem for the compiler to map expressions to complex assembler instructions.
117 //
118 // \95 They represent an operation graphics hardware is likely to accelerate at some point. The
119 // trigonometry functions fall into this category.
120 //
121 // Many of the functions are similar to the same named ones in common C libraries, but they support
122 // vector input as well as the more traditional scalar input.
123 //
124 // Applications should be encouraged to use the built-in functions rather than do the equivalent
125 // computations in their own shader code since the built-in functions are assumed to be optimal
126 // (e.g., perhaps supported directly in hardware).
127 //
128 // User code can replace built-in functions with their own if they choose, by simply re-declaring
129 // and defining the same name and argument list.
130 //
131
132 //
133 // Texture Lookup Functions
134 //
135 // Texture lookup functions are available to both vertex and fragment shaders. However, level
136 // of detail is not computed by fixed functionality for vertex shaders, so there are some
137 // differences in operation between vertex and fragment texture lookups. The functions in the table
138 // below provide access to textures through samplers, as set up through the OpenGL API. Texture
139 // properties such as size, pixel format, number of dimensions, filtering method, number of mip-map
140 // levels, depth comparison, and so on are also defined by OpenGL API calls. Such properties are
141 // taken into account as the texture is accessed via the built-in functions defined below.
142 //
143 // If a non-shadow texture call is made to a sampler whose texture has depth comparisons enabled,
144 // then results are undefined. If a shadow texture call is made to a sampler whose texture does not
145 // have depth comparisions enabled, the results are also undefined.
146 //
147 // In all functions below, the bias parameter is optional for fragment shaders. The bias parameter
148 // is not accepted in a vertex shader. For a fragment shader, if bias is present, it is added to
149 // the calculated level of detail prior to performing the texture access operation. If the bias
150 // parameter is not provided, then the implementation automatically selects level of detail:
151 // For a texture that is not mip-mapped, the texture is used directly. If it is mip-mapped and
152 // running in a fragment shader, the LOD computed by the implementation is used to do the texture
153 // lookup. If it is mip-mapped and running on the vertex shader, then the base texture is used.
154 //
155 // The built-ins suffixed with \93Lod\94 are allowed only in a vertex shader. For the \93Lod\94 functions,
156 // lod is directly used as the level of detail.
157 //
158
159 //
160 // Use the texture coordinate coord to do a texture lookup in the 1D texture currently bound
161 // to sampler. For the projective (\93Proj\94) versions, the texture coordinate coord.s is divided by
162 // the last component of coord.
163 //
164 // XXX
165 vec4 texture1D (sampler1D sampler, float coord, float bias) {
166 return vec4 (0.0);
167 }
168 vec4 texture1DProj (sampler1D sampler, vec2 coord, float bias) {
169 return texture1D (sampler, coord.s / coord.t, bias);
170 }
171 vec4 texture1DProj (sampler1D sampler, vec4 coord, float bias) {
172 return texture1D (sampler, coord.s / coord.q, bias);
173 }
174
175 //
176 // Use the texture coordinate coord to do a texture lookup in the 2D texture currently bound
177 // to sampler. For the projective (\93Proj\94) versions, the texture coordinate (coord.s, coord.t) is
178 // divided by the last component of coord. The third component of coord is ignored for the vec4
179 // coord variant.
180 //
181 // XXX
182 vec4 texture2D (sampler2D sampler, vec2 coord, float bias) {
183 return vec4 (0.0);
184 }
185 vec4 texture2DProj (sampler2D sampler, vec3 coord, float bias) {
186 return texture2D (sampler, vec2 (coord.s / coord.p, coord.t / coord.p), bias);
187 }
188 vec4 texture2DProj (sampler2D sampler, vec4 coord, float bias) {
189 return texture2D (sampler, vec2 (coord.s / coord.q, coord.s / coord.q), bias);
190 }
191
192 //
193 // Use the texture coordinate coord to do a texture lookup in the 3D texture currently bound
194 // to sampler. For the projective (\93Proj\94) versions, the texture coordinate is divided by coord.q.
195 //
196 // XXX
197 vec4 texture3D (sampler3D sampler, vec3 coord, float bias) {
198 return vec4 (0.0);
199 }
200 vec4 texture3DProj (sampler3D sampler, vec4 coord, float bias) {
201 return texture3DProj (sampler, vec3 (coord.s / coord.q, coord.t / coord.q, coord.p / coord.q),
202 bias);
203 }
204
205 //
206 // Use the texture coordinate coord to do a texture lookup in the cube map texture currently bound
207 // to sampler. The direction of coord is used to select which face to do a 2-dimensional texture
208 // lookup in, as described in section 3.8.6 in version 1.4 of the OpenGL specification.
209 //
210 // XXX
211 vec4 textureCube (samplerCube sampler, vec3 coord, float bias) {
212 return vec4 (0.0);
213 }
214
215 //
216 // Use texture coordinate coord to do a depth comparison lookup on the depth texture bound
217 // to sampler, as described in section 3.8.14 of version 1.4 of the OpenGL specification. The 3rd
218 // component of coord (coord.p) is used as the R value. The texture bound to sampler must be a
219 // depth texture, or results are undefined. For the projective (\93Proj\94) version of each built-in,
220 // the texture coordinate is divide by coord.q, giving a depth value R of coord.p/coord.q. The
221 // second component of coord is ignored for the \931D\94 variants.
222 //
223 // XXX
224 vec4 shadow1D (sampler1DShadow sampler, vec3 coord, float bias) {
225 return vec4 (0.0);
226 }
227 // XXX
228 vec4 shadow2D (sampler2DShadow sampler, vec3 coord, float bias) {
229 return vec4 (0.0);
230 }
231 vec4 shadow1DProj (sampler1DShadow sampler, vec4 coord, float bias) {
232 return shadow1D (sampler, vec3 (coord.s / coord.q, 0.0, coord.p / coord.q), bias);
233 }
234 vec4 shadow2DProj (sampler2DShadow sampler, vec4 coord, float bias) {
235 return shadow2D (sampler, vec3 (coord.s / coord.q, coord.t / coord.q, coord.p / coord.q), bias);
236 }
237
238 //
239 // Fragment processing functions are only available in shaders intended for use on the fragment
240 // processor. Derivatives may be computationally expensive and/or numerically unstable. Therefore,
241 // an OpenGL implementation may approximate the true derivatives by using a fast but not entirely
242 // accurate derivative computation.
243 //
244 // The expected behavior of a derivative is specified using forward/backward differencing.
245 //
246 // Forward differencing:
247 //
248 // F(x+dx) - F(x) ~ dFdx(x) * dx 1a
249 // dFdx(x) ~ (F(x+dx) - F(x)) / dx 1b
250 //
251 // Backward differencing:
252 //
253 // F(x-dx) - F(x) ~ -dFdx(x) * dx 2a
254 // dFdx(x) ~ (F(x) - F(x-dx)) / dx 2b
255 //
256 // With single-sample rasterization, dx <= 1.0 in equations 1b and 2b. For multi-sample
257 // rasterization, dx < 2.0 in equations 1b and 2b.
258 //
259 // dFdy is approximated similarly, with y replacing x.
260 //
261 // A GL implementation may use the above or other methods to perform the calculation, subject
262 // to the following conditions:
263 //
264 // 1) The method may use piecewise linear approximations. Such linear approximations imply that
265 // higher order derivatives, dFdx(dFdx(x)) and above, are undefined.
266 //
267 // 2) The method may assume that the function evaluated is continuous. Therefore derivatives within
268 // the body of a non-uniform conditional are undefined.
269 //
270 // 3) The method may differ per fragment, subject to the constraint that the method may vary by
271 // window coordinates, not screen coordinates. The invariance requirement described in section
272 // 3.1 of the OpenGL 1.4 specification is relaxed for derivative calculations, because
273 // the method may be a function of fragment location.
274 //
275 // Other properties that are desirable, but not required, are:
276 //
277 // 4) Functions should be evaluated within the interior of a primitive (interpolated, not
278 // extrapolated).
279 //
280 // 5) Functions for dFdx should be evaluated while holding y constant. Functions for dFdy should
281 // be evaluated while holding x constant. However, mixed higher order derivatives, like
282 // dFdx(dFdy(y)) and dFdy(dFdx(x)) are undefined.
283 //
284 // In some implementations, varying degrees of derivative accuracy may be obtained by providing
285 // GL hints (section 5.6 of the OpenGL 1.4 specification), allowing a user to make an image
286 // quality versus speed tradeoff.
287 //
288
289 //
290 // Returns the derivative in x using local differencing for the input argument p.
291 //
292 // XXX
293 float dFdx (float p) {
294 return 0.0;
295 }
296 // XXX
297 vec2 dFdx (vec2 p) {
298 return vec2 (0.0);
299 }
300 // XXX
301 vec3 dFdx (vec3 p) {
302 return vec3 (0.0);
303 }
304 // XXX
305 vec4 dFdx (vec4 p) {
306 return vec4 (0.0);
307 }
308
309 //
310 // Returns the derivative in y using local differencing for the input argument p.
311 //
312 // These two functions are commonly used to estimate the filter width used to anti-alias procedural
313 // textures.We are assuming that the expression is being evaluated in parallel on a SIMD array so
314 // that at any given point in time the value of the function is known at the grid points
315 // represented by the SIMD array. Local differencing between SIMD array elements can therefore
316 // be used to derive dFdx, dFdy, etc.
317 //
318 // XXX
319 float dFdy (float p) {
320 return 0.0;
321 }
322 // XXX
323 vec2 dFdy (vec2 p) {
324 return vec2 (0.0);
325 }
326 // XXX
327 vec3 dFdy (vec3 p) {
328 return vec3 (0.0);
329 }
330 // XXX
331 vec4 dFdy (vec4 p) {
332 return vec4 (0.0);
333 }
334
335 //
336 // Returns the sum of the absolute derivative in x and y using local differencing for the input
337 // argument p, i.e.:
338 //
339 // return = abs (dFdx (p)) + abs (dFdy (p));
340 //
341
342 float fwidth (float p) {
343 return abs (dFdx (p)) + abs (dFdy (p));
344 }
345 vec2 fwidth (vec2 p) {
346 return abs (dFdx (p)) + abs (dFdy (p));
347 }
348 vec3 fwidth (vec3 p) {
349 return abs (dFdx (p)) + abs (dFdy (p));
350 }
351 vec4 fwidth (vec4 p) {
352 return abs (dFdx (p)) + abs (dFdy (p));
353 }
354