mesa: remove old swrast-based compressed texel fetch code
[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 "mfeatures.h"
42 #include "mipmap.h"
43 #include "texcompress.h"
44 #include "texcompress_rgtc.h"
45 #include "texstore.h"
46
47
48 #define RGTC_DEBUG 0
49
50 static void unsigned_encode_rgtc_ubyte(GLubyte *blkaddr, GLubyte srccolors[4][4],
51 GLint numxpixels, GLint numypixels);
52 static void signed_encode_rgtc_ubyte(GLbyte *blkaddr, GLbyte srccolors[4][4],
53 GLint numxpixels, GLint numypixels);
54
55 static void unsigned_fetch_texel_rgtc(unsigned srcRowStride, const GLubyte *pixdata,
56 unsigned i, unsigned j, GLubyte *value, unsigned comps);
57
58 static void signed_fetch_texel_rgtc(unsigned srcRowStride, const GLbyte *pixdata,
59 unsigned i, unsigned j, GLbyte *value, unsigned comps);
60
61 static void extractsrc_u( GLubyte srcpixels[4][4], const GLubyte *srcaddr,
62 GLint srcRowStride, GLint numxpixels, GLint numypixels, GLint comps)
63 {
64 GLubyte i, j;
65 const GLubyte *curaddr;
66 for (j = 0; j < numypixels; j++) {
67 curaddr = srcaddr + j * srcRowStride * comps;
68 for (i = 0; i < numxpixels; i++) {
69 srcpixels[j][i] = *curaddr;
70 curaddr += comps;
71 }
72 }
73 }
74
75 static void extractsrc_s( GLbyte srcpixels[4][4], const GLfloat *srcaddr,
76 GLint srcRowStride, GLint numxpixels, GLint numypixels, GLint comps)
77 {
78 GLubyte i, j;
79 const GLfloat *curaddr;
80 for (j = 0; j < numypixels; j++) {
81 curaddr = srcaddr + j * srcRowStride * comps;
82 for (i = 0; i < numxpixels; i++) {
83 srcpixels[j][i] = FLOAT_TO_BYTE_TEX(*curaddr);
84 curaddr += comps;
85 }
86 }
87 }
88
89
90 GLboolean
91 _mesa_texstore_red_rgtc1(TEXSTORE_PARAMS)
92 {
93 GLubyte *dst;
94 const GLubyte *tempImage = NULL;
95 int i, j;
96 int numxpixels, numypixels;
97 const GLubyte *srcaddr;
98 GLubyte srcpixels[4][4];
99 GLubyte *blkaddr;
100 GLint dstRowDiff;
101 ASSERT(dstFormat == MESA_FORMAT_RED_RGTC1 ||
102 dstFormat == MESA_FORMAT_L_LATC1);
103
104 tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
105 baseInternalFormat,
106 _mesa_get_format_base_format(dstFormat),
107 srcWidth, srcHeight, srcDepth,
108 srcFormat, srcType, srcAddr,
109 srcPacking);
110 if (!tempImage)
111 return GL_FALSE; /* out of memory */
112
113 dst = dstSlices[0];
114
115 blkaddr = dst;
116 dstRowDiff = dstRowStride >= (srcWidth * 2) ? dstRowStride - (((srcWidth + 3) & ~3) * 2) : 0;
117 for (j = 0; j < srcHeight; j+=4) {
118 if (srcHeight > j + 3) numypixels = 4;
119 else numypixels = srcHeight - j;
120 srcaddr = tempImage + j * srcWidth;
121 for (i = 0; i < srcWidth; i += 4) {
122 if (srcWidth > i + 3) numxpixels = 4;
123 else numxpixels = srcWidth - i;
124 extractsrc_u(srcpixels, srcaddr, srcWidth, numxpixels, numypixels, 1);
125 unsigned_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
126 srcaddr += numxpixels;
127 blkaddr += 8;
128 }
129 blkaddr += dstRowDiff;
130 }
131
132 free((void *) tempImage);
133
134 return GL_TRUE;
135 }
136
137 GLboolean
138 _mesa_texstore_signed_red_rgtc1(TEXSTORE_PARAMS)
139 {
140 GLbyte *dst;
141 const GLfloat *tempImage = NULL;
142 int i, j;
143 int numxpixels, numypixels;
144 const GLfloat *srcaddr;
145 GLbyte srcpixels[4][4];
146 GLbyte *blkaddr;
147 GLint dstRowDiff;
148 ASSERT(dstFormat == MESA_FORMAT_SIGNED_RED_RGTC1 ||
149 dstFormat == MESA_FORMAT_SIGNED_L_LATC1);
150
151 tempImage = _mesa_make_temp_float_image(ctx, dims,
152 baseInternalFormat,
153 _mesa_get_format_base_format(dstFormat),
154 srcWidth, srcHeight, srcDepth,
155 srcFormat, srcType, srcAddr,
156 srcPacking, 0x0);
157 if (!tempImage)
158 return GL_FALSE; /* out of memory */
159
160 dst = (GLbyte *) dstSlices[0];
161
162 blkaddr = dst;
163 dstRowDiff = dstRowStride >= (srcWidth * 2) ? dstRowStride - (((srcWidth + 3) & ~3) * 2) : 0;
164 for (j = 0; j < srcHeight; j+=4) {
165 if (srcHeight > j + 3) numypixels = 4;
166 else numypixels = srcHeight - j;
167 srcaddr = tempImage + j * srcWidth;
168 for (i = 0; i < srcWidth; i += 4) {
169 if (srcWidth > i + 3) numxpixels = 4;
170 else numxpixels = srcWidth - i;
171 extractsrc_s(srcpixels, srcaddr, srcWidth, numxpixels, numypixels, 1);
172 signed_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
173 srcaddr += numxpixels;
174 blkaddr += 8;
175 }
176 blkaddr += dstRowDiff;
177 }
178
179 free((void *) tempImage);
180
181 return GL_TRUE;
182 }
183
184 GLboolean
185 _mesa_texstore_rg_rgtc2(TEXSTORE_PARAMS)
186 {
187 GLubyte *dst;
188 const GLubyte *tempImage = NULL;
189 int i, j;
190 int numxpixels, numypixels;
191 const GLubyte *srcaddr;
192 GLubyte srcpixels[4][4];
193 GLubyte *blkaddr;
194 GLint dstRowDiff;
195
196 ASSERT(dstFormat == MESA_FORMAT_RG_RGTC2 ||
197 dstFormat == MESA_FORMAT_LA_LATC2);
198
199 tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
200 baseInternalFormat,
201 _mesa_get_format_base_format(dstFormat),
202 srcWidth, srcHeight, srcDepth,
203 srcFormat, srcType, srcAddr,
204 srcPacking);
205 if (!tempImage)
206 return GL_FALSE; /* out of memory */
207
208 dst = dstSlices[0];
209
210 blkaddr = dst;
211 dstRowDiff = dstRowStride >= (srcWidth * 4) ? dstRowStride - (((srcWidth + 3) & ~3) * 4) : 0;
212 for (j = 0; j < srcHeight; j+=4) {
213 if (srcHeight > j + 3) numypixels = 4;
214 else numypixels = srcHeight - j;
215 srcaddr = tempImage + j * srcWidth * 2;
216 for (i = 0; i < srcWidth; i += 4) {
217 if (srcWidth > i + 3) numxpixels = 4;
218 else numxpixels = srcWidth - i;
219 extractsrc_u(srcpixels, srcaddr, srcWidth, numxpixels, numypixels, 2);
220 unsigned_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
221
222 blkaddr += 8;
223 extractsrc_u(srcpixels, (GLubyte *)srcaddr + 1, srcWidth, numxpixels, numypixels, 2);
224 unsigned_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
225
226 blkaddr += 8;
227
228 srcaddr += numxpixels * 2;
229 }
230 blkaddr += dstRowDiff;
231 }
232
233 free((void *) tempImage);
234
235 return GL_TRUE;
236 }
237
238 GLboolean
239 _mesa_texstore_signed_rg_rgtc2(TEXSTORE_PARAMS)
240 {
241 GLbyte *dst;
242 const GLfloat *tempImage = NULL;
243 int i, j;
244 int numxpixels, numypixels;
245 const GLfloat *srcaddr;
246 GLbyte srcpixels[4][4];
247 GLbyte *blkaddr;
248 GLint dstRowDiff;
249
250 ASSERT(dstFormat == MESA_FORMAT_SIGNED_RG_RGTC2 ||
251 dstFormat == MESA_FORMAT_SIGNED_LA_LATC2);
252
253 tempImage = _mesa_make_temp_float_image(ctx, dims,
254 baseInternalFormat,
255 _mesa_get_format_base_format(dstFormat),
256 srcWidth, srcHeight, srcDepth,
257 srcFormat, srcType, srcAddr,
258 srcPacking, 0x0);
259 if (!tempImage)
260 return GL_FALSE; /* out of memory */
261
262 dst = (GLbyte *) dstSlices[0];
263
264 blkaddr = dst;
265 dstRowDiff = dstRowStride >= (srcWidth * 4) ? dstRowStride - (((srcWidth + 3) & ~3) * 4) : 0;
266 for (j = 0; j < srcHeight; j += 4) {
267 if (srcHeight > j + 3) numypixels = 4;
268 else numypixels = srcHeight - j;
269 srcaddr = tempImage + j * srcWidth * 2;
270 for (i = 0; i < srcWidth; i += 4) {
271 if (srcWidth > i + 3) numxpixels = 4;
272 else numxpixels = srcWidth - i;
273
274 extractsrc_s(srcpixels, srcaddr, srcWidth, numxpixels, numypixels, 2);
275 signed_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
276 blkaddr += 8;
277
278 extractsrc_s(srcpixels, srcaddr + 1, srcWidth, numxpixels, numypixels, 2);
279 signed_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
280 blkaddr += 8;
281
282 srcaddr += numxpixels * 2;
283
284 }
285 blkaddr += dstRowDiff;
286 }
287
288 free((void *) tempImage);
289
290 return GL_TRUE;
291 }
292
293
294 #define TAG(x) unsigned_##x
295
296 #define TYPE GLubyte
297 #define T_MIN 0
298 #define T_MAX 0xff
299
300 #include "texcompress_rgtc_tmp.h"
301
302 #undef TAG
303 #undef TYPE
304 #undef T_MIN
305 #undef T_MAX
306
307 #define TAG(x) signed_##x
308 #define TYPE GLbyte
309 #define T_MIN (GLbyte)-128
310 #define T_MAX (GLbyte)127
311
312 #include "texcompress_rgtc_tmp.h"
313
314 #undef TAG
315 #undef TYPE
316 #undef T_MIN
317 #undef T_MAX
318
319
320
321 static void
322 fetch_red_rgtc1(const GLubyte *map, const GLuint imageOffsets[],
323 GLint rowStride, GLint i, GLint j, GLint k, GLfloat *texel)
324 {
325 GLubyte red;
326 GLuint sliceOffset = k ? imageOffsets[k] / 2 : 0;
327 unsigned_fetch_texel_rgtc(rowStride, map + sliceOffset, i, j, &red, 1);
328 texel[RCOMP] = UBYTE_TO_FLOAT(red);
329 texel[GCOMP] = 0.0;
330 texel[BCOMP] = 0.0;
331 texel[ACOMP] = 1.0;
332 }
333
334 static void
335 fetch_l_latc1(const GLubyte *map, const GLuint imageOffsets[],
336 GLint rowStride, GLint i, GLint j, GLint k, GLfloat *texel)
337 {
338 GLubyte red;
339 GLuint sliceOffset = k ? imageOffsets[k] / 2 : 0;
340 unsigned_fetch_texel_rgtc(rowStride, map + sliceOffset, i, j, &red, 1);
341 texel[RCOMP] =
342 texel[GCOMP] =
343 texel[BCOMP] = UBYTE_TO_FLOAT(red);
344 texel[ACOMP] = 1.0;
345 }
346
347 static void
348 fetch_signed_red_rgtc1(const GLubyte *map, const GLuint imageOffsets[],
349 GLint rowStride, GLint i, GLint j, GLint k,
350 GLfloat *texel)
351 {
352 GLbyte red;
353 GLuint sliceOffset = k ? imageOffsets[k] / 2 : 0;
354 signed_fetch_texel_rgtc(rowStride, (const GLbyte *) map + sliceOffset,
355 i, j, &red, 1);
356 texel[RCOMP] = BYTE_TO_FLOAT_TEX(red);
357 texel[GCOMP] = 0.0;
358 texel[BCOMP] = 0.0;
359 texel[ACOMP] = 1.0;
360 }
361
362 static void
363 fetch_signed_l_latc1(const GLubyte *map, const GLuint imageOffsets[],
364 GLint rowStride, GLint i, GLint j, GLint k,
365 GLfloat *texel)
366 {
367 GLubyte red;
368 GLuint sliceOffset = k ? imageOffsets[k] / 2 : 0;
369 unsigned_fetch_texel_rgtc(rowStride, map + sliceOffset, 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 }