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