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 "u_format_rgb9e5.h" 32 #include "u_format_r11g11b10f.h" 33 34 35 void 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 = *(const uint32_t *)src; 46 #ifdef PIPE_ARCH_BIG_ENDIAN 47 value = util_bswap32(value); 48 #endif 49 rgb9e5_to_float3(value, dst); 50 dst[3] = 1; /* a */ 51 src += 4; 52 dst += 4; 53 } 54 src_row += src_stride; 55 dst_row += dst_stride/sizeof(*dst_row); 56 } 57 } 58 59 void 60 util_format_r9g9b9e5_float_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, 61 const float *src_row, unsigned src_stride, 62 unsigned width, unsigned height) 63 { 64 unsigned x, y; 65 for(y = 0; y < height; y += 1) { 66 const float *src = src_row; 67 uint8_t *dst = dst_row; 68 for(x = 0; x < width; x += 1) { 69 uint32_t value = float3_to_rgb9e5(src); 70 #ifdef PIPE_ARCH_BIG_ENDIAN 71 value = util_bswap32(value); 72 #endif 73 *(uint32_t *)dst = value; 74 src += 4; 75 dst += 4; 76 } 77 dst_row += dst_stride; 78 src_row += src_stride/sizeof(*src_row); 79 } 80 } 81 82 void 83 util_format_r9g9b9e5_float_fetch_rgba_float(float *dst, const uint8_t *src, 84 unsigned i, unsigned j) 85 { 86 uint32_t value = *(const uint32_t *)src; 87 #ifdef PIPE_ARCH_BIG_ENDIAN 88 value = util_bswap32(value); 89 #endif 90 rgb9e5_to_float3(value, dst); 91 dst[3] = 1; /* a */ 92 } 93 94 95 void 96 util_format_r9g9b9e5_float_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, 97 const uint8_t *src_row, unsigned src_stride, 98 unsigned width, unsigned height) 99 { 100 unsigned x, y; 101 float p[3]; 102 for(y = 0; y < height; y += 1) { 103 uint8_t *dst = dst_row; 104 const uint8_t *src = src_row; 105 for(x = 0; x < width; x += 1) { 106 uint32_t value = *(const uint32_t *)src; 107 #ifdef PIPE_ARCH_BIG_ENDIAN 108 value = util_bswap32(value); 109 #endif 110 rgb9e5_to_float3(value, p); 111 dst[0] = float_to_ubyte(p[0]); /* r */ 112 dst[1] = float_to_ubyte(p[1]); /* g */ 113 dst[2] = float_to_ubyte(p[2]); /* b */ 114 dst[3] = 255; /* a */ 115 src += 4; 116 dst += 4; 117 } 118 src_row += src_stride; 119 dst_row += dst_stride/sizeof(*dst_row); 120 } 121 } 122 123 124 void 125 util_format_r9g9b9e5_float_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, 126 const uint8_t *src_row, unsigned src_stride, 127 unsigned width, unsigned height) 128 { 129 unsigned x, y; 130 float p[3]; 131 for(y = 0; y < height; y += 1) { 132 const uint8_t *src = src_row; 133 uint8_t *dst = dst_row; 134 for(x = 0; x < width; x += 1) { 135 uint32_t value; 136 p[0] = ubyte_to_float(src[0]); 137 p[1] = ubyte_to_float(src[1]); 138 p[2] = ubyte_to_float(src[2]); 139 value = float3_to_rgb9e5(p); 140 #ifdef PIPE_ARCH_BIG_ENDIAN 141 value = util_bswap32(value); 142 #endif 143 *(uint32_t *)dst = value; 144 src += 4; 145 dst += 4; 146 } 147 dst_row += dst_stride; 148 src_row += src_stride/sizeof(*src_row); 149 } 150 } 151 152 153 void 154 util_format_r11g11b10_float_unpack_rgba_float(float *dst_row, unsigned dst_stride, 155 const uint8_t *src_row, unsigned src_stride, 156 unsigned width, unsigned height) 157 { 158 unsigned x, y; 159 for(y = 0; y < height; y += 1) { 160 float *dst = dst_row; 161 const uint8_t *src = src_row; 162 for(x = 0; x < width; x += 1) { 163 uint32_t value = *(const uint32_t *)src; 164 #ifdef PIPE_ARCH_BIG_ENDIAN 165 value = util_bswap32(value); 166 #endif 167 r11g11b10f_to_float3(value, dst); 168 dst[3] = 1; /* a */ 169 src += 4; 170 dst += 4; 171 } 172 src_row += src_stride; 173 dst_row += dst_stride/sizeof(*dst_row); 174 } 175 } 176 177 void 178 util_format_r11g11b10_float_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, 179 const float *src_row, unsigned src_stride, 180 unsigned width, unsigned height) 181 { 182 unsigned x, y; 183 for(y = 0; y < height; y += 1) { 184 const float *src = src_row; 185 uint8_t *dst = dst_row; 186 for(x = 0; x < width; x += 1) { 187 uint32_t value = float3_to_r11g11b10f(src); 188 #ifdef PIPE_ARCH_BIG_ENDIAN 189 value = util_bswap32(value); 190 #endif 191 *(uint32_t *)dst = value; 192 src += 4; 193 dst += 4; 194 } 195 dst_row += dst_stride; 196 src_row += src_stride/sizeof(*src_row); 197 } 198 } 199 200 void 201 util_format_r11g11b10_float_fetch_rgba_float(float *dst, const uint8_t *src, 202 unsigned i, unsigned j) 203 { 204 uint32_t value = *(const uint32_t *)src; 205 #ifdef PIPE_ARCH_BIG_ENDIAN 206 value = util_bswap32(value); 207 #endif 208 r11g11b10f_to_float3(value, dst); 209 dst[3] = 1; /* a */ 210 } 211 212 213 void 214 util_format_r11g11b10_float_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, 215 const uint8_t *src_row, unsigned src_stride, 216 unsigned width, unsigned height) 217 { 218 unsigned x, y; 219 float p[3]; 220 for(y = 0; y < height; y += 1) { 221 uint8_t *dst = dst_row; 222 const uint8_t *src = src_row; 223 for(x = 0; x < width; x += 1) { 224 uint32_t value = *(const uint32_t *)src; 225 #ifdef PIPE_ARCH_BIG_ENDIAN 226 value = util_bswap32(value); 227 #endif 228 r11g11b10f_to_float3(value, p); 229 dst[0] = float_to_ubyte(p[0]); /* r */ 230 dst[1] = float_to_ubyte(p[1]); /* g */ 231 dst[2] = float_to_ubyte(p[2]); /* b */ 232 dst[3] = 255; /* a */ 233 src += 4; 234 dst += 4; 235 } 236 src_row += src_stride; 237 dst_row += dst_stride/sizeof(*dst_row); 238 } 239 } 240 241 242 void 243 util_format_r11g11b10_float_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, 244 const uint8_t *src_row, unsigned src_stride, 245 unsigned width, unsigned height) 246 { 247 unsigned x, y; 248 float p[3]; 249 for(y = 0; y < height; y += 1) { 250 const uint8_t *src = src_row; 251 uint8_t *dst = dst_row; 252 for(x = 0; x < width; x += 1) { 253 uint32_t value; 254 p[0] = ubyte_to_float(src[0]); 255 p[1] = ubyte_to_float(src[1]); 256 p[2] = ubyte_to_float(src[2]); 257 value = float3_to_r11g11b10f(p); 258 #ifdef PIPE_ARCH_BIG_ENDIAN 259 value = util_bswap32(value); 260 #endif 261 *(uint32_t *)dst = value; 262 src += 4; 263 dst += 4; 264 } 265 dst_row += dst_stride; 266 src_row += src_stride/sizeof(*src_row); 267 } 268 } 269 270 271 void 272 util_format_r1_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, 273 const uint8_t *src_row, unsigned src_stride, 274 unsigned width, unsigned height) 275 { 276 277 } 278 279 280 void 281 util_format_r1_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, 282 const float *src_row, unsigned src_stride, 283 unsigned width, unsigned height) 284 { 285 286 } 287 288 289 void 290 util_format_r1_unorm_fetch_rgba_float(float *dst, const uint8_t *src, 291 unsigned i, unsigned j) 292 { 293 294 } 295 296 297 void 298 util_format_r1_unorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, 299 const uint8_t *src_row, unsigned src_stride, 300 unsigned width, unsigned height) 301 { 302 303 } 304 305 306 void 307 util_format_r1_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, 308 const uint8_t *src_row, unsigned src_stride, 309 unsigned width, unsigned height) 310 { 311 } 312 313 314 /* 315 * PIPE_FORMAT_R8G8Bx_SNORM 316 * 317 * A.k.a. D3DFMT_CxV8U8 318 */ 319 320 static uint8_t 321 r8g8bx_derive(int16_t r, int16_t g) 322 { 323 /* Derive blue from red and green components. 324 * Apparently, we must always use integers to perform calculations, 325 * otherwise the results won't match D3D's CxV8U8 definition. 326 */ 327 return (uint8_t)sqrtf(0x7f * 0x7f - r * r - g * g) * 0xff / 0x7f; 328 } 329 330 void 331 util_format_r8g8bx_snorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, 332 const uint8_t *src_row, unsigned src_stride, 333 unsigned width, unsigned height) 334 { 335 unsigned x, y; 336 337 for(y = 0; y < height; y += 1) { 338 float *dst = dst_row; 339 const uint16_t *src = (const uint16_t *)src_row; 340 for(x = 0; x < width; x += 1) { 341 uint16_t value = *src++; 342 int16_t r, g; 343 344 #ifdef PIPE_ARCH_BIG_ENDIAN 345 value = util_bswap32(value); 346 #endif 347 348 r = ((int16_t)(value << 8)) >> 8; 349 g = ((int16_t)(value << 0)) >> 8; 350 351 dst[0] = (float)(r * (1.0f/0x7f)); /* r */ 352 dst[1] = (float)(g * (1.0f/0x7f)); /* g */ 353 dst[2] = r8g8bx_derive(r, g) * (1.0f/0xff); /* b */ 354 dst[3] = 1.0f; /* a */ 355 dst += 4; 356 } 357 src_row += src_stride; 358 dst_row += dst_stride/sizeof(*dst_row); 359 } 360 } 361 362 363 void 364 util_format_r8g8bx_snorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, 365 const uint8_t *src_row, unsigned src_stride, 366 unsigned width, unsigned height) 367 { 368 unsigned x, y; 369 for(y = 0; y < height; y += 1) { 370 uint8_t *dst = dst_row; 371 const uint16_t *src = (const uint16_t *)src_row; 372 for(x = 0; x < width; x += 1) { 373 uint16_t value = *src++; 374 int16_t r, g; 375 376 #ifdef PIPE_ARCH_BIG_ENDIAN 377 value = util_bswap32(value); 378 #endif 379 380 r = ((int16_t)(value << 8)) >> 8; 381 g = ((int16_t)(value << 0)) >> 8; 382 383 dst[0] = (uint8_t)(((uint16_t)MAX2(r, 0)) * 0xff / 0x7f); /* r */ 384 dst[1] = (uint8_t)(((uint16_t)MAX2(g, 0)) * 0xff / 0x7f); /* g */ 385 dst[2] = r8g8bx_derive(r, g); /* b */ 386 dst[3] = 255; /* a */ 387 dst += 4; 388 } 389 src_row += src_stride; 390 dst_row += dst_stride/sizeof(*dst_row); 391 } 392 } 393 394 395 void 396 util_format_r8g8bx_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, 397 const float *src_row, unsigned src_stride, 398 unsigned width, unsigned height) 399 { 400 unsigned x, y; 401 for(y = 0; y < height; y += 1) { 402 const float *src = src_row; 403 uint16_t *dst = (uint16_t *)dst_row; 404 for(x = 0; x < width; x += 1) { 405 uint16_t value = 0; 406 407 value |= (uint16_t)(((int8_t)(CLAMP(src[0], -1, 1) * 0x7f)) & 0xff) ; 408 value |= (uint16_t)((((int8_t)(CLAMP(src[1], -1, 1) * 0x7f)) & 0xff) << 8) ; 409 410 #ifdef PIPE_ARCH_BIG_ENDIAN 411 value = util_bswap32(value); 412 #endif 413 414 *dst++ = value; 415 416 src += 4; 417 } 418 dst_row += dst_stride; 419 src_row += src_stride/sizeof(*src_row); 420 } 421 } 422 423 424 void 425 util_format_r8g8bx_snorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, 426 const uint8_t *src_row, unsigned src_stride, 427 unsigned width, unsigned height) 428 { 429 unsigned x, y; 430 431 for(y = 0; y < height; y += 1) { 432 const uint8_t *src = src_row; 433 uint16_t *dst = (uint16_t *)dst_row; 434 for(x = 0; x < width; x += 1) { 435 uint16_t value = 0; 436 437 value |= src[0] >> 1; 438 value |= (src[1] >> 1) << 8; 439 440 #ifdef PIPE_ARCH_BIG_ENDIAN 441 value = util_bswap32(value); 442 #endif 443 444 *dst++ = value; 445 446 src += 4; 447 } 448 dst_row += dst_stride; 449 src_row += src_stride/sizeof(*src_row); 450 } 451 } 452 453 454 void 455 util_format_r8g8bx_snorm_fetch_rgba_float(float *dst, const uint8_t *src, 456 unsigned i, unsigned j) 457 { 458 uint16_t value = *(const uint16_t *)src; 459 int16_t r, g; 460 461 #ifdef PIPE_ARCH_BIG_ENDIAN 462 value = util_bswap32(value); 463 #endif 464 465 r = ((int16_t)(value << 8)) >> 8; 466 g = ((int16_t)(value << 0)) >> 8; 467 468 dst[0] = r * (1.0f/0x7f); /* r */ 469 dst[1] = g * (1.0f/0x7f); /* g */ 470 dst[2] = r8g8bx_derive(r, g) * (1.0f/0xff); /* b */ 471 dst[3] = 1.0f; /* a */ 472 } 473