mesa: remove feature tests
[mesa.git] / src / mesa / main / texfetch.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 7.7
4 *
5 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
6 * Copyright (c) 2009 VMware, Inc.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26
27 /**
28 * \file texfetch.c
29 *
30 * Texel fetch/store functions
31 *
32 * \author Gareth Hughes
33 */
34
35
36 #include "colormac.h"
37 #include "context.h"
38 #include "texcompress.h"
39 #include "texcompress_fxt1.h"
40 #include "texcompress_s3tc.h"
41 #include "texfetch.h"
42
43
44 /**
45 * Convert an 8-bit sRGB value from non-linear space to a
46 * linear RGB value in [0, 1].
47 * Implemented with a 256-entry lookup table.
48 */
49 static INLINE GLfloat
50 nonlinear_to_linear(GLubyte cs8)
51 {
52 static GLfloat table[256];
53 static GLboolean tableReady = GL_FALSE;
54 if (!tableReady) {
55 /* compute lookup table now */
56 GLuint i;
57 for (i = 0; i < 256; i++) {
58 const GLfloat cs = UBYTE_TO_FLOAT(i);
59 if (cs <= 0.04045) {
60 table[i] = cs / 12.92f;
61 }
62 else {
63 table[i] = (GLfloat) _mesa_pow((cs + 0.055) / 1.055, 2.4);
64 }
65 }
66 tableReady = GL_TRUE;
67 }
68 return table[cs8];
69 }
70
71
72
73 /* Texel fetch routines for all supported formats
74 */
75 #define DIM 1
76 #include "texfetch_tmp.h"
77
78 #define DIM 2
79 #include "texfetch_tmp.h"
80
81 #define DIM 3
82 #include "texfetch_tmp.h"
83
84 /**
85 * Null texel fetch function.
86 *
87 * Have to have this so the FetchTexel function pointer is never NULL.
88 */
89 static void fetch_null_texelf( const struct gl_texture_image *texImage,
90 GLint i, GLint j, GLint k, GLfloat *texel )
91 {
92 (void) texImage; (void) i; (void) j; (void) k;
93 texel[RCOMP] = 0.0;
94 texel[GCOMP] = 0.0;
95 texel[BCOMP] = 0.0;
96 texel[ACOMP] = 0.0;
97 _mesa_warning(NULL, "fetch_null_texelf() called!");
98 }
99
100 static void store_null_texel(struct gl_texture_image *texImage,
101 GLint i, GLint j, GLint k, const void *texel)
102 {
103 (void) texImage;
104 (void) i;
105 (void) j;
106 (void) k;
107 (void) texel;
108 /* no-op */
109 }
110
111
112
113 /**
114 * Table to map MESA_FORMAT_ to texel fetch/store funcs.
115 * XXX this is somewhat temporary.
116 */
117 static struct {
118 GLuint Name;
119 FetchTexelFuncF Fetch1D;
120 FetchTexelFuncF Fetch2D;
121 FetchTexelFuncF Fetch3D;
122 StoreTexelFunc StoreTexel;
123 }
124 texfetch_funcs[MESA_FORMAT_COUNT] =
125 {
126 {
127 MESA_FORMAT_SRGB8,
128 fetch_texel_1d_srgb8,
129 fetch_texel_2d_srgb8,
130 fetch_texel_3d_srgb8,
131 store_texel_srgb8
132 },
133 {
134 MESA_FORMAT_SRGBA8,
135 fetch_texel_1d_srgba8,
136 fetch_texel_2d_srgba8,
137 fetch_texel_3d_srgba8,
138 store_texel_srgba8
139 },
140 {
141 MESA_FORMAT_SARGB8,
142 fetch_texel_1d_sargb8,
143 fetch_texel_2d_sargb8,
144 fetch_texel_3d_sargb8,
145 store_texel_sargb8
146 },
147 {
148 MESA_FORMAT_SL8,
149 fetch_texel_1d_sl8,
150 fetch_texel_2d_sl8,
151 fetch_texel_3d_sl8,
152 store_texel_sl8
153 },
154 {
155 MESA_FORMAT_SLA8,
156 fetch_texel_1d_sla8,
157 fetch_texel_2d_sla8,
158 fetch_texel_3d_sla8,
159 store_texel_sla8
160 },
161 {
162 MESA_FORMAT_RGB_FXT1,
163 NULL,
164 _mesa_fetch_texel_2d_f_rgb_fxt1,
165 NULL,
166 NULL
167 },
168 {
169 MESA_FORMAT_RGBA_FXT1,
170 NULL,
171 _mesa_fetch_texel_2d_f_rgba_fxt1,
172 NULL,
173 NULL
174 },
175 {
176 MESA_FORMAT_RGB_DXT1,
177 NULL,
178 _mesa_fetch_texel_2d_f_rgb_dxt1,
179 NULL,
180 NULL
181 },
182 {
183 MESA_FORMAT_RGBA_DXT1,
184 NULL,
185 _mesa_fetch_texel_2d_f_rgba_dxt1,
186 NULL,
187 NULL
188 },
189 {
190 MESA_FORMAT_RGBA_DXT3,
191 NULL,
192 _mesa_fetch_texel_2d_f_rgba_dxt3,
193 NULL,
194 NULL
195 },
196 {
197 MESA_FORMAT_RGBA_DXT5,
198 NULL,
199 _mesa_fetch_texel_2d_f_rgba_dxt5,
200 NULL,
201 NULL
202 },
203 {
204 MESA_FORMAT_SRGB_DXT1,
205 NULL,
206 _mesa_fetch_texel_2d_f_srgb_dxt1,
207 NULL,
208 NULL
209 },
210 {
211 MESA_FORMAT_SRGBA_DXT1,
212 NULL,
213 _mesa_fetch_texel_2d_f_srgba_dxt1,
214 NULL,
215 NULL
216 },
217 {
218 MESA_FORMAT_SRGBA_DXT3,
219 NULL,
220 _mesa_fetch_texel_2d_f_srgba_dxt3,
221 NULL,
222 NULL
223 },
224 {
225 MESA_FORMAT_SRGBA_DXT5,
226 NULL,
227 _mesa_fetch_texel_2d_f_srgba_dxt5,
228 NULL,
229 NULL
230 },
231 {
232 MESA_FORMAT_RGBA_FLOAT32,
233 fetch_texel_1d_f_rgba_f32,
234 fetch_texel_2d_f_rgba_f32,
235 fetch_texel_3d_f_rgba_f32,
236 store_texel_rgba_f32
237 },
238 {
239 MESA_FORMAT_RGBA_FLOAT16,
240 fetch_texel_1d_f_rgba_f16,
241 fetch_texel_2d_f_rgba_f16,
242 fetch_texel_3d_f_rgba_f16,
243 store_texel_rgba_f16
244 },
245 {
246 MESA_FORMAT_RGB_FLOAT32,
247 fetch_texel_1d_f_rgb_f32,
248 fetch_texel_2d_f_rgb_f32,
249 fetch_texel_3d_f_rgb_f32,
250 store_texel_rgb_f32
251 },
252 {
253 MESA_FORMAT_RGB_FLOAT16,
254 fetch_texel_1d_f_rgb_f16,
255 fetch_texel_2d_f_rgb_f16,
256 fetch_texel_3d_f_rgb_f16,
257 store_texel_rgb_f16
258 },
259 {
260 MESA_FORMAT_ALPHA_FLOAT32,
261 fetch_texel_1d_f_alpha_f32,
262 fetch_texel_2d_f_alpha_f32,
263 fetch_texel_3d_f_alpha_f32,
264 store_texel_alpha_f32
265 },
266 {
267 MESA_FORMAT_ALPHA_FLOAT16,
268 fetch_texel_1d_f_alpha_f16,
269 fetch_texel_2d_f_alpha_f16,
270 fetch_texel_3d_f_alpha_f16,
271 store_texel_alpha_f16
272 },
273 {
274 MESA_FORMAT_LUMINANCE_FLOAT32,
275 fetch_texel_1d_f_luminance_f32,
276 fetch_texel_2d_f_luminance_f32,
277 fetch_texel_3d_f_luminance_f32,
278 store_texel_luminance_f32
279 },
280 {
281 MESA_FORMAT_LUMINANCE_FLOAT16,
282 fetch_texel_1d_f_luminance_f16,
283 fetch_texel_2d_f_luminance_f16,
284 fetch_texel_3d_f_luminance_f16,
285 store_texel_luminance_f16
286 },
287 {
288 MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32,
289 fetch_texel_1d_f_luminance_alpha_f32,
290 fetch_texel_2d_f_luminance_alpha_f32,
291 fetch_texel_3d_f_luminance_alpha_f32,
292 store_texel_luminance_alpha_f32
293 },
294 {
295 MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16,
296 fetch_texel_1d_f_luminance_alpha_f16,
297 fetch_texel_2d_f_luminance_alpha_f16,
298 fetch_texel_3d_f_luminance_alpha_f16,
299 store_texel_luminance_alpha_f16
300 },
301 {
302 MESA_FORMAT_INTENSITY_FLOAT32,
303 fetch_texel_1d_f_intensity_f32,
304 fetch_texel_2d_f_intensity_f32,
305 fetch_texel_3d_f_intensity_f32,
306 store_texel_intensity_f32
307 },
308 {
309 MESA_FORMAT_INTENSITY_FLOAT16,
310 fetch_texel_1d_f_intensity_f16,
311 fetch_texel_2d_f_intensity_f16,
312 fetch_texel_3d_f_intensity_f16,
313 store_texel_intensity_f16
314 },
315 {
316 MESA_FORMAT_DUDV8,
317 fetch_texel_1d_dudv8,
318 fetch_texel_2d_dudv8,
319 fetch_texel_3d_dudv8,
320 NULL
321 },
322 {
323 MESA_FORMAT_SIGNED_RGBA8888,
324 fetch_texel_1d_signed_rgba8888,
325 fetch_texel_2d_signed_rgba8888,
326 fetch_texel_3d_signed_rgba8888,
327 store_texel_signed_rgba8888
328 },
329 {
330 MESA_FORMAT_SIGNED_RGBA8888_REV,
331 fetch_texel_1d_signed_rgba8888_rev,
332 fetch_texel_2d_signed_rgba8888_rev,
333 fetch_texel_3d_signed_rgba8888_rev,
334 store_texel_signed_rgba8888_rev
335 },
336 {
337 MESA_FORMAT_RGBA8888,
338 fetch_texel_1d_f_rgba8888,
339 fetch_texel_2d_f_rgba8888,
340 fetch_texel_3d_f_rgba8888,
341 store_texel_rgba8888
342 },
343 {
344 MESA_FORMAT_RGBA8888_REV,
345 fetch_texel_1d_f_rgba8888_rev,
346 fetch_texel_2d_f_rgba8888_rev,
347 fetch_texel_3d_f_rgba8888_rev,
348 store_texel_rgba8888_rev
349 },
350 {
351 MESA_FORMAT_ARGB8888,
352 fetch_texel_1d_f_argb8888,
353 fetch_texel_2d_f_argb8888,
354 fetch_texel_3d_f_argb8888,
355 store_texel_argb8888
356 },
357 {
358 MESA_FORMAT_ARGB8888_REV,
359 fetch_texel_1d_f_argb8888_rev,
360 fetch_texel_2d_f_argb8888_rev,
361 fetch_texel_3d_f_argb8888_rev,
362 store_texel_argb8888_rev
363 },
364 {
365 MESA_FORMAT_RGB888,
366 fetch_texel_1d_f_rgb888,
367 fetch_texel_2d_f_rgb888,
368 fetch_texel_3d_f_rgb888,
369 store_texel_rgb888
370 },
371 {
372 MESA_FORMAT_BGR888,
373 fetch_texel_1d_f_bgr888,
374 fetch_texel_2d_f_bgr888,
375 fetch_texel_3d_f_bgr888,
376 store_texel_bgr888
377 },
378 {
379 MESA_FORMAT_RGB565,
380 fetch_texel_1d_f_rgb565,
381 fetch_texel_2d_f_rgb565,
382 fetch_texel_3d_f_rgb565,
383 store_texel_rgb565
384 },
385 {
386 MESA_FORMAT_RGB565_REV,
387 fetch_texel_1d_f_rgb565_rev,
388 fetch_texel_2d_f_rgb565_rev,
389 fetch_texel_3d_f_rgb565_rev,
390 store_texel_rgb565_rev
391 },
392 {
393 MESA_FORMAT_ARGB4444,
394 fetch_texel_1d_f_argb4444,
395 fetch_texel_2d_f_argb4444,
396 fetch_texel_3d_f_argb4444,
397 store_texel_argb4444
398 },
399 {
400 MESA_FORMAT_ARGB4444_REV,
401 fetch_texel_1d_f_argb4444_rev,
402 fetch_texel_2d_f_argb4444_rev,
403 fetch_texel_3d_f_argb4444_rev,
404 store_texel_argb4444_rev
405 },
406 {
407 MESA_FORMAT_RGBA5551,
408 fetch_texel_1d_f_rgba5551,
409 fetch_texel_2d_f_rgba5551,
410 fetch_texel_3d_f_rgba5551,
411 store_texel_rgba5551
412 },
413 {
414 MESA_FORMAT_ARGB1555,
415 fetch_texel_1d_f_argb1555,
416 fetch_texel_2d_f_argb1555,
417 fetch_texel_3d_f_argb1555,
418 store_texel_argb1555
419 },
420 {
421 MESA_FORMAT_ARGB1555_REV,
422 fetch_texel_1d_f_argb1555_rev,
423 fetch_texel_2d_f_argb1555_rev,
424 fetch_texel_3d_f_argb1555_rev,
425 store_texel_argb1555_rev
426 },
427 {
428 MESA_FORMAT_AL88,
429 fetch_texel_1d_f_al88,
430 fetch_texel_2d_f_al88,
431 fetch_texel_3d_f_al88,
432 store_texel_al88
433 },
434 {
435 MESA_FORMAT_AL88_REV,
436 fetch_texel_1d_f_al88_rev,
437 fetch_texel_2d_f_al88_rev,
438 fetch_texel_3d_f_al88_rev,
439 store_texel_al88_rev
440 },
441 {
442 MESA_FORMAT_RGB332,
443 fetch_texel_1d_f_rgb332,
444 fetch_texel_2d_f_rgb332,
445 fetch_texel_3d_f_rgb332,
446 store_texel_rgb332
447 },
448 {
449 MESA_FORMAT_A8,
450 fetch_texel_1d_f_a8,
451 fetch_texel_2d_f_a8,
452 fetch_texel_3d_f_a8,
453 store_texel_a8
454 },
455 {
456 MESA_FORMAT_L8,
457 fetch_texel_1d_f_l8,
458 fetch_texel_2d_f_l8,
459 fetch_texel_3d_f_l8,
460 store_texel_l8
461 },
462 {
463 MESA_FORMAT_I8,
464 fetch_texel_1d_f_i8,
465 fetch_texel_2d_f_i8,
466 fetch_texel_3d_f_i8,
467 store_texel_i8
468 },
469 {
470 MESA_FORMAT_CI8,
471 fetch_texel_1d_f_ci8,
472 fetch_texel_2d_f_ci8,
473 fetch_texel_3d_f_ci8,
474 store_texel_ci8
475 },
476 {
477 MESA_FORMAT_YCBCR,
478 fetch_texel_1d_f_ycbcr,
479 fetch_texel_2d_f_ycbcr,
480 fetch_texel_3d_f_ycbcr,
481 store_texel_ycbcr
482 },
483 {
484 MESA_FORMAT_YCBCR_REV,
485 fetch_texel_1d_f_ycbcr_rev,
486 fetch_texel_2d_f_ycbcr_rev,
487 fetch_texel_3d_f_ycbcr_rev,
488 store_texel_ycbcr_rev
489 },
490 {
491 MESA_FORMAT_Z24_S8,
492 fetch_texel_1d_f_z24_s8,
493 fetch_texel_2d_f_z24_s8,
494 fetch_texel_3d_f_z24_s8,
495 store_texel_z24_s8
496 },
497 {
498 MESA_FORMAT_S8_Z24,
499 fetch_texel_1d_f_s8_z24,
500 fetch_texel_2d_f_s8_z24,
501 fetch_texel_3d_f_s8_z24,
502 store_texel_s8_z24
503 },
504 {
505 MESA_FORMAT_Z16,
506 fetch_texel_1d_f_z16,
507 fetch_texel_2d_f_z16,
508 fetch_texel_3d_f_z16,
509 store_texel_z16
510 },
511 {
512 MESA_FORMAT_Z32,
513 fetch_texel_1d_f_z32,
514 fetch_texel_2d_f_z32,
515 fetch_texel_3d_f_z32,
516 store_texel_z32
517 }
518 };
519
520
521 static FetchTexelFuncF
522 _mesa_get_texel_fetch_func(gl_format format, GLuint dims)
523 {
524 FetchTexelFuncF f;
525 GLuint i;
526 /* XXX replace loop with direct table lookup */
527 for (i = 0; i < MESA_FORMAT_COUNT; i++) {
528 if (texfetch_funcs[i].Name == format) {
529 switch (dims) {
530 case 1:
531 f = texfetch_funcs[i].Fetch1D;
532 break;
533 case 2:
534 f = texfetch_funcs[i].Fetch2D;
535 break;
536 case 3:
537 f = texfetch_funcs[i].Fetch3D;
538 break;
539 }
540 if (!f)
541 f = fetch_null_texelf;
542 return f;
543 }
544 }
545 return NULL;
546 }
547
548
549 StoreTexelFunc
550 _mesa_get_texel_store_func(gl_format format)
551 {
552 GLuint i;
553 /* XXX replace loop with direct table lookup */
554 for (i = 0; i < MESA_FORMAT_COUNT; i++) {
555 if (texfetch_funcs[i].Name == format) {
556 if (texfetch_funcs[i].StoreTexel)
557 return texfetch_funcs[i].StoreTexel;
558 else
559 return store_null_texel;
560 }
561 }
562 return NULL;
563 }
564
565
566
567 /**
568 * Adaptor for fetching a GLchan texel from a float-valued texture.
569 */
570 static void
571 fetch_texel_float_to_chan(const struct gl_texture_image *texImage,
572 GLint i, GLint j, GLint k, GLchan *texelOut)
573 {
574 GLfloat temp[4];
575 GLenum baseFormat = _mesa_get_format_base_format(texImage->TexFormat);
576
577 ASSERT(texImage->FetchTexelf);
578 texImage->FetchTexelf(texImage, i, j, k, temp);
579 if (baseFormat == GL_DEPTH_COMPONENT ||
580 baseFormat == GL_DEPTH_STENCIL_EXT) {
581 /* just one channel */
582 UNCLAMPED_FLOAT_TO_CHAN(texelOut[0], temp[0]);
583 }
584 else {
585 /* four channels */
586 UNCLAMPED_FLOAT_TO_CHAN(texelOut[0], temp[0]);
587 UNCLAMPED_FLOAT_TO_CHAN(texelOut[1], temp[1]);
588 UNCLAMPED_FLOAT_TO_CHAN(texelOut[2], temp[2]);
589 UNCLAMPED_FLOAT_TO_CHAN(texelOut[3], temp[3]);
590 }
591 }
592
593
594 #if 0
595 /**
596 * Adaptor for fetching a float texel from a GLchan-valued texture.
597 */
598 static void
599 fetch_texel_chan_to_float(const struct gl_texture_image *texImage,
600 GLint i, GLint j, GLint k, GLfloat *texelOut)
601 {
602 GLchan temp[4];
603 GLenum baseFormat = _mesa_get_format_base_format(texImage->TexFormat);
604
605 ASSERT(texImage->FetchTexelc);
606 texImage->FetchTexelc(texImage, i, j, k, temp);
607 if (baseFormat == GL_DEPTH_COMPONENT ||
608 baseFormat == GL_DEPTH_STENCIL_EXT) {
609 /* just one channel */
610 texelOut[0] = CHAN_TO_FLOAT(temp[0]);
611 }
612 else {
613 /* four channels */
614 texelOut[0] = CHAN_TO_FLOAT(temp[0]);
615 texelOut[1] = CHAN_TO_FLOAT(temp[1]);
616 texelOut[2] = CHAN_TO_FLOAT(temp[2]);
617 texelOut[3] = CHAN_TO_FLOAT(temp[3]);
618 }
619 }
620 #endif
621
622
623 /**
624 * Initialize the texture image's FetchTexelc and FetchTexelf methods.
625 */
626 void
627 _mesa_set_fetch_functions(struct gl_texture_image *texImage, GLuint dims)
628 {
629 ASSERT(dims == 1 || dims == 2 || dims == 3);
630 ASSERT(texImage->TexFormat);
631
632 if (!texImage->FetchTexelf) {
633 texImage->FetchTexelf =
634 _mesa_get_texel_fetch_func(texImage->TexFormat, dims);
635 }
636
637 /* now check if we need to use a float/chan adaptor */
638 if (!texImage->FetchTexelc) {
639 texImage->FetchTexelc = fetch_texel_float_to_chan;
640 }
641
642 ASSERT(texImage->FetchTexelc);
643 ASSERT(texImage->FetchTexelf);
644 }