1 /**************************************************************************
2  *
3  * Copyright 2010 VMware, Inc.
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 SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
17  * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
18  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20  * USE OR OTHER DEALINGS IN THE SOFTWARE.
21  *
22  * The above copyright notice and this permission notice (including the
23  * next paragraph) shall be included in all copies or substantial portions
24  * of the Software.
25  *
26  **************************************************************************/
27 
28 
29 #include "u_math.h"
30 #include "u_format_other.h"
31 #include "util/format_rgb9e5.h"
32 #include "util/format_r11g11b10f.h"
33 
34 
35 void
util_format_r9g9b9e5_float_unpack_rgba_float(float * dst_row,unsigned dst_stride,const uint8_t * src_row,unsigned src_stride,unsigned width,unsigned height)36 util_format_r9g9b9e5_float_unpack_rgba_float(float *dst_row, unsigned dst_stride,
37                                         const uint8_t *src_row, unsigned src_stride,
38                                         unsigned width, unsigned height)
39 {
40    unsigned x, y;
41    for(y = 0; y < height; y += 1) {
42       float *dst = dst_row;
43       const uint8_t *src = src_row;
44       for(x = 0; x < width; x += 1) {
45          uint32_t value = util_cpu_to_le32(*(const uint32_t *)src);
46          rgb9e5_to_float3(value, dst);
47          dst[3] = 1; /* a */
48          src += 4;
49          dst += 4;
50       }
51       src_row += src_stride;
52       dst_row += dst_stride/sizeof(*dst_row);
53    }
54 }
55 
56 void
util_format_r9g9b9e5_float_pack_rgba_float(uint8_t * dst_row,unsigned dst_stride,const float * src_row,unsigned src_stride,unsigned width,unsigned height)57 util_format_r9g9b9e5_float_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride,
58                                       const float *src_row, unsigned src_stride,
59                                       unsigned width, unsigned height)
60 {
61    unsigned x, y;
62    for(y = 0; y < height; y += 1) {
63       const float *src = src_row;
64       uint8_t *dst = dst_row;
65       for(x = 0; x < width; x += 1) {
66          uint32_t value = util_cpu_to_le32(float3_to_rgb9e5(src));
67          *(uint32_t *)dst = value;
68          src += 4;
69          dst += 4;
70       }
71       dst_row += dst_stride;
72       src_row += src_stride/sizeof(*src_row);
73    }
74 }
75 
76 void
util_format_r9g9b9e5_float_fetch_rgba_float(float * dst,const uint8_t * src,unsigned i,unsigned j)77 util_format_r9g9b9e5_float_fetch_rgba_float(float *dst, const uint8_t *src,
78                                        unsigned i, unsigned j)
79 {
80    uint32_t value = util_cpu_to_le32(*(const uint32_t *)src);
81    rgb9e5_to_float3(value, dst);
82    dst[3] = 1; /* a */
83 }
84 
85 
86 void
util_format_r9g9b9e5_float_unpack_rgba_8unorm(uint8_t * dst_row,unsigned dst_stride,const uint8_t * src_row,unsigned src_stride,unsigned width,unsigned height)87 util_format_r9g9b9e5_float_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
88                                          const uint8_t *src_row, unsigned src_stride,
89                                          unsigned width, unsigned height)
90 {
91    unsigned x, y;
92    float p[3];
93    for(y = 0; y < height; y += 1) {
94       uint8_t *dst = dst_row;
95       const uint8_t *src = src_row;
96       for(x = 0; x < width; x += 1) {
97          uint32_t value = util_cpu_to_le32(*(const uint32_t *)src);
98          rgb9e5_to_float3(value, p);
99          dst[0] = float_to_ubyte(p[0]); /* r */
100          dst[1] = float_to_ubyte(p[1]); /* g */
101          dst[2] = float_to_ubyte(p[2]); /* b */
102          dst[3] = 255; /* a */
103          src += 4;
104          dst += 4;
105       }
106       src_row += src_stride;
107       dst_row += dst_stride/sizeof(*dst_row);
108    }
109 }
110 
111 
112 void
util_format_r9g9b9e5_float_pack_rgba_8unorm(uint8_t * dst_row,unsigned dst_stride,const uint8_t * src_row,unsigned src_stride,unsigned width,unsigned height)113 util_format_r9g9b9e5_float_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
114                                        const uint8_t *src_row, unsigned src_stride,
115                                        unsigned width, unsigned height)
116 {
117    unsigned x, y;
118    float p[3];
119    for(y = 0; y < height; y += 1) {
120       const uint8_t *src = src_row;
121       uint8_t *dst = dst_row;
122       for(x = 0; x < width; x += 1) {
123          uint32_t value;
124          p[0] = ubyte_to_float(src[0]);
125          p[1] = ubyte_to_float(src[1]);
126          p[2] = ubyte_to_float(src[2]);
127          value = util_cpu_to_le32(float3_to_rgb9e5(p));
128          *(uint32_t *)dst = value;
129          src += 4;
130          dst += 4;
131       }
132       dst_row += dst_stride;
133       src_row += src_stride/sizeof(*src_row);
134    }
135 }
136 
137 
138 void
util_format_r11g11b10_float_unpack_rgba_float(float * dst_row,unsigned dst_stride,const uint8_t * src_row,unsigned src_stride,unsigned width,unsigned height)139 util_format_r11g11b10_float_unpack_rgba_float(float *dst_row, unsigned dst_stride,
140                                         const uint8_t *src_row, unsigned src_stride,
141                                         unsigned width, unsigned height)
142 {
143    unsigned x, y;
144    for(y = 0; y < height; y += 1) {
145       float *dst = dst_row;
146       const uint8_t *src = src_row;
147       for(x = 0; x < width; x += 1) {
148          uint32_t value = util_cpu_to_le32(*(const uint32_t *)src);
149          r11g11b10f_to_float3(value, dst);
150          dst[3] = 1; /* a */
151          src += 4;
152          dst += 4;
153       }
154       src_row += src_stride;
155       dst_row += dst_stride/sizeof(*dst_row);
156    }
157 }
158 
159 void
util_format_r11g11b10_float_pack_rgba_float(uint8_t * dst_row,unsigned dst_stride,const float * src_row,unsigned src_stride,unsigned width,unsigned height)160 util_format_r11g11b10_float_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride,
161                                       const float *src_row, unsigned src_stride,
162                                       unsigned width, unsigned height)
163 {
164    unsigned x, y;
165    for(y = 0; y < height; y += 1) {
166       const float *src = src_row;
167       uint8_t *dst = dst_row;
168       for(x = 0; x < width; x += 1) {
169          uint32_t value = util_cpu_to_le32(float3_to_r11g11b10f(src));
170          *(uint32_t *)dst = value;
171          src += 4;
172          dst += 4;
173       }
174       dst_row += dst_stride;
175       src_row += src_stride/sizeof(*src_row);
176    }
177 }
178 
179 void
util_format_r11g11b10_float_fetch_rgba_float(float * dst,const uint8_t * src,unsigned i,unsigned j)180 util_format_r11g11b10_float_fetch_rgba_float(float *dst, const uint8_t *src,
181                                        unsigned i, unsigned j)
182 {
183    uint32_t value = util_cpu_to_le32(*(const uint32_t *)src);
184    r11g11b10f_to_float3(value, dst);
185    dst[3] = 1; /* a */
186 }
187 
188 
189 void
util_format_r11g11b10_float_unpack_rgba_8unorm(uint8_t * dst_row,unsigned dst_stride,const uint8_t * src_row,unsigned src_stride,unsigned width,unsigned height)190 util_format_r11g11b10_float_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
191                                          const uint8_t *src_row, unsigned src_stride,
192                                          unsigned width, unsigned height)
193 {
194    unsigned x, y;
195    float p[3];
196    for(y = 0; y < height; y += 1) {
197       uint8_t *dst = dst_row;
198       const uint8_t *src = src_row;
199       for(x = 0; x < width; x += 1) {
200          uint32_t value = util_cpu_to_le32(*(const uint32_t *)src);
201          r11g11b10f_to_float3(value, p);
202          dst[0] = float_to_ubyte(p[0]); /* r */
203          dst[1] = float_to_ubyte(p[1]); /* g */
204          dst[2] = float_to_ubyte(p[2]); /* b */
205          dst[3] = 255; /* a */
206          src += 4;
207          dst += 4;
208       }
209       src_row += src_stride;
210       dst_row += dst_stride/sizeof(*dst_row);
211    }
212 }
213 
214 
215 void
util_format_r11g11b10_float_pack_rgba_8unorm(uint8_t * dst_row,unsigned dst_stride,const uint8_t * src_row,unsigned src_stride,unsigned width,unsigned height)216 util_format_r11g11b10_float_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
217                                        const uint8_t *src_row, unsigned src_stride,
218                                        unsigned width, unsigned height)
219 {
220    unsigned x, y;
221    float p[3];
222    for(y = 0; y < height; y += 1) {
223       const uint8_t *src = src_row;
224       uint8_t *dst = dst_row;
225       for(x = 0; x < width; x += 1) {
226          uint32_t value;
227          p[0] = ubyte_to_float(src[0]);
228          p[1] = ubyte_to_float(src[1]);
229          p[2] = ubyte_to_float(src[2]);
230          value = util_cpu_to_le32(float3_to_r11g11b10f(p));
231          *(uint32_t *)dst = value;
232          src += 4;
233          dst += 4;
234       }
235       dst_row += dst_stride;
236       src_row += src_stride/sizeof(*src_row);
237    }
238 }
239 
240 
241 void
util_format_r1_unorm_unpack_rgba_float(float * dst_row,unsigned dst_stride,const uint8_t * src_row,unsigned src_stride,unsigned width,unsigned height)242 util_format_r1_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride,
243                                   const uint8_t *src_row, unsigned src_stride,
244                                   unsigned width, unsigned height)
245 {
246 
247 }
248 
249 
250 void
util_format_r1_unorm_pack_rgba_float(uint8_t * dst_row,unsigned dst_stride,const float * src_row,unsigned src_stride,unsigned width,unsigned height)251 util_format_r1_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride,
252                                 const float *src_row, unsigned src_stride,
253                                 unsigned width, unsigned height)
254 {
255 
256 }
257 
258 
259 void
util_format_r1_unorm_fetch_rgba_float(float * dst,const uint8_t * src,unsigned i,unsigned j)260 util_format_r1_unorm_fetch_rgba_float(float *dst, const uint8_t *src,
261                                  unsigned i, unsigned j)
262 {
263 
264 }
265 
266 
267 void
util_format_r1_unorm_unpack_rgba_8unorm(uint8_t * dst_row,unsigned dst_stride,const uint8_t * src_row,unsigned src_stride,unsigned width,unsigned height)268 util_format_r1_unorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
269                                    const uint8_t *src_row, unsigned src_stride,
270                                    unsigned width, unsigned height)
271 {
272 
273 }
274 
275 
276 void
util_format_r1_unorm_pack_rgba_8unorm(uint8_t * dst_row,unsigned dst_stride,const uint8_t * src_row,unsigned src_stride,unsigned width,unsigned height)277 util_format_r1_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
278                                  const uint8_t *src_row, unsigned src_stride,
279                                  unsigned width, unsigned height)
280 {
281 }
282 
283 
284 /*
285  * PIPE_FORMAT_R8G8Bx_SNORM
286  *
287  * A.k.a. D3DFMT_CxV8U8
288  */
289 
290 static uint8_t
r8g8bx_derive(int16_t r,int16_t g)291 r8g8bx_derive(int16_t r, int16_t g)
292 {
293    /* Derive blue from red and green components.
294     * Apparently, we must always use integers to perform calculations,
295     * otherwise the results won't match D3D's CxV8U8 definition.
296     */
297    return (uint8_t)sqrtf(0x7f * 0x7f - r * r - g * g) * 0xff / 0x7f;
298 }
299 
300 void
util_format_r8g8bx_snorm_unpack_rgba_float(float * dst_row,unsigned dst_stride,const uint8_t * src_row,unsigned src_stride,unsigned width,unsigned height)301 util_format_r8g8bx_snorm_unpack_rgba_float(float *dst_row, unsigned dst_stride,
302                                       const uint8_t *src_row, unsigned src_stride,
303                                       unsigned width, unsigned height)
304 {
305    unsigned x, y;
306 
307    for(y = 0; y < height; y += 1) {
308       float *dst = dst_row;
309       const uint16_t *src = (const uint16_t *)src_row;
310       for(x = 0; x < width; x += 1) {
311          uint16_t value = util_cpu_to_le16(*src++);
312          int16_t r, g;
313 
314          r = ((int16_t)(value << 8)) >> 8;
315          g = ((int16_t)(value << 0)) >> 8;
316 
317          dst[0] = (float)(r * (1.0f/0x7f)); /* r */
318          dst[1] = (float)(g * (1.0f/0x7f)); /* g */
319          dst[2] = r8g8bx_derive(r, g) * (1.0f/0xff); /* b */
320          dst[3] = 1.0f; /* a */
321          dst += 4;
322       }
323       src_row += src_stride;
324       dst_row += dst_stride/sizeof(*dst_row);
325    }
326 }
327 
328 
329 void
util_format_r8g8bx_snorm_unpack_rgba_8unorm(uint8_t * dst_row,unsigned dst_stride,const uint8_t * src_row,unsigned src_stride,unsigned width,unsigned height)330 util_format_r8g8bx_snorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
331                                        const uint8_t *src_row, unsigned src_stride,
332                                        unsigned width, unsigned height)
333 {
334    unsigned x, y;
335    for(y = 0; y < height; y += 1) {
336       uint8_t *dst = dst_row;
337       const uint16_t *src = (const uint16_t *)src_row;
338       for(x = 0; x < width; x += 1) {
339          uint16_t value = util_cpu_to_le16(*src++);
340          int16_t r, g;
341 
342          r = ((int16_t)(value << 8)) >> 8;
343          g = ((int16_t)(value << 0)) >> 8;
344 
345          dst[0] = (uint8_t)(((uint16_t)MAX2(r, 0)) * 0xff / 0x7f); /* r */
346          dst[1] = (uint8_t)(((uint16_t)MAX2(g, 0)) * 0xff / 0x7f); /* g */
347          dst[2] = r8g8bx_derive(r, g); /* b */
348          dst[3] = 255; /* a */
349          dst += 4;
350       }
351       src_row += src_stride;
352       dst_row += dst_stride/sizeof(*dst_row);
353    }
354 }
355 
356 
357 void
util_format_r8g8bx_snorm_pack_rgba_float(uint8_t * dst_row,unsigned dst_stride,const float * src_row,unsigned src_stride,unsigned width,unsigned height)358 util_format_r8g8bx_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride,
359                                     const float *src_row, unsigned src_stride,
360                                     unsigned width, unsigned height)
361 {
362    unsigned x, y;
363    for(y = 0; y < height; y += 1) {
364       const float *src = src_row;
365       uint16_t *dst = (uint16_t *)dst_row;
366       for(x = 0; x < width; x += 1) {
367          uint16_t value = 0;
368 
369          value |= (uint16_t)(((int8_t)(CLAMP(src[0], -1, 1) * 0x7f)) & 0xff) ;
370          value |= (uint16_t)((((int8_t)(CLAMP(src[1], -1, 1) * 0x7f)) & 0xff) << 8) ;
371 
372          *dst++ = util_le16_to_cpu(value);
373 
374          src += 4;
375       }
376       dst_row += dst_stride;
377       src_row += src_stride/sizeof(*src_row);
378    }
379 }
380 
381 
382 void
util_format_r8g8bx_snorm_pack_rgba_8unorm(uint8_t * dst_row,unsigned dst_stride,const uint8_t * src_row,unsigned src_stride,unsigned width,unsigned height)383 util_format_r8g8bx_snorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
384                                      const uint8_t *src_row, unsigned src_stride,
385                                      unsigned width, unsigned height)
386 {
387    unsigned x, y;
388 
389    for(y = 0; y < height; y += 1) {
390       const uint8_t *src = src_row;
391       uint16_t *dst = (uint16_t *)dst_row;
392       for(x = 0; x < width; x += 1) {
393          uint16_t value = 0;
394 
395          value |= src[0] >> 1;
396          value |= (src[1] >> 1) << 8;
397 
398          *dst++ = util_le16_to_cpu(value);
399 
400          src += 4;
401       }
402       dst_row += dst_stride;
403       src_row += src_stride/sizeof(*src_row);
404    }
405 }
406 
407 
408 void
util_format_r8g8bx_snorm_fetch_rgba_float(float * dst,const uint8_t * src,unsigned i,unsigned j)409 util_format_r8g8bx_snorm_fetch_rgba_float(float *dst, const uint8_t *src,
410                                      unsigned i, unsigned j)
411 {
412    uint16_t value = util_cpu_to_le16(*(const uint16_t *)src);
413    int16_t r, g;
414 
415    r = ((int16_t)(value << 8)) >> 8;
416    g = ((int16_t)(value << 0)) >> 8;
417 
418    dst[0] = r * (1.0f/0x7f); /* r */
419    dst[1] = g * (1.0f/0x7f); /* g */
420    dst[2] = r8g8bx_derive(r, g) * (1.0f/0xff); /* b */
421    dst[3] = 1.0f; /* a */
422 }
423