1 /************************************************************************** 2 * 3 * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. 4 * Copyright (c) 2008 VMware, Inc. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the "Software"), 8 * to deal in the Software without restriction, including without limitation 9 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 * and/or sell copies of the Software, and to permit persons to whom the 11 * Software is furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included 14 * in all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 * OTHER DEALINGS IN THE SOFTWARE. 23 * 24 **************************************************************************/ 25 26 #include "u_dl.h" 27 #include "u_math.h" 28 #include "u_format.h" 29 #include "u_format_s3tc.h" 30 #include "util/format_srgb.h" 31 32 33 #if defined(_WIN32) || defined(WIN32) 34 #define DXTN_LIBNAME "dxtn.dll" 35 #elif defined(__CYGWIN__) 36 #define DXTN_LIBNAME "cygtxc_dxtn.dll" 37 #elif defined(__APPLE__) 38 #define DXTN_LIBNAME "libtxc_dxtn.dylib" 39 #else 40 #define DXTN_LIBNAME "libtxc_dxtn.so" 41 #endif 42 43 44 static void 45 util_format_dxt1_rgb_fetch_stub(int src_stride, 46 const uint8_t *src, 47 int col, int row, 48 uint8_t *dst) 49 { 50 assert(0); 51 } 52 53 54 static void 55 util_format_dxt1_rgba_fetch_stub(int src_stride, 56 const uint8_t *src, 57 int col, int row, 58 uint8_t *dst ) 59 { 60 assert(0); 61 } 62 63 64 static void 65 util_format_dxt3_rgba_fetch_stub(int src_stride, 66 const uint8_t *src, 67 int col, int row, 68 uint8_t *dst ) 69 { 70 assert(0); 71 } 72 73 74 static void 75 util_format_dxt5_rgba_fetch_stub(int src_stride, 76 const uint8_t *src, 77 int col, int row, 78 uint8_t *dst ) 79 { 80 assert(0); 81 } 82 83 84 static void 85 util_format_dxtn_pack_stub(int src_comps, 86 int width, int height, 87 const uint8_t *src, 88 enum util_format_dxtn dst_format, 89 uint8_t *dst, 90 int dst_stride) 91 { 92 assert(0); 93 } 94 95 96 boolean util_format_s3tc_enabled = FALSE; 97 98 util_format_dxtn_fetch_t util_format_dxt1_rgb_fetch = util_format_dxt1_rgb_fetch_stub; 99 util_format_dxtn_fetch_t util_format_dxt1_rgba_fetch = util_format_dxt1_rgba_fetch_stub; 100 util_format_dxtn_fetch_t util_format_dxt3_rgba_fetch = util_format_dxt3_rgba_fetch_stub; 101 util_format_dxtn_fetch_t util_format_dxt5_rgba_fetch = util_format_dxt5_rgba_fetch_stub; 102 103 util_format_dxtn_pack_t util_format_dxtn_pack = util_format_dxtn_pack_stub; 104 105 106 void 107 util_format_s3tc_init(void) 108 { 109 static boolean first_time = TRUE; 110 struct util_dl_library *library = NULL; 111 util_dl_proc fetch_2d_texel_rgb_dxt1; 112 util_dl_proc fetch_2d_texel_rgba_dxt1; 113 util_dl_proc fetch_2d_texel_rgba_dxt3; 114 util_dl_proc fetch_2d_texel_rgba_dxt5; 115 util_dl_proc tx_compress_dxtn; 116 117 if (!first_time) 118 return; 119 first_time = FALSE; 120 121 if (util_format_s3tc_enabled) 122 return; 123 124 library = util_dl_open(DXTN_LIBNAME); 125 if (!library) { 126 debug_printf("couldn't open " DXTN_LIBNAME ", software DXTn " 127 "compression/decompression unavailable\n"); 128 return; 129 } 130 131 fetch_2d_texel_rgb_dxt1 = 132 util_dl_get_proc_address(library, "fetch_2d_texel_rgb_dxt1"); 133 fetch_2d_texel_rgba_dxt1 = 134 util_dl_get_proc_address(library, "fetch_2d_texel_rgba_dxt1"); 135 fetch_2d_texel_rgba_dxt3 = 136 util_dl_get_proc_address(library, "fetch_2d_texel_rgba_dxt3"); 137 fetch_2d_texel_rgba_dxt5 = 138 util_dl_get_proc_address(library, "fetch_2d_texel_rgba_dxt5"); 139 tx_compress_dxtn = 140 util_dl_get_proc_address(library, "tx_compress_dxtn"); 141 142 if (!util_format_dxt1_rgb_fetch || 143 !util_format_dxt1_rgba_fetch || 144 !util_format_dxt3_rgba_fetch || 145 !util_format_dxt5_rgba_fetch || 146 !util_format_dxtn_pack) { 147 debug_printf("couldn't reference all symbols in " DXTN_LIBNAME 148 ", software DXTn compression/decompression " 149 "unavailable\n"); 150 util_dl_close(library); 151 return; 152 } 153 154 util_format_dxt1_rgb_fetch = (util_format_dxtn_fetch_t)fetch_2d_texel_rgb_dxt1; 155 util_format_dxt1_rgba_fetch = (util_format_dxtn_fetch_t)fetch_2d_texel_rgba_dxt1; 156 util_format_dxt3_rgba_fetch = (util_format_dxtn_fetch_t)fetch_2d_texel_rgba_dxt3; 157 util_format_dxt5_rgba_fetch = (util_format_dxtn_fetch_t)fetch_2d_texel_rgba_dxt5; 158 util_format_dxtn_pack = (util_format_dxtn_pack_t)tx_compress_dxtn; 159 util_format_s3tc_enabled = TRUE; 160 } 161 162 163 /* 164 * Pixel fetch. 165 */ 166 167 void 168 util_format_dxt1_rgb_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j) 169 { 170 util_format_dxt1_rgb_fetch(0, src, i, j, dst); 171 } 172 173 void 174 util_format_dxt1_rgba_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j) 175 { 176 util_format_dxt1_rgba_fetch(0, src, i, j, dst); 177 } 178 179 void 180 util_format_dxt3_rgba_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j) 181 { 182 util_format_dxt3_rgba_fetch(0, src, i, j, dst); 183 } 184 185 void 186 util_format_dxt5_rgba_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j) 187 { 188 util_format_dxt5_rgba_fetch(0, src, i, j, dst); 189 } 190 191 void 192 util_format_dxt1_rgb_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j) 193 { 194 uint8_t tmp[4]; 195 util_format_dxt1_rgb_fetch(0, src, i, j, tmp); 196 dst[0] = ubyte_to_float(tmp[0]); 197 dst[1] = ubyte_to_float(tmp[1]); 198 dst[2] = ubyte_to_float(tmp[2]); 199 dst[3] = 1.0; 200 } 201 202 void 203 util_format_dxt1_rgba_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j) 204 { 205 uint8_t tmp[4]; 206 util_format_dxt1_rgba_fetch(0, src, i, j, tmp); 207 dst[0] = ubyte_to_float(tmp[0]); 208 dst[1] = ubyte_to_float(tmp[1]); 209 dst[2] = ubyte_to_float(tmp[2]); 210 dst[3] = ubyte_to_float(tmp[3]); 211 } 212 213 void 214 util_format_dxt3_rgba_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j) 215 { 216 uint8_t tmp[4]; 217 util_format_dxt3_rgba_fetch(0, src, i, j, tmp); 218 dst[0] = ubyte_to_float(tmp[0]); 219 dst[1] = ubyte_to_float(tmp[1]); 220 dst[2] = ubyte_to_float(tmp[2]); 221 dst[3] = ubyte_to_float(tmp[3]); 222 } 223 224 void 225 util_format_dxt5_rgba_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j) 226 { 227 uint8_t tmp[4]; 228 util_format_dxt5_rgba_fetch(0, src, i, j, tmp); 229 dst[0] = ubyte_to_float(tmp[0]); 230 dst[1] = ubyte_to_float(tmp[1]); 231 dst[2] = ubyte_to_float(tmp[2]); 232 dst[3] = ubyte_to_float(tmp[3]); 233 } 234 235 236 /* 237 * Block decompression. 238 */ 239 240 static inline void 241 util_format_dxtn_rgb_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, 242 const uint8_t *src_row, unsigned src_stride, 243 unsigned width, unsigned height, 244 util_format_dxtn_fetch_t fetch, 245 unsigned block_size, boolean srgb) 246 { 247 const unsigned bw = 4, bh = 4, comps = 4; 248 unsigned x, y, i, j; 249 for(y = 0; y < height; y += bh) { 250 const uint8_t *src = src_row; 251 for(x = 0; x < width; x += bw) { 252 for(j = 0; j < bh; ++j) { 253 for(i = 0; i < bw; ++i) { 254 uint8_t *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*comps; 255 fetch(0, src, i, j, dst); 256 if (srgb) { 257 dst[0] = util_format_srgb_to_linear_8unorm(dst[0]); 258 dst[1] = util_format_srgb_to_linear_8unorm(dst[1]); 259 dst[2] = util_format_srgb_to_linear_8unorm(dst[2]); 260 } 261 } 262 } 263 src += block_size; 264 } 265 src_row += src_stride; 266 } 267 } 268 269 void 270 util_format_dxt1_rgb_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, 271 const uint8_t *src_row, unsigned src_stride, 272 unsigned width, unsigned height) 273 { 274 util_format_dxtn_rgb_unpack_rgba_8unorm(dst_row, dst_stride, 275 src_row, src_stride, 276 width, height, 277 util_format_dxt1_rgb_fetch, 278 8, FALSE); 279 } 280 281 void 282 util_format_dxt1_rgba_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, 283 const uint8_t *src_row, unsigned src_stride, 284 unsigned width, unsigned height) 285 { 286 util_format_dxtn_rgb_unpack_rgba_8unorm(dst_row, dst_stride, 287 src_row, src_stride, 288 width, height, 289 util_format_dxt1_rgba_fetch, 290 8, FALSE); 291 } 292 293 void 294 util_format_dxt3_rgba_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, 295 const uint8_t *src_row, unsigned src_stride, 296 unsigned width, unsigned height) 297 { 298 util_format_dxtn_rgb_unpack_rgba_8unorm(dst_row, dst_stride, 299 src_row, src_stride, 300 width, height, 301 util_format_dxt3_rgba_fetch, 302 16, FALSE); 303 } 304 305 void 306 util_format_dxt5_rgba_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, 307 const uint8_t *src_row, unsigned src_stride, 308 unsigned width, unsigned height) 309 { 310 util_format_dxtn_rgb_unpack_rgba_8unorm(dst_row, dst_stride, 311 src_row, src_stride, 312 width, height, 313 util_format_dxt5_rgba_fetch, 314 16, FALSE); 315 } 316 317 static inline void 318 util_format_dxtn_rgb_unpack_rgba_float(float *dst_row, unsigned dst_stride, 319 const uint8_t *src_row, unsigned src_stride, 320 unsigned width, unsigned height, 321 util_format_dxtn_fetch_t fetch, 322 unsigned block_size, boolean srgb) 323 { 324 unsigned x, y, i, j; 325 for(y = 0; y < height; y += 4) { 326 const uint8_t *src = src_row; 327 for(x = 0; x < width; x += 4) { 328 for(j = 0; j < 4; ++j) { 329 for(i = 0; i < 4; ++i) { 330 float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4; 331 uint8_t tmp[4]; 332 fetch(0, src, i, j, tmp); 333 if (srgb) { 334 dst[0] = util_format_srgb_8unorm_to_linear_float(tmp[0]); 335 dst[1] = util_format_srgb_8unorm_to_linear_float(tmp[1]); 336 dst[2] = util_format_srgb_8unorm_to_linear_float(tmp[2]); 337 } 338 else { 339 dst[0] = ubyte_to_float(tmp[0]); 340 dst[1] = ubyte_to_float(tmp[1]); 341 dst[2] = ubyte_to_float(tmp[2]); 342 } 343 dst[3] = ubyte_to_float(tmp[3]); 344 } 345 } 346 src += block_size; 347 } 348 src_row += src_stride; 349 } 350 } 351 352 void 353 util_format_dxt1_rgb_unpack_rgba_float(float *dst_row, unsigned dst_stride, 354 const uint8_t *src_row, unsigned src_stride, 355 unsigned width, unsigned height) 356 { 357 util_format_dxtn_rgb_unpack_rgba_float(dst_row, dst_stride, 358 src_row, src_stride, 359 width, height, 360 util_format_dxt1_rgb_fetch, 361 8, FALSE); 362 } 363 364 void 365 util_format_dxt1_rgba_unpack_rgba_float(float *dst_row, unsigned dst_stride, 366 const uint8_t *src_row, unsigned src_stride, 367 unsigned width, unsigned height) 368 { 369 util_format_dxtn_rgb_unpack_rgba_float(dst_row, dst_stride, 370 src_row, src_stride, 371 width, height, 372 util_format_dxt1_rgba_fetch, 373 8, FALSE); 374 } 375 376 void 377 util_format_dxt3_rgba_unpack_rgba_float(float *dst_row, unsigned dst_stride, 378 const uint8_t *src_row, unsigned src_stride, 379 unsigned width, unsigned height) 380 { 381 util_format_dxtn_rgb_unpack_rgba_float(dst_row, dst_stride, 382 src_row, src_stride, 383 width, height, 384 util_format_dxt3_rgba_fetch, 385 16, FALSE); 386 } 387 388 void 389 util_format_dxt5_rgba_unpack_rgba_float(float *dst_row, unsigned dst_stride, 390 const uint8_t *src_row, unsigned src_stride, 391 unsigned width, unsigned height) 392 { 393 util_format_dxtn_rgb_unpack_rgba_float(dst_row, dst_stride, 394 src_row, src_stride, 395 width, height, 396 util_format_dxt5_rgba_fetch, 397 16, FALSE); 398 } 399 400 401 /* 402 * Block compression. 403 */ 404 405 static inline void 406 util_format_dxtn_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, 407 const uint8_t *src, unsigned src_stride, 408 unsigned width, unsigned height, 409 enum util_format_dxtn format, 410 unsigned block_size, boolean srgb) 411 { 412 const unsigned bw = 4, bh = 4, comps = 4; 413 unsigned x, y, i, j, k; 414 for(y = 0; y < height; y += bh) { 415 uint8_t *dst = dst_row; 416 for(x = 0; x < width; x += bw) { 417 uint8_t tmp[4][4][4]; /* [bh][bw][comps] */ 418 for(j = 0; j < bh; ++j) { 419 for(i = 0; i < bw; ++i) { 420 uint8_t src_tmp; 421 for(k = 0; k < 3; ++k) { 422 src_tmp = src[(y + j)*src_stride/sizeof(*src) + (x+i)*comps + k]; 423 if (srgb) { 424 tmp[j][i][k] = util_format_linear_to_srgb_8unorm(src_tmp); 425 } 426 else { 427 tmp[j][i][k] = src_tmp; 428 } 429 } 430 /* for sake of simplicity there's an unneeded 4th component for dxt1_rgb */ 431 tmp[j][i][3] = src[(y + j)*src_stride/sizeof(*src) + (x+i)*comps + 3]; 432 } 433 } 434 /* even for dxt1_rgb have 4 src comps */ 435 util_format_dxtn_pack(4, 4, 4, &tmp[0][0][0], format, dst, 0); 436 dst += block_size; 437 } 438 dst_row += dst_stride / sizeof(*dst_row); 439 } 440 441 } 442 443 void 444 util_format_dxt1_rgb_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, 445 const uint8_t *src, unsigned src_stride, 446 unsigned width, unsigned height) 447 { 448 util_format_dxtn_pack_rgba_8unorm(dst_row, dst_stride, src, src_stride, 449 width, height, UTIL_FORMAT_DXT1_RGB, 450 8, FALSE); 451 } 452 453 void 454 util_format_dxt1_rgba_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, 455 const uint8_t *src, unsigned src_stride, 456 unsigned width, unsigned height) 457 { 458 util_format_dxtn_pack_rgba_8unorm(dst_row, dst_stride, src, src_stride, 459 width, height, UTIL_FORMAT_DXT1_RGBA, 460 8, FALSE); 461 } 462 463 void 464 util_format_dxt3_rgba_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, 465 const uint8_t *src, unsigned src_stride, 466 unsigned width, unsigned height) 467 { 468 util_format_dxtn_pack_rgba_8unorm(dst_row, dst_stride, src, src_stride, 469 width, height, UTIL_FORMAT_DXT3_RGBA, 470 16, FALSE); 471 } 472 473 void 474 util_format_dxt5_rgba_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, 475 const uint8_t *src, unsigned src_stride, 476 unsigned width, unsigned height) 477 { 478 util_format_dxtn_pack_rgba_8unorm(dst_row, dst_stride, src, src_stride, 479 width, height, UTIL_FORMAT_DXT5_RGBA, 480 16, FALSE); 481 } 482 483 static inline void 484 util_format_dxtn_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, 485 const float *src, unsigned src_stride, 486 unsigned width, unsigned height, 487 enum util_format_dxtn format, 488 unsigned block_size, boolean srgb) 489 { 490 unsigned x, y, i, j, k; 491 for(y = 0; y < height; y += 4) { 492 uint8_t *dst = dst_row; 493 for(x = 0; x < width; x += 4) { 494 uint8_t tmp[4][4][4]; 495 for(j = 0; j < 4; ++j) { 496 for(i = 0; i < 4; ++i) { 497 float src_tmp; 498 for(k = 0; k < 3; ++k) { 499 src_tmp = src[(y + j)*src_stride/sizeof(*src) + (x+i)*4 + k]; 500 if (srgb) { 501 tmp[j][i][k] = util_format_linear_float_to_srgb_8unorm(src_tmp); 502 } 503 else { 504 tmp[j][i][k] = float_to_ubyte(src_tmp); 505 } 506 } 507 /* for sake of simplicity there's an unneeded 4th component for dxt1_rgb */ 508 src_tmp = src[(y + j)*src_stride/sizeof(*src) + (x+i)*4 + 3]; 509 tmp[j][i][3] = float_to_ubyte(src_tmp); 510 } 511 } 512 util_format_dxtn_pack(4, 4, 4, &tmp[0][0][0], format, dst, 0); 513 dst += block_size; 514 } 515 dst_row += 4*dst_stride/sizeof(*dst_row); 516 } 517 } 518 519 void 520 util_format_dxt1_rgb_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, 521 const float *src, unsigned src_stride, 522 unsigned width, unsigned height) 523 { 524 util_format_dxtn_pack_rgba_float(dst_row, dst_stride, src, src_stride, 525 width, height, UTIL_FORMAT_DXT1_RGB, 526 8, FALSE); 527 } 528 529 void 530 util_format_dxt1_rgba_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, 531 const float *src, unsigned src_stride, 532 unsigned width, unsigned height) 533 { 534 util_format_dxtn_pack_rgba_float(dst_row, dst_stride, src, src_stride, 535 width, height, UTIL_FORMAT_DXT1_RGBA, 536 8, FALSE); 537 } 538 539 void 540 util_format_dxt3_rgba_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, 541 const float *src, unsigned src_stride, 542 unsigned width, unsigned height) 543 { 544 util_format_dxtn_pack_rgba_float(dst_row, dst_stride, src, src_stride, 545 width, height, UTIL_FORMAT_DXT3_RGBA, 546 16, FALSE); 547 } 548 549 void 550 util_format_dxt5_rgba_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, 551 const float *src, unsigned src_stride, 552 unsigned width, unsigned height) 553 { 554 util_format_dxtn_pack_rgba_float(dst_row, dst_stride, src, src_stride, 555 width, height, UTIL_FORMAT_DXT5_RGBA, 556 16, FALSE); 557 } 558 559 560 /* 561 * SRGB variants. 562 */ 563 564 void 565 util_format_dxt1_srgb_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j) 566 { 567 uint8_t tmp[4]; 568 util_format_dxt1_rgb_fetch(0, src, i, j, tmp); 569 dst[0] = util_format_srgb_to_linear_8unorm(tmp[0]); 570 dst[1] = util_format_srgb_to_linear_8unorm(tmp[1]); 571 dst[2] = util_format_srgb_to_linear_8unorm(tmp[2]); 572 dst[3] = 255; 573 } 574 575 void 576 util_format_dxt1_srgba_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j) 577 { 578 uint8_t tmp[4]; 579 util_format_dxt1_rgba_fetch(0, src, i, j, tmp); 580 dst[0] = util_format_srgb_to_linear_8unorm(tmp[0]); 581 dst[1] = util_format_srgb_to_linear_8unorm(tmp[1]); 582 dst[2] = util_format_srgb_to_linear_8unorm(tmp[2]); 583 dst[3] = tmp[3]; 584 } 585 586 void 587 util_format_dxt3_srgba_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j) 588 { 589 uint8_t tmp[4]; 590 util_format_dxt3_rgba_fetch(0, src, i, j, tmp); 591 dst[0] = util_format_srgb_to_linear_8unorm(tmp[0]); 592 dst[1] = util_format_srgb_to_linear_8unorm(tmp[1]); 593 dst[2] = util_format_srgb_to_linear_8unorm(tmp[2]); 594 dst[3] = tmp[3]; 595 } 596 597 void 598 util_format_dxt5_srgba_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j) 599 { 600 uint8_t tmp[4]; 601 util_format_dxt5_rgba_fetch(0, src, i, j, tmp); 602 dst[0] = util_format_srgb_to_linear_8unorm(tmp[0]); 603 dst[1] = util_format_srgb_to_linear_8unorm(tmp[1]); 604 dst[2] = util_format_srgb_to_linear_8unorm(tmp[2]); 605 dst[3] = tmp[3]; 606 } 607 608 void 609 util_format_dxt1_srgb_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j) 610 { 611 uint8_t tmp[4]; 612 util_format_dxt1_rgb_fetch(0, src, i, j, tmp); 613 dst[0] = util_format_srgb_8unorm_to_linear_float(tmp[0]); 614 dst[1] = util_format_srgb_8unorm_to_linear_float(tmp[1]); 615 dst[2] = util_format_srgb_8unorm_to_linear_float(tmp[2]); 616 dst[3] = 1.0f; 617 } 618 619 void 620 util_format_dxt1_srgba_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j) 621 { 622 uint8_t tmp[4]; 623 util_format_dxt1_rgba_fetch(0, src, i, j, tmp); 624 dst[0] = util_format_srgb_8unorm_to_linear_float(tmp[0]); 625 dst[1] = util_format_srgb_8unorm_to_linear_float(tmp[1]); 626 dst[2] = util_format_srgb_8unorm_to_linear_float(tmp[2]); 627 dst[3] = ubyte_to_float(tmp[3]); 628 } 629 630 void 631 util_format_dxt3_srgba_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j) 632 { 633 uint8_t tmp[4]; 634 util_format_dxt3_rgba_fetch(0, src, i, j, tmp); 635 dst[0] = util_format_srgb_8unorm_to_linear_float(tmp[0]); 636 dst[1] = util_format_srgb_8unorm_to_linear_float(tmp[1]); 637 dst[2] = util_format_srgb_8unorm_to_linear_float(tmp[2]); 638 dst[3] = ubyte_to_float(tmp[3]); 639 } 640 641 void 642 util_format_dxt5_srgba_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j) 643 { 644 uint8_t tmp[4]; 645 util_format_dxt5_rgba_fetch(0, src, i, j, tmp); 646 dst[0] = util_format_srgb_8unorm_to_linear_float(tmp[0]); 647 dst[1] = util_format_srgb_8unorm_to_linear_float(tmp[1]); 648 dst[2] = util_format_srgb_8unorm_to_linear_float(tmp[2]); 649 dst[3] = ubyte_to_float(tmp[3]); 650 } 651 652 void 653 util_format_dxt1_srgb_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) 654 { 655 util_format_dxtn_rgb_unpack_rgba_8unorm(dst_row, dst_stride, 656 src_row, src_stride, 657 width, height, 658 util_format_dxt1_rgb_fetch, 659 8, TRUE); 660 } 661 662 void 663 util_format_dxt1_srgba_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) 664 { 665 util_format_dxtn_rgb_unpack_rgba_8unorm(dst_row, dst_stride, 666 src_row, src_stride, 667 width, height, 668 util_format_dxt1_rgba_fetch, 669 8, TRUE); 670 } 671 672 void 673 util_format_dxt3_srgba_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) 674 { 675 util_format_dxtn_rgb_unpack_rgba_8unorm(dst_row, dst_stride, 676 src_row, src_stride, 677 width, height, 678 util_format_dxt3_rgba_fetch, 679 16, TRUE); 680 } 681 682 void 683 util_format_dxt5_srgba_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) 684 { 685 util_format_dxtn_rgb_unpack_rgba_8unorm(dst_row, dst_stride, 686 src_row, src_stride, 687 width, height, 688 util_format_dxt5_rgba_fetch, 689 16, TRUE); 690 } 691 692 void 693 util_format_dxt1_srgb_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) 694 { 695 util_format_dxtn_rgb_unpack_rgba_float(dst_row, dst_stride, 696 src_row, src_stride, 697 width, height, 698 util_format_dxt1_rgb_fetch, 699 8, TRUE); 700 } 701 702 void 703 util_format_dxt1_srgba_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) 704 { 705 util_format_dxtn_rgb_unpack_rgba_float(dst_row, dst_stride, 706 src_row, src_stride, 707 width, height, 708 util_format_dxt1_rgba_fetch, 709 8, TRUE); 710 } 711 712 void 713 util_format_dxt3_srgba_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) 714 { 715 util_format_dxtn_rgb_unpack_rgba_float(dst_row, dst_stride, 716 src_row, src_stride, 717 width, height, 718 util_format_dxt3_rgba_fetch, 719 16, TRUE); 720 } 721 722 void 723 util_format_dxt5_srgba_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) 724 { 725 util_format_dxtn_rgb_unpack_rgba_float(dst_row, dst_stride, 726 src_row, src_stride, 727 width, height, 728 util_format_dxt5_rgba_fetch, 729 16, TRUE); 730 } 731 732 void 733 util_format_dxt1_srgb_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) 734 { 735 util_format_dxtn_pack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride, 736 width, height, UTIL_FORMAT_DXT1_RGB, 737 8, TRUE); 738 } 739 740 void 741 util_format_dxt1_srgba_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) 742 { 743 util_format_dxtn_pack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride, 744 width, height, UTIL_FORMAT_DXT1_RGBA, 745 8, TRUE); 746 } 747 748 void 749 util_format_dxt3_srgba_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) 750 { 751 util_format_dxtn_pack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride, 752 width, height, UTIL_FORMAT_DXT3_RGBA, 753 16, TRUE); 754 } 755 756 void 757 util_format_dxt5_srgba_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) 758 { 759 util_format_dxtn_pack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride, 760 width, height, UTIL_FORMAT_DXT5_RGBA, 761 16, TRUE); 762 } 763 764 void 765 util_format_dxt1_srgb_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height) 766 { 767 util_format_dxtn_pack_rgba_float(dst_row, dst_stride, src_row, src_stride, 768 width, height, UTIL_FORMAT_DXT1_RGB, 769 8, TRUE); 770 } 771 772 void 773 util_format_dxt1_srgba_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height) 774 { 775 util_format_dxtn_pack_rgba_float(dst_row, dst_stride, src_row, src_stride, 776 width, height, UTIL_FORMAT_DXT1_RGBA, 777 8, TRUE); 778 } 779 780 void 781 util_format_dxt3_srgba_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height) 782 { 783 util_format_dxtn_pack_rgba_float(dst_row, dst_stride, src_row, src_stride, 784 width, height, UTIL_FORMAT_DXT3_RGBA, 785 16, TRUE); 786 } 787 788 void 789 util_format_dxt5_srgba_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height) 790 { 791 util_format_dxtn_pack_rgba_float(dst_row, dst_stride, src_row, src_stride, 792 width, height, UTIL_FORMAT_DXT5_RGBA, 793 16, TRUE); 794 } 795 796