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 "texcompress_rgtc.h"
49 static void unsigned_encode_rgtc_ubyte(GLubyte
*blkaddr
, GLubyte srccolors
[4][4],
50 GLint numxpixels
, GLint numypixels
);
51 static void signed_encode_rgtc_ubyte(GLbyte
*blkaddr
, GLbyte srccolors
[4][4],
52 GLint numxpixels
, GLint numypixels
);
54 static void unsigned_fetch_texel_rgtc(unsigned srcRowStride
, const GLubyte
*pixdata
,
55 unsigned i
, unsigned j
, GLubyte
*value
, unsigned comps
);
57 static void signed_fetch_texel_rgtc(unsigned srcRowStride
, const GLbyte
*pixdata
,
58 unsigned i
, unsigned j
, GLbyte
*value
, unsigned comps
);
60 static void extractsrc_u( GLubyte srcpixels
[4][4], const GLubyte
*srcaddr
,
61 GLint srcRowStride
, GLint numxpixels
, GLint numypixels
, GLint comps
)
64 const GLubyte
*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
] = *curaddr
;
74 static void extractsrc_s( GLbyte srcpixels
[4][4], const GLfloat
*srcaddr
,
75 GLint srcRowStride
, GLint numxpixels
, GLint numypixels
, GLint comps
)
78 const GLfloat
*curaddr
;
79 for (j
= 0; j
< numypixels
; j
++) {
80 curaddr
= srcaddr
+ j
* srcRowStride
* comps
;
81 for (i
= 0; i
< numxpixels
; i
++) {
82 srcpixels
[j
][i
] = FLOAT_TO_BYTE_TEX(*curaddr
);
90 _mesa_texstore_red_rgtc1(TEXSTORE_PARAMS
)
93 const GLubyte
*tempImage
= NULL
;
95 int numxpixels
, numypixels
;
96 const GLubyte
*srcaddr
;
97 GLubyte srcpixels
[4][4];
100 ASSERT(dstFormat
== MESA_FORMAT_R_RGTC1_UNORM
||
101 dstFormat
== MESA_FORMAT_L_LATC1_UNORM
);
103 tempImage
= _mesa_make_temp_ubyte_image(ctx
, dims
,
105 _mesa_get_format_base_format(dstFormat
),
106 srcWidth
, srcHeight
, srcDepth
,
107 srcFormat
, srcType
, srcAddr
,
110 return GL_FALSE
; /* out of memory */
115 dstRowDiff
= dstRowStride
>= (srcWidth
* 2) ? dstRowStride
- (((srcWidth
+ 3) & ~3) * 2) : 0;
116 for (j
= 0; j
< srcHeight
; j
+=4) {
117 if (srcHeight
> j
+ 3) numypixels
= 4;
118 else numypixels
= srcHeight
- j
;
119 srcaddr
= tempImage
+ j
* srcWidth
;
120 for (i
= 0; i
< srcWidth
; i
+= 4) {
121 if (srcWidth
> i
+ 3) numxpixels
= 4;
122 else numxpixels
= srcWidth
- i
;
123 extractsrc_u(srcpixels
, srcaddr
, srcWidth
, numxpixels
, numypixels
, 1);
124 unsigned_encode_rgtc_ubyte(blkaddr
, srcpixels
, numxpixels
, numypixels
);
125 srcaddr
+= numxpixels
;
128 blkaddr
+= dstRowDiff
;
131 free((void *) tempImage
);
137 _mesa_texstore_signed_red_rgtc1(TEXSTORE_PARAMS
)
140 const GLfloat
*tempImage
= NULL
;
142 int numxpixels
, numypixels
;
143 const GLfloat
*srcaddr
;
144 GLbyte srcpixels
[4][4];
147 ASSERT(dstFormat
== MESA_FORMAT_R_RGTC1_SNORM
||
148 dstFormat
== MESA_FORMAT_L_LATC1_SNORM
);
150 tempImage
= _mesa_make_temp_float_image(ctx
, dims
,
152 _mesa_get_format_base_format(dstFormat
),
153 srcWidth
, srcHeight
, srcDepth
,
154 srcFormat
, srcType
, srcAddr
,
157 return GL_FALSE
; /* out of memory */
159 dst
= (GLbyte
*) dstSlices
[0];
162 dstRowDiff
= dstRowStride
>= (srcWidth
* 2) ? dstRowStride
- (((srcWidth
+ 3) & ~3) * 2) : 0;
163 for (j
= 0; j
< srcHeight
; j
+=4) {
164 if (srcHeight
> j
+ 3) numypixels
= 4;
165 else numypixels
= srcHeight
- j
;
166 srcaddr
= tempImage
+ j
* srcWidth
;
167 for (i
= 0; i
< srcWidth
; i
+= 4) {
168 if (srcWidth
> i
+ 3) numxpixels
= 4;
169 else numxpixels
= srcWidth
- i
;
170 extractsrc_s(srcpixels
, srcaddr
, srcWidth
, numxpixels
, numypixels
, 1);
171 signed_encode_rgtc_ubyte(blkaddr
, srcpixels
, numxpixels
, numypixels
);
172 srcaddr
+= numxpixels
;
175 blkaddr
+= dstRowDiff
;
178 free((void *) tempImage
);
184 _mesa_texstore_rg_rgtc2(TEXSTORE_PARAMS
)
187 const GLubyte
*tempImage
= NULL
;
189 int numxpixels
, numypixels
;
190 const GLubyte
*srcaddr
;
191 GLubyte srcpixels
[4][4];
195 ASSERT(dstFormat
== MESA_FORMAT_RG_RGTC2_UNORM
||
196 dstFormat
== MESA_FORMAT_LA_LATC2_UNORM
);
198 tempImage
= _mesa_make_temp_ubyte_image(ctx
, dims
,
200 _mesa_get_format_base_format(dstFormat
),
201 srcWidth
, srcHeight
, srcDepth
,
202 srcFormat
, srcType
, srcAddr
,
205 return GL_FALSE
; /* out of memory */
210 dstRowDiff
= dstRowStride
>= (srcWidth
* 4) ? dstRowStride
- (((srcWidth
+ 3) & ~3) * 4) : 0;
211 for (j
= 0; j
< srcHeight
; j
+=4) {
212 if (srcHeight
> j
+ 3) numypixels
= 4;
213 else numypixels
= srcHeight
- j
;
214 srcaddr
= tempImage
+ j
* srcWidth
* 2;
215 for (i
= 0; i
< srcWidth
; i
+= 4) {
216 if (srcWidth
> i
+ 3) numxpixels
= 4;
217 else numxpixels
= srcWidth
- i
;
218 extractsrc_u(srcpixels
, srcaddr
, srcWidth
, numxpixels
, numypixels
, 2);
219 unsigned_encode_rgtc_ubyte(blkaddr
, srcpixels
, numxpixels
, numypixels
);
222 extractsrc_u(srcpixels
, (GLubyte
*)srcaddr
+ 1, srcWidth
, numxpixels
, numypixels
, 2);
223 unsigned_encode_rgtc_ubyte(blkaddr
, srcpixels
, numxpixels
, numypixels
);
227 srcaddr
+= numxpixels
* 2;
229 blkaddr
+= dstRowDiff
;
232 free((void *) tempImage
);
238 _mesa_texstore_signed_rg_rgtc2(TEXSTORE_PARAMS
)
241 const GLfloat
*tempImage
= NULL
;
243 int numxpixels
, numypixels
;
244 const GLfloat
*srcaddr
;
245 GLbyte srcpixels
[4][4];
249 ASSERT(dstFormat
== MESA_FORMAT_RG_RGTC2_SNORM
||
250 dstFormat
== MESA_FORMAT_LA_LATC2_SNORM
);
252 tempImage
= _mesa_make_temp_float_image(ctx
, dims
,
254 _mesa_get_format_base_format(dstFormat
),
255 srcWidth
, srcHeight
, srcDepth
,
256 srcFormat
, srcType
, srcAddr
,
259 return GL_FALSE
; /* out of memory */
261 dst
= (GLbyte
*) dstSlices
[0];
264 dstRowDiff
= dstRowStride
>= (srcWidth
* 4) ? dstRowStride
- (((srcWidth
+ 3) & ~3) * 4) : 0;
265 for (j
= 0; j
< srcHeight
; j
+= 4) {
266 if (srcHeight
> j
+ 3) numypixels
= 4;
267 else numypixels
= srcHeight
- j
;
268 srcaddr
= tempImage
+ j
* srcWidth
* 2;
269 for (i
= 0; i
< srcWidth
; i
+= 4) {
270 if (srcWidth
> i
+ 3) numxpixels
= 4;
271 else numxpixels
= srcWidth
- i
;
273 extractsrc_s(srcpixels
, srcaddr
, srcWidth
, numxpixels
, numypixels
, 2);
274 signed_encode_rgtc_ubyte(blkaddr
, srcpixels
, numxpixels
, numypixels
);
277 extractsrc_s(srcpixels
, srcaddr
+ 1, srcWidth
, numxpixels
, numypixels
, 2);
278 signed_encode_rgtc_ubyte(blkaddr
, srcpixels
, numxpixels
, numypixels
);
281 srcaddr
+= numxpixels
* 2;
284 blkaddr
+= dstRowDiff
;
287 free((void *) tempImage
);
293 #define TAG(x) unsigned_##x
299 #include "texcompress_rgtc_tmp.h"
306 #define TAG(x) signed_##x
308 #define T_MIN (GLbyte)-128
309 #define T_MAX (GLbyte)127
311 #include "texcompress_rgtc_tmp.h"
321 fetch_red_rgtc1(const GLubyte
*map
,
322 GLint rowStride
, GLint i
, GLint j
, GLfloat
*texel
)
325 unsigned_fetch_texel_rgtc(rowStride
, map
, i
, j
, &red
, 1);
326 texel
[RCOMP
] = UBYTE_TO_FLOAT(red
);
333 fetch_l_latc1(const GLubyte
*map
,
334 GLint rowStride
, GLint i
, GLint j
, GLfloat
*texel
)
337 unsigned_fetch_texel_rgtc(rowStride
, map
, i
, j
, &red
, 1);
340 texel
[BCOMP
] = UBYTE_TO_FLOAT(red
);
345 fetch_signed_red_rgtc1(const GLubyte
*map
,
346 GLint rowStride
, GLint i
, GLint j
, GLfloat
*texel
)
349 signed_fetch_texel_rgtc(rowStride
, (const GLbyte
*) map
,
351 texel
[RCOMP
] = BYTE_TO_FLOAT_TEX(red
);
358 fetch_signed_l_latc1(const GLubyte
*map
,
359 GLint rowStride
, GLint i
, GLint j
, GLfloat
*texel
)
362 signed_fetch_texel_rgtc(rowStride
, (GLbyte
*) map
,
366 texel
[BCOMP
] = BYTE_TO_FLOAT(red
);
371 fetch_rg_rgtc2(const GLubyte
*map
,
372 GLint rowStride
, GLint i
, GLint j
, GLfloat
*texel
)
375 unsigned_fetch_texel_rgtc(rowStride
,
378 unsigned_fetch_texel_rgtc(rowStride
,
381 texel
[RCOMP
] = UBYTE_TO_FLOAT(red
);
382 texel
[GCOMP
] = UBYTE_TO_FLOAT(green
);
388 fetch_la_latc2(const GLubyte
*map
,
389 GLint rowStride
, GLint i
, GLint j
, GLfloat
*texel
)
392 unsigned_fetch_texel_rgtc(rowStride
,
395 unsigned_fetch_texel_rgtc(rowStride
,
400 texel
[BCOMP
] = UBYTE_TO_FLOAT(red
);
401 texel
[ACOMP
] = UBYTE_TO_FLOAT(green
);
406 fetch_signed_rg_rgtc2(const GLubyte
*map
,
407 GLint rowStride
, GLint i
, GLint j
, GLfloat
*texel
)
410 signed_fetch_texel_rgtc(rowStride
,
413 signed_fetch_texel_rgtc(rowStride
,
416 texel
[RCOMP
] = BYTE_TO_FLOAT_TEX(red
);
417 texel
[GCOMP
] = BYTE_TO_FLOAT_TEX(green
);
424 fetch_signed_la_latc2(const GLubyte
*map
,
425 GLint rowStride
, GLint i
, GLint j
, GLfloat
*texel
)
428 signed_fetch_texel_rgtc(rowStride
,
431 signed_fetch_texel_rgtc(rowStride
,
436 texel
[BCOMP
] = BYTE_TO_FLOAT_TEX(red
);
437 texel
[ACOMP
] = BYTE_TO_FLOAT_TEX(green
);
441 compressed_fetch_func
442 _mesa_get_compressed_rgtc_func(mesa_format format
)
445 case MESA_FORMAT_R_RGTC1_UNORM
:
446 return fetch_red_rgtc1
;
447 case MESA_FORMAT_L_LATC1_UNORM
:
448 return fetch_l_latc1
;
449 case MESA_FORMAT_R_RGTC1_SNORM
:
450 return fetch_signed_red_rgtc1
;
451 case MESA_FORMAT_L_LATC1_SNORM
:
452 return fetch_signed_l_latc1
;
453 case MESA_FORMAT_RG_RGTC2_UNORM
:
454 return fetch_rg_rgtc2
;
455 case MESA_FORMAT_LA_LATC2_UNORM
:
456 return fetch_la_latc2
;
457 case MESA_FORMAT_RG_RGTC2_SNORM
:
458 return fetch_signed_rg_rgtc2
;
459 case MESA_FORMAT_LA_LATC2_SNORM
:
460 return fetch_signed_la_latc2
;