mesa: Add missing include guards
[mesa.git] / src / mesa / main / texcompress_bptc.c
1 /*
2 * Copyright (C) 2014 Intel Corporation
3 *
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:
10 *
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
13 * Software.
14 *
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.
22 */
23
24 /**
25 * \file texcompress_bptc.c
26 * GL_ARB_texture_compression_bptc support.
27 */
28
29 #include <stdbool.h>
30 #include "texcompress.h"
31 #include "texcompress_bptc.h"
32 #include "texcompress_bptc_tmp.h"
33 #include "texstore.h"
34 #include "image.h"
35 #include "mtypes.h"
36
37 static void
38 fetch_bptc_rgb_float(const GLubyte *map,
39 GLint rowStride, GLint i, GLint j,
40 GLfloat *texel,
41 bool is_signed)
42 {
43 const GLubyte *block;
44
45 block = map + (((rowStride + 3) / 4) * (j / 4) + (i / 4)) * 16;
46
47 fetch_rgb_float_from_block(block, texel, (i % 4) + (j % 4) * 4, is_signed);
48 }
49
50 static void
51 fetch_bptc_rgb_signed_float(const GLubyte *map,
52 GLint rowStride, GLint i, GLint j,
53 GLfloat *texel)
54 {
55 fetch_bptc_rgb_float(map, rowStride, i, j, texel, true);
56 }
57
58 static void
59 fetch_bptc_rgb_unsigned_float(const GLubyte *map,
60 GLint rowStride, GLint i, GLint j,
61 GLfloat *texel)
62 {
63 fetch_bptc_rgb_float(map, rowStride, i, j, texel, false);
64 }
65
66 static void
67 fetch_bptc_rgba_unorm_bytes(const GLubyte *map,
68 GLint rowStride, GLint i, GLint j,
69 GLubyte *texel)
70 {
71 const GLubyte *block;
72
73 block = map + (((rowStride + 3) / 4) * (j / 4) + (i / 4)) * 16;
74
75 fetch_rgba_unorm_from_block(block, texel, (i % 4) + (j % 4) * 4);
76 }
77
78 static void
79 fetch_bptc_rgba_unorm(const GLubyte *map,
80 GLint rowStride, GLint i, GLint j,
81 GLfloat *texel)
82 {
83 GLubyte texel_bytes[4];
84
85 fetch_bptc_rgba_unorm_bytes(map, rowStride, i, j, texel_bytes);
86
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]);
91 }
92
93 static void
94 fetch_bptc_srgb_alpha_unorm(const GLubyte *map,
95 GLint rowStride, GLint i, GLint j,
96 GLfloat *texel)
97 {
98 GLubyte texel_bytes[4];
99
100 fetch_bptc_rgba_unorm_bytes(map, rowStride, i, j, texel_bytes);
101
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]);
106 }
107
108 compressed_fetch_func
109 _mesa_get_bptc_fetch_func(mesa_format format)
110 {
111 switch (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;
120 default:
121 return NULL;
122 }
123 }
124
125 GLboolean
126 _mesa_texstore_bptc_rgba_unorm(TEXSTORE_PARAMS)
127 {
128 const GLubyte *pixels;
129 const GLubyte *tempImage = NULL;
130 int rowstride;
131
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));
140 if (!tempImage)
141 return GL_FALSE; /* out of memory */
142 tempImageSlices[0] = (GLubyte *) tempImage;
143 _mesa_texstore(ctx, dims,
144 baseInternalFormat,
145 _mesa_little_endian() ? MESA_FORMAT_R8G8B8A8_UNORM
146 : MESA_FORMAT_A8B8G8R8_UNORM,
147 rgbaRowStride, tempImageSlices,
148 srcWidth, srcHeight, srcDepth,
149 srcFormat, srcType, srcAddr,
150 srcPacking);
151
152 pixels = tempImage;
153 rowstride = srcWidth * 4;
154 } else {
155 pixels = _mesa_image_address2d(srcPacking, srcAddr, srcWidth, srcHeight,
156 srcFormat, srcType, 0, 0);
157 rowstride = _mesa_image_row_stride(srcPacking, srcWidth,
158 srcFormat, srcType);
159 }
160
161 compress_rgba_unorm(srcWidth, srcHeight,
162 pixels, rowstride,
163 dstSlices[0], dstRowStride);
164
165 free((void *) tempImage);
166
167 return GL_TRUE;
168 }
169
170 static GLboolean
171 texstore_bptc_rgb_float(TEXSTORE_PARAMS,
172 bool is_signed)
173 {
174 const float *pixels;
175 const float *tempImage = NULL;
176 int rowstride;
177
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));
186 if (!tempImage)
187 return GL_FALSE; /* out of memory */
188 tempImageSlices[0] = (GLfloat *) tempImage;
189 _mesa_texstore(ctx, dims,
190 baseInternalFormat,
191 MESA_FORMAT_RGB_FLOAT32,
192 rgbRowStride, (GLubyte **)tempImageSlices,
193 srcWidth, srcHeight, srcDepth,
194 srcFormat, srcType, srcAddr,
195 srcPacking);
196
197 pixels = tempImage;
198 rowstride = srcWidth * sizeof(float) * 3;
199 } else {
200 pixels = _mesa_image_address2d(srcPacking, srcAddr, srcWidth, srcHeight,
201 srcFormat, srcType, 0, 0);
202 rowstride = _mesa_image_row_stride(srcPacking, srcWidth,
203 srcFormat, srcType);
204 }
205
206 compress_rgb_float(srcWidth, srcHeight,
207 pixels, rowstride,
208 dstSlices[0], dstRowStride,
209 is_signed);
210
211 free((void *) tempImage);
212
213 return GL_TRUE;
214 }
215
216 GLboolean
217 _mesa_texstore_bptc_rgb_signed_float(TEXSTORE_PARAMS)
218 {
219 assert(dstFormat == MESA_FORMAT_BPTC_RGB_SIGNED_FLOAT);
220
221 return texstore_bptc_rgb_float(ctx, dims, baseInternalFormat,
222 dstFormat, dstRowStride, dstSlices,
223 srcWidth, srcHeight, srcDepth,
224 srcFormat, srcType,
225 srcAddr, srcPacking,
226 true /* signed */);
227 }
228
229 GLboolean
230 _mesa_texstore_bptc_rgb_unsigned_float(TEXSTORE_PARAMS)
231 {
232 assert(dstFormat == MESA_FORMAT_BPTC_RGB_UNSIGNED_FLOAT);
233
234 return texstore_bptc_rgb_float(ctx, dims, baseInternalFormat,
235 dstFormat, dstRowStride, dstSlices,
236 srcWidth, srcHeight, srcDepth,
237 srcFormat, srcType,
238 srcAddr, srcPacking,
239 false /* unsigned */);
240 }