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.
42 #include "texcompress.h"
43 #include "util/rgtc.h"
44 #include "texcompress_rgtc.h"
47 static void extractsrc_u( GLubyte srcpixels
[4][4], const GLubyte
*srcaddr
,
48 GLint srcRowStride
, GLint numxpixels
, GLint numypixels
, GLint comps
)
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
;
61 static void extractsrc_s( GLbyte srcpixels
[4][4], const GLfloat
*srcaddr
,
62 GLint srcRowStride
, GLint numxpixels
, GLint numypixels
, GLint comps
)
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
);
77 _mesa_texstore_red_rgtc1(TEXSTORE_PARAMS
)
80 const GLubyte
*tempImage
= NULL
;
82 int numxpixels
, numypixels
;
83 const GLubyte
*srcaddr
;
84 GLubyte srcpixels
[4][4];
86 GLint dstRowDiff
, redRowStride
;
87 GLubyte
*tempImageSlices
[1];
89 assert(dstFormat
== MESA_FORMAT_R_RGTC1_UNORM
||
90 dstFormat
== MESA_FORMAT_L_LATC1_UNORM
);
92 tempImage
= malloc(srcWidth
* srcHeight
* 1 * sizeof(GLubyte
));
94 return GL_FALSE
; /* out of memory */
95 redRowStride
= 1 * srcWidth
* sizeof(GLubyte
);
96 tempImageSlices
[0] = (GLubyte
*) tempImage
;
97 _mesa_texstore(ctx
, dims
,
100 redRowStride
, tempImageSlices
,
101 srcWidth
, srcHeight
, srcDepth
,
102 srcFormat
, srcType
, srcAddr
,
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
;
121 blkaddr
+= dstRowDiff
;
124 free((void *) tempImage
);
130 _mesa_texstore_signed_red_rgtc1(TEXSTORE_PARAMS
)
133 const GLfloat
*tempImage
= NULL
;
135 int numxpixels
, numypixels
;
136 const GLfloat
*srcaddr
;
137 GLbyte srcpixels
[4][4];
139 GLint dstRowDiff
, redRowStride
;
140 GLfloat
*tempImageSlices
[1];
142 assert(dstFormat
== MESA_FORMAT_R_RGTC1_SNORM
||
143 dstFormat
== MESA_FORMAT_L_LATC1_SNORM
);
145 redRowStride
= 1 * srcWidth
* sizeof(GLfloat
);
146 tempImage
= malloc(srcWidth
* srcHeight
* 1 * sizeof(GLfloat
));
148 return GL_FALSE
; /* out of memory */
149 tempImageSlices
[0] = (GLfloat
*) tempImage
;
150 _mesa_texstore(ctx
, dims
,
152 MESA_FORMAT_R_FLOAT32
,
153 redRowStride
, (GLubyte
**)tempImageSlices
,
154 srcWidth
, srcHeight
, srcDepth
,
155 srcFormat
, srcType
, srcAddr
,
158 dst
= (GLbyte
*) dstSlices
[0];
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
;
174 blkaddr
+= dstRowDiff
;
177 free((void *) tempImage
);
183 _mesa_texstore_rg_rgtc2(TEXSTORE_PARAMS
)
186 const GLubyte
*tempImage
= NULL
;
188 int numxpixels
, numypixels
;
189 const GLubyte
*srcaddr
;
190 GLubyte srcpixels
[4][4];
192 GLint dstRowDiff
, rgRowStride
;
193 mesa_format tempFormat
;
194 GLubyte
*tempImageSlices
[1];
196 assert(dstFormat
== MESA_FORMAT_RG_RGTC2_UNORM
||
197 dstFormat
== MESA_FORMAT_LA_LATC2_UNORM
);
199 if (baseInternalFormat
== GL_RG
)
200 tempFormat
= _mesa_little_endian() ? MESA_FORMAT_R8G8_UNORM
201 : MESA_FORMAT_G8R8_UNORM
;
203 tempFormat
= _mesa_little_endian() ? MESA_FORMAT_L8A8_UNORM
204 : MESA_FORMAT_A8L8_UNORM
;
206 rgRowStride
= 2 * srcWidth
* sizeof(GLubyte
);
207 tempImage
= malloc(srcWidth
* srcHeight
* 2 * sizeof(GLubyte
));
209 return GL_FALSE
; /* out of memory */
210 tempImageSlices
[0] = (GLubyte
*) tempImage
;
211 _mesa_texstore(ctx
, dims
,
214 rgRowStride
, tempImageSlices
,
215 srcWidth
, srcHeight
, srcDepth
,
216 srcFormat
, srcType
, srcAddr
,
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
);
234 extractsrc_u(srcpixels
, (GLubyte
*)srcaddr
+ 1, srcWidth
, numxpixels
, numypixels
, 2);
235 util_format_unsigned_encode_rgtc_ubyte(blkaddr
, srcpixels
, numxpixels
, numypixels
);
239 srcaddr
+= numxpixels
* 2;
241 blkaddr
+= dstRowDiff
;
244 free((void *) tempImage
);
250 _mesa_texstore_signed_rg_rgtc2(TEXSTORE_PARAMS
)
253 const GLfloat
*tempImage
= NULL
;
255 int numxpixels
, numypixels
;
256 const GLfloat
*srcaddr
;
257 GLbyte srcpixels
[4][4];
259 GLint dstRowDiff
, rgRowStride
;
260 mesa_format tempFormat
;
261 GLfloat
*tempImageSlices
[1];
263 assert(dstFormat
== MESA_FORMAT_RG_RGTC2_SNORM
||
264 dstFormat
== MESA_FORMAT_LA_LATC2_SNORM
);
266 if (baseInternalFormat
== GL_RG
)
267 tempFormat
= MESA_FORMAT_RG_FLOAT32
;
269 tempFormat
= MESA_FORMAT_LA_FLOAT32
;
271 rgRowStride
= 2 * srcWidth
* sizeof(GLfloat
);
272 tempImage
= malloc(srcWidth
* srcHeight
* 2 * sizeof(GLfloat
));
274 return GL_FALSE
; /* out of memory */
275 tempImageSlices
[0] = (GLfloat
*) tempImage
;
276 _mesa_texstore(ctx
, dims
,
279 rgRowStride
, (GLubyte
**)tempImageSlices
,
280 srcWidth
, srcHeight
, srcDepth
,
281 srcFormat
, srcType
, srcAddr
,
284 dst
= (GLbyte
*) dstSlices
[0];
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
;
296 extractsrc_s(srcpixels
, srcaddr
, srcWidth
, numxpixels
, numypixels
, 2);
297 util_format_signed_encode_rgtc_ubyte(blkaddr
, srcpixels
, numxpixels
, numypixels
);
300 extractsrc_s(srcpixels
, srcaddr
+ 1, srcWidth
, numxpixels
, numypixels
, 2);
301 util_format_signed_encode_rgtc_ubyte(blkaddr
, srcpixels
, numxpixels
, numypixels
);
304 srcaddr
+= numxpixels
* 2;
307 blkaddr
+= dstRowDiff
;
310 free((void *) tempImage
);
316 fetch_red_rgtc1(const GLubyte
*map
,
317 GLint rowStride
, GLint i
, GLint j
, GLfloat
*texel
)
320 util_format_unsigned_fetch_texel_rgtc(rowStride
, map
, i
, j
, &red
, 1);
321 texel
[RCOMP
] = UBYTE_TO_FLOAT(red
);
328 fetch_l_latc1(const GLubyte
*map
,
329 GLint rowStride
, GLint i
, GLint j
, GLfloat
*texel
)
332 util_format_unsigned_fetch_texel_rgtc(rowStride
, map
, i
, j
, &red
, 1);
335 texel
[BCOMP
] = UBYTE_TO_FLOAT(red
);
340 fetch_signed_red_rgtc1(const GLubyte
*map
,
341 GLint rowStride
, GLint i
, GLint j
, GLfloat
*texel
)
344 util_format_signed_fetch_texel_rgtc(rowStride
, (const GLbyte
*) map
,
346 texel
[RCOMP
] = BYTE_TO_FLOAT_TEX(red
);
353 fetch_signed_l_latc1(const GLubyte
*map
,
354 GLint rowStride
, GLint i
, GLint j
, GLfloat
*texel
)
357 util_format_signed_fetch_texel_rgtc(rowStride
, (GLbyte
*) map
,
361 texel
[BCOMP
] = BYTE_TO_FLOAT(red
);
366 fetch_rg_rgtc2(const GLubyte
*map
,
367 GLint rowStride
, GLint i
, GLint j
, GLfloat
*texel
)
370 util_format_unsigned_fetch_texel_rgtc(rowStride
,
373 util_format_unsigned_fetch_texel_rgtc(rowStride
,
376 texel
[RCOMP
] = UBYTE_TO_FLOAT(red
);
377 texel
[GCOMP
] = UBYTE_TO_FLOAT(green
);
383 fetch_la_latc2(const GLubyte
*map
,
384 GLint rowStride
, GLint i
, GLint j
, GLfloat
*texel
)
387 util_format_unsigned_fetch_texel_rgtc(rowStride
,
390 util_format_unsigned_fetch_texel_rgtc(rowStride
,
395 texel
[BCOMP
] = UBYTE_TO_FLOAT(red
);
396 texel
[ACOMP
] = UBYTE_TO_FLOAT(green
);
401 fetch_signed_rg_rgtc2(const GLubyte
*map
,
402 GLint rowStride
, GLint i
, GLint j
, GLfloat
*texel
)
405 util_format_signed_fetch_texel_rgtc(rowStride
,
408 util_format_signed_fetch_texel_rgtc(rowStride
,
411 texel
[RCOMP
] = BYTE_TO_FLOAT_TEX(red
);
412 texel
[GCOMP
] = BYTE_TO_FLOAT_TEX(green
);
419 fetch_signed_la_latc2(const GLubyte
*map
,
420 GLint rowStride
, GLint i
, GLint j
, GLfloat
*texel
)
423 util_format_signed_fetch_texel_rgtc(rowStride
,
426 util_format_signed_fetch_texel_rgtc(rowStride
,
431 texel
[BCOMP
] = BYTE_TO_FLOAT_TEX(red
);
432 texel
[ACOMP
] = BYTE_TO_FLOAT_TEX(green
);
436 compressed_fetch_func
437 _mesa_get_compressed_rgtc_func(mesa_format 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
;