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 "mfeatures.h"
43 #include "texcompress.h"
44 #include "texcompress_rgtc.h"
46 #include "swrast/s_context.h"
51 static void unsigned_encode_rgtc_ubyte(GLubyte
*blkaddr
, GLubyte srccolors
[4][4],
52 GLint numxpixels
, GLint numypixels
);
53 static void signed_encode_rgtc_ubyte(GLbyte
*blkaddr
, GLbyte srccolors
[4][4],
54 GLint numxpixels
, GLint numypixels
);
56 static void unsigned_fetch_texel_rgtc(unsigned srcRowStride
, const GLubyte
*pixdata
,
57 unsigned i
, unsigned j
, GLubyte
*value
, unsigned comps
);
59 static void signed_fetch_texel_rgtc(unsigned srcRowStride
, const GLbyte
*pixdata
,
60 unsigned i
, unsigned j
, GLbyte
*value
, unsigned comps
);
62 static void extractsrc_u( GLubyte srcpixels
[4][4], const GLubyte
*srcaddr
,
63 GLint srcRowStride
, GLint numxpixels
, GLint numypixels
, GLint comps
)
66 const GLubyte
*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
;
76 static void extractsrc_s( GLbyte srcpixels
[4][4], const GLfloat
*srcaddr
,
77 GLint srcRowStride
, GLint numxpixels
, GLint numypixels
, GLint comps
)
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
);
92 _mesa_texstore_red_rgtc1(TEXSTORE_PARAMS
)
95 const GLubyte
*tempImage
= NULL
;
97 int numxpixels
, numypixels
;
98 const GLubyte
*srcaddr
;
99 GLubyte srcpixels
[4][4];
102 ASSERT(dstFormat
== MESA_FORMAT_RED_RGTC1
||
103 dstFormat
== MESA_FORMAT_L_LATC1
);
105 tempImage
= _mesa_make_temp_ubyte_image(ctx
, dims
,
107 _mesa_get_format_base_format(dstFormat
),
108 srcWidth
, srcHeight
, srcDepth
,
109 srcFormat
, srcType
, srcAddr
,
112 return GL_FALSE
; /* out of memory */
117 dstRowDiff
= dstRowStride
>= (srcWidth
* 2) ? dstRowStride
- (((srcWidth
+ 3) & ~3) * 2) : 0;
118 for (j
= 0; j
< srcHeight
; j
+=4) {
119 if (srcHeight
> j
+ 3) numypixels
= 4;
120 else numypixels
= srcHeight
- j
;
121 srcaddr
= tempImage
+ j
* srcWidth
;
122 for (i
= 0; i
< srcWidth
; i
+= 4) {
123 if (srcWidth
> i
+ 3) numxpixels
= 4;
124 else numxpixels
= srcWidth
- i
;
125 extractsrc_u(srcpixels
, srcaddr
, srcWidth
, numxpixels
, numypixels
, 1);
126 unsigned_encode_rgtc_ubyte(blkaddr
, srcpixels
, numxpixels
, numypixels
);
127 srcaddr
+= numxpixels
;
130 blkaddr
+= dstRowDiff
;
133 free((void *) tempImage
);
139 _mesa_texstore_signed_red_rgtc1(TEXSTORE_PARAMS
)
142 const GLfloat
*tempImage
= NULL
;
144 int numxpixels
, numypixels
;
145 const GLfloat
*srcaddr
;
146 GLbyte srcpixels
[4][4];
149 ASSERT(dstFormat
== MESA_FORMAT_SIGNED_RED_RGTC1
||
150 dstFormat
== MESA_FORMAT_SIGNED_L_LATC1
);
152 tempImage
= _mesa_make_temp_float_image(ctx
, dims
,
154 _mesa_get_format_base_format(dstFormat
),
155 srcWidth
, srcHeight
, srcDepth
,
156 srcFormat
, srcType
, srcAddr
,
159 return GL_FALSE
; /* out of memory */
161 dst
= (GLbyte
*) dstSlices
[0];
164 dstRowDiff
= dstRowStride
>= (srcWidth
* 2) ? dstRowStride
- (((srcWidth
+ 3) & ~3) * 2) : 0;
165 for (j
= 0; j
< srcHeight
; j
+=4) {
166 if (srcHeight
> j
+ 3) numypixels
= 4;
167 else numypixels
= srcHeight
- j
;
168 srcaddr
= tempImage
+ j
* srcWidth
;
169 for (i
= 0; i
< srcWidth
; i
+= 4) {
170 if (srcWidth
> i
+ 3) numxpixels
= 4;
171 else numxpixels
= srcWidth
- i
;
172 extractsrc_s(srcpixels
, srcaddr
, srcWidth
, numxpixels
, numypixels
, 1);
173 signed_encode_rgtc_ubyte(blkaddr
, srcpixels
, numxpixels
, numypixels
);
174 srcaddr
+= numxpixels
;
177 blkaddr
+= dstRowDiff
;
180 free((void *) tempImage
);
186 _mesa_texstore_rg_rgtc2(TEXSTORE_PARAMS
)
189 const GLubyte
*tempImage
= NULL
;
191 int numxpixels
, numypixels
;
192 const GLubyte
*srcaddr
;
193 GLubyte srcpixels
[4][4];
197 ASSERT(dstFormat
== MESA_FORMAT_RG_RGTC2
||
198 dstFormat
== MESA_FORMAT_LA_LATC2
);
200 tempImage
= _mesa_make_temp_ubyte_image(ctx
, dims
,
202 _mesa_get_format_base_format(dstFormat
),
203 srcWidth
, srcHeight
, srcDepth
,
204 srcFormat
, srcType
, srcAddr
,
207 return GL_FALSE
; /* out of memory */
212 dstRowDiff
= dstRowStride
>= (srcWidth
* 4) ? dstRowStride
- (((srcWidth
+ 3) & ~3) * 4) : 0;
213 for (j
= 0; j
< srcHeight
; j
+=4) {
214 if (srcHeight
> j
+ 3) numypixels
= 4;
215 else numypixels
= srcHeight
- j
;
216 srcaddr
= tempImage
+ j
* srcWidth
* 2;
217 for (i
= 0; i
< srcWidth
; i
+= 4) {
218 if (srcWidth
> i
+ 3) numxpixels
= 4;
219 else numxpixels
= srcWidth
- i
;
220 extractsrc_u(srcpixels
, srcaddr
, srcWidth
, numxpixels
, numypixels
, 2);
221 unsigned_encode_rgtc_ubyte(blkaddr
, srcpixels
, numxpixels
, numypixels
);
224 extractsrc_u(srcpixels
, (GLubyte
*)srcaddr
+ 1, srcWidth
, numxpixels
, numypixels
, 2);
225 unsigned_encode_rgtc_ubyte(blkaddr
, srcpixels
, numxpixels
, numypixels
);
229 srcaddr
+= numxpixels
* 2;
231 blkaddr
+= dstRowDiff
;
234 free((void *) tempImage
);
240 _mesa_texstore_signed_rg_rgtc2(TEXSTORE_PARAMS
)
243 const GLfloat
*tempImage
= NULL
;
245 int numxpixels
, numypixels
;
246 const GLfloat
*srcaddr
;
247 GLbyte srcpixels
[4][4];
251 ASSERT(dstFormat
== MESA_FORMAT_SIGNED_RG_RGTC2
||
252 dstFormat
== MESA_FORMAT_SIGNED_LA_LATC2
);
254 tempImage
= _mesa_make_temp_float_image(ctx
, dims
,
256 _mesa_get_format_base_format(dstFormat
),
257 srcWidth
, srcHeight
, srcDepth
,
258 srcFormat
, srcType
, srcAddr
,
261 return GL_FALSE
; /* out of memory */
263 dst
= (GLbyte
*) dstSlices
[0];
266 dstRowDiff
= dstRowStride
>= (srcWidth
* 4) ? dstRowStride
- (((srcWidth
+ 3) & ~3) * 4) : 0;
267 for (j
= 0; j
< srcHeight
; j
+= 4) {
268 if (srcHeight
> j
+ 3) numypixels
= 4;
269 else numypixels
= srcHeight
- j
;
270 srcaddr
= tempImage
+ j
* srcWidth
* 2;
271 for (i
= 0; i
< srcWidth
; i
+= 4) {
272 if (srcWidth
> i
+ 3) numxpixels
= 4;
273 else numxpixels
= srcWidth
- i
;
275 extractsrc_s(srcpixels
, srcaddr
, srcWidth
, numxpixels
, numypixels
, 2);
276 signed_encode_rgtc_ubyte(blkaddr
, srcpixels
, numxpixels
, numypixels
);
279 extractsrc_s(srcpixels
, srcaddr
+ 1, srcWidth
, numxpixels
, numypixels
, 2);
280 signed_encode_rgtc_ubyte(blkaddr
, srcpixels
, numxpixels
, numypixels
);
283 srcaddr
+= numxpixels
* 2;
286 blkaddr
+= dstRowDiff
;
289 free((void *) tempImage
);
295 _mesa_fetch_texel_2d_f_red_rgtc1(const struct swrast_texture_image
*texImage
,
296 GLint i
, GLint j
, GLint k
, GLfloat
*texel
)
299 unsigned_fetch_texel_rgtc(texImage
->RowStride
, texImage
->Map
,
301 texel
[RCOMP
] = UBYTE_TO_FLOAT(red
);
308 _mesa_fetch_texel_2d_f_signed_red_rgtc1(const struct swrast_texture_image
*texImage
,
309 GLint i
, GLint j
, GLint k
, GLfloat
*texel
)
312 signed_fetch_texel_rgtc(texImage
->RowStride
, (GLbyte
*)(texImage
->Map
),
314 texel
[RCOMP
] = BYTE_TO_FLOAT_TEX(red
);
321 _mesa_fetch_texel_2d_f_rg_rgtc2(const struct swrast_texture_image
*texImage
,
322 GLint i
, GLint j
, GLint k
, GLfloat
*texel
)
325 unsigned_fetch_texel_rgtc(texImage
->RowStride
, texImage
->Map
,
327 unsigned_fetch_texel_rgtc(texImage
->RowStride
, texImage
->Map
+ 8,
329 texel
[RCOMP
] = UBYTE_TO_FLOAT(red
);
330 texel
[GCOMP
] = UBYTE_TO_FLOAT(green
);
336 _mesa_fetch_texel_2d_f_signed_rg_rgtc2(const struct swrast_texture_image
*texImage
,
337 GLint i
, GLint j
, GLint k
, GLfloat
*texel
)
340 signed_fetch_texel_rgtc(texImage
->RowStride
, (GLbyte
*)(texImage
->Map
),
342 signed_fetch_texel_rgtc(texImage
->RowStride
, (GLbyte
*)(texImage
->Map
) + 8,
344 texel
[RCOMP
] = BYTE_TO_FLOAT_TEX(red
);
345 texel
[GCOMP
] = BYTE_TO_FLOAT_TEX(green
);
351 _mesa_fetch_texel_2d_f_l_latc1(const struct swrast_texture_image
*texImage
,
352 GLint i
, GLint j
, GLint k
, GLfloat
*texel
)
355 unsigned_fetch_texel_rgtc(texImage
->RowStride
, texImage
->Map
,
359 texel
[BCOMP
] = UBYTE_TO_FLOAT(red
);
364 _mesa_fetch_texel_2d_f_signed_l_latc1(const struct swrast_texture_image
*texImage
,
365 GLint i
, GLint j
, GLint k
, GLfloat
*texel
)
368 signed_fetch_texel_rgtc(texImage
->RowStride
, (GLbyte
*)(texImage
->Map
),
372 texel
[BCOMP
] = BYTE_TO_FLOAT_TEX(red
);
377 _mesa_fetch_texel_2d_f_la_latc2(const struct swrast_texture_image
*texImage
,
378 GLint i
, GLint j
, GLint k
, GLfloat
*texel
)
381 unsigned_fetch_texel_rgtc(texImage
->RowStride
, texImage
->Map
,
383 unsigned_fetch_texel_rgtc(texImage
->RowStride
, texImage
->Map
+ 8,
387 texel
[BCOMP
] = UBYTE_TO_FLOAT(red
);
388 texel
[ACOMP
] = UBYTE_TO_FLOAT(green
);
392 _mesa_fetch_texel_2d_f_signed_la_latc2(const struct swrast_texture_image
*texImage
,
393 GLint i
, GLint j
, GLint k
, GLfloat
*texel
)
396 signed_fetch_texel_rgtc(texImage
->RowStride
, (GLbyte
*)(texImage
->Map
),
398 signed_fetch_texel_rgtc(texImage
->RowStride
, (GLbyte
*)(texImage
->Map
) + 8,
402 texel
[BCOMP
] = BYTE_TO_FLOAT_TEX(red
);
403 texel
[ACOMP
] = BYTE_TO_FLOAT_TEX(green
);
406 #define TAG(x) unsigned_##x
412 #include "texcompress_rgtc_tmp.h"
419 #define TAG(x) signed_##x
421 #define T_MIN (GLbyte)-128
422 #define T_MAX (GLbyte)127
424 #include "texcompress_rgtc_tmp.h"