2 * Copyright (C) 2014 Intel Corporation
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
25 * \file texcompress_bptc.c
26 * GL_ARB_texture_compression_bptc support.
30 #include "texcompress.h"
31 #include "texcompress_bptc.h"
32 #include "texcompress_bptc_tmp.h"
38 fetch_bptc_rgb_float(const GLubyte
*map
,
39 GLint rowStride
, GLint i
, GLint j
,
45 block
= map
+ (((rowStride
+ 3) / 4) * (j
/ 4) + (i
/ 4)) * 16;
47 fetch_rgb_float_from_block(block
, texel
, (i
% 4) + (j
% 4) * 4, is_signed
);
51 fetch_bptc_rgb_signed_float(const GLubyte
*map
,
52 GLint rowStride
, GLint i
, GLint j
,
55 fetch_bptc_rgb_float(map
, rowStride
, i
, j
, texel
, true);
59 fetch_bptc_rgb_unsigned_float(const GLubyte
*map
,
60 GLint rowStride
, GLint i
, GLint j
,
63 fetch_bptc_rgb_float(map
, rowStride
, i
, j
, texel
, false);
67 fetch_bptc_rgba_unorm_bytes(const GLubyte
*map
,
68 GLint rowStride
, GLint i
, GLint j
,
73 block
= map
+ (((rowStride
+ 3) / 4) * (j
/ 4) + (i
/ 4)) * 16;
75 fetch_rgba_unorm_from_block(block
, texel
, (i
% 4) + (j
% 4) * 4);
79 fetch_bptc_rgba_unorm(const GLubyte
*map
,
80 GLint rowStride
, GLint i
, GLint j
,
83 GLubyte texel_bytes
[4];
85 fetch_bptc_rgba_unorm_bytes(map
, rowStride
, i
, j
, texel_bytes
);
87 texel
[RCOMP
] = UBYTE_TO_FLOAT(texel_bytes
[0]);
88 texel
[GCOMP
] = UBYTE_TO_FLOAT(texel_bytes
[1]);
89 texel
[BCOMP
] = UBYTE_TO_FLOAT(texel_bytes
[2]);
90 texel
[ACOMP
] = UBYTE_TO_FLOAT(texel_bytes
[3]);
94 fetch_bptc_srgb_alpha_unorm(const GLubyte
*map
,
95 GLint rowStride
, GLint i
, GLint j
,
98 GLubyte texel_bytes
[4];
100 fetch_bptc_rgba_unorm_bytes(map
, rowStride
, i
, j
, texel_bytes
);
102 texel
[RCOMP
] = util_format_srgb_8unorm_to_linear_float(texel_bytes
[0]);
103 texel
[GCOMP
] = util_format_srgb_8unorm_to_linear_float(texel_bytes
[1]);
104 texel
[BCOMP
] = util_format_srgb_8unorm_to_linear_float(texel_bytes
[2]);
105 texel
[ACOMP
] = UBYTE_TO_FLOAT(texel_bytes
[3]);
108 compressed_fetch_func
109 _mesa_get_bptc_fetch_func(mesa_format format
)
112 case MESA_FORMAT_BPTC_RGBA_UNORM
:
113 return fetch_bptc_rgba_unorm
;
114 case MESA_FORMAT_BPTC_SRGB_ALPHA_UNORM
:
115 return fetch_bptc_srgb_alpha_unorm
;
116 case MESA_FORMAT_BPTC_RGB_SIGNED_FLOAT
:
117 return fetch_bptc_rgb_signed_float
;
118 case MESA_FORMAT_BPTC_RGB_UNSIGNED_FLOAT
:
119 return fetch_bptc_rgb_unsigned_float
;
126 _mesa_texstore_bptc_rgba_unorm(TEXSTORE_PARAMS
)
128 const GLubyte
*pixels
;
129 const GLubyte
*tempImage
= NULL
;
132 if (srcFormat
!= GL_RGBA
||
133 srcType
!= GL_UNSIGNED_BYTE
||
134 ctx
->_ImageTransferState
||
135 srcPacking
->SwapBytes
) {
136 /* convert image to RGBA/ubyte */
137 GLubyte
*tempImageSlices
[1];
138 int rgbaRowStride
= 4 * srcWidth
* sizeof(GLubyte
);
139 tempImage
= malloc(srcWidth
* srcHeight
* 4 * sizeof(GLubyte
));
141 return GL_FALSE
; /* out of memory */
142 tempImageSlices
[0] = (GLubyte
*) tempImage
;
143 _mesa_texstore(ctx
, dims
,
145 #if UTIL_ARCH_LITTLE_ENDIAN
146 MESA_FORMAT_R8G8B8A8_UNORM
,
148 MESA_FORMAT_A8B8G8R8_UNORM
,
150 rgbaRowStride
, tempImageSlices
,
151 srcWidth
, srcHeight
, srcDepth
,
152 srcFormat
, srcType
, srcAddr
,
156 rowstride
= srcWidth
* 4;
158 pixels
= _mesa_image_address2d(srcPacking
, srcAddr
, srcWidth
, srcHeight
,
159 srcFormat
, srcType
, 0, 0);
160 rowstride
= _mesa_image_row_stride(srcPacking
, srcWidth
,
164 compress_rgba_unorm(srcWidth
, srcHeight
,
166 dstSlices
[0], dstRowStride
);
168 free((void *) tempImage
);
174 texstore_bptc_rgb_float(TEXSTORE_PARAMS
,
178 const float *tempImage
= NULL
;
181 if (srcFormat
!= GL_RGB
||
182 srcType
!= GL_FLOAT
||
183 ctx
->_ImageTransferState
||
184 srcPacking
->SwapBytes
) {
185 /* convert image to RGB/float */
186 GLfloat
*tempImageSlices
[1];
187 int rgbRowStride
= 3 * srcWidth
* sizeof(GLfloat
);
188 tempImage
= malloc(srcWidth
* srcHeight
* 3 * sizeof(GLfloat
));
190 return GL_FALSE
; /* out of memory */
191 tempImageSlices
[0] = (GLfloat
*) tempImage
;
192 _mesa_texstore(ctx
, dims
,
194 MESA_FORMAT_RGB_FLOAT32
,
195 rgbRowStride
, (GLubyte
**)tempImageSlices
,
196 srcWidth
, srcHeight
, srcDepth
,
197 srcFormat
, srcType
, srcAddr
,
201 rowstride
= srcWidth
* sizeof(float) * 3;
203 pixels
= _mesa_image_address2d(srcPacking
, srcAddr
, srcWidth
, srcHeight
,
204 srcFormat
, srcType
, 0, 0);
205 rowstride
= _mesa_image_row_stride(srcPacking
, srcWidth
,
209 compress_rgb_float(srcWidth
, srcHeight
,
211 dstSlices
[0], dstRowStride
,
214 free((void *) tempImage
);
220 _mesa_texstore_bptc_rgb_signed_float(TEXSTORE_PARAMS
)
222 assert(dstFormat
== MESA_FORMAT_BPTC_RGB_SIGNED_FLOAT
);
224 return texstore_bptc_rgb_float(ctx
, dims
, baseInternalFormat
,
225 dstFormat
, dstRowStride
, dstSlices
,
226 srcWidth
, srcHeight
, srcDepth
,
233 _mesa_texstore_bptc_rgb_unsigned_float(TEXSTORE_PARAMS
)
235 assert(dstFormat
== MESA_FORMAT_BPTC_RGB_UNSIGNED_FLOAT
);
237 return texstore_bptc_rgb_float(ctx
, dims
, baseInternalFormat
,
238 dstFormat
, dstRowStride
, dstSlices
,
239 srcWidth
, srcHeight
, srcDepth
,
242 false /* unsigned */);