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];
87 ASSERT(dstFormat
== MESA_FORMAT_R_RGTC1_UNORM
||
88 dstFormat
== MESA_FORMAT_L_LATC1_UNORM
);
90 tempImage
= _mesa_make_temp_ubyte_image(ctx
, dims
,
92 _mesa_get_format_base_format(dstFormat
),
93 srcWidth
, srcHeight
, srcDepth
,
94 srcFormat
, srcType
, srcAddr
,
97 return GL_FALSE
; /* out of memory */
102 dstRowDiff
= dstRowStride
>= (srcWidth
* 2) ? dstRowStride
- (((srcWidth
+ 3) & ~3) * 2) : 0;
103 for (j
= 0; j
< srcHeight
; j
+=4) {
104 if (srcHeight
> j
+ 3) numypixels
= 4;
105 else numypixels
= srcHeight
- j
;
106 srcaddr
= tempImage
+ j
* srcWidth
;
107 for (i
= 0; i
< srcWidth
; i
+= 4) {
108 if (srcWidth
> i
+ 3) numxpixels
= 4;
109 else numxpixels
= srcWidth
- i
;
110 extractsrc_u(srcpixels
, srcaddr
, srcWidth
, numxpixels
, numypixels
, 1);
111 util_format_unsigned_encode_rgtc_ubyte(blkaddr
, srcpixels
, numxpixels
, numypixels
);
112 srcaddr
+= numxpixels
;
115 blkaddr
+= dstRowDiff
;
118 free((void *) tempImage
);
124 _mesa_texstore_signed_red_rgtc1(TEXSTORE_PARAMS
)
127 const GLfloat
*tempImage
= NULL
;
129 int numxpixels
, numypixels
;
130 const GLfloat
*srcaddr
;
131 GLbyte srcpixels
[4][4];
134 ASSERT(dstFormat
== MESA_FORMAT_R_RGTC1_SNORM
||
135 dstFormat
== MESA_FORMAT_L_LATC1_SNORM
);
137 tempImage
= _mesa_make_temp_float_image(ctx
, dims
,
139 _mesa_get_format_base_format(dstFormat
),
140 srcWidth
, srcHeight
, srcDepth
,
141 srcFormat
, srcType
, srcAddr
,
144 return GL_FALSE
; /* out of memory */
146 dst
= (GLbyte
*) dstSlices
[0];
149 dstRowDiff
= dstRowStride
>= (srcWidth
* 2) ? dstRowStride
- (((srcWidth
+ 3) & ~3) * 2) : 0;
150 for (j
= 0; j
< srcHeight
; j
+=4) {
151 if (srcHeight
> j
+ 3) numypixels
= 4;
152 else numypixels
= srcHeight
- j
;
153 srcaddr
= tempImage
+ j
* srcWidth
;
154 for (i
= 0; i
< srcWidth
; i
+= 4) {
155 if (srcWidth
> i
+ 3) numxpixels
= 4;
156 else numxpixels
= srcWidth
- i
;
157 extractsrc_s(srcpixels
, srcaddr
, srcWidth
, numxpixels
, numypixels
, 1);
158 util_format_signed_encode_rgtc_ubyte(blkaddr
, srcpixels
, numxpixels
, numypixels
);
159 srcaddr
+= numxpixels
;
162 blkaddr
+= dstRowDiff
;
165 free((void *) tempImage
);
171 _mesa_texstore_rg_rgtc2(TEXSTORE_PARAMS
)
174 const GLubyte
*tempImage
= NULL
;
176 int numxpixels
, numypixels
;
177 const GLubyte
*srcaddr
;
178 GLubyte srcpixels
[4][4];
182 ASSERT(dstFormat
== MESA_FORMAT_RG_RGTC2_UNORM
||
183 dstFormat
== MESA_FORMAT_LA_LATC2_UNORM
);
185 tempImage
= _mesa_make_temp_ubyte_image(ctx
, dims
,
187 _mesa_get_format_base_format(dstFormat
),
188 srcWidth
, srcHeight
, srcDepth
,
189 srcFormat
, srcType
, srcAddr
,
192 return GL_FALSE
; /* out of memory */
197 dstRowDiff
= dstRowStride
>= (srcWidth
* 4) ? dstRowStride
- (((srcWidth
+ 3) & ~3) * 4) : 0;
198 for (j
= 0; j
< srcHeight
; j
+=4) {
199 if (srcHeight
> j
+ 3) numypixels
= 4;
200 else numypixels
= srcHeight
- j
;
201 srcaddr
= tempImage
+ j
* srcWidth
* 2;
202 for (i
= 0; i
< srcWidth
; i
+= 4) {
203 if (srcWidth
> i
+ 3) numxpixels
= 4;
204 else numxpixels
= srcWidth
- i
;
205 extractsrc_u(srcpixels
, srcaddr
, srcWidth
, numxpixels
, numypixels
, 2);
206 util_format_unsigned_encode_rgtc_ubyte(blkaddr
, srcpixels
, numxpixels
, numypixels
);
209 extractsrc_u(srcpixels
, (GLubyte
*)srcaddr
+ 1, srcWidth
, numxpixels
, numypixels
, 2);
210 util_format_unsigned_encode_rgtc_ubyte(blkaddr
, srcpixels
, numxpixels
, numypixels
);
214 srcaddr
+= numxpixels
* 2;
216 blkaddr
+= dstRowDiff
;
219 free((void *) tempImage
);
225 _mesa_texstore_signed_rg_rgtc2(TEXSTORE_PARAMS
)
228 const GLfloat
*tempImage
= NULL
;
230 int numxpixels
, numypixels
;
231 const GLfloat
*srcaddr
;
232 GLbyte srcpixels
[4][4];
236 ASSERT(dstFormat
== MESA_FORMAT_RG_RGTC2_SNORM
||
237 dstFormat
== MESA_FORMAT_LA_LATC2_SNORM
);
239 tempImage
= _mesa_make_temp_float_image(ctx
, dims
,
241 _mesa_get_format_base_format(dstFormat
),
242 srcWidth
, srcHeight
, srcDepth
,
243 srcFormat
, srcType
, srcAddr
,
246 return GL_FALSE
; /* out of memory */
248 dst
= (GLbyte
*) dstSlices
[0];
251 dstRowDiff
= dstRowStride
>= (srcWidth
* 4) ? dstRowStride
- (((srcWidth
+ 3) & ~3) * 4) : 0;
252 for (j
= 0; j
< srcHeight
; j
+= 4) {
253 if (srcHeight
> j
+ 3) numypixels
= 4;
254 else numypixels
= srcHeight
- j
;
255 srcaddr
= tempImage
+ j
* srcWidth
* 2;
256 for (i
= 0; i
< srcWidth
; i
+= 4) {
257 if (srcWidth
> i
+ 3) numxpixels
= 4;
258 else numxpixels
= srcWidth
- i
;
260 extractsrc_s(srcpixels
, srcaddr
, srcWidth
, numxpixels
, numypixels
, 2);
261 util_format_signed_encode_rgtc_ubyte(blkaddr
, srcpixels
, numxpixels
, numypixels
);
264 extractsrc_s(srcpixels
, srcaddr
+ 1, srcWidth
, numxpixels
, numypixels
, 2);
265 util_format_signed_encode_rgtc_ubyte(blkaddr
, srcpixels
, numxpixels
, numypixels
);
268 srcaddr
+= numxpixels
* 2;
271 blkaddr
+= dstRowDiff
;
274 free((void *) tempImage
);
280 fetch_red_rgtc1(const GLubyte
*map
,
281 GLint rowStride
, GLint i
, GLint j
, GLfloat
*texel
)
284 util_format_unsigned_fetch_texel_rgtc(rowStride
, map
, i
, j
, &red
, 1);
285 texel
[RCOMP
] = UBYTE_TO_FLOAT(red
);
292 fetch_l_latc1(const GLubyte
*map
,
293 GLint rowStride
, GLint i
, GLint j
, GLfloat
*texel
)
296 util_format_unsigned_fetch_texel_rgtc(rowStride
, map
, i
, j
, &red
, 1);
299 texel
[BCOMP
] = UBYTE_TO_FLOAT(red
);
304 fetch_signed_red_rgtc1(const GLubyte
*map
,
305 GLint rowStride
, GLint i
, GLint j
, GLfloat
*texel
)
308 util_format_signed_fetch_texel_rgtc(rowStride
, (const GLbyte
*) map
,
310 texel
[RCOMP
] = BYTE_TO_FLOAT_TEX(red
);
317 fetch_signed_l_latc1(const GLubyte
*map
,
318 GLint rowStride
, GLint i
, GLint j
, GLfloat
*texel
)
321 util_format_signed_fetch_texel_rgtc(rowStride
, (GLbyte
*) map
,
325 texel
[BCOMP
] = BYTE_TO_FLOAT(red
);
330 fetch_rg_rgtc2(const GLubyte
*map
,
331 GLint rowStride
, GLint i
, GLint j
, GLfloat
*texel
)
334 util_format_unsigned_fetch_texel_rgtc(rowStride
,
337 util_format_unsigned_fetch_texel_rgtc(rowStride
,
340 texel
[RCOMP
] = UBYTE_TO_FLOAT(red
);
341 texel
[GCOMP
] = UBYTE_TO_FLOAT(green
);
347 fetch_la_latc2(const GLubyte
*map
,
348 GLint rowStride
, GLint i
, GLint j
, GLfloat
*texel
)
351 util_format_unsigned_fetch_texel_rgtc(rowStride
,
354 util_format_unsigned_fetch_texel_rgtc(rowStride
,
359 texel
[BCOMP
] = UBYTE_TO_FLOAT(red
);
360 texel
[ACOMP
] = UBYTE_TO_FLOAT(green
);
365 fetch_signed_rg_rgtc2(const GLubyte
*map
,
366 GLint rowStride
, GLint i
, GLint j
, GLfloat
*texel
)
369 util_format_signed_fetch_texel_rgtc(rowStride
,
372 util_format_signed_fetch_texel_rgtc(rowStride
,
375 texel
[RCOMP
] = BYTE_TO_FLOAT_TEX(red
);
376 texel
[GCOMP
] = BYTE_TO_FLOAT_TEX(green
);
383 fetch_signed_la_latc2(const GLubyte
*map
,
384 GLint rowStride
, GLint i
, GLint j
, GLfloat
*texel
)
387 util_format_signed_fetch_texel_rgtc(rowStride
,
390 util_format_signed_fetch_texel_rgtc(rowStride
,
395 texel
[BCOMP
] = BYTE_TO_FLOAT_TEX(red
);
396 texel
[ACOMP
] = BYTE_TO_FLOAT_TEX(green
);
400 compressed_fetch_func
401 _mesa_get_compressed_rgtc_func(mesa_format format
)
404 case MESA_FORMAT_R_RGTC1_UNORM
:
405 return fetch_red_rgtc1
;
406 case MESA_FORMAT_L_LATC1_UNORM
:
407 return fetch_l_latc1
;
408 case MESA_FORMAT_R_RGTC1_SNORM
:
409 return fetch_signed_red_rgtc1
;
410 case MESA_FORMAT_L_LATC1_SNORM
:
411 return fetch_signed_l_latc1
;
412 case MESA_FORMAT_RG_RGTC2_UNORM
:
413 return fetch_rg_rgtc2
;
414 case MESA_FORMAT_LA_LATC2_UNORM
:
415 return fetch_la_latc2
;
416 case MESA_FORMAT_RG_RGTC2_SNORM
:
417 return fetch_signed_rg_rgtc2
;
418 case MESA_FORMAT_LA_LATC2_SNORM
:
419 return fetch_signed_la_latc2
;