mesa: s/_mesa_make_temp_chan_image()/_mesa_make_temp_ubyte_image()
[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 #include "swrast/s_context.h"
47
48
49 #define RGTC_DEBUG 0
50
51 static void unsigned_encode_rgtc_chan(GLubyte *blkaddr, GLubyte srccolors[4][4],
52 GLint numxpixels, GLint numypixels);
53 static void signed_encode_rgtc_chan(GLbyte *blkaddr, GLbyte srccolors[4][4],
54 GLint numxpixels, GLint numypixels);
55
56 static void unsigned_fetch_texel_rgtc(unsigned srcRowStride, const GLubyte *pixdata,
57 unsigned i, unsigned j, GLubyte *value, unsigned comps);
58
59 static void signed_fetch_texel_rgtc(unsigned srcRowStride, const GLbyte *pixdata,
60 unsigned i, unsigned j, GLbyte *value, unsigned comps);
61
62 static void extractsrc_u( GLubyte srcpixels[4][4], const GLchan *srcaddr,
63 GLint srcRowStride, GLint numxpixels, GLint numypixels, GLint comps)
64 {
65 GLubyte i, j;
66 const GLchan *curaddr;
67 for (j = 0; j < numypixels; j++) {
68 curaddr = srcaddr + j * srcRowStride * comps;
69 for (i = 0; i < numxpixels; i++) {
70 srcpixels[j][i] = *curaddr / (CHAN_MAX / 255);
71 curaddr += comps;
72 }
73 }
74 }
75
76 static void extractsrc_s( GLbyte srcpixels[4][4], const GLfloat *srcaddr,
77 GLint srcRowStride, GLint numxpixels, GLint numypixels, GLint comps)
78 {
79 GLubyte i, j;
80 const GLfloat *curaddr;
81 for (j = 0; j < numypixels; j++) {
82 curaddr = srcaddr + j * srcRowStride * comps;
83 for (i = 0; i < numxpixels; i++) {
84 srcpixels[j][i] = FLOAT_TO_BYTE_TEX(*curaddr);
85 curaddr += comps;
86 }
87 }
88 }
89
90
91 GLboolean
92 _mesa_texstore_red_rgtc1(TEXSTORE_PARAMS)
93 {
94 GLubyte *dst;
95 const GLint texWidth = dstRowStride * 4 / 8; /* a bit of a hack */
96 const GLubyte *tempImage = NULL;
97 int i, j;
98 int numxpixels, numypixels;
99 const GLchan *srcaddr;
100 GLubyte srcpixels[4][4];
101 GLubyte *blkaddr;
102 GLint dstRowDiff;
103 ASSERT(dstFormat == MESA_FORMAT_RED_RGTC1 ||
104 dstFormat == MESA_FORMAT_L_LATC1);
105 ASSERT(dstXoffset % 4 == 0);
106 ASSERT(dstYoffset % 4 == 0);
107 ASSERT(dstZoffset % 4 == 0);
108 (void) dstZoffset;
109 (void) dstImageOffsets;
110
111
112 tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
113 baseInternalFormat,
114 _mesa_get_format_base_format(dstFormat),
115 srcWidth, srcHeight, srcDepth,
116 srcFormat, srcType, srcAddr,
117 srcPacking);
118 if (!tempImage)
119 return GL_FALSE; /* out of memory */
120
121 dst = _mesa_compressed_image_address(dstXoffset, dstYoffset, 0,
122 dstFormat,
123 texWidth, (GLubyte *) dstAddr);
124
125 blkaddr = dst;
126 dstRowDiff = dstRowStride >= (srcWidth * 2) ? dstRowStride - (((srcWidth + 3) & ~3) * 2) : 0;
127 for (j = 0; j < srcHeight; j+=4) {
128 if (srcHeight > j + 3) numypixels = 4;
129 else numypixels = srcHeight - j;
130 srcaddr = tempImage + j * srcWidth;
131 for (i = 0; i < srcWidth; i += 4) {
132 if (srcWidth > i + 3) numxpixels = 4;
133 else numxpixels = srcWidth - i;
134 extractsrc_u(srcpixels, srcaddr, srcWidth, numxpixels, numypixels, 1);
135 unsigned_encode_rgtc_chan(blkaddr, srcpixels, numxpixels, numypixels);
136 srcaddr += numxpixels;
137 blkaddr += 8;
138 }
139 blkaddr += dstRowDiff;
140 }
141 if (tempImage)
142 free((void *) tempImage);
143
144 return GL_TRUE;
145 }
146
147 GLboolean
148 _mesa_texstore_signed_red_rgtc1(TEXSTORE_PARAMS)
149 {
150 GLbyte *dst;
151 const GLint texWidth = dstRowStride * 4 / 8; /* a bit of a hack */
152 const GLfloat *tempImage = NULL;
153 int i, j;
154 int numxpixels, numypixels;
155 const GLfloat *srcaddr;
156 GLbyte srcpixels[4][4];
157 GLbyte *blkaddr;
158 GLint dstRowDiff;
159 ASSERT(dstFormat == MESA_FORMAT_SIGNED_RED_RGTC1 ||
160 dstFormat == MESA_FORMAT_SIGNED_L_LATC1);
161 ASSERT(dstXoffset % 4 == 0);
162 ASSERT(dstYoffset % 4 == 0);
163 ASSERT(dstZoffset % 4 == 0);
164 (void) dstZoffset;
165 (void) dstImageOffsets;
166
167 tempImage = _mesa_make_temp_float_image(ctx, dims,
168 baseInternalFormat,
169 _mesa_get_format_base_format(dstFormat),
170 srcWidth, srcHeight, srcDepth,
171 srcFormat, srcType, srcAddr,
172 srcPacking, 0x0);
173 if (!tempImage)
174 return GL_FALSE; /* out of memory */
175
176 dst = (GLbyte *)_mesa_compressed_image_address(dstXoffset, dstYoffset, 0,
177 dstFormat,
178 texWidth, (GLubyte *) dstAddr);
179
180 blkaddr = dst;
181 dstRowDiff = dstRowStride >= (srcWidth * 2) ? dstRowStride - (((srcWidth + 3) & ~3) * 2) : 0;
182 for (j = 0; j < srcHeight; j+=4) {
183 if (srcHeight > j + 3) numypixels = 4;
184 else numypixels = srcHeight - j;
185 srcaddr = tempImage + j * srcWidth;
186 for (i = 0; i < srcWidth; i += 4) {
187 if (srcWidth > i + 3) numxpixels = 4;
188 else numxpixels = srcWidth - i;
189 extractsrc_s(srcpixels, srcaddr, srcWidth, numxpixels, numypixels, 1);
190 signed_encode_rgtc_chan(blkaddr, srcpixels, numxpixels, numypixels);
191 srcaddr += numxpixels;
192 blkaddr += 8;
193 }
194 blkaddr += dstRowDiff;
195 }
196 if (tempImage)
197 free((void *) tempImage);
198
199 return GL_TRUE;
200 }
201
202 GLboolean
203 _mesa_texstore_rg_rgtc2(TEXSTORE_PARAMS)
204 {
205 GLubyte *dst;
206 const GLint texWidth = dstRowStride * 4 / 16; /* a bit of a hack */
207 const GLubyte *tempImage = NULL;
208 int i, j;
209 int numxpixels, numypixels;
210 const GLchan *srcaddr;
211 GLubyte srcpixels[4][4];
212 GLubyte *blkaddr;
213 GLint dstRowDiff;
214
215 ASSERT(dstFormat == MESA_FORMAT_RG_RGTC2 ||
216 dstFormat == MESA_FORMAT_LA_LATC2);
217 ASSERT(dstXoffset % 4 == 0);
218 ASSERT(dstYoffset % 4 == 0);
219 ASSERT(dstZoffset % 4 == 0);
220 (void) dstZoffset;
221 (void) dstImageOffsets;
222
223 tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
224 baseInternalFormat,
225 _mesa_get_format_base_format(dstFormat),
226 srcWidth, srcHeight, srcDepth,
227 srcFormat, srcType, srcAddr,
228 srcPacking);
229 if (!tempImage)
230 return GL_FALSE; /* out of memory */
231
232 dst = _mesa_compressed_image_address(dstXoffset, dstYoffset, 0,
233 dstFormat,
234 texWidth, (GLubyte *) dstAddr);
235
236 blkaddr = dst;
237 dstRowDiff = dstRowStride >= (srcWidth * 4) ? dstRowStride - (((srcWidth + 3) & ~3) * 4) : 0;
238 for (j = 0; j < srcHeight; j+=4) {
239 if (srcHeight > j + 3) numypixels = 4;
240 else numypixels = srcHeight - j;
241 srcaddr = tempImage + j * srcWidth * 2;
242 for (i = 0; i < srcWidth; i += 4) {
243 if (srcWidth > i + 3) numxpixels = 4;
244 else numxpixels = srcWidth - i;
245 extractsrc_u(srcpixels, srcaddr, srcWidth, numxpixels, numypixels, 2);
246 unsigned_encode_rgtc_chan(blkaddr, srcpixels, numxpixels, numypixels);
247
248 blkaddr += 8;
249 extractsrc_u(srcpixels, (GLchan *)srcaddr + 1, srcWidth, numxpixels, numypixels, 2);
250 unsigned_encode_rgtc_chan(blkaddr, srcpixels, numxpixels, numypixels);
251
252 blkaddr += 8;
253
254 srcaddr += numxpixels * 2;
255 }
256 blkaddr += dstRowDiff;
257 }
258 if (tempImage)
259 free((void *) tempImage);
260
261 return GL_TRUE;
262 }
263
264 GLboolean
265 _mesa_texstore_signed_rg_rgtc2(TEXSTORE_PARAMS)
266 {
267 GLbyte *dst;
268 const GLint texWidth = dstRowStride * 4 / 16; /* a bit of a hack */
269 const GLfloat *tempImage = NULL;
270 int i, j;
271 int numxpixels, numypixels;
272 const GLfloat *srcaddr;
273 GLbyte srcpixels[4][4];
274 GLbyte *blkaddr;
275 GLint dstRowDiff;
276
277 ASSERT(dstFormat == MESA_FORMAT_SIGNED_RG_RGTC2 ||
278 dstFormat == MESA_FORMAT_SIGNED_LA_LATC2);
279 ASSERT(dstXoffset % 4 == 0);
280 ASSERT(dstYoffset % 4 == 0);
281 ASSERT(dstZoffset % 4 == 0);
282 (void) dstZoffset;
283 (void) dstImageOffsets;
284
285 tempImage = _mesa_make_temp_float_image(ctx, dims,
286 baseInternalFormat,
287 _mesa_get_format_base_format(dstFormat),
288 srcWidth, srcHeight, srcDepth,
289 srcFormat, srcType, srcAddr,
290 srcPacking, 0x0);
291 if (!tempImage)
292 return GL_FALSE; /* out of memory */
293
294 dst = (GLbyte *)_mesa_compressed_image_address(dstXoffset, dstYoffset, 0,
295 dstFormat,
296 texWidth, (GLubyte *) dstAddr);
297
298 blkaddr = dst;
299 dstRowDiff = dstRowStride >= (srcWidth * 4) ? dstRowStride - (((srcWidth + 3) & ~3) * 4) : 0;
300 for (j = 0; j < srcHeight; j += 4) {
301 if (srcHeight > j + 3) numypixels = 4;
302 else numypixels = srcHeight - j;
303 srcaddr = tempImage + j * srcWidth * 2;
304 for (i = 0; i < srcWidth; i += 4) {
305 if (srcWidth > i + 3) numxpixels = 4;
306 else numxpixels = srcWidth - i;
307
308 extractsrc_s(srcpixels, srcaddr, srcWidth, numxpixels, numypixels, 2);
309 signed_encode_rgtc_chan(blkaddr, srcpixels, numxpixels, numypixels);
310 blkaddr += 8;
311
312 extractsrc_s(srcpixels, srcaddr + 1, srcWidth, numxpixels, numypixels, 2);
313 signed_encode_rgtc_chan(blkaddr, srcpixels, numxpixels, numypixels);
314 blkaddr += 8;
315
316 srcaddr += numxpixels * 2;
317
318 }
319 blkaddr += dstRowDiff;
320 }
321 if (tempImage)
322 free((void *) tempImage);
323
324 return GL_TRUE;
325 }
326
327 void
328 _mesa_fetch_texel_2d_f_red_rgtc1(const struct swrast_texture_image *texImage,
329 GLint i, GLint j, GLint k, GLfloat *texel)
330 {
331 GLubyte red;
332 unsigned_fetch_texel_rgtc(texImage->Base.RowStride, (GLubyte *)(texImage->Base.Data),
333 i, j, &red, 1);
334 texel[RCOMP] = UBYTE_TO_FLOAT(red);
335 texel[GCOMP] = 0.0;
336 texel[BCOMP] = 0.0;
337 texel[ACOMP] = 1.0;
338 }
339
340 void
341 _mesa_fetch_texel_2d_f_signed_red_rgtc1(const struct swrast_texture_image *texImage,
342 GLint i, GLint j, GLint k, GLfloat *texel)
343 {
344 GLbyte red;
345 signed_fetch_texel_rgtc(texImage->Base.RowStride, (GLbyte *)(texImage->Base.Data),
346 i, j, &red, 1);
347 texel[RCOMP] = BYTE_TO_FLOAT_TEX(red);
348 texel[GCOMP] = 0.0;
349 texel[BCOMP] = 0.0;
350 texel[ACOMP] = 1.0;
351 }
352
353 void
354 _mesa_fetch_texel_2d_f_rg_rgtc2(const struct swrast_texture_image *texImage,
355 GLint i, GLint j, GLint k, GLfloat *texel)
356 {
357 GLubyte red, green;
358 unsigned_fetch_texel_rgtc(texImage->Base.RowStride, (GLubyte *)(texImage->Base.Data),
359 i, j, &red, 2);
360 unsigned_fetch_texel_rgtc(texImage->Base.RowStride, (GLubyte *)(texImage->Base.Data) + 8,
361 i, j, &green, 2);
362 texel[RCOMP] = UBYTE_TO_FLOAT(red);
363 texel[GCOMP] = UBYTE_TO_FLOAT(green);
364 texel[BCOMP] = 0.0;
365 texel[ACOMP] = 1.0;
366 }
367
368 void
369 _mesa_fetch_texel_2d_f_signed_rg_rgtc2(const struct swrast_texture_image *texImage,
370 GLint i, GLint j, GLint k, GLfloat *texel)
371 {
372 GLbyte red, green;
373 signed_fetch_texel_rgtc(texImage->Base.RowStride, (GLbyte *)(texImage->Base.Data),
374 i, j, &red, 2);
375 signed_fetch_texel_rgtc(texImage->Base.RowStride, (GLbyte *)(texImage->Base.Data) + 8,
376 i, j, &green, 2);
377 texel[RCOMP] = BYTE_TO_FLOAT_TEX(red);
378 texel[GCOMP] = BYTE_TO_FLOAT_TEX(green);
379 texel[BCOMP] = 0.0;
380 texel[ACOMP] = 1.0;
381 }
382
383 void
384 _mesa_fetch_texel_2d_f_l_latc1(const struct swrast_texture_image *texImage,
385 GLint i, GLint j, GLint k, GLfloat *texel)
386 {
387 GLubyte red;
388 unsigned_fetch_texel_rgtc(texImage->Base.RowStride, (GLubyte *)(texImage->Base.Data),
389 i, j, &red, 1);
390 texel[RCOMP] =
391 texel[GCOMP] =
392 texel[BCOMP] = UBYTE_TO_FLOAT(red);
393 texel[ACOMP] = 1.0;
394 }
395
396 void
397 _mesa_fetch_texel_2d_f_signed_l_latc1(const struct swrast_texture_image *texImage,
398 GLint i, GLint j, GLint k, GLfloat *texel)
399 {
400 GLbyte red;
401 signed_fetch_texel_rgtc(texImage->Base.RowStride, (GLbyte *)(texImage->Base.Data),
402 i, j, &red, 1);
403 texel[RCOMP] =
404 texel[GCOMP] =
405 texel[BCOMP] = BYTE_TO_FLOAT_TEX(red);
406 texel[ACOMP] = 1.0;
407 }
408
409 void
410 _mesa_fetch_texel_2d_f_la_latc2(const struct swrast_texture_image *texImage,
411 GLint i, GLint j, GLint k, GLfloat *texel)
412 {
413 GLubyte red, green;
414 unsigned_fetch_texel_rgtc(texImage->Base.RowStride, (GLubyte *)(texImage->Base.Data),
415 i, j, &red, 2);
416 unsigned_fetch_texel_rgtc(texImage->Base.RowStride, (GLubyte *)(texImage->Base.Data) + 8,
417 i, j, &green, 2);
418 texel[RCOMP] =
419 texel[GCOMP] =
420 texel[BCOMP] = UBYTE_TO_FLOAT(red);
421 texel[ACOMP] = UBYTE_TO_FLOAT(green);
422 }
423
424 void
425 _mesa_fetch_texel_2d_f_signed_la_latc2(const struct swrast_texture_image *texImage,
426 GLint i, GLint j, GLint k, GLfloat *texel)
427 {
428 GLbyte red, green;
429 signed_fetch_texel_rgtc(texImage->Base.RowStride, (GLbyte *)(texImage->Base.Data),
430 i, j, &red, 2);
431 signed_fetch_texel_rgtc(texImage->Base.RowStride, (GLbyte *)(texImage->Base.Data) + 8,
432 i, j, &green, 2);
433 texel[RCOMP] =
434 texel[GCOMP] =
435 texel[BCOMP] = BYTE_TO_FLOAT_TEX(red);
436 texel[ACOMP] = BYTE_TO_FLOAT_TEX(green);
437 }
438
439 #define TAG(x) unsigned_##x
440
441 #define TYPE GLubyte
442 #define T_MIN 0
443 #define T_MAX 0xff
444
445 #include "texcompress_rgtc_tmp.h"
446
447 #undef TAG
448 #undef TYPE
449 #undef T_MIN
450 #undef T_MAX
451
452 #define TAG(x) signed_##x
453 #define TYPE GLbyte
454 #define T_MIN (GLbyte)-128
455 #define T_MAX (GLbyte)127
456
457 #include "texcompress_rgtc_tmp.h"
458
459 #undef TAG
460 #undef TYPE
461 #undef T_MIN
462 #undef T_MAX