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 "util/format/u_format_other.h" 30#include "util/u_math.h" 31#include "util/format_rgb9e5.h" 32#include "util/format_r11g11b10f.h" 33 34 35void 36util_format_r9g9b9e5_float_unpack_rgba_float(void *restrict dst_row, 37 const uint8_t *restrict src_row, 38 unsigned width) 39{ 40 unsigned x; 41 float *dst = dst_row; 42 const uint8_t *src = src_row; 43 for(x = 0; x < width; x += 1) { 44 uint32_t value = util_cpu_to_le32(*(const uint32_t *)src); 45 rgb9e5_to_float3(value, dst); 46 dst[3] = 1; /* a */ 47 src += 4; 48 dst += 4; 49 } 50} 51 52void 53util_format_r9g9b9e5_float_pack_rgba_float(uint8_t *restrict dst_row, unsigned dst_stride, 54 const float *restrict src_row, unsigned src_stride, 55 unsigned width, unsigned height) 56{ 57 unsigned x, y; 58 for(y = 0; y < height; y += 1) { 59 const float *src = src_row; 60 uint8_t *dst = dst_row; 61 for(x = 0; x < width; x += 1) { 62 uint32_t value = util_cpu_to_le32(float3_to_rgb9e5(src)); 63 *(uint32_t *)dst = value; 64 src += 4; 65 dst += 4; 66 } 67 dst_row += dst_stride; 68 src_row += src_stride/sizeof(*src_row); 69 } 70} 71 72void 73util_format_r9g9b9e5_float_fetch_rgba(void *restrict in_dst, const uint8_t *restrict src, 74 UNUSED unsigned i, UNUSED unsigned j) 75{ 76 float *dst = in_dst; 77 uint32_t value = util_cpu_to_le32(*(const uint32_t *)src); 78 rgb9e5_to_float3(value, dst); 79 dst[3] = 1; /* a */ 80} 81 82 83void 84util_format_r9g9b9e5_float_unpack_rgba_8unorm(uint8_t *restrict dst_row, 85 const uint8_t *restrict src_row, 86 unsigned width) 87{ 88 unsigned x; 89 float p[3]; 90 uint8_t *dst = dst_row; 91 const uint8_t *src = src_row; 92 for(x = 0; x < width; x += 1) { 93 uint32_t value = util_cpu_to_le32(*(const uint32_t *)src); 94 rgb9e5_to_float3(value, p); 95 dst[0] = float_to_ubyte(p[0]); /* r */ 96 dst[1] = float_to_ubyte(p[1]); /* g */ 97 dst[2] = float_to_ubyte(p[2]); /* b */ 98 dst[3] = 255; /* a */ 99 src += 4; 100 dst += 4; 101 } 102} 103 104 105void 106util_format_r9g9b9e5_float_pack_rgba_8unorm(uint8_t *restrict dst_row, unsigned dst_stride, 107 const uint8_t *restrict src_row, unsigned src_stride, 108 unsigned width, unsigned height) 109{ 110 unsigned x, y; 111 float p[3]; 112 for(y = 0; y < height; y += 1) { 113 const uint8_t *src = src_row; 114 uint8_t *dst = dst_row; 115 for(x = 0; x < width; x += 1) { 116 uint32_t value; 117 p[0] = ubyte_to_float(src[0]); 118 p[1] = ubyte_to_float(src[1]); 119 p[2] = ubyte_to_float(src[2]); 120 value = util_cpu_to_le32(float3_to_rgb9e5(p)); 121 *(uint32_t *)dst = value; 122 src += 4; 123 dst += 4; 124 } 125 dst_row += dst_stride; 126 src_row += src_stride/sizeof(*src_row); 127 } 128} 129 130 131void 132util_format_r11g11b10_float_unpack_rgba_float(void *restrict dst_row, 133 const uint8_t *restrict src_row, 134 unsigned width) 135{ 136 unsigned x; 137 float *dst = dst_row; 138 const uint8_t *src = src_row; 139 for(x = 0; x < width; x += 1) { 140 uint32_t value = util_cpu_to_le32(*(const uint32_t *)src); 141 r11g11b10f_to_float3(value, dst); 142 dst[3] = 1; /* a */ 143 src += 4; 144 dst += 4; 145 } 146} 147 148void 149util_format_r11g11b10_float_pack_rgba_float(uint8_t *restrict dst_row, unsigned dst_stride, 150 const float *restrict src_row, unsigned src_stride, 151 unsigned width, unsigned height) 152{ 153 unsigned x, y; 154 for(y = 0; y < height; y += 1) { 155 const float *src = src_row; 156 uint8_t *dst = dst_row; 157 for(x = 0; x < width; x += 1) { 158 uint32_t value = util_cpu_to_le32(float3_to_r11g11b10f(src)); 159 *(uint32_t *)dst = value; 160 src += 4; 161 dst += 4; 162 } 163 dst_row += dst_stride; 164 src_row += src_stride/sizeof(*src_row); 165 } 166} 167 168void 169util_format_r11g11b10_float_fetch_rgba(void *restrict in_dst, const uint8_t *restrict src, 170 UNUSED unsigned i, UNUSED unsigned j) 171{ 172 float *dst = in_dst; 173 uint32_t value = util_cpu_to_le32(*(const uint32_t *)src); 174 r11g11b10f_to_float3(value, dst); 175 dst[3] = 1; /* a */ 176} 177 178 179void 180util_format_r11g11b10_float_unpack_rgba_8unorm(uint8_t *restrict dst_row, 181 const uint8_t *restrict src_row, 182 unsigned width) 183{ 184 unsigned x; 185 float p[3]; 186 uint8_t *dst = dst_row; 187 const uint8_t *src = src_row; 188 for(x = 0; x < width; x += 1) { 189 uint32_t value = util_cpu_to_le32(*(const uint32_t *)src); 190 r11g11b10f_to_float3(value, p); 191 dst[0] = float_to_ubyte(p[0]); /* r */ 192 dst[1] = float_to_ubyte(p[1]); /* g */ 193 dst[2] = float_to_ubyte(p[2]); /* b */ 194 dst[3] = 255; /* a */ 195 src += 4; 196 dst += 4; 197 } 198} 199 200 201void 202util_format_r11g11b10_float_pack_rgba_8unorm(uint8_t *restrict dst_row, unsigned dst_stride, 203 const uint8_t *restrict src_row, unsigned src_stride, 204 unsigned width, unsigned height) 205{ 206 unsigned x, y; 207 float p[3]; 208 for(y = 0; y < height; y += 1) { 209 const uint8_t *src = src_row; 210 uint8_t *dst = dst_row; 211 for(x = 0; x < width; x += 1) { 212 uint32_t value; 213 p[0] = ubyte_to_float(src[0]); 214 p[1] = ubyte_to_float(src[1]); 215 p[2] = ubyte_to_float(src[2]); 216 value = util_cpu_to_le32(float3_to_r11g11b10f(p)); 217 *(uint32_t *)dst = value; 218 src += 4; 219 dst += 4; 220 } 221 dst_row += dst_stride; 222 src_row += src_stride/sizeof(*src_row); 223 } 224} 225 226/* 227 * PIPE_FORMAT_R8G8Bx_SNORM 228 * 229 * A.k.a. D3DFMT_CxV8U8 230 */ 231 232static uint8_t 233r8g8bx_derive(int16_t r, int16_t g) 234{ 235 /* Derive blue from red and green components. 236 * Apparently, we must always use integers to perform calculations, 237 * otherwise the results won't match D3D's CxV8U8 definition. 238 */ 239 return (uint8_t)sqrtf(0x7f * 0x7f - r * r - g * g) * 0xff / 0x7f; 240} 241 242void 243util_format_r8g8bx_snorm_unpack_rgba_float(void *restrict dst_row, 244 const uint8_t *restrict src_row, unsigned width) 245{ 246 unsigned x; 247 float *dst = dst_row; 248 const uint16_t *src = (const uint16_t *)src_row; 249 for(x = 0; x < width; x += 1) { 250 uint16_t value = util_cpu_to_le16(*src++); 251 int16_t r, g; 252 253 r = ((int16_t)(value << 8)) >> 8; 254 g = ((int16_t)(value << 0)) >> 8; 255 256 dst[0] = (float)(r * (1.0f/0x7f)); /* r */ 257 dst[1] = (float)(g * (1.0f/0x7f)); /* g */ 258 dst[2] = r8g8bx_derive(r, g) * (1.0f/0xff); /* b */ 259 dst[3] = 1.0f; /* a */ 260 dst += 4; 261 } 262} 263 264 265void 266util_format_r8g8bx_snorm_unpack_rgba_8unorm(uint8_t *restrict dst, 267 const uint8_t *restrict src_row, 268 unsigned width) 269{ 270 unsigned x; 271 const uint16_t *src = (const uint16_t *)src_row; 272 for(x = 0; x < width; x += 1) { 273 uint16_t value = util_cpu_to_le16(*src++); 274 int16_t r, g; 275 276 r = ((int16_t)(value << 8)) >> 8; 277 g = ((int16_t)(value << 0)) >> 8; 278 279 dst[0] = (uint8_t)(((uint16_t)MAX2(r, 0)) * 0xff / 0x7f); /* r */ 280 dst[1] = (uint8_t)(((uint16_t)MAX2(g, 0)) * 0xff / 0x7f); /* g */ 281 dst[2] = r8g8bx_derive(r, g); /* b */ 282 dst[3] = 255; /* a */ 283 dst += 4; 284 } 285} 286 287 288void 289util_format_r8g8bx_snorm_pack_rgba_float(uint8_t *restrict dst_row, unsigned dst_stride, 290 const float *restrict src_row, unsigned src_stride, 291 unsigned width, unsigned height) 292{ 293 unsigned x, y; 294 for(y = 0; y < height; y += 1) { 295 const float *src = src_row; 296 uint16_t *dst = (uint16_t *)dst_row; 297 for(x = 0; x < width; x += 1) { 298 uint16_t value = 0; 299 300 value |= (uint16_t)(((int8_t)(CLAMP(src[0], -1, 1) * 0x7f)) & 0xff) ; 301 value |= (uint16_t)((((int8_t)(CLAMP(src[1], -1, 1) * 0x7f)) & 0xff) << 8) ; 302 303 *dst++ = util_le16_to_cpu(value); 304 305 src += 4; 306 } 307 dst_row += dst_stride; 308 src_row += src_stride/sizeof(*src_row); 309 } 310} 311 312 313void 314util_format_r8g8bx_snorm_pack_rgba_8unorm(uint8_t *restrict dst_row, unsigned dst_stride, 315 const uint8_t *restrict src_row, unsigned src_stride, 316 unsigned width, unsigned height) 317{ 318 unsigned x, y; 319 320 for(y = 0; y < height; y += 1) { 321 const uint8_t *src = src_row; 322 uint16_t *dst = (uint16_t *)dst_row; 323 for(x = 0; x < width; x += 1) { 324 uint16_t value = 0; 325 326 value |= src[0] >> 1; 327 value |= (src[1] >> 1) << 8; 328 329 *dst++ = util_le16_to_cpu(value); 330 331 src += 4; 332 } 333 dst_row += dst_stride; 334 src_row += src_stride/sizeof(*src_row); 335 } 336} 337 338 339void 340util_format_r8g8bx_snorm_fetch_rgba(void *restrict in_dst, const uint8_t *restrict src, 341 UNUSED unsigned i, UNUSED unsigned j) 342{ 343 float *dst = in_dst; 344 uint16_t value = util_cpu_to_le16(*(const uint16_t *)src); 345 int16_t r, g; 346 347 r = ((int16_t)(value << 8)) >> 8; 348 g = ((int16_t)(value << 0)) >> 8; 349 350 dst[0] = r * (1.0f/0x7f); /* r */ 351 dst[1] = g * (1.0f/0x7f); /* g */ 352 dst[2] = r8g8bx_derive(r, g) * (1.0f/0xff); /* b */ 353 dst[3] = 1.0f; /* a */ 354} 355