mesa: remove #include "mfeatures.h" from numerous source files
[mesa.git] / src / mesa / main / texcompress_rgtc.c
1 /*
2 * Copyright (C) 2011 Red Hat Inc.
3 *
4 * block compression parts are:
5 * Copyright (C) 2004 Roland Scheidegger All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the next
15 * paragraph) shall be included in all copies or substantial portions of the
16 * Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 * DEALINGS IN THE SOFTWARE.
25 *
26 * Author:
27 * Dave Airlie
28 */
29
30 /**
31 * \file texcompress_rgtc.c
32 * GL_EXT_texture_compression_rgtc support.
33 */
34
35
36 #include "glheader.h"
37 #include "imports.h"
38 #include "colormac.h"
39 #include "image.h"
40 #include "macros.h"
41 #include "mipmap.h"
42 #include "texcompress.h"
43 #include "texcompress_rgtc.h"
44 #include "texstore.h"
45
46
47 #define RGTC_DEBUG 0
48
49 static void unsigned_encode_rgtc_ubyte(GLubyte *blkaddr, GLubyte srccolors[4][4],
50 GLint numxpixels, GLint numypixels);
51 static void signed_encode_rgtc_ubyte(GLbyte *blkaddr, GLbyte srccolors[4][4],
52 GLint numxpixels, GLint numypixels);
53
54 static void unsigned_fetch_texel_rgtc(unsigned srcRowStride, const GLubyte *pixdata,
55 unsigned i, unsigned j, GLubyte *value, unsigned comps);
56
57 static void signed_fetch_texel_rgtc(unsigned srcRowStride, const GLbyte *pixdata,
58 unsigned i, unsigned j, GLbyte *value, unsigned comps);
59
60 static void extractsrc_u( GLubyte srcpixels[4][4], const GLubyte *srcaddr,
61 GLint srcRowStride, GLint numxpixels, GLint numypixels, GLint comps)
62 {
63 GLubyte i, j;
64 const GLubyte *curaddr;
65 for (j = 0; j < numypixels; j++) {
66 curaddr = srcaddr + j * srcRowStride * comps;
67 for (i = 0; i < numxpixels; i++) {
68 srcpixels[j][i] = *curaddr;
69 curaddr += comps;
70 }
71 }
72 }
73
74 static void extractsrc_s( GLbyte srcpixels[4][4], const GLfloat *srcaddr,
75 GLint srcRowStride, GLint numxpixels, GLint numypixels, GLint comps)
76 {
77 GLubyte i, j;
78 const GLfloat *curaddr;
79 for (j = 0; j < numypixels; j++) {
80 curaddr = srcaddr + j * srcRowStride * comps;
81 for (i = 0; i < numxpixels; i++) {
82 srcpixels[j][i] = FLOAT_TO_BYTE_TEX(*curaddr);
83 curaddr += comps;
84 }
85 }
86 }
87
88
89 GLboolean
90 _mesa_texstore_red_rgtc1(TEXSTORE_PARAMS)
91 {
92 GLubyte *dst;
93 const GLubyte *tempImage = NULL;
94 int i, j;
95 int numxpixels, numypixels;
96 const GLubyte *srcaddr;
97 GLubyte srcpixels[4][4];
98 GLubyte *blkaddr;
99 GLint dstRowDiff;
100 ASSERT(dstFormat == MESA_FORMAT_RED_RGTC1 ||
101 dstFormat == MESA_FORMAT_L_LATC1);
102
103 tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
104 baseInternalFormat,
105 _mesa_get_format_base_format(dstFormat),
106 srcWidth, srcHeight, srcDepth,
107 srcFormat, srcType, srcAddr,
108 srcPacking);
109 if (!tempImage)
110 return GL_FALSE; /* out of memory */
111
112 dst = dstSlices[0];
113
114 blkaddr = dst;
115 dstRowDiff = dstRowStride >= (srcWidth * 2) ? dstRowStride - (((srcWidth + 3) & ~3) * 2) : 0;
116 for (j = 0; j < srcHeight; j+=4) {
117 if (srcHeight > j + 3) numypixels = 4;
118 else numypixels = srcHeight - j;
119 srcaddr = tempImage + j * srcWidth;
120 for (i = 0; i < srcWidth; i += 4) {
121 if (srcWidth > i + 3) numxpixels = 4;
122 else numxpixels = srcWidth - i;
123 extractsrc_u(srcpixels, srcaddr, srcWidth, numxpixels, numypixels, 1);
124 unsigned_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
125 srcaddr += numxpixels;
126 blkaddr += 8;
127 }
128 blkaddr += dstRowDiff;
129 }
130
131 free((void *) tempImage);
132
133 return GL_TRUE;
134 }
135
136 GLboolean
137 _mesa_texstore_signed_red_rgtc1(TEXSTORE_PARAMS)
138 {
139 GLbyte *dst;
140 const GLfloat *tempImage = NULL;
141 int i, j;
142 int numxpixels, numypixels;
143 const GLfloat *srcaddr;
144 GLbyte srcpixels[4][4];
145 GLbyte *blkaddr;
146 GLint dstRowDiff;
147 ASSERT(dstFormat == MESA_FORMAT_SIGNED_RED_RGTC1 ||
148 dstFormat == MESA_FORMAT_SIGNED_L_LATC1);
149
150 tempImage = _mesa_make_temp_float_image(ctx, dims,
151 baseInternalFormat,
152 _mesa_get_format_base_format(dstFormat),
153 srcWidth, srcHeight, srcDepth,
154 srcFormat, srcType, srcAddr,
155 srcPacking, 0x0);
156 if (!tempImage)
157 return GL_FALSE; /* out of memory */
158
159 dst = (GLbyte *) dstSlices[0];
160
161 blkaddr = dst;
162 dstRowDiff = dstRowStride >= (srcWidth * 2) ? dstRowStride - (((srcWidth + 3) & ~3) * 2) : 0;
163 for (j = 0; j < srcHeight; j+=4) {
164 if (srcHeight > j + 3) numypixels = 4;
165 else numypixels = srcHeight - j;
166 srcaddr = tempImage + j * srcWidth;
167 for (i = 0; i < srcWidth; i += 4) {
168 if (srcWidth > i + 3) numxpixels = 4;
169 else numxpixels = srcWidth - i;
170 extractsrc_s(srcpixels, srcaddr, srcWidth, numxpixels, numypixels, 1);
171 signed_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
172 srcaddr += numxpixels;
173 blkaddr += 8;
174 }
175 blkaddr += dstRowDiff;
176 }
177
178 free((void *) tempImage);
179
180 return GL_TRUE;
181 }
182
183 GLboolean
184 _mesa_texstore_rg_rgtc2(TEXSTORE_PARAMS)
185 {
186 GLubyte *dst;
187 const GLubyte *tempImage = NULL;
188 int i, j;
189 int numxpixels, numypixels;
190 const GLubyte *srcaddr;
191 GLubyte srcpixels[4][4];
192 GLubyte *blkaddr;
193 GLint dstRowDiff;
194
195 ASSERT(dstFormat == MESA_FORMAT_RG_RGTC2 ||
196 dstFormat == MESA_FORMAT_LA_LATC2);
197
198 tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
199 baseInternalFormat,
200 _mesa_get_format_base_format(dstFormat),
201 srcWidth, srcHeight, srcDepth,
202 srcFormat, srcType, srcAddr,
203 srcPacking);
204 if (!tempImage)
205 return GL_FALSE; /* out of memory */
206
207 dst = dstSlices[0];
208
209 blkaddr = dst;
210 dstRowDiff = dstRowStride >= (srcWidth * 4) ? dstRowStride - (((srcWidth + 3) & ~3) * 4) : 0;
211 for (j = 0; j < srcHeight; j+=4) {
212 if (srcHeight > j + 3) numypixels = 4;
213 else numypixels = srcHeight - j;
214 srcaddr = tempImage + j * srcWidth * 2;
215 for (i = 0; i < srcWidth; i += 4) {
216 if (srcWidth > i + 3) numxpixels = 4;
217 else numxpixels = srcWidth - i;
218 extractsrc_u(srcpixels, srcaddr, srcWidth, numxpixels, numypixels, 2);
219 unsigned_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
220
221 blkaddr += 8;
222 extractsrc_u(srcpixels, (GLubyte *)srcaddr + 1, srcWidth, numxpixels, numypixels, 2);
223 unsigned_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
224
225 blkaddr += 8;
226
227 srcaddr += numxpixels * 2;
228 }
229 blkaddr += dstRowDiff;
230 }
231
232 free((void *) tempImage);
233
234 return GL_TRUE;
235 }
236
237 GLboolean
238 _mesa_texstore_signed_rg_rgtc2(TEXSTORE_PARAMS)
239 {
240 GLbyte *dst;
241 const GLfloat *tempImage = NULL;
242 int i, j;
243 int numxpixels, numypixels;
244 const GLfloat *srcaddr;
245 GLbyte srcpixels[4][4];
246 GLbyte *blkaddr;
247 GLint dstRowDiff;
248
249 ASSERT(dstFormat == MESA_FORMAT_SIGNED_RG_RGTC2 ||
250 dstFormat == MESA_FORMAT_SIGNED_LA_LATC2);
251
252 tempImage = _mesa_make_temp_float_image(ctx, dims,
253 baseInternalFormat,
254 _mesa_get_format_base_format(dstFormat),
255 srcWidth, srcHeight, srcDepth,
256 srcFormat, srcType, srcAddr,
257 srcPacking, 0x0);
258 if (!tempImage)
259 return GL_FALSE; /* out of memory */
260
261 dst = (GLbyte *) dstSlices[0];
262
263 blkaddr = dst;
264 dstRowDiff = dstRowStride >= (srcWidth * 4) ? dstRowStride - (((srcWidth + 3) & ~3) * 4) : 0;
265 for (j = 0; j < srcHeight; j += 4) {
266 if (srcHeight > j + 3) numypixels = 4;
267 else numypixels = srcHeight - j;
268 srcaddr = tempImage + j * srcWidth * 2;
269 for (i = 0; i < srcWidth; i += 4) {
270 if (srcWidth > i + 3) numxpixels = 4;
271 else numxpixels = srcWidth - i;
272
273 extractsrc_s(srcpixels, srcaddr, srcWidth, numxpixels, numypixels, 2);
274 signed_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
275 blkaddr += 8;
276
277 extractsrc_s(srcpixels, srcaddr + 1, srcWidth, numxpixels, numypixels, 2);
278 signed_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
279 blkaddr += 8;
280
281 srcaddr += numxpixels * 2;
282
283 }
284 blkaddr += dstRowDiff;
285 }
286
287 free((void *) tempImage);
288
289 return GL_TRUE;
290 }
291
292
293 #define TAG(x) unsigned_##x
294
295 #define TYPE GLubyte
296 #define T_MIN 0
297 #define T_MAX 0xff
298
299 #include "texcompress_rgtc_tmp.h"
300
301 #undef TAG
302 #undef TYPE
303 #undef T_MIN
304 #undef T_MAX
305
306 #define TAG(x) signed_##x
307 #define TYPE GLbyte
308 #define T_MIN (GLbyte)-128
309 #define T_MAX (GLbyte)127
310
311 #include "texcompress_rgtc_tmp.h"
312
313 #undef TAG
314 #undef TYPE
315 #undef T_MIN
316 #undef T_MAX
317
318
319
320 static void
321 fetch_red_rgtc1(const GLubyte *map, const GLuint imageOffsets[],
322 GLint rowStride, GLint i, GLint j, GLint k, GLfloat *texel)
323 {
324 GLubyte red;
325 GLuint sliceOffset = k ? imageOffsets[k] / 2 : 0;
326 unsigned_fetch_texel_rgtc(rowStride, map + sliceOffset, i, j, &red, 1);
327 texel[RCOMP] = UBYTE_TO_FLOAT(red);
328 texel[GCOMP] = 0.0;
329 texel[BCOMP] = 0.0;
330 texel[ACOMP] = 1.0;
331 }
332
333 static void
334 fetch_l_latc1(const GLubyte *map, const GLuint imageOffsets[],
335 GLint rowStride, GLint i, GLint j, GLint k, GLfloat *texel)
336 {
337 GLubyte red;
338 GLuint sliceOffset = k ? imageOffsets[k] / 2 : 0;
339 unsigned_fetch_texel_rgtc(rowStride, map + sliceOffset, i, j, &red, 1);
340 texel[RCOMP] =
341 texel[GCOMP] =
342 texel[BCOMP] = UBYTE_TO_FLOAT(red);
343 texel[ACOMP] = 1.0;
344 }
345
346 static void
347 fetch_signed_red_rgtc1(const GLubyte *map, const GLuint imageOffsets[],
348 GLint rowStride, GLint i, GLint j, GLint k,
349 GLfloat *texel)
350 {
351 GLbyte red;
352 GLuint sliceOffset = k ? imageOffsets[k] / 2 : 0;
353 signed_fetch_texel_rgtc(rowStride, (const GLbyte *) map + sliceOffset,
354 i, j, &red, 1);
355 texel[RCOMP] = BYTE_TO_FLOAT_TEX(red);
356 texel[GCOMP] = 0.0;
357 texel[BCOMP] = 0.0;
358 texel[ACOMP] = 1.0;
359 }
360
361 static void
362 fetch_signed_l_latc1(const GLubyte *map, const GLuint imageOffsets[],
363 GLint rowStride, GLint i, GLint j, GLint k,
364 GLfloat *texel)
365 {
366 GLbyte red;
367 GLuint sliceOffset = k ? imageOffsets[k] / 2 : 0;
368 signed_fetch_texel_rgtc(rowStride, (GLbyte *) map + sliceOffset,
369 i, j, &red, 1);
370 texel[RCOMP] =
371 texel[GCOMP] =
372 texel[BCOMP] = BYTE_TO_FLOAT(red);
373 texel[ACOMP] = 1.0;
374 }
375
376 static void
377 fetch_rg_rgtc2(const GLubyte *map, const GLuint imageOffsets[],
378 GLint rowStride, GLint i, GLint j, GLint k,
379 GLfloat *texel)
380 {
381 GLubyte red, green;
382 GLuint sliceOffset = k ? imageOffsets[k] : 0;
383 unsigned_fetch_texel_rgtc(rowStride,
384 map + sliceOffset,
385 i, j, &red, 2);
386 unsigned_fetch_texel_rgtc(rowStride,
387 map + sliceOffset + 8,
388 i, j, &green, 2);
389 texel[RCOMP] = UBYTE_TO_FLOAT(red);
390 texel[GCOMP] = UBYTE_TO_FLOAT(green);
391 texel[BCOMP] = 0.0;
392 texel[ACOMP] = 1.0;
393 }
394
395 static void
396 fetch_la_latc2(const GLubyte *map, const GLuint imageOffsets[],
397 GLint rowStride, GLint i, GLint j, GLint k,
398 GLfloat *texel)
399 {
400 GLubyte red, green;
401 GLuint sliceOffset = k ? imageOffsets[k] : 0;
402 unsigned_fetch_texel_rgtc(rowStride,
403 map + sliceOffset,
404 i, j, &red, 2);
405 unsigned_fetch_texel_rgtc(rowStride,
406 map + sliceOffset + 8,
407 i, j, &green, 2);
408 texel[RCOMP] =
409 texel[GCOMP] =
410 texel[BCOMP] = UBYTE_TO_FLOAT(red);
411 texel[ACOMP] = UBYTE_TO_FLOAT(green);
412 }
413
414
415 static void
416 fetch_signed_rg_rgtc2(const GLubyte *map, const GLuint imageOffsets[],
417 GLint rowStride, GLint i, GLint j, GLint k,
418 GLfloat *texel)
419 {
420 GLbyte red, green;
421 GLuint sliceOffset = k ? imageOffsets[k] : 0;
422 signed_fetch_texel_rgtc(rowStride,
423 (GLbyte *) map + sliceOffset,
424 i, j, &red, 2);
425 signed_fetch_texel_rgtc(rowStride,
426 (GLbyte *) map + sliceOffset + 8,
427 i, j, &green, 2);
428 texel[RCOMP] = BYTE_TO_FLOAT_TEX(red);
429 texel[GCOMP] = BYTE_TO_FLOAT_TEX(green);
430 texel[BCOMP] = 0.0;
431 texel[ACOMP] = 1.0;
432 }
433
434
435 static void
436 fetch_signed_la_latc2(const GLubyte *map, const GLuint imageOffsets[],
437 GLint rowStride, GLint i, GLint j, GLint k,
438 GLfloat *texel)
439 {
440 GLbyte red, green;
441 GLuint sliceOffset = k ? imageOffsets[k] : 0;
442 signed_fetch_texel_rgtc(rowStride,
443 (GLbyte *) map + sliceOffset,
444 i, j, &red, 2);
445 signed_fetch_texel_rgtc(rowStride,
446 (GLbyte *) map + sliceOffset + 8,
447 i, j, &green, 2);
448 texel[RCOMP] =
449 texel[GCOMP] =
450 texel[BCOMP] = BYTE_TO_FLOAT_TEX(red);
451 texel[ACOMP] = BYTE_TO_FLOAT_TEX(green);
452 }
453
454
455 compressed_fetch_func
456 _mesa_get_compressed_rgtc_func(gl_format format)
457 {
458 switch (format) {
459 case MESA_FORMAT_RED_RGTC1:
460 return fetch_red_rgtc1;
461 case MESA_FORMAT_L_LATC1:
462 return fetch_l_latc1;
463 case MESA_FORMAT_SIGNED_RED_RGTC1:
464 return fetch_signed_red_rgtc1;
465 case MESA_FORMAT_SIGNED_L_LATC1:
466 return fetch_signed_l_latc1;
467 case MESA_FORMAT_RG_RGTC2:
468 return fetch_rg_rgtc2;
469 case MESA_FORMAT_LA_LATC2:
470 return fetch_la_latc2;
471 case MESA_FORMAT_SIGNED_RG_RGTC2:
472 return fetch_signed_rg_rgtc2;
473 case MESA_FORMAT_SIGNED_LA_LATC2:
474 return fetch_signed_la_latc2;
475 default:
476 return NULL;
477 }
478 }