Merge commit 'origin/gallium-0.1' into gallium-tex-surfaces
[mesa.git] / src / gallium / auxiliary / util / u_pack_color.h
1 /**************************************************************************
2 *
3 * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28 /**
29 * @file
30 * Functions to produce packed colors/Z from floats.
31 */
32
33
34 #ifndef U_PACK_COLOR_H
35 #define U_PACK_COLOR_H
36
37
38 #include "pipe/p_compiler.h"
39 #include "pipe/p_format.h"
40
41
42 /**
43 * Pack ubyte R,G,B,A into dest pixel.
44 */
45 static INLINE void
46 util_pack_color_ub(ubyte r, ubyte g, ubyte b, ubyte a,
47 enum pipe_format format, void *dest)
48 {
49 switch (format) {
50 case PIPE_FORMAT_R8G8B8A8_UNORM:
51 {
52 uint *d = (uint *) dest;
53 *d = (r << 24) | (g << 16) | (b << 8) | a;
54 }
55 return;
56 case PIPE_FORMAT_R8G8B8X8_UNORM:
57 {
58 uint *d = (uint *) dest;
59 *d = (r << 24) | (g << 16) | (b << 8) | 0xff;
60 }
61 return;
62 case PIPE_FORMAT_A8R8G8B8_UNORM:
63 {
64 uint *d = (uint *) dest;
65 *d = (a << 24) | (r << 16) | (g << 8) | b;
66 }
67 return;
68 case PIPE_FORMAT_X8R8G8B8_UNORM:
69 {
70 uint *d = (uint *) dest;
71 *d = (0xff << 24) | (r << 16) | (g << 8) | b;
72 }
73 return;
74 case PIPE_FORMAT_B8G8R8A8_UNORM:
75 {
76 uint *d = (uint *) dest;
77 *d = (b << 24) | (g << 16) | (r << 8) | a;
78 }
79 return;
80 case PIPE_FORMAT_B8G8R8X8_UNORM:
81 {
82 uint *d = (uint *) dest;
83 *d = (b << 24) | (g << 16) | (r << 8) | 0xff;
84 }
85 return;
86 case PIPE_FORMAT_R5G6B5_UNORM:
87 {
88 ushort *d = (ushort *) dest;
89 *d = ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | (b >> 3);
90 }
91 return;
92 case PIPE_FORMAT_A1R5G5B5_UNORM:
93 {
94 ushort *d = (ushort *) dest;
95 *d = ((a & 0x80) << 8) | ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | (b >> 3);
96 }
97 return;
98 case PIPE_FORMAT_A4R4G4B4_UNORM:
99 {
100 ushort *d = (ushort *) dest;
101 *d = ((a & 0xf0) << 8) | ((r & 0xf0) << 4) | ((g & 0xf0) << 0) | (b >> 4);
102 }
103 return;
104 case PIPE_FORMAT_A8_UNORM:
105 {
106 ubyte *d = (ubyte *) dest;
107 *d = a;
108 }
109 return;
110 case PIPE_FORMAT_L8_UNORM:
111 case PIPE_FORMAT_I8_UNORM:
112 {
113 ubyte *d = (ubyte *) dest;
114 *d = r;
115 }
116 return;
117 case PIPE_FORMAT_R32G32B32A32_FLOAT:
118 {
119 float *d = (float *) dest;
120 d[0] = (float)r / 255.0f;
121 d[1] = (float)g / 255.0f;
122 d[2] = (float)b / 255.0f;
123 d[3] = (float)a / 255.0f;
124 }
125 return;
126 case PIPE_FORMAT_R32G32B32_FLOAT:
127 {
128 float *d = (float *) dest;
129 d[0] = (float)r / 255.0f;
130 d[1] = (float)g / 255.0f;
131 d[2] = (float)b / 255.0f;
132 }
133 return;
134
135 /* XXX lots more cases to add */
136 default:
137 debug_print_format("gallium: unhandled format in util_pack_color_ub()", format);
138 assert(0);
139 }
140 }
141
142
143 /**
144 * Note rgba outside [0,1] will be clamped for int pixel formats.
145 */
146 static INLINE void
147 util_pack_color(const float rgba[4], enum pipe_format format, void *dest)
148 {
149 ubyte r, g, b, a;
150
151 if (pf_size_x(format) <= 8) {
152 /* format uses 8-bit components or less */
153 UNCLAMPED_FLOAT_TO_UBYTE(r, rgba[0]);
154 UNCLAMPED_FLOAT_TO_UBYTE(g, rgba[1]);
155 UNCLAMPED_FLOAT_TO_UBYTE(b, rgba[2]);
156 UNCLAMPED_FLOAT_TO_UBYTE(a, rgba[3]);
157 }
158
159 switch (format) {
160 case PIPE_FORMAT_R8G8B8A8_UNORM:
161 {
162 uint *d = (uint *) dest;
163 *d = (r << 24) | (g << 16) | (b << 8) | a;
164 }
165 return;
166 case PIPE_FORMAT_R8G8B8X8_UNORM:
167 {
168 uint *d = (uint *) dest;
169 *d = (r << 24) | (g << 16) | (b << 8) | 0xff;
170 }
171 return;
172 case PIPE_FORMAT_A8R8G8B8_UNORM:
173 {
174 uint *d = (uint *) dest;
175 *d = (a << 24) | (r << 16) | (g << 8) | b;
176 }
177 return;
178 case PIPE_FORMAT_X8R8G8B8_UNORM:
179 {
180 uint *d = (uint *) dest;
181 *d = (0xff << 24) | (r << 16) | (g << 8) | b;
182 }
183 return;
184 case PIPE_FORMAT_B8G8R8A8_UNORM:
185 {
186 uint *d = (uint *) dest;
187 *d = (b << 24) | (g << 16) | (r << 8) | a;
188 }
189 return;
190 case PIPE_FORMAT_B8G8R8X8_UNORM:
191 {
192 uint *d = (uint *) dest;
193 *d = (b << 24) | (g << 16) | (r << 8) | 0xff;
194 }
195 return;
196 case PIPE_FORMAT_R5G6B5_UNORM:
197 {
198 ushort *d = (ushort *) dest;
199 *d = ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | (b >> 3);
200 }
201 return;
202 case PIPE_FORMAT_A1R5G5B5_UNORM:
203 {
204 ushort *d = (ushort *) dest;
205 *d = ((a & 0x80) << 8) | ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | (b >> 3);
206 }
207 return;
208 case PIPE_FORMAT_A4R4G4B4_UNORM:
209 {
210 ushort *d = (ushort *) dest;
211 *d = ((a & 0xf0) << 8) | ((r & 0xf0) << 4) | ((g & 0xf0) << 0) | (b >> 4);
212 }
213 return;
214 case PIPE_FORMAT_A8_UNORM:
215 {
216 ubyte *d = (ubyte *) dest;
217 *d = a;
218 }
219 return;
220 case PIPE_FORMAT_L8_UNORM:
221 case PIPE_FORMAT_I8_UNORM:
222 {
223 ubyte *d = (ubyte *) dest;
224 *d = r;
225 }
226 return;
227 case PIPE_FORMAT_R32G32B32A32_FLOAT:
228 {
229 float *d = (float *) dest;
230 d[0] = rgba[0];
231 d[1] = rgba[1];
232 d[2] = rgba[2];
233 d[3] = rgba[3];
234 }
235 return;
236 case PIPE_FORMAT_R32G32B32_FLOAT:
237 {
238 float *d = (float *) dest;
239 d[0] = rgba[0];
240 d[1] = rgba[1];
241 d[2] = rgba[2];
242 }
243 return;
244 /* XXX lots more cases to add */
245 default:
246 debug_print_format("gallium: unhandled format in util_pack_color()", format);
247 assert(0);
248 }
249 }
250
251
252 /**
253 * Note: it's assumed that z is in [0,1]
254 */
255 static INLINE uint
256 util_pack_z(enum pipe_format format, double z)
257 {
258 switch (format) {
259 case PIPE_FORMAT_Z16_UNORM:
260 return (uint) (z * 0xffff);
261 case PIPE_FORMAT_Z32_UNORM:
262 /* special-case to avoid overflow */
263 if (z == 1.0)
264 return 0xffffffff;
265 else
266 return (uint) (z * 0xffffffff);
267 case PIPE_FORMAT_S8Z24_UNORM:
268 case PIPE_FORMAT_X8Z24_UNORM:
269 return (uint) (z * 0xffffff);
270 case PIPE_FORMAT_Z24S8_UNORM:
271 case PIPE_FORMAT_Z24X8_UNORM:
272 return ((uint) (z * 0xffffff)) << 8;
273 default:
274 debug_print_format("gallium: unhandled format in util_pack_z()", format);
275 assert(0);
276 return 0;
277 }
278 }
279
280
281 #endif /* U_PACK_COLOR_H */