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 35void 36util_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 59void 60util_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 82void 83util_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 95void 96util_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 124void 125util_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 153void 154util_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 177void 178util_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 200void 201util_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 213void 214util_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 242void 243util_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 271void 272util_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 280void 281util_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 289void 290util_format_r1_unorm_fetch_rgba_float(float *dst, const uint8_t *src, 291 unsigned i, unsigned j) 292{ 293 294} 295 296 297void 298util_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 306void 307util_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 320static uint8_t 321r8g8bx_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 330void 331util_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 363void 364util_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 395void 396util_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 424void 425util_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 454void 455util_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