1/* 2 * Copyright 2010-2019 Branimir Karadzic. All rights reserved. 3 * License: https://github.com/bkaradzic/bx#license-bsd-2-clause 4 */ 5 6#ifndef BX_PIXEL_FORMAT_H_HEADER_GUARD 7# error "Must be included from bx/pixelformat.h" 8#endif // BX_PIXEL_FORMAT_H_HEADER_GUARD 9 10namespace bx 11{ 12 inline uint32_t toUnorm(float _value, float _scale) 13 { 14 return uint32_t(round(clamp(_value, 0.0f, 1.0f) * _scale) ); 15 } 16 17 inline float fromUnorm(uint32_t _value, float _scale) 18 { 19 return float(_value) / _scale; 20 } 21 22 inline int32_t toSnorm(float _value, float _scale) 23 { 24 return int32_t(round( 25 clamp(_value, -1.0f, 1.0f) * _scale) 26 ); 27 } 28 29 inline float fromSnorm(int32_t _value, float _scale) 30 { 31 return max(-1.0f, float(_value) / _scale); 32 } 33 34 // A8 35 inline void packA8(void* _dst, const float* _src) 36 { 37 uint8_t* dst = (uint8_t*)_dst; 38 dst[0] = uint8_t(toUnorm(_src[3], 255.0f) ); 39 } 40 41 inline void unpackA8(float* _dst, const void* _src) 42 { 43 const uint8_t* src = (const uint8_t*)_src; 44 const float aa = fromUnorm(src[0], 255.0f); 45 _dst[0] = aa; 46 _dst[1] = aa; 47 _dst[2] = aa; 48 _dst[3] = aa; 49 } 50 51 // R8 52 inline void packR8(void* _dst, const float* _src) 53 { 54 uint8_t* dst = (uint8_t*)_dst; 55 dst[0] = uint8_t(toUnorm(_src[0], 255.0f) ); 56 } 57 58 inline void unpackR8(float* _dst, const void* _src) 59 { 60 const uint8_t* src = (const uint8_t*)_src; 61 _dst[0] = fromUnorm(src[0], 255.0f); 62 _dst[1] = 0.0f; 63 _dst[2] = 0.0f; 64 _dst[3] = 1.0f; 65 } 66 67 // R8S 68 inline void packR8S(void* _dst, const float* _src) 69 { 70 int8_t* dst = (int8_t*)_dst; 71 dst[0] = int8_t(toSnorm(_src[0], 127.0f) ); 72 } 73 74 inline void unpackR8S(float* _dst, const void* _src) 75 { 76 const int8_t* src = (const int8_t*)_src; 77 _dst[0] = fromSnorm(src[0], 127.0f); 78 _dst[1] = 0.0f; 79 _dst[2] = 0.0f; 80 _dst[3] = 1.0f; 81 } 82 83 // R8I 84 inline void packR8I(void* _dst, const float* _src) 85 { 86 int8_t* dst = (int8_t*)_dst; 87 dst[0] = int8_t(_src[0]); 88 } 89 90 inline void unpackR8I(float* _dst, const void* _src) 91 { 92 const int8_t* src = (const int8_t*)_src; 93 _dst[0] = float(src[0]); 94 _dst[1] = 0.0f; 95 _dst[2] = 0.0f; 96 _dst[3] = 1.0f; 97 } 98 99 // R8U 100 inline void packR8U(void* _dst, const float* _src) 101 { 102 uint8_t* dst = (uint8_t*)_dst; 103 dst[0] = uint8_t(_src[0]); 104 } 105 106 inline void unpackR8U(float* _dst, const void* _src) 107 { 108 const uint8_t* src = (const uint8_t*)_src; 109 _dst[0] = float(src[0]); 110 _dst[1] = 0.0f; 111 _dst[2] = 0.0f; 112 _dst[3] = 1.0f; 113 } 114 115 // RG8 116 inline void packRg8(void* _dst, const float* _src) 117 { 118 uint8_t* dst = (uint8_t*)_dst; 119 dst[0] = uint8_t(toUnorm(_src[0], 255.0f) ); 120 dst[1] = uint8_t(toUnorm(_src[1], 255.0f) ); 121 } 122 123 inline void unpackRg8(float* _dst, const void* _src) 124 { 125 const uint8_t* src = (const uint8_t*)_src; 126 _dst[0] = fromUnorm(src[0], 255.0f); 127 _dst[1] = fromUnorm(src[1], 255.0f); 128 _dst[2] = 0.0f; 129 _dst[3] = 1.0f; 130 } 131 132 // RG8S 133 inline void packRg8S(void* _dst, const float* _src) 134 { 135 int8_t* dst = (int8_t*)_dst; 136 dst[0] = int8_t(toSnorm(_src[0], 127.0f) ); 137 dst[1] = int8_t(toSnorm(_src[1], 127.0f) ); 138 } 139 140 inline void unpackRg8S(float* _dst, const void* _src) 141 { 142 const int8_t* src = (const int8_t*)_src; 143 _dst[0] = fromSnorm(src[0], 127.0f); 144 _dst[1] = fromSnorm(src[1], 127.0f); 145 _dst[2] = 0.0f; 146 _dst[3] = 1.0f; 147 } 148 149 // RG8I 150 inline void packRg8I(void* _dst, const float* _src) 151 { 152 int8_t* dst = (int8_t*)_dst; 153 dst[0] = int8_t(_src[0]); 154 dst[1] = int8_t(_src[1]); 155 } 156 157 inline void unpackRg8I(float* _dst, const void* _src) 158 { 159 const int8_t* src = (const int8_t*)_src; 160 _dst[0] = float(src[0]); 161 _dst[1] = float(src[1]); 162 _dst[2] = 0.0f; 163 _dst[3] = 1.0f; 164 } 165 166 // RG8U 167 inline void packRg8U(void* _dst, const float* _src) 168 { 169 uint8_t* dst = (uint8_t*)_dst; 170 dst[0] = uint8_t(_src[0]); 171 dst[1] = uint8_t(_src[1]); 172 } 173 174 inline void unpackRg8U(float* _dst, const void* _src) 175 { 176 const uint8_t* src = (const uint8_t*)_src; 177 _dst[0] = float(src[0]); 178 _dst[1] = float(src[1]); 179 _dst[2] = 0.0f; 180 _dst[3] = 1.0f; 181 } 182 183 // RGB8 184 inline void packRgb8(void* _dst, const float* _src) 185 { 186 uint8_t* dst = (uint8_t*)_dst; 187 dst[0] = uint8_t(toUnorm(_src[0], 255.0f) ); 188 dst[1] = uint8_t(toUnorm(_src[1], 255.0f) ); 189 dst[2] = uint8_t(toUnorm(_src[2], 255.0f) ); 190 } 191 192 inline void unpackRgb8(float* _dst, const void* _src) 193 { 194 const uint8_t* src = (const uint8_t*)_src; 195 _dst[0] = fromUnorm(src[0], 255.0f); 196 _dst[1] = fromUnorm(src[1], 255.0f); 197 _dst[2] = fromUnorm(src[2], 255.0f); 198 _dst[3] = 1.0f; 199 } 200 201 // RGB8S 202 inline void packRgb8S(void* _dst, const float* _src) 203 { 204 int8_t* dst = (int8_t*)_dst; 205 dst[0] = int8_t(toSnorm(_src[0], 127.0f) ); 206 dst[1] = int8_t(toSnorm(_src[1], 127.0f) ); 207 dst[2] = int8_t(toSnorm(_src[2], 127.0f) ); 208 } 209 210 inline void unpackRgb8S(float* _dst, const void* _src) 211 { 212 const int8_t* src = (const int8_t*)_src; 213 _dst[0] = fromSnorm(src[0], 127.0f); 214 _dst[1] = fromSnorm(src[1], 127.0f); 215 _dst[2] = fromSnorm(src[2], 127.0f); 216 _dst[3] = 1.0f; 217 } 218 219 // RGB8I 220 inline void packRgb8I(void* _dst, const float* _src) 221 { 222 int8_t* dst = (int8_t*)_dst; 223 dst[0] = int8_t(_src[0]); 224 dst[1] = int8_t(_src[1]); 225 dst[2] = int8_t(_src[2]); 226 } 227 228 inline void unpackRgb8I(float* _dst, const void* _src) 229 { 230 const int8_t* src = (const int8_t*)_src; 231 _dst[0] = float(src[0]); 232 _dst[1] = float(src[1]); 233 _dst[2] = float(src[2]); 234 _dst[3] = 1.0f; 235 } 236 237 // RGB8U 238 inline void packRgb8U(void* _dst, const float* _src) 239 { 240 uint8_t* dst = (uint8_t*)_dst; 241 dst[0] = uint8_t(_src[0]); 242 dst[1] = uint8_t(_src[1]); 243 dst[2] = uint8_t(_src[2]); 244 } 245 246 inline void unpackRgb8U(float* _dst, const void* _src) 247 { 248 const uint8_t* src = (const uint8_t*)_src; 249 _dst[0] = float(src[0]); 250 _dst[1] = float(src[1]); 251 _dst[2] = float(src[2]); 252 _dst[3] = 1.0f; 253 } 254 255 // BGRA8 256 inline void packBgra8(void* _dst, const float* _src) 257 { 258 uint8_t* dst = (uint8_t*)_dst; 259 dst[2] = uint8_t(toUnorm(_src[0], 255.0f) ); 260 dst[1] = uint8_t(toUnorm(_src[1], 255.0f) ); 261 dst[0] = uint8_t(toUnorm(_src[2], 255.0f) ); 262 dst[3] = uint8_t(toUnorm(_src[3], 255.0f) ); 263 } 264 265 inline void unpackBgra8(float* _dst, const void* _src) 266 { 267 const uint8_t* src = (const uint8_t*)_src; 268 _dst[0] = fromUnorm(src[2], 255.0f); 269 _dst[1] = fromUnorm(src[1], 255.0f); 270 _dst[2] = fromUnorm(src[0], 255.0f); 271 _dst[3] = fromUnorm(src[3], 255.0f); 272 } 273 274 // RGBA8 275 inline void packRgba8(void* _dst, const float* _src) 276 { 277 uint8_t* dst = (uint8_t*)_dst; 278 dst[0] = uint8_t(toUnorm(_src[0], 255.0f) ); 279 dst[1] = uint8_t(toUnorm(_src[1], 255.0f) ); 280 dst[2] = uint8_t(toUnorm(_src[2], 255.0f) ); 281 dst[3] = uint8_t(toUnorm(_src[3], 255.0f) ); 282 } 283 284 inline void unpackRgba8(float* _dst, const void* _src) 285 { 286 const uint8_t* src = (const uint8_t*)_src; 287 _dst[0] = fromUnorm(src[0], 255.0f); 288 _dst[1] = fromUnorm(src[1], 255.0f); 289 _dst[2] = fromUnorm(src[2], 255.0f); 290 _dst[3] = fromUnorm(src[3], 255.0f); 291 } 292 293 // RGBA8S 294 inline void packRgba8S(void* _dst, const float* _src) 295 { 296 int8_t* dst = (int8_t*)_dst; 297 dst[0] = int8_t(toSnorm(_src[0], 127.0f) ); 298 dst[1] = int8_t(toSnorm(_src[1], 127.0f) ); 299 dst[2] = int8_t(toSnorm(_src[2], 127.0f) ); 300 dst[3] = int8_t(toSnorm(_src[3], 127.0f) ); 301 } 302 303 inline void unpackRgba8S(float* _dst, const void* _src) 304 { 305 const int8_t* src = (const int8_t*)_src; 306 _dst[0] = fromSnorm(src[0], 127.0f); 307 _dst[1] = fromSnorm(src[1], 127.0f); 308 _dst[2] = fromSnorm(src[2], 127.0f); 309 _dst[3] = fromSnorm(src[3], 127.0f); 310 } 311 312 // RGBA8I 313 inline void packRgba8I(void* _dst, const float* _src) 314 { 315 int8_t* dst = (int8_t*)_dst; 316 dst[0] = int8_t(_src[0]); 317 dst[1] = int8_t(_src[1]); 318 dst[2] = int8_t(_src[2]); 319 dst[3] = int8_t(_src[3]); 320 } 321 322 inline void unpackRgba8I(float* _dst, const void* _src) 323 { 324 const int8_t* src = (const int8_t*)_src; 325 _dst[0] = float(src[0]); 326 _dst[1] = float(src[1]); 327 _dst[2] = float(src[2]); 328 _dst[3] = float(src[3]); 329 } 330 331 // RGBA8U 332 inline void packRgba8U(void* _dst, const float* _src) 333 { 334 uint8_t* dst = (uint8_t*)_dst; 335 dst[0] = uint8_t(_src[0]); 336 dst[1] = uint8_t(_src[1]); 337 dst[2] = uint8_t(_src[2]); 338 dst[3] = uint8_t(_src[3]); 339 } 340 341 inline void unpackRgba8U(float* _dst, const void* _src) 342 { 343 const uint8_t* src = (const uint8_t*)_src; 344 _dst[0] = float(src[0]); 345 _dst[1] = float(src[1]); 346 _dst[2] = float(src[2]); 347 _dst[3] = float(src[3]); 348 } 349 350 // R16 351 inline void packR16(void* _dst, const float* _src) 352 { 353 uint16_t* dst = (uint16_t*)_dst; 354 dst[0] = uint16_t(toUnorm(_src[0], 65535.0f) ); 355 } 356 357 inline void unpackR16(float* _dst, const void* _src) 358 { 359 const uint16_t* src = (const uint16_t*)_src; 360 _dst[0] = fromUnorm(src[0], 65535.0f); 361 _dst[1] = 0.0f; 362 _dst[2] = 0.0f; 363 _dst[3] = 1.0f; 364 } 365 366 // R16S 367 inline void packR16S(void* _dst, const float* _src) 368 { 369 int16_t* dst = (int16_t*)_dst; 370 dst[0] = int16_t(toSnorm(_src[0], 32767.0f) ); 371 } 372 373 inline void unpackR16S(float* _dst, const void* _src) 374 { 375 const int16_t* src = (const int16_t*)_src; 376 _dst[0] = fromSnorm(src[0], 32767.0f); 377 _dst[1] = 0.0f; 378 _dst[2] = 0.0f; 379 _dst[3] = 1.0f; 380 } 381 382 // R16I 383 inline void packR16I(void* _dst, const float* _src) 384 { 385 int16_t* dst = (int16_t*)_dst; 386 dst[0] = int16_t(_src[0]); 387 } 388 389 inline void unpackR16I(float* _dst, const void* _src) 390 { 391 const int16_t* src = (const int16_t*)_src; 392 _dst[0] = float(src[0]); 393 _dst[1] = 0.0f; 394 _dst[2] = 0.0f; 395 _dst[3] = 1.0f; 396 } 397 398 // R16U 399 inline void packR16U(void* _dst, const float* _src) 400 { 401 uint16_t* dst = (uint16_t*)_dst; 402 dst[0] = uint16_t(_src[0]); 403 } 404 405 inline void unpackR16U(float* _dst, const void* _src) 406 { 407 const uint16_t* src = (const uint16_t*)_src; 408 _dst[0] = float(src[0]); 409 } 410 411 // R16F 412 inline void packR16F(void* _dst, const float* _src) 413 { 414 uint16_t* dst = (uint16_t*)_dst; 415 dst[0] = halfFromFloat(_src[0]); 416 } 417 418 inline void unpackR16F(float* _dst, const void* _src) 419 { 420 const uint16_t* src = (const uint16_t*)_src; 421 _dst[0] = halfToFloat(src[0]); 422 _dst[1] = 0.0f; 423 _dst[2] = 0.0f; 424 _dst[3] = 1.0f; 425 } 426 427 // RG16 428 inline void packRg16(void* _dst, const float* _src) 429 { 430 uint16_t* dst = (uint16_t*)_dst; 431 dst[0] = uint16_t(toUnorm(_src[0], 65535.0f) ); 432 dst[1] = uint16_t(toUnorm(_src[1], 65535.0f) ); 433 } 434 435 inline void unpackRg16(float* _dst, const void* _src) 436 { 437 const uint16_t* src = (const uint16_t*)_src; 438 _dst[0] = fromUnorm(src[0], 65535.0f); 439 _dst[1] = fromUnorm(src[1], 65535.0f); 440 _dst[2] = 0.0f; 441 _dst[3] = 1.0f; 442 } 443 444 // RG16S 445 inline void packRg16S(void* _dst, const float* _src) 446 { 447 int16_t* dst = (int16_t*)_dst; 448 dst[0] = int16_t(toSnorm(_src[0], 32767.0f) ); 449 dst[1] = int16_t(toSnorm(_src[1], 32767.0f) ); 450 } 451 452 inline void unpackRg16S(float* _dst, const void* _src) 453 { 454 const int16_t* src = (const int16_t*)_src; 455 _dst[0] = fromSnorm(src[0], 32767.0f); 456 _dst[1] = fromSnorm(src[1], 32767.0f); 457 _dst[2] = 0.0f; 458 _dst[3] = 1.0f; 459 } 460 461 // RG16I 462 inline void packRg16I(void* _dst, const float* _src) 463 { 464 int16_t* dst = (int16_t*)_dst; 465 dst[0] = int16_t(_src[0]); 466 dst[1] = int16_t(_src[1]); 467 } 468 469 inline void unpackRg16I(float* _dst, const void* _src) 470 { 471 const int16_t* src = (const int16_t*)_src; 472 _dst[0] = float(src[0]); 473 _dst[1] = float(src[1]); 474 _dst[2] = 0.0f; 475 _dst[3] = 1.0f; 476 } 477 478 // RG16U 479 inline void packRg16U(void* _dst, const float* _src) 480 { 481 uint16_t* dst = (uint16_t*)_dst; 482 dst[0] = uint16_t(_src[0]); 483 dst[1] = uint16_t(_src[1]); 484 } 485 486 inline void unpackRg16U(float* _dst, const void* _src) 487 { 488 const uint16_t* src = (const uint16_t*)_src; 489 _dst[0] = float(src[0]); 490 _dst[1] = float(src[1]); 491 _dst[2] = 0.0f; 492 _dst[3] = 1.0f; 493 } 494 495 // RG16F 496 inline void packRg16F(void* _dst, const float* _src) 497 { 498 uint16_t* dst = (uint16_t*)_dst; 499 dst[0] = halfFromFloat(_src[0]); 500 dst[1] = halfFromFloat(_src[1]); 501 } 502 503 inline void unpackRg16F(float* _dst, const void* _src) 504 { 505 const uint16_t* src = (const uint16_t*)_src; 506 _dst[0] = halfToFloat(src[0]); 507 _dst[1] = halfToFloat(src[1]); 508 _dst[2] = 0.0f; 509 _dst[3] = 1.0f; 510 } 511 512 // RGBA16 513 inline void packRgba16(void* _dst, const float* _src) 514 { 515 uint16_t* dst = (uint16_t*)_dst; 516 dst[0] = uint16_t(toUnorm(_src[0], 65535.0f) ); 517 dst[1] = uint16_t(toUnorm(_src[1], 65535.0f) ); 518 dst[2] = uint16_t(toUnorm(_src[2], 65535.0f) ); 519 dst[3] = uint16_t(toUnorm(_src[3], 65535.0f) ); 520 } 521 522 inline void unpackRgba16(float* _dst, const void* _src) 523 { 524 const uint16_t* src = (const uint16_t*)_src; 525 _dst[0] = fromUnorm(src[0], 65535.0f); 526 _dst[1] = fromUnorm(src[1], 65535.0f); 527 _dst[2] = fromUnorm(src[2], 65535.0f); 528 _dst[3] = fromUnorm(src[3], 65535.0f); 529 } 530 531 // RGBA16S 532 inline void packRgba16S(void* _dst, const float* _src) 533 { 534 int16_t* dst = (int16_t*)_dst; 535 dst[0] = int16_t(toSnorm(_src[0], 32767.0f) ); 536 dst[1] = int16_t(toSnorm(_src[1], 32767.0f) ); 537 dst[2] = int16_t(toSnorm(_src[2], 32767.0f) ); 538 dst[3] = int16_t(toSnorm(_src[3], 32767.0f) ); 539 } 540 541 inline void unpackRgba16S(float* _dst, const void* _src) 542 { 543 const int16_t* src = (const int16_t*)_src; 544 _dst[0] = fromSnorm(src[0], 32767.0f); 545 _dst[1] = fromSnorm(src[1], 32767.0f); 546 _dst[2] = fromSnorm(src[2], 32767.0f); 547 _dst[3] = fromSnorm(src[3], 32767.0f); 548 } 549 550 // RGBA16I 551 inline void packRgba16I(void* _dst, const float* _src) 552 { 553 int16_t* dst = (int16_t*)_dst; 554 dst[0] = int16_t(_src[0]); 555 dst[1] = int16_t(_src[1]); 556 dst[2] = int16_t(_src[2]); 557 dst[3] = int16_t(_src[3]); 558 } 559 560 inline void unpackRgba16I(float* _dst, const void* _src) 561 { 562 const int16_t* src = (const int16_t*)_src; 563 _dst[0] = float(src[0]); 564 _dst[1] = float(src[1]); 565 _dst[2] = float(src[2]); 566 _dst[3] = float(src[3]); 567 } 568 569 // RGBA16U 570 inline void packRgba16U(void* _dst, const float* _src) 571 { 572 uint16_t* dst = (uint16_t*)_dst; 573 dst[0] = uint16_t(_src[0]); 574 dst[1] = uint16_t(_src[1]); 575 dst[2] = uint16_t(_src[2]); 576 dst[3] = uint16_t(_src[3]); 577 } 578 579 inline void unpackRgba16U(float* _dst, const void* _src) 580 { 581 const uint16_t* src = (const uint16_t*)_src; 582 _dst[0] = float(src[0]); 583 _dst[1] = float(src[1]); 584 _dst[2] = float(src[2]); 585 _dst[3] = float(src[3]); 586 } 587 588 // RGBA16F 589 inline void packRgba16F(void* _dst, const float* _src) 590 { 591 uint16_t* dst = (uint16_t*)_dst; 592 dst[0] = halfFromFloat(_src[0]); 593 dst[1] = halfFromFloat(_src[1]); 594 dst[2] = halfFromFloat(_src[2]); 595 dst[3] = halfFromFloat(_src[3]); 596 } 597 598 inline void unpackRgba16F(float* _dst, const void* _src) 599 { 600 const uint16_t* src = (const uint16_t*)_src; 601 _dst[0] = halfToFloat(src[0]); 602 _dst[1] = halfToFloat(src[1]); 603 _dst[2] = halfToFloat(src[2]); 604 _dst[3] = halfToFloat(src[3]); 605 } 606 607 // R24 608 inline void packR24(void* _dst, const float* _src) 609 { 610 uint8_t* dst = (uint8_t*)_dst; 611 const uint32_t rr = uint32_t(toUnorm(_src[0], 16777216.0f) ); 612 dst[0] = uint8_t(rr ); 613 dst[1] = uint8_t(rr>> 8); 614 dst[2] = uint8_t(rr>>16); 615 } 616 617 inline void unpackR24(float* _dst, const void* _src) 618 { 619 const uint8_t* src = (const uint8_t*)_src; 620 const uint32_t rr = 0 621 | (src[0] ) 622 | (src[1]<< 8) 623 | (src[2]<<16) 624 ; 625 626 _dst[0] = fromUnorm(rr, 16777216.0f); 627 _dst[1] = 0.0f; 628 _dst[2] = 0.0f; 629 _dst[3] = 1.0f; 630 } 631 632 // R24G8 633 inline void packR24G8(void* _dst, const float* _src) 634 { 635 uint8_t* dst = (uint8_t*)_dst; 636 const uint32_t rr = uint32_t(toUnorm(_src[0], 16777216.0f) ); 637 dst[0] = uint8_t(rr ); 638 dst[1] = uint8_t(rr>> 8); 639 dst[2] = uint8_t(rr>>16); 640 dst[3] = uint8_t(toUnorm(_src[1], 255.0f) ); 641 } 642 643 inline void unpackR24G8(float* _dst, const void* _src) 644 { 645 const uint8_t* src = (const uint8_t*)_src; 646 const uint32_t rr = 0 647 | (src[0] ) 648 | (src[1]<< 8) 649 | (src[2]<<16) 650 ; 651 652 _dst[0] = fromUnorm(rr, 16777216.0f); 653 _dst[1] = fromUnorm(src[3], 255.0f); 654 _dst[2] = 0.0f; 655 _dst[3] = 1.0f; 656 } 657 658 // R32I 659 inline void packR32I(void* _dst, const float* _src) 660 { 661 memCopy(_dst, _src, 4); 662 } 663 664 inline void unpackR32I(float* _dst, const void* _src) 665 { 666 memCopy(_dst, _src, 4); 667 } 668 669 // R32U 670 inline void packR32U(void* _dst, const float* _src) 671 { 672 memCopy(_dst, _src, 4); 673 } 674 675 inline void unpackR32U(float* _dst, const void* _src) 676 { 677 memCopy(_dst, _src, 4); 678 } 679 680 // R32F 681 inline void packR32F(void* _dst, const float* _src) 682 { 683 memCopy(_dst, _src, 4); 684 } 685 686 inline void unpackR32F(float* _dst, const void* _src) 687 { 688 memCopy(_dst, _src, 4); 689 } 690 691 // RG32I 692 inline void packRg32I(void* _dst, const float* _src) 693 { 694 memCopy(_dst, _src, 8); 695 } 696 697 inline void unpackRg32I(float* _dst, const void* _src) 698 { 699 memCopy(_dst, _src, 8); 700 } 701 702 // RG32U 703 inline void packRg32U(void* _dst, const float* _src) 704 { 705 memCopy(_dst, _src, 8); 706 } 707 708 inline void unpackRg32U(float* _dst, const void* _src) 709 { 710 memCopy(_dst, _src, 8); 711 } 712 713 // RG32F 714 inline void packRg32F(void* _dst, const float* _src) 715 { 716 memCopy(_dst, _src, 8); 717 } 718 719 inline void unpackRg32F(float* _dst, const void* _src) 720 { 721 memCopy(_dst, _src, 8); 722 } 723 724 template<int32_t MantissaBits, int32_t ExpBits> 725 inline void encodeRgbE(float* _dst, const float* _src) 726 { 727 // Reference(s): 728 // - https://web.archive.org/web/20181126040035/https://www.khronos.org/registry/OpenGL/extensions/EXT/EXT_texture_shared_exponent.txt 729 // 730 const int32_t expMax = (1<<ExpBits) - 1; 731 const int32_t expBias = (1<<(ExpBits - 1) ) - 1; 732 const float sharedExpMax = float(expMax) / float(expMax + 1) * float(1 << (expMax - expBias) ); 733 734 const float rr = clamp(_src[0], 0.0f, sharedExpMax); 735 const float gg = clamp(_src[1], 0.0f, sharedExpMax); 736 const float bb = clamp(_src[2], 0.0f, sharedExpMax); 737 const float mm = max(rr, gg, bb); 738 union { float ff; uint32_t ui; } cast = { mm }; 739 int32_t expShared = int32_t(uint32_imax(uint32_t(-expBias-1), ( ( (cast.ui>>23) & 0xff) - 127) ) ) + 1 + expBias; 740 float denom = pow(2.0f, float(expShared - expBias - MantissaBits) ); 741 742 if ( (1<<MantissaBits) == int32_t(round(mm/denom) ) ) 743 { 744 denom *= 2.0f; 745 ++expShared; 746 } 747 748 const float invDenom = 1.0f/denom; 749 _dst[0] = round(rr * invDenom); 750 _dst[1] = round(gg * invDenom); 751 _dst[2] = round(bb * invDenom); 752 _dst[3] = float(expShared); 753 } 754 755 template<int32_t MantissaBits, int32_t ExpBits> 756 inline void decodeRgbE(float* _dst, const float* _src) 757 { 758 const int32_t expBias = (1<<(ExpBits - 1) ) - 1; 759 const float exponent = _src[3]-float(expBias-MantissaBits); 760 const float scale = pow(2.0f, exponent); 761 _dst[0] = _src[0] * scale; 762 _dst[1] = _src[1] * scale; 763 _dst[2] = _src[2] * scale; 764 } 765 766 // RGB9E5F 767 inline void packRgb9E5F(void* _dst, const float* _src) 768 { 769 float tmp[4]; 770 encodeRgbE<9, 5>(tmp, _src); 771 772 *( (uint32_t*)_dst) = 0 773 | (uint32_t(tmp[0]) ) 774 | (uint32_t(tmp[1]) << 9) 775 | (uint32_t(tmp[2]) <<18) 776 | (uint32_t(tmp[3]) <<27) 777 ; 778 } 779 780 inline void unpackRgb9E5F(float* _dst, const void* _src) 781 { 782 uint32_t packed = *( (const uint32_t*)_src); 783 784 float tmp[4]; 785 tmp[0] = float( ( (packed ) & 0x1ff) ) / 511.0f; 786 tmp[1] = float( ( (packed>> 9) & 0x1ff) ) / 511.0f; 787 tmp[2] = float( ( (packed>>18) & 0x1ff) ) / 511.0f; 788 tmp[3] = float( ( (packed>>27) & 0x1f) ); 789 790 decodeRgbE<9, 5>(_dst, tmp); 791 } 792 793 // RGBA32I 794 inline void packRgba32I(void* _dst, const float* _src) 795 { 796 memCopy(_dst, _src, 16); 797 } 798 799 inline void unpackRgba32I(float* _dst, const void* _src) 800 { 801 memCopy(_dst, _src, 16); 802 } 803 804 // RGBA32U 805 inline void packRgba32U(void* _dst, const float* _src) 806 { 807 memCopy(_dst, _src, 16); 808 } 809 810 inline void unpackRgba32U(float* _dst, const void* _src) 811 { 812 memCopy(_dst, _src, 16); 813 } 814 815 // RGBA32F 816 inline void packRgba32F(void* _dst, const float* _src) 817 { 818 memCopy(_dst, _src, 16); 819 } 820 821 inline void unpackRgba32F(float* _dst, const void* _src) 822 { 823 memCopy(_dst, _src, 16); 824 } 825 826 // R5G6B5 827 inline void packR5G6B5(void* _dst, const float* _src) 828 { 829 *( (uint16_t*)_dst) = 0 830 | uint16_t(toUnorm(_src[0], 31.0f)<<11) 831 | uint16_t(toUnorm(_src[1], 63.0f)<< 5) 832 | uint16_t(toUnorm(_src[2], 31.0f) ) 833 ; 834 } 835 836 inline void unpackR5G6B5(float* _dst, const void* _src) 837 { 838 uint16_t packed = *( (const uint16_t*)_src); 839 _dst[0] = float( ( (packed>>11) & 0x1f) ) / 31.0f; 840 _dst[1] = float( ( (packed>> 5) & 0x3f) ) / 63.0f; 841 _dst[2] = float( ( (packed ) & 0x1f) ) / 31.0f; 842 _dst[3] = 1.0f; 843 } 844 845 // RGBA4 846 inline void packRgba4(void* _dst, const float* _src) 847 { 848 *( (uint16_t*)_dst) = 0 849 | uint16_t(toUnorm(_src[0], 15.0f) ) 850 | uint16_t(toUnorm(_src[1], 15.0f)<< 4) 851 | uint16_t(toUnorm(_src[2], 15.0f)<< 8) 852 | uint16_t(toUnorm(_src[3], 15.0f)<<12) 853 ; 854 } 855 856 inline void unpackRgba4(float* _dst, const void* _src) 857 { 858 uint16_t packed = *( (const uint16_t*)_src); 859 _dst[0] = float( ( (packed ) & 0xf) ) / 15.0f; 860 _dst[1] = float( ( (packed>> 4) & 0xf) ) / 15.0f; 861 _dst[2] = float( ( (packed>> 8) & 0xf) ) / 15.0f; 862 _dst[3] = float( ( (packed>>12) & 0xf) ) / 15.0f; 863 } 864 865 // RGBA4 866 inline void packBgra4(void* _dst, const float* _src) 867 { 868 *( (uint16_t*)_dst) = 0 869 | uint16_t(toUnorm(_src[0], 15.0f)<< 8) 870 | uint16_t(toUnorm(_src[1], 15.0f)<< 4) 871 | uint16_t(toUnorm(_src[2], 15.0f) ) 872 | uint16_t(toUnorm(_src[3], 15.0f)<<12) 873 ; 874 } 875 876 inline void unpackBgra4(float* _dst, const void* _src) 877 { 878 uint16_t packed = *( (const uint16_t*)_src); 879 _dst[0] = float( ( (packed>> 8) & 0xf) ) / 15.0f; 880 _dst[1] = float( ( (packed>> 4) & 0xf) ) / 15.0f; 881 _dst[2] = float( ( (packed ) & 0xf) ) / 15.0f; 882 _dst[3] = float( ( (packed>>12) & 0xf) ) / 15.0f; 883 } 884 885 // RGB5A1 886 inline void packRgb5a1(void* _dst, const float* _src) 887 { 888 *( (uint16_t*)_dst) = 0 889 | uint16_t(toUnorm(_src[0], 31.0f) ) 890 | uint16_t(toUnorm(_src[1], 31.0f)<< 5) 891 | uint16_t(toUnorm(_src[2], 31.0f)<<10) 892 | uint16_t(toUnorm(_src[3], 1.0f)<<15) 893 ; 894 } 895 896 inline void unpackRgb5a1(float* _dst, const void* _src) 897 { 898 uint16_t packed = *( (const uint16_t*)_src); 899 _dst[0] = float( ( (packed ) & 0x1f) ) / 31.0f; 900 _dst[1] = float( ( (packed>> 5) & 0x1f) ) / 31.0f; 901 _dst[2] = float( ( (packed>>10) & 0x1f) ) / 31.0f; 902 _dst[3] = float( ( (packed>>14) & 0x1) ); 903 } 904 905 // BGR5A1 906 inline void packBgr5a1(void* _dst, const float* _src) 907 { 908 *( (uint16_t*)_dst) = 0 909 | uint16_t(toUnorm(_src[0], 31.0f)<<10) 910 | uint16_t(toUnorm(_src[1], 31.0f)<< 5) 911 | uint16_t(toUnorm(_src[2], 31.0f) ) 912 | uint16_t(toUnorm(_src[3], 1.0f)<<15) 913 ; 914 } 915 916 inline void unpackBgr5a1(float* _dst, const void* _src) 917 { 918 uint16_t packed = *( (const uint16_t*)_src); 919 _dst[0] = float( ( (packed>>10) & 0x1f) ) / 31.0f; 920 _dst[1] = float( ( (packed>> 5) & 0x1f) ) / 31.0f; 921 _dst[2] = float( ( (packed ) & 0x1f) ) / 31.0f; 922 _dst[3] = float( ( (packed>>14) & 0x1) ); 923 } 924 925 // RGB10A2 926 inline void packRgb10A2(void* _dst, const float* _src) 927 { 928 *( (uint32_t*)_dst) = 0 929 | (toUnorm(_src[0], 1023.0f) ) 930 | (toUnorm(_src[1], 1023.0f)<<10) 931 | (toUnorm(_src[2], 1023.0f)<<20) 932 | (toUnorm(_src[3], 3.0f)<<30) 933 ; 934 } 935 936 inline void unpackRgb10A2(float* _dst, const void* _src) 937 { 938 uint32_t packed = *( (const uint32_t*)_src); 939 _dst[0] = float( ( (packed ) & 0x3ff) ) / 1023.0f; 940 _dst[1] = float( ( (packed>>10) & 0x3ff) ) / 1023.0f; 941 _dst[2] = float( ( (packed>>20) & 0x3ff) ) / 1023.0f; 942 _dst[3] = float( ( (packed>>30) & 0x3) ) / 3.0f; 943 } 944 945 // RG11B10F 946 inline void packRG11B10F(void* _dst, const float* _src) 947 { 948 *( (uint32_t*)_dst) = 0 949 | ( (halfFromFloat(_src[0])>> 4) & 0x7ff) 950 | ( (halfFromFloat(_src[0])<< 7) & 0x3ff800) 951 | ( (halfFromFloat(_src[0])<<17) & 0xffc00000) 952 ; 953 } 954 955 inline void unpackRG11B10F(float* _dst, const void* _src) 956 { 957 uint32_t packed = *( (const uint32_t*)_src); 958 _dst[0] = halfToFloat( (packed<< 4) & 0x7ff0); 959 _dst[1] = halfToFloat( (packed>> 7) & 0x7ff0); 960 _dst[2] = halfToFloat( (packed>>17) & 0x7fe0); 961 _dst[3] = 1.0f; 962 } 963} // namespace bx 964