2 * Copyright (C) 2011 Red Hat Inc.
4 * block compression parts are:
5 * Copyright (C) 2004 Roland Scheidegger All Rights Reserved.
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:
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
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.
31 * \file texcompress_rgtc.c
32 * GL_EXT_texture_compression_rgtc support.
41 #include "texcompress.h"
42 #include "util/rgtc.h"
43 #include "texcompress_rgtc.h"
46 static void extractsrc_u( GLubyte srcpixels
[4][4], const GLubyte
*srcaddr
,
47 GLint srcRowStride
, GLint numxpixels
, GLint numypixels
, GLint comps
)
50 const GLubyte
*curaddr
;
51 for (j
= 0; j
< numypixels
; j
++) {
52 curaddr
= srcaddr
+ j
* srcRowStride
* comps
;
53 for (i
= 0; i
< numxpixels
; i
++) {
54 srcpixels
[j
][i
] = *curaddr
;
60 static void extractsrc_s( GLbyte srcpixels
[4][4], const GLfloat
*srcaddr
,
61 GLint srcRowStride
, GLint numxpixels
, GLint numypixels
, GLint comps
)
64 const GLfloat
*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
] = FLOAT_TO_BYTE_TEX(*curaddr
);
76 _mesa_texstore_red_rgtc1(TEXSTORE_PARAMS
)
79 const GLubyte
*tempImage
= NULL
;
81 int numxpixels
, numypixels
;
82 const GLubyte
*srcaddr
;
83 GLubyte srcpixels
[4][4];
85 GLint dstRowDiff
, redRowStride
;
86 GLubyte
*tempImageSlices
[1];
88 assert(dstFormat
== MESA_FORMAT_R_RGTC1_UNORM
||
89 dstFormat
== MESA_FORMAT_L_LATC1_UNORM
);
91 tempImage
= malloc(srcWidth
* srcHeight
* 1 * sizeof(GLubyte
));
93 return GL_FALSE
; /* out of memory */
94 redRowStride
= 1 * srcWidth
* sizeof(GLubyte
);
95 tempImageSlices
[0] = (GLubyte
*) tempImage
;
96 _mesa_texstore(ctx
, dims
,
99 redRowStride
, tempImageSlices
,
100 srcWidth
, srcHeight
, srcDepth
,
101 srcFormat
, srcType
, srcAddr
,
107 dstRowDiff
= dstRowStride
>= (srcWidth
* 2) ? dstRowStride
- (((srcWidth
+ 3) & ~3) * 2) : 0;
108 for (j
= 0; j
< srcHeight
; j
+=4) {
109 if (srcHeight
> j
+ 3) numypixels
= 4;
110 else numypixels
= srcHeight
- j
;
111 srcaddr
= tempImage
+ j
* srcWidth
;
112 for (i
= 0; i
< srcWidth
; i
+= 4) {
113 if (srcWidth
> i
+ 3) numxpixels
= 4;
114 else numxpixels
= srcWidth
- i
;
115 extractsrc_u(srcpixels
, srcaddr
, srcWidth
, numxpixels
, numypixels
, 1);
116 util_format_unsigned_encode_rgtc_ubyte(blkaddr
, srcpixels
, numxpixels
, numypixels
);
117 srcaddr
+= numxpixels
;
120 blkaddr
+= dstRowDiff
;
123 free((void *) tempImage
);
129 _mesa_texstore_signed_red_rgtc1(TEXSTORE_PARAMS
)
132 const GLfloat
*tempImage
= NULL
;
134 int numxpixels
, numypixels
;
135 const GLfloat
*srcaddr
;
136 GLbyte srcpixels
[4][4];
138 GLint dstRowDiff
, redRowStride
;
139 GLfloat
*tempImageSlices
[1];
141 assert(dstFormat
== MESA_FORMAT_R_RGTC1_SNORM
||
142 dstFormat
== MESA_FORMAT_L_LATC1_SNORM
);
144 redRowStride
= 1 * srcWidth
* sizeof(GLfloat
);
145 tempImage
= malloc(srcWidth
* srcHeight
* 1 * sizeof(GLfloat
));
147 return GL_FALSE
; /* out of memory */
148 tempImageSlices
[0] = (GLfloat
*) tempImage
;
149 _mesa_texstore(ctx
, dims
,
151 MESA_FORMAT_R_FLOAT32
,
152 redRowStride
, (GLubyte
**)tempImageSlices
,
153 srcWidth
, srcHeight
, srcDepth
,
154 srcFormat
, srcType
, srcAddr
,
157 dst
= (GLbyte
*) dstSlices
[0];
160 dstRowDiff
= dstRowStride
>= (srcWidth
* 2) ? dstRowStride
- (((srcWidth
+ 3) & ~3) * 2) : 0;
161 for (j
= 0; j
< srcHeight
; j
+=4) {
162 if (srcHeight
> j
+ 3) numypixels
= 4;
163 else numypixels
= srcHeight
- j
;
164 srcaddr
= tempImage
+ j
* srcWidth
;
165 for (i
= 0; i
< srcWidth
; i
+= 4) {
166 if (srcWidth
> i
+ 3) numxpixels
= 4;
167 else numxpixels
= srcWidth
- i
;
168 extractsrc_s(srcpixels
, srcaddr
, srcWidth
, numxpixels
, numypixels
, 1);
169 util_format_signed_encode_rgtc_ubyte(blkaddr
, srcpixels
, numxpixels
, numypixels
);
170 srcaddr
+= numxpixels
;
173 blkaddr
+= dstRowDiff
;
176 free((void *) tempImage
);
182 _mesa_texstore_rg_rgtc2(TEXSTORE_PARAMS
)
185 const GLubyte
*tempImage
= NULL
;
187 int numxpixels
, numypixels
;
188 const GLubyte
*srcaddr
;
189 GLubyte srcpixels
[4][4];
191 GLint dstRowDiff
, rgRowStride
;
192 mesa_format tempFormat
;
193 GLubyte
*tempImageSlices
[1];
195 assert(dstFormat
== MESA_FORMAT_RG_RGTC2_UNORM
||
196 dstFormat
== MESA_FORMAT_LA_LATC2_UNORM
);
198 if (baseInternalFormat
== GL_RG
)
199 tempFormat
= _mesa_little_endian() ? MESA_FORMAT_R8G8_UNORM
200 : MESA_FORMAT_G8R8_UNORM
;
202 tempFormat
= _mesa_little_endian() ? MESA_FORMAT_L8A8_UNORM
203 : MESA_FORMAT_A8L8_UNORM
;
205 rgRowStride
= 2 * srcWidth
* sizeof(GLubyte
);
206 tempImage
= malloc(srcWidth
* srcHeight
* 2 * sizeof(GLubyte
));
208 return GL_FALSE
; /* out of memory */
209 tempImageSlices
[0] = (GLubyte
*) tempImage
;
210 _mesa_texstore(ctx
, dims
,
213 rgRowStride
, tempImageSlices
,
214 srcWidth
, srcHeight
, srcDepth
,
215 srcFormat
, srcType
, srcAddr
,
221 dstRowDiff
= dstRowStride
>= (srcWidth
* 4) ? dstRowStride
- (((srcWidth
+ 3) & ~3) * 4) : 0;
222 for (j
= 0; j
< srcHeight
; j
+=4) {
223 if (srcHeight
> j
+ 3) numypixels
= 4;
224 else numypixels
= srcHeight
- j
;
225 srcaddr
= tempImage
+ j
* srcWidth
* 2;
226 for (i
= 0; i
< srcWidth
; i
+= 4) {
227 if (srcWidth
> i
+ 3) numxpixels
= 4;
228 else numxpixels
= srcWidth
- i
;
229 extractsrc_u(srcpixels
, srcaddr
, srcWidth
, numxpixels
, numypixels
, 2);
230 util_format_unsigned_encode_rgtc_ubyte(blkaddr
, srcpixels
, numxpixels
, numypixels
);
233 extractsrc_u(srcpixels
, (GLubyte
*)srcaddr
+ 1, srcWidth
, numxpixels
, numypixels
, 2);
234 util_format_unsigned_encode_rgtc_ubyte(blkaddr
, srcpixels
, numxpixels
, numypixels
);
238 srcaddr
+= numxpixels
* 2;
240 blkaddr
+= dstRowDiff
;
243 free((void *) tempImage
);
249 _mesa_texstore_signed_rg_rgtc2(TEXSTORE_PARAMS
)
252 const GLfloat
*tempImage
= NULL
;
254 int numxpixels
, numypixels
;
255 const GLfloat
*srcaddr
;
256 GLbyte srcpixels
[4][4];
258 GLint dstRowDiff
, rgRowStride
;
259 mesa_format tempFormat
;
260 GLfloat
*tempImageSlices
[1];
262 assert(dstFormat
== MESA_FORMAT_RG_RGTC2_SNORM
||
263 dstFormat
== MESA_FORMAT_LA_LATC2_SNORM
);
265 if (baseInternalFormat
== GL_RG
)
266 tempFormat
= MESA_FORMAT_RG_FLOAT32
;
268 tempFormat
= MESA_FORMAT_LA_FLOAT32
;
270 rgRowStride
= 2 * srcWidth
* sizeof(GLfloat
);
271 tempImage
= malloc(srcWidth
* srcHeight
* 2 * sizeof(GLfloat
));
273 return GL_FALSE
; /* out of memory */
274 tempImageSlices
[0] = (GLfloat
*) tempImage
;
275 _mesa_texstore(ctx
, dims
,
278 rgRowStride
, (GLubyte
**)tempImageSlices
,
279 srcWidth
, srcHeight
, srcDepth
,
280 srcFormat
, srcType
, srcAddr
,
283 dst
= (GLbyte
*) dstSlices
[0];
286 dstRowDiff
= dstRowStride
>= (srcWidth
* 4) ? dstRowStride
- (((srcWidth
+ 3) & ~3) * 4) : 0;
287 for (j
= 0; j
< srcHeight
; j
+= 4) {
288 if (srcHeight
> j
+ 3) numypixels
= 4;
289 else numypixels
= srcHeight
- j
;
290 srcaddr
= tempImage
+ j
* srcWidth
* 2;
291 for (i
= 0; i
< srcWidth
; i
+= 4) {
292 if (srcWidth
> i
+ 3) numxpixels
= 4;
293 else numxpixels
= srcWidth
- i
;
295 extractsrc_s(srcpixels
, srcaddr
, srcWidth
, numxpixels
, numypixels
, 2);
296 util_format_signed_encode_rgtc_ubyte(blkaddr
, srcpixels
, numxpixels
, numypixels
);
299 extractsrc_s(srcpixels
, srcaddr
+ 1, srcWidth
, numxpixels
, numypixels
, 2);
300 util_format_signed_encode_rgtc_ubyte(blkaddr
, srcpixels
, numxpixels
, numypixels
);
303 srcaddr
+= numxpixels
* 2;
306 blkaddr
+= dstRowDiff
;
309 free((void *) tempImage
);
315 fetch_red_rgtc1(const GLubyte
*map
,
316 GLint rowStride
, GLint i
, GLint j
, GLfloat
*texel
)
319 util_format_unsigned_fetch_texel_rgtc(rowStride
, map
, i
, j
, &red
, 1);
320 texel
[RCOMP
] = UBYTE_TO_FLOAT(red
);
327 fetch_l_latc1(const GLubyte
*map
,
328 GLint rowStride
, GLint i
, GLint j
, GLfloat
*texel
)
331 util_format_unsigned_fetch_texel_rgtc(rowStride
, map
, i
, j
, &red
, 1);
334 texel
[BCOMP
] = UBYTE_TO_FLOAT(red
);
339 fetch_signed_red_rgtc1(const GLubyte
*map
,
340 GLint rowStride
, GLint i
, GLint j
, GLfloat
*texel
)
343 util_format_signed_fetch_texel_rgtc(rowStride
, (const GLbyte
*) map
,
345 texel
[RCOMP
] = BYTE_TO_FLOAT_TEX(red
);
352 fetch_signed_l_latc1(const GLubyte
*map
,
353 GLint rowStride
, GLint i
, GLint j
, GLfloat
*texel
)
356 util_format_signed_fetch_texel_rgtc(rowStride
, (GLbyte
*) map
,
360 texel
[BCOMP
] = BYTE_TO_FLOAT(red
);
365 fetch_rg_rgtc2(const GLubyte
*map
,
366 GLint rowStride
, GLint i
, GLint j
, GLfloat
*texel
)
369 util_format_unsigned_fetch_texel_rgtc(rowStride
,
372 util_format_unsigned_fetch_texel_rgtc(rowStride
,
375 texel
[RCOMP
] = UBYTE_TO_FLOAT(red
);
376 texel
[GCOMP
] = UBYTE_TO_FLOAT(green
);
382 fetch_la_latc2(const GLubyte
*map
,
383 GLint rowStride
, GLint i
, GLint j
, GLfloat
*texel
)
386 util_format_unsigned_fetch_texel_rgtc(rowStride
,
389 util_format_unsigned_fetch_texel_rgtc(rowStride
,
394 texel
[BCOMP
] = UBYTE_TO_FLOAT(red
);
395 texel
[ACOMP
] = UBYTE_TO_FLOAT(green
);
400 fetch_signed_rg_rgtc2(const GLubyte
*map
,
401 GLint rowStride
, GLint i
, GLint j
, GLfloat
*texel
)
404 util_format_signed_fetch_texel_rgtc(rowStride
,
407 util_format_signed_fetch_texel_rgtc(rowStride
,
410 texel
[RCOMP
] = BYTE_TO_FLOAT_TEX(red
);
411 texel
[GCOMP
] = BYTE_TO_FLOAT_TEX(green
);
418 fetch_signed_la_latc2(const GLubyte
*map
,
419 GLint rowStride
, GLint i
, GLint j
, GLfloat
*texel
)
422 util_format_signed_fetch_texel_rgtc(rowStride
,
425 util_format_signed_fetch_texel_rgtc(rowStride
,
430 texel
[BCOMP
] = BYTE_TO_FLOAT_TEX(red
);
431 texel
[ACOMP
] = BYTE_TO_FLOAT_TEX(green
);
435 compressed_fetch_func
436 _mesa_get_compressed_rgtc_func(mesa_format format
)
439 case MESA_FORMAT_R_RGTC1_UNORM
:
440 return fetch_red_rgtc1
;
441 case MESA_FORMAT_L_LATC1_UNORM
:
442 return fetch_l_latc1
;
443 case MESA_FORMAT_R_RGTC1_SNORM
:
444 return fetch_signed_red_rgtc1
;
445 case MESA_FORMAT_L_LATC1_SNORM
:
446 return fetch_signed_l_latc1
;
447 case MESA_FORMAT_RG_RGTC2_UNORM
:
448 return fetch_rg_rgtc2
;
449 case MESA_FORMAT_LA_LATC2_UNORM
:
450 return fetch_la_latc2
;
451 case MESA_FORMAT_RG_RGTC2_SNORM
:
452 return fetch_signed_rg_rgtc2
;
453 case MESA_FORMAT_LA_LATC2_SNORM
:
454 return fetch_signed_la_latc2
;