mesa: Remove _mesa_make_temp_ubyte_image
[mesa.git] / src / mesa / main / texcompress_rgtc.c
1 /*
2 * Copyright (C) 2011 Red Hat Inc.
3 *
4 * block compression parts are:
5 * Copyright (C) 2004 Roland Scheidegger All Rights Reserved.
6 *
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:
13 *
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
16 * Software.
17 *
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.
25 *
26 * Author:
27 * Dave Airlie
28 */
29
30 /**
31 * \file texcompress_rgtc.c
32 * GL_EXT_texture_compression_rgtc support.
33 */
34
35
36 #include "glheader.h"
37 #include "imports.h"
38 #include "colormac.h"
39 #include "image.h"
40 #include "macros.h"
41 #include "mipmap.h"
42 #include "texcompress.h"
43 #include "util/rgtc.h"
44 #include "texcompress_rgtc.h"
45 #include "texstore.h"
46
47 static void extractsrc_u( GLubyte srcpixels[4][4], const GLubyte *srcaddr,
48 GLint srcRowStride, GLint numxpixels, GLint numypixels, GLint comps)
49 {
50 GLubyte i, j;
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;
56 curaddr += comps;
57 }
58 }
59 }
60
61 static void extractsrc_s( GLbyte srcpixels[4][4], const GLfloat *srcaddr,
62 GLint srcRowStride, GLint numxpixels, GLint numypixels, GLint comps)
63 {
64 GLubyte i, j;
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);
70 curaddr += comps;
71 }
72 }
73 }
74
75
76 GLboolean
77 _mesa_texstore_red_rgtc1(TEXSTORE_PARAMS)
78 {
79 GLubyte *dst;
80 const GLubyte *tempImage = NULL;
81 int i, j;
82 int numxpixels, numypixels;
83 const GLubyte *srcaddr;
84 GLubyte srcpixels[4][4];
85 GLubyte *blkaddr;
86 GLint dstRowDiff, redRowStride;
87 GLubyte *tempImageSlices[1];
88
89 ASSERT(dstFormat == MESA_FORMAT_R_RGTC1_UNORM ||
90 dstFormat == MESA_FORMAT_L_LATC1_UNORM);
91
92 tempImage = malloc(srcWidth * srcHeight * 1 * sizeof(GLubyte));
93 if (!tempImage)
94 return GL_FALSE; /* out of memory */
95 redRowStride = 1 * srcWidth * sizeof(GLubyte);
96 tempImageSlices[0] = (GLubyte *) tempImage;
97 _mesa_texstore(ctx, dims,
98 baseInternalFormat,
99 MESA_FORMAT_R_UNORM8,
100 redRowStride, tempImageSlices,
101 srcWidth, srcHeight, srcDepth,
102 srcFormat, srcType, srcAddr,
103 srcPacking);
104
105 dst = dstSlices[0];
106
107 blkaddr = dst;
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;
119 blkaddr += 8;
120 }
121 blkaddr += dstRowDiff;
122 }
123
124 free((void *) tempImage);
125
126 return GL_TRUE;
127 }
128
129 GLboolean
130 _mesa_texstore_signed_red_rgtc1(TEXSTORE_PARAMS)
131 {
132 GLbyte *dst;
133 const GLfloat *tempImage = NULL;
134 int i, j;
135 int numxpixels, numypixels;
136 const GLfloat *srcaddr;
137 GLbyte srcpixels[4][4];
138 GLbyte *blkaddr;
139 GLint dstRowDiff;
140 ASSERT(dstFormat == MESA_FORMAT_R_RGTC1_SNORM ||
141 dstFormat == MESA_FORMAT_L_LATC1_SNORM);
142
143 tempImage = _mesa_make_temp_float_image(ctx, dims,
144 baseInternalFormat,
145 _mesa_get_format_base_format(dstFormat),
146 srcWidth, srcHeight, srcDepth,
147 srcFormat, srcType, srcAddr,
148 srcPacking, 0x0);
149 if (!tempImage)
150 return GL_FALSE; /* out of memory */
151
152 dst = (GLbyte *) dstSlices[0];
153
154 blkaddr = dst;
155 dstRowDiff = dstRowStride >= (srcWidth * 2) ? dstRowStride - (((srcWidth + 3) & ~3) * 2) : 0;
156 for (j = 0; j < srcHeight; j+=4) {
157 if (srcHeight > j + 3) numypixels = 4;
158 else numypixels = srcHeight - j;
159 srcaddr = tempImage + j * srcWidth;
160 for (i = 0; i < srcWidth; i += 4) {
161 if (srcWidth > i + 3) numxpixels = 4;
162 else numxpixels = srcWidth - i;
163 extractsrc_s(srcpixels, srcaddr, srcWidth, numxpixels, numypixels, 1);
164 util_format_signed_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
165 srcaddr += numxpixels;
166 blkaddr += 8;
167 }
168 blkaddr += dstRowDiff;
169 }
170
171 free((void *) tempImage);
172
173 return GL_TRUE;
174 }
175
176 GLboolean
177 _mesa_texstore_rg_rgtc2(TEXSTORE_PARAMS)
178 {
179 GLubyte *dst;
180 const GLubyte *tempImage = NULL;
181 int i, j;
182 int numxpixels, numypixels;
183 const GLubyte *srcaddr;
184 GLubyte srcpixels[4][4];
185 GLubyte *blkaddr;
186 GLint dstRowDiff, rgRowStride;
187 mesa_format tempFormat;
188 GLubyte *tempImageSlices[1];
189
190 ASSERT(dstFormat == MESA_FORMAT_RG_RGTC2_UNORM ||
191 dstFormat == MESA_FORMAT_LA_LATC2_UNORM);
192
193 if (baseInternalFormat == GL_RG)
194 tempFormat = MESA_FORMAT_R8G8_UNORM;
195 else
196 tempFormat = MESA_FORMAT_L8A8_UNORM;
197
198 rgRowStride = 2 * srcWidth * sizeof(GLubyte);
199 tempImage = malloc(srcWidth * srcHeight * 2 * sizeof(GLubyte));
200 if (!tempImage)
201 return GL_FALSE; /* out of memory */
202 tempImageSlices[0] = (GLubyte *) tempImage;
203 _mesa_texstore(ctx, dims,
204 baseInternalFormat,
205 tempFormat,
206 rgRowStride, tempImageSlices,
207 srcWidth, srcHeight, srcDepth,
208 srcFormat, srcType, srcAddr,
209 srcPacking);
210
211 dst = dstSlices[0];
212
213 blkaddr = dst;
214 dstRowDiff = dstRowStride >= (srcWidth * 4) ? dstRowStride - (((srcWidth + 3) & ~3) * 4) : 0;
215 for (j = 0; j < srcHeight; j+=4) {
216 if (srcHeight > j + 3) numypixels = 4;
217 else numypixels = srcHeight - j;
218 srcaddr = tempImage + j * srcWidth * 2;
219 for (i = 0; i < srcWidth; i += 4) {
220 if (srcWidth > i + 3) numxpixels = 4;
221 else numxpixels = srcWidth - i;
222 extractsrc_u(srcpixels, srcaddr, srcWidth, numxpixels, numypixels, 2);
223 util_format_unsigned_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
224
225 blkaddr += 8;
226 extractsrc_u(srcpixels, (GLubyte *)srcaddr + 1, srcWidth, numxpixels, numypixels, 2);
227 util_format_unsigned_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
228
229 blkaddr += 8;
230
231 srcaddr += numxpixels * 2;
232 }
233 blkaddr += dstRowDiff;
234 }
235
236 free((void *) tempImage);
237
238 return GL_TRUE;
239 }
240
241 GLboolean
242 _mesa_texstore_signed_rg_rgtc2(TEXSTORE_PARAMS)
243 {
244 GLbyte *dst;
245 const GLfloat *tempImage = NULL;
246 int i, j;
247 int numxpixels, numypixels;
248 const GLfloat *srcaddr;
249 GLbyte srcpixels[4][4];
250 GLbyte *blkaddr;
251 GLint dstRowDiff;
252
253 ASSERT(dstFormat == MESA_FORMAT_RG_RGTC2_SNORM ||
254 dstFormat == MESA_FORMAT_LA_LATC2_SNORM);
255
256 tempImage = _mesa_make_temp_float_image(ctx, dims,
257 baseInternalFormat,
258 _mesa_get_format_base_format(dstFormat),
259 srcWidth, srcHeight, srcDepth,
260 srcFormat, srcType, srcAddr,
261 srcPacking, 0x0);
262 if (!tempImage)
263 return GL_FALSE; /* out of memory */
264
265 dst = (GLbyte *) dstSlices[0];
266
267 blkaddr = dst;
268 dstRowDiff = dstRowStride >= (srcWidth * 4) ? dstRowStride - (((srcWidth + 3) & ~3) * 4) : 0;
269 for (j = 0; j < srcHeight; j += 4) {
270 if (srcHeight > j + 3) numypixels = 4;
271 else numypixels = srcHeight - j;
272 srcaddr = tempImage + j * srcWidth * 2;
273 for (i = 0; i < srcWidth; i += 4) {
274 if (srcWidth > i + 3) numxpixels = 4;
275 else numxpixels = srcWidth - i;
276
277 extractsrc_s(srcpixels, srcaddr, srcWidth, numxpixels, numypixels, 2);
278 util_format_signed_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
279 blkaddr += 8;
280
281 extractsrc_s(srcpixels, srcaddr + 1, srcWidth, numxpixels, numypixels, 2);
282 util_format_signed_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
283 blkaddr += 8;
284
285 srcaddr += numxpixels * 2;
286
287 }
288 blkaddr += dstRowDiff;
289 }
290
291 free((void *) tempImage);
292
293 return GL_TRUE;
294 }
295
296 static void
297 fetch_red_rgtc1(const GLubyte *map,
298 GLint rowStride, GLint i, GLint j, GLfloat *texel)
299 {
300 GLubyte red;
301 util_format_unsigned_fetch_texel_rgtc(rowStride, map, i, j, &red, 1);
302 texel[RCOMP] = UBYTE_TO_FLOAT(red);
303 texel[GCOMP] = 0.0;
304 texel[BCOMP] = 0.0;
305 texel[ACOMP] = 1.0;
306 }
307
308 static void
309 fetch_l_latc1(const GLubyte *map,
310 GLint rowStride, GLint i, GLint j, GLfloat *texel)
311 {
312 GLubyte red;
313 util_format_unsigned_fetch_texel_rgtc(rowStride, map, i, j, &red, 1);
314 texel[RCOMP] =
315 texel[GCOMP] =
316 texel[BCOMP] = UBYTE_TO_FLOAT(red);
317 texel[ACOMP] = 1.0;
318 }
319
320 static void
321 fetch_signed_red_rgtc1(const GLubyte *map,
322 GLint rowStride, GLint i, GLint j, GLfloat *texel)
323 {
324 GLbyte red;
325 util_format_signed_fetch_texel_rgtc(rowStride, (const GLbyte *) map,
326 i, j, &red, 1);
327 texel[RCOMP] = BYTE_TO_FLOAT_TEX(red);
328 texel[GCOMP] = 0.0;
329 texel[BCOMP] = 0.0;
330 texel[ACOMP] = 1.0;
331 }
332
333 static void
334 fetch_signed_l_latc1(const GLubyte *map,
335 GLint rowStride, GLint i, GLint j, GLfloat *texel)
336 {
337 GLbyte red;
338 util_format_signed_fetch_texel_rgtc(rowStride, (GLbyte *) map,
339 i, j, &red, 1);
340 texel[RCOMP] =
341 texel[GCOMP] =
342 texel[BCOMP] = BYTE_TO_FLOAT(red);
343 texel[ACOMP] = 1.0;
344 }
345
346 static void
347 fetch_rg_rgtc2(const GLubyte *map,
348 GLint rowStride, GLint i, GLint j, GLfloat *texel)
349 {
350 GLubyte red, green;
351 util_format_unsigned_fetch_texel_rgtc(rowStride,
352 map,
353 i, j, &red, 2);
354 util_format_unsigned_fetch_texel_rgtc(rowStride,
355 map + 8,
356 i, j, &green, 2);
357 texel[RCOMP] = UBYTE_TO_FLOAT(red);
358 texel[GCOMP] = UBYTE_TO_FLOAT(green);
359 texel[BCOMP] = 0.0;
360 texel[ACOMP] = 1.0;
361 }
362
363 static void
364 fetch_la_latc2(const GLubyte *map,
365 GLint rowStride, GLint i, GLint j, GLfloat *texel)
366 {
367 GLubyte red, green;
368 util_format_unsigned_fetch_texel_rgtc(rowStride,
369 map,
370 i, j, &red, 2);
371 util_format_unsigned_fetch_texel_rgtc(rowStride,
372 map + 8,
373 i, j, &green, 2);
374 texel[RCOMP] =
375 texel[GCOMP] =
376 texel[BCOMP] = UBYTE_TO_FLOAT(red);
377 texel[ACOMP] = UBYTE_TO_FLOAT(green);
378 }
379
380
381 static void
382 fetch_signed_rg_rgtc2(const GLubyte *map,
383 GLint rowStride, GLint i, GLint j, GLfloat *texel)
384 {
385 GLbyte red, green;
386 util_format_signed_fetch_texel_rgtc(rowStride,
387 (GLbyte *) map,
388 i, j, &red, 2);
389 util_format_signed_fetch_texel_rgtc(rowStride,
390 (GLbyte *) map + 8,
391 i, j, &green, 2);
392 texel[RCOMP] = BYTE_TO_FLOAT_TEX(red);
393 texel[GCOMP] = BYTE_TO_FLOAT_TEX(green);
394 texel[BCOMP] = 0.0;
395 texel[ACOMP] = 1.0;
396 }
397
398
399 static void
400 fetch_signed_la_latc2(const GLubyte *map,
401 GLint rowStride, GLint i, GLint j, GLfloat *texel)
402 {
403 GLbyte red, green;
404 util_format_signed_fetch_texel_rgtc(rowStride,
405 (GLbyte *) map,
406 i, j, &red, 2);
407 util_format_signed_fetch_texel_rgtc(rowStride,
408 (GLbyte *) map + 8,
409 i, j, &green, 2);
410 texel[RCOMP] =
411 texel[GCOMP] =
412 texel[BCOMP] = BYTE_TO_FLOAT_TEX(red);
413 texel[ACOMP] = BYTE_TO_FLOAT_TEX(green);
414 }
415
416
417 compressed_fetch_func
418 _mesa_get_compressed_rgtc_func(mesa_format format)
419 {
420 switch (format) {
421 case MESA_FORMAT_R_RGTC1_UNORM:
422 return fetch_red_rgtc1;
423 case MESA_FORMAT_L_LATC1_UNORM:
424 return fetch_l_latc1;
425 case MESA_FORMAT_R_RGTC1_SNORM:
426 return fetch_signed_red_rgtc1;
427 case MESA_FORMAT_L_LATC1_SNORM:
428 return fetch_signed_l_latc1;
429 case MESA_FORMAT_RG_RGTC2_UNORM:
430 return fetch_rg_rgtc2;
431 case MESA_FORMAT_LA_LATC2_UNORM:
432 return fetch_la_latc2;
433 case MESA_FORMAT_RG_RGTC2_SNORM:
434 return fetch_signed_rg_rgtc2;
435 case MESA_FORMAT_LA_LATC2_SNORM:
436 return fetch_signed_la_latc2;
437 default:
438 return NULL;
439 }
440 }