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 _mesa_little_endian() ? MESA_FORMAT_R8G8B8A8_UNORM
146 : MESA_FORMAT_A8B8G8R8_UNORM
,
147 rgbaRowStride
, tempImageSlices
,
148 srcWidth
, srcHeight
, srcDepth
,
149 srcFormat
, srcType
, srcAddr
,
153 rowstride
= srcWidth
* 4;
155 pixels
= _mesa_image_address2d(srcPacking
, srcAddr
, srcWidth
, srcHeight
,
156 srcFormat
, srcType
, 0, 0);
157 rowstride
= _mesa_image_row_stride(srcPacking
, srcWidth
,
161 compress_rgba_unorm(srcWidth
, srcHeight
,
163 dstSlices
[0], dstRowStride
);
165 free((void *) tempImage
);
171 texstore_bptc_rgb_float(TEXSTORE_PARAMS
,
175 const float *tempImage
= NULL
;
178 if (srcFormat
!= GL_RGB
||
179 srcType
!= GL_FLOAT
||
180 ctx
->_ImageTransferState
||
181 srcPacking
->SwapBytes
) {
182 /* convert image to RGB/float */
183 GLfloat
*tempImageSlices
[1];
184 int rgbRowStride
= 3 * srcWidth
* sizeof(GLfloat
);
185 tempImage
= malloc(srcWidth
* srcHeight
* 3 * sizeof(GLfloat
));
187 return GL_FALSE
; /* out of memory */
188 tempImageSlices
[0] = (GLfloat
*) tempImage
;
189 _mesa_texstore(ctx
, dims
,
191 MESA_FORMAT_RGB_FLOAT32
,
192 rgbRowStride
, (GLubyte
**)tempImageSlices
,
193 srcWidth
, srcHeight
, srcDepth
,
194 srcFormat
, srcType
, srcAddr
,
198 rowstride
= srcWidth
* sizeof(float) * 3;
200 pixels
= _mesa_image_address2d(srcPacking
, srcAddr
, srcWidth
, srcHeight
,
201 srcFormat
, srcType
, 0, 0);
202 rowstride
= _mesa_image_row_stride(srcPacking
, srcWidth
,
206 compress_rgb_float(srcWidth
, srcHeight
,
208 dstSlices
[0], dstRowStride
,
211 free((void *) tempImage
);
217 _mesa_texstore_bptc_rgb_signed_float(TEXSTORE_PARAMS
)
219 assert(dstFormat
== MESA_FORMAT_BPTC_RGB_SIGNED_FLOAT
);
221 return texstore_bptc_rgb_float(ctx
, dims
, baseInternalFormat
,
222 dstFormat
, dstRowStride
, dstSlices
,
223 srcWidth
, srcHeight
, srcDepth
,
230 _mesa_texstore_bptc_rgb_unsigned_float(TEXSTORE_PARAMS
)
232 assert(dstFormat
== MESA_FORMAT_BPTC_RGB_UNSIGNED_FLOAT
);
234 return texstore_bptc_rgb_float(ctx
, dims
, baseInternalFormat
,
235 dstFormat
, dstRowStride
, dstSlices
,
236 srcWidth
, srcHeight
, srcDepth
,
239 false /* unsigned */);