mesa: include mtypes.h less
[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 "config.h"
37 #include "glheader.h"
38 #include "imports.h"
39 #include "image.h"
40 #include "macros.h"
41 #include "mipmap.h"
42 #include "texcompress.h"
43 #include "util/rgtc.h"
44 #include "texcompress_rgtc.h"
45 #include "texstore.h"
46
47 static void extractsrc_u( GLubyte srcpixels[4][4], const GLubyte *srcaddr,
48 GLint srcRowStride, GLint numxpixels, GLint numypixels, GLint comps)
49 {
50 GLubyte i, j;
51 const GLubyte *curaddr;
52 for (j = 0; j < numypixels; j++) {
53 curaddr = srcaddr + j * srcRowStride * comps;
54 for (i = 0; i < numxpixels; i++) {
55 srcpixels[j][i] = *curaddr;
56 curaddr += comps;
57 }
58 }
59 }
60
61 static void extractsrc_s( GLbyte srcpixels[4][4], const GLfloat *srcaddr,
62 GLint srcRowStride, GLint numxpixels, GLint numypixels, GLint comps)
63 {
64 GLubyte i, j;
65 const GLfloat *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] = FLOAT_TO_BYTE_TEX(*curaddr);
70 curaddr += comps;
71 }
72 }
73 }
74
75
76 GLboolean
77 _mesa_texstore_red_rgtc1(TEXSTORE_PARAMS)
78 {
79 GLubyte *dst;
80 const GLubyte *tempImage = NULL;
81 int i, j;
82 int numxpixels, numypixels;
83 const GLubyte *srcaddr;
84 GLubyte srcpixels[4][4];
85 GLubyte *blkaddr;
86 GLint dstRowDiff, redRowStride;
87 GLubyte *tempImageSlices[1];
88
89 assert(dstFormat == MESA_FORMAT_R_RGTC1_UNORM ||
90 dstFormat == MESA_FORMAT_L_LATC1_UNORM);
91
92 tempImage = malloc(srcWidth * srcHeight * 1 * sizeof(GLubyte));
93 if (!tempImage)
94 return GL_FALSE; /* out of memory */
95 redRowStride = 1 * srcWidth * sizeof(GLubyte);
96 tempImageSlices[0] = (GLubyte *) tempImage;
97 _mesa_texstore(ctx, dims,
98 baseInternalFormat,
99 MESA_FORMAT_R_UNORM8,
100 redRowStride, tempImageSlices,
101 srcWidth, srcHeight, srcDepth,
102 srcFormat, srcType, srcAddr,
103 srcPacking);
104
105 dst = dstSlices[0];
106
107 blkaddr = dst;
108 dstRowDiff = dstRowStride >= (srcWidth * 2) ? dstRowStride - (((srcWidth + 3) & ~3) * 2) : 0;
109 for (j = 0; j < srcHeight; j+=4) {
110 if (srcHeight > j + 3) numypixels = 4;
111 else numypixels = srcHeight - j;
112 srcaddr = tempImage + j * srcWidth;
113 for (i = 0; i < srcWidth; i += 4) {
114 if (srcWidth > i + 3) numxpixels = 4;
115 else numxpixels = srcWidth - i;
116 extractsrc_u(srcpixels, srcaddr, srcWidth, numxpixels, numypixels, 1);
117 util_format_unsigned_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
118 srcaddr += numxpixels;
119 blkaddr += 8;
120 }
121 blkaddr += dstRowDiff;
122 }
123
124 free((void *) tempImage);
125
126 return GL_TRUE;
127 }
128
129 GLboolean
130 _mesa_texstore_signed_red_rgtc1(TEXSTORE_PARAMS)
131 {
132 GLbyte *dst;
133 const GLfloat *tempImage = NULL;
134 int i, j;
135 int numxpixels, numypixels;
136 const GLfloat *srcaddr;
137 GLbyte srcpixels[4][4];
138 GLbyte *blkaddr;
139 GLint dstRowDiff, redRowStride;
140 GLfloat *tempImageSlices[1];
141
142 assert(dstFormat == MESA_FORMAT_R_RGTC1_SNORM ||
143 dstFormat == MESA_FORMAT_L_LATC1_SNORM);
144
145 redRowStride = 1 * srcWidth * sizeof(GLfloat);
146 tempImage = malloc(srcWidth * srcHeight * 1 * sizeof(GLfloat));
147 if (!tempImage)
148 return GL_FALSE; /* out of memory */
149 tempImageSlices[0] = (GLfloat *) tempImage;
150 _mesa_texstore(ctx, dims,
151 baseInternalFormat,
152 MESA_FORMAT_R_FLOAT32,
153 redRowStride, (GLubyte **)tempImageSlices,
154 srcWidth, srcHeight, srcDepth,
155 srcFormat, srcType, srcAddr,
156 srcPacking);
157
158 dst = (GLbyte *) dstSlices[0];
159
160 blkaddr = dst;
161 dstRowDiff = dstRowStride >= (srcWidth * 2) ? dstRowStride - (((srcWidth + 3) & ~3) * 2) : 0;
162 for (j = 0; j < srcHeight; j+=4) {
163 if (srcHeight > j + 3) numypixels = 4;
164 else numypixels = srcHeight - j;
165 srcaddr = tempImage + j * srcWidth;
166 for (i = 0; i < srcWidth; i += 4) {
167 if (srcWidth > i + 3) numxpixels = 4;
168 else numxpixels = srcWidth - i;
169 extractsrc_s(srcpixels, srcaddr, srcWidth, numxpixels, numypixels, 1);
170 util_format_signed_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
171 srcaddr += numxpixels;
172 blkaddr += 8;
173 }
174 blkaddr += dstRowDiff;
175 }
176
177 free((void *) tempImage);
178
179 return GL_TRUE;
180 }
181
182 GLboolean
183 _mesa_texstore_rg_rgtc2(TEXSTORE_PARAMS)
184 {
185 GLubyte *dst;
186 const GLubyte *tempImage = NULL;
187 int i, j;
188 int numxpixels, numypixels;
189 const GLubyte *srcaddr;
190 GLubyte srcpixels[4][4];
191 GLubyte *blkaddr;
192 GLint dstRowDiff, rgRowStride;
193 mesa_format tempFormat;
194 GLubyte *tempImageSlices[1];
195
196 assert(dstFormat == MESA_FORMAT_RG_RGTC2_UNORM ||
197 dstFormat == MESA_FORMAT_LA_LATC2_UNORM);
198
199 if (baseInternalFormat == GL_RG)
200 tempFormat = _mesa_little_endian() ? MESA_FORMAT_R8G8_UNORM
201 : MESA_FORMAT_G8R8_UNORM;
202 else
203 tempFormat = _mesa_little_endian() ? MESA_FORMAT_L8A8_UNORM
204 : MESA_FORMAT_A8L8_UNORM;
205
206 rgRowStride = 2 * srcWidth * sizeof(GLubyte);
207 tempImage = malloc(srcWidth * srcHeight * 2 * sizeof(GLubyte));
208 if (!tempImage)
209 return GL_FALSE; /* out of memory */
210 tempImageSlices[0] = (GLubyte *) tempImage;
211 _mesa_texstore(ctx, dims,
212 baseInternalFormat,
213 tempFormat,
214 rgRowStride, tempImageSlices,
215 srcWidth, srcHeight, srcDepth,
216 srcFormat, srcType, srcAddr,
217 srcPacking);
218
219 dst = dstSlices[0];
220
221 blkaddr = dst;
222 dstRowDiff = dstRowStride >= (srcWidth * 4) ? dstRowStride - (((srcWidth + 3) & ~3) * 4) : 0;
223 for (j = 0; j < srcHeight; j+=4) {
224 if (srcHeight > j + 3) numypixels = 4;
225 else numypixels = srcHeight - j;
226 srcaddr = tempImage + j * srcWidth * 2;
227 for (i = 0; i < srcWidth; i += 4) {
228 if (srcWidth > i + 3) numxpixels = 4;
229 else numxpixels = srcWidth - i;
230 extractsrc_u(srcpixels, srcaddr, srcWidth, numxpixels, numypixels, 2);
231 util_format_unsigned_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
232
233 blkaddr += 8;
234 extractsrc_u(srcpixels, (GLubyte *)srcaddr + 1, srcWidth, numxpixels, numypixels, 2);
235 util_format_unsigned_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
236
237 blkaddr += 8;
238
239 srcaddr += numxpixels * 2;
240 }
241 blkaddr += dstRowDiff;
242 }
243
244 free((void *) tempImage);
245
246 return GL_TRUE;
247 }
248
249 GLboolean
250 _mesa_texstore_signed_rg_rgtc2(TEXSTORE_PARAMS)
251 {
252 GLbyte *dst;
253 const GLfloat *tempImage = NULL;
254 int i, j;
255 int numxpixels, numypixels;
256 const GLfloat *srcaddr;
257 GLbyte srcpixels[4][4];
258 GLbyte *blkaddr;
259 GLint dstRowDiff, rgRowStride;
260 mesa_format tempFormat;
261 GLfloat *tempImageSlices[1];
262
263 assert(dstFormat == MESA_FORMAT_RG_RGTC2_SNORM ||
264 dstFormat == MESA_FORMAT_LA_LATC2_SNORM);
265
266 if (baseInternalFormat == GL_RG)
267 tempFormat = MESA_FORMAT_RG_FLOAT32;
268 else
269 tempFormat = MESA_FORMAT_LA_FLOAT32;
270
271 rgRowStride = 2 * srcWidth * sizeof(GLfloat);
272 tempImage = malloc(srcWidth * srcHeight * 2 * sizeof(GLfloat));
273 if (!tempImage)
274 return GL_FALSE; /* out of memory */
275 tempImageSlices[0] = (GLfloat *) tempImage;
276 _mesa_texstore(ctx, dims,
277 baseInternalFormat,
278 tempFormat,
279 rgRowStride, (GLubyte **)tempImageSlices,
280 srcWidth, srcHeight, srcDepth,
281 srcFormat, srcType, srcAddr,
282 srcPacking);
283
284 dst = (GLbyte *) dstSlices[0];
285
286 blkaddr = dst;
287 dstRowDiff = dstRowStride >= (srcWidth * 4) ? dstRowStride - (((srcWidth + 3) & ~3) * 4) : 0;
288 for (j = 0; j < srcHeight; j += 4) {
289 if (srcHeight > j + 3) numypixels = 4;
290 else numypixels = srcHeight - j;
291 srcaddr = tempImage + j * srcWidth * 2;
292 for (i = 0; i < srcWidth; i += 4) {
293 if (srcWidth > i + 3) numxpixels = 4;
294 else numxpixels = srcWidth - i;
295
296 extractsrc_s(srcpixels, srcaddr, srcWidth, numxpixels, numypixels, 2);
297 util_format_signed_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
298 blkaddr += 8;
299
300 extractsrc_s(srcpixels, srcaddr + 1, srcWidth, numxpixels, numypixels, 2);
301 util_format_signed_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
302 blkaddr += 8;
303
304 srcaddr += numxpixels * 2;
305
306 }
307 blkaddr += dstRowDiff;
308 }
309
310 free((void *) tempImage);
311
312 return GL_TRUE;
313 }
314
315 static void
316 fetch_red_rgtc1(const GLubyte *map,
317 GLint rowStride, GLint i, GLint j, GLfloat *texel)
318 {
319 GLubyte red;
320 util_format_unsigned_fetch_texel_rgtc(rowStride, map, i, j, &red, 1);
321 texel[RCOMP] = UBYTE_TO_FLOAT(red);
322 texel[GCOMP] = 0.0;
323 texel[BCOMP] = 0.0;
324 texel[ACOMP] = 1.0;
325 }
326
327 static void
328 fetch_l_latc1(const GLubyte *map,
329 GLint rowStride, GLint i, GLint j, GLfloat *texel)
330 {
331 GLubyte red;
332 util_format_unsigned_fetch_texel_rgtc(rowStride, map, i, j, &red, 1);
333 texel[RCOMP] =
334 texel[GCOMP] =
335 texel[BCOMP] = UBYTE_TO_FLOAT(red);
336 texel[ACOMP] = 1.0;
337 }
338
339 static void
340 fetch_signed_red_rgtc1(const GLubyte *map,
341 GLint rowStride, GLint i, GLint j, GLfloat *texel)
342 {
343 GLbyte red;
344 util_format_signed_fetch_texel_rgtc(rowStride, (const GLbyte *) map,
345 i, j, &red, 1);
346 texel[RCOMP] = BYTE_TO_FLOAT_TEX(red);
347 texel[GCOMP] = 0.0;
348 texel[BCOMP] = 0.0;
349 texel[ACOMP] = 1.0;
350 }
351
352 static void
353 fetch_signed_l_latc1(const GLubyte *map,
354 GLint rowStride, GLint i, GLint j, GLfloat *texel)
355 {
356 GLbyte red;
357 util_format_signed_fetch_texel_rgtc(rowStride, (GLbyte *) map,
358 i, j, &red, 1);
359 texel[RCOMP] =
360 texel[GCOMP] =
361 texel[BCOMP] = BYTE_TO_FLOAT(red);
362 texel[ACOMP] = 1.0;
363 }
364
365 static void
366 fetch_rg_rgtc2(const GLubyte *map,
367 GLint rowStride, GLint i, GLint j, GLfloat *texel)
368 {
369 GLubyte red, green;
370 util_format_unsigned_fetch_texel_rgtc(rowStride,
371 map,
372 i, j, &red, 2);
373 util_format_unsigned_fetch_texel_rgtc(rowStride,
374 map + 8,
375 i, j, &green, 2);
376 texel[RCOMP] = UBYTE_TO_FLOAT(red);
377 texel[GCOMP] = UBYTE_TO_FLOAT(green);
378 texel[BCOMP] = 0.0;
379 texel[ACOMP] = 1.0;
380 }
381
382 static void
383 fetch_la_latc2(const GLubyte *map,
384 GLint rowStride, GLint i, GLint j, GLfloat *texel)
385 {
386 GLubyte red, green;
387 util_format_unsigned_fetch_texel_rgtc(rowStride,
388 map,
389 i, j, &red, 2);
390 util_format_unsigned_fetch_texel_rgtc(rowStride,
391 map + 8,
392 i, j, &green, 2);
393 texel[RCOMP] =
394 texel[GCOMP] =
395 texel[BCOMP] = UBYTE_TO_FLOAT(red);
396 texel[ACOMP] = UBYTE_TO_FLOAT(green);
397 }
398
399
400 static void
401 fetch_signed_rg_rgtc2(const GLubyte *map,
402 GLint rowStride, GLint i, GLint j, GLfloat *texel)
403 {
404 GLbyte red, green;
405 util_format_signed_fetch_texel_rgtc(rowStride,
406 (GLbyte *) map,
407 i, j, &red, 2);
408 util_format_signed_fetch_texel_rgtc(rowStride,
409 (GLbyte *) map + 8,
410 i, j, &green, 2);
411 texel[RCOMP] = BYTE_TO_FLOAT_TEX(red);
412 texel[GCOMP] = BYTE_TO_FLOAT_TEX(green);
413 texel[BCOMP] = 0.0;
414 texel[ACOMP] = 1.0;
415 }
416
417
418 static void
419 fetch_signed_la_latc2(const GLubyte *map,
420 GLint rowStride, GLint i, GLint j, GLfloat *texel)
421 {
422 GLbyte red, green;
423 util_format_signed_fetch_texel_rgtc(rowStride,
424 (GLbyte *) map,
425 i, j, &red, 2);
426 util_format_signed_fetch_texel_rgtc(rowStride,
427 (GLbyte *) map + 8,
428 i, j, &green, 2);
429 texel[RCOMP] =
430 texel[GCOMP] =
431 texel[BCOMP] = BYTE_TO_FLOAT_TEX(red);
432 texel[ACOMP] = BYTE_TO_FLOAT_TEX(green);
433 }
434
435
436 compressed_fetch_func
437 _mesa_get_compressed_rgtc_func(mesa_format format)
438 {
439 switch (format) {
440 case MESA_FORMAT_R_RGTC1_UNORM:
441 return fetch_red_rgtc1;
442 case MESA_FORMAT_L_LATC1_UNORM:
443 return fetch_l_latc1;
444 case MESA_FORMAT_R_RGTC1_SNORM:
445 return fetch_signed_red_rgtc1;
446 case MESA_FORMAT_L_LATC1_SNORM:
447 return fetch_signed_l_latc1;
448 case MESA_FORMAT_RG_RGTC2_UNORM:
449 return fetch_rg_rgtc2;
450 case MESA_FORMAT_LA_LATC2_UNORM:
451 return fetch_la_latc2;
452 case MESA_FORMAT_RG_RGTC2_SNORM:
453 return fetch_signed_rg_rgtc2;
454 case MESA_FORMAT_LA_LATC2_SNORM:
455 return fetch_signed_la_latc2;
456 default:
457 return NULL;
458 }
459 }