s_texfetch.c revision af69d88d
1/* 2 * Mesa 3-D graphics library 3 * 4 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 5 * Copyright (c) 2009 VMware, Inc. 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * copy of this software and associated documentation files (the "Software"), 9 * to deal in the Software without restriction, including without limitation 10 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 * and/or sell copies of the Software, and to permit persons to whom the 12 * Software is furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included 15 * in all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 * OTHER DEALINGS IN THE SOFTWARE. 24 */ 25 26 27/** 28 * \file s_texfetch.c 29 * 30 * Texel fetch/store functions 31 * 32 * \author Gareth Hughes 33 */ 34 35 36#include "main/colormac.h" 37#include "main/macros.h" 38#include "main/texcompress.h" 39#include "main/texcompress_fxt1.h" 40#include "main/texcompress_s3tc.h" 41#include "main/texcompress_rgtc.h" 42#include "main/texcompress_etc.h" 43#include "main/teximage.h" 44#include "main/samplerobj.h" 45#include "s_context.h" 46#include "s_texfetch.h" 47#include "../../gallium/auxiliary/util/u_format_rgb9e5.h" 48#include "../../gallium/auxiliary/util/u_format_r11g11b10f.h" 49#include "util/format_srgb.h" 50 51 52/* Texel fetch routines for all supported formats 53 */ 54#define DIM 1 55#include "s_texfetch_tmp.h" 56 57#define DIM 2 58#include "s_texfetch_tmp.h" 59 60#define DIM 3 61#include "s_texfetch_tmp.h" 62 63 64/** 65 * All compressed texture texel fetching is done though this function. 66 * Basically just call a core-Mesa texel fetch function. 67 */ 68static void 69fetch_compressed(const struct swrast_texture_image *swImage, 70 GLint i, GLint j, GLint k, GLfloat *texel) 71{ 72 /* The FetchCompressedTexel function takes an integer pixel rowstride, 73 * while the image's rowstride is bytes per row of blocks. 74 */ 75 GLuint bw, bh; 76 GLuint texelBytes = _mesa_get_format_bytes(swImage->Base.TexFormat); 77 _mesa_get_format_block_size(swImage->Base.TexFormat, &bw, &bh); 78 assert(swImage->RowStride * bw % texelBytes == 0); 79 80 swImage->FetchCompressedTexel(swImage->ImageSlices[k], 81 swImage->RowStride * bw / texelBytes, 82 i, j, texel); 83} 84 85 86 87/** 88 * Null texel fetch function. 89 * 90 * Have to have this so the FetchTexel function pointer is never NULL. 91 */ 92static void fetch_null_texelf( const struct swrast_texture_image *texImage, 93 GLint i, GLint j, GLint k, GLfloat *texel ) 94{ 95 (void) texImage; (void) i; (void) j; (void) k; 96 texel[RCOMP] = 0.0; 97 texel[GCOMP] = 0.0; 98 texel[BCOMP] = 0.0; 99 texel[ACOMP] = 0.0; 100 _mesa_warning(NULL, "fetch_null_texelf() called!"); 101} 102 103 104#define FETCH_FUNCS(NAME) \ 105 { \ 106 MESA_FORMAT_ ## NAME, \ 107 fetch_texel_1d_ ## NAME, \ 108 fetch_texel_2d_ ## NAME, \ 109 fetch_texel_3d_ ## NAME, \ 110 } 111 112#define FETCH_NULL(NAME) \ 113 { \ 114 MESA_FORMAT_ ## NAME, \ 115 NULL, \ 116 NULL, \ 117 NULL \ 118 } 119 120/** 121 * Table to map MESA_FORMAT_ to texel fetch/store funcs. 122 */ 123static struct { 124 mesa_format Name; 125 FetchTexelFunc Fetch1D; 126 FetchTexelFunc Fetch2D; 127 FetchTexelFunc Fetch3D; 128} 129texfetch_funcs[] = 130{ 131 { 132 MESA_FORMAT_NONE, 133 fetch_null_texelf, 134 fetch_null_texelf, 135 fetch_null_texelf 136 }, 137 138 /* Packed unorm formats */ 139 FETCH_FUNCS(A8B8G8R8_UNORM), 140 FETCH_FUNCS(X8B8G8R8_UNORM), 141 FETCH_FUNCS(R8G8B8A8_UNORM), 142 FETCH_FUNCS(R8G8B8X8_UNORM), 143 FETCH_FUNCS(B8G8R8A8_UNORM), 144 FETCH_FUNCS(B8G8R8X8_UNORM), 145 FETCH_FUNCS(A8R8G8B8_UNORM), 146 FETCH_FUNCS(X8R8G8B8_UNORM), 147 FETCH_FUNCS(L16A16_UNORM), 148 FETCH_FUNCS(A16L16_UNORM), 149 FETCH_FUNCS(B5G6R5_UNORM), 150 FETCH_FUNCS(R5G6B5_UNORM), 151 FETCH_FUNCS(B4G4R4A4_UNORM), 152 FETCH_NULL(B4G4R4X4_UNORM), 153 FETCH_FUNCS(A4R4G4B4_UNORM), 154 FETCH_FUNCS(A1B5G5R5_UNORM), 155 FETCH_FUNCS(B5G5R5A1_UNORM), 156 FETCH_NULL(B5G5R5X1_UNORM), 157 FETCH_FUNCS(A1R5G5B5_UNORM), 158 FETCH_FUNCS(L8A8_UNORM), 159 FETCH_FUNCS(A8L8_UNORM), 160 FETCH_FUNCS(R8G8_UNORM), 161 FETCH_FUNCS(G8R8_UNORM), 162 FETCH_FUNCS(L4A4_UNORM), 163 FETCH_FUNCS(B2G3R3_UNORM), 164 FETCH_FUNCS(R16G16_UNORM), 165 FETCH_FUNCS(G16R16_UNORM), 166 FETCH_FUNCS(B10G10R10A2_UNORM), 167 FETCH_NULL(B10G10R10X2_UNORM), 168 FETCH_FUNCS(R10G10B10A2_UNORM), 169 FETCH_FUNCS(S8_UINT_Z24_UNORM), 170 { 171 MESA_FORMAT_X8_UINT_Z24_UNORM, 172 fetch_texel_1d_S8_UINT_Z24_UNORM, 173 fetch_texel_2d_S8_UINT_Z24_UNORM, 174 fetch_texel_3d_S8_UINT_Z24_UNORM 175 }, 176 FETCH_FUNCS(Z24_UNORM_S8_UINT), 177 { 178 MESA_FORMAT_Z24_UNORM_X8_UINT, 179 fetch_texel_1d_Z24_UNORM_S8_UINT, 180 fetch_texel_2d_Z24_UNORM_S8_UINT, 181 fetch_texel_3d_Z24_UNORM_S8_UINT 182 }, 183 FETCH_FUNCS(YCBCR), 184 FETCH_FUNCS(YCBCR_REV), 185 186 /* Array unorm formats */ 187 FETCH_FUNCS(A_UNORM8), 188 FETCH_FUNCS(A_UNORM16), 189 FETCH_FUNCS(L_UNORM8), 190 FETCH_FUNCS(L_UNORM16), 191 FETCH_FUNCS(I_UNORM8), 192 FETCH_FUNCS(I_UNORM16), 193 FETCH_FUNCS(R_UNORM8), 194 FETCH_FUNCS(R_UNORM16), 195 FETCH_FUNCS(BGR_UNORM8), 196 FETCH_FUNCS(RGB_UNORM8), 197 FETCH_FUNCS(RGBA_UNORM16), 198 FETCH_FUNCS(RGBX_UNORM16), 199 FETCH_FUNCS(Z_UNORM16), 200 FETCH_FUNCS(Z_UNORM32), 201 FETCH_NULL(S_UINT8), 202 203 /* Packed signed/normalized formats */ 204 FETCH_FUNCS(A8B8G8R8_SNORM), 205 FETCH_FUNCS(X8B8G8R8_SNORM), 206 FETCH_FUNCS(R8G8B8A8_SNORM), 207 FETCH_NULL(R8G8B8X8_SNORM), 208 FETCH_FUNCS(R16G16_SNORM), 209 FETCH_NULL(G16R16_SNORM), 210 FETCH_FUNCS(R8G8_SNORM), 211 FETCH_NULL(G8R8_SNORM), 212 FETCH_FUNCS(L8A8_SNORM), 213 214 /* Array signed/normalized formats */ 215 FETCH_FUNCS(A_SNORM8), 216 FETCH_FUNCS(A_SNORM16), 217 FETCH_FUNCS(L_SNORM8), 218 FETCH_FUNCS(L_SNORM16), 219 FETCH_FUNCS(I_SNORM8), 220 FETCH_FUNCS(I_SNORM16), 221 FETCH_FUNCS(R_SNORM8), 222 FETCH_FUNCS(R_SNORM16), 223 FETCH_FUNCS(LA_SNORM16), 224 FETCH_FUNCS(RGB_SNORM16), 225 FETCH_FUNCS(RGBA_SNORM16), 226 FETCH_NULL(RGBX_SNORM16), 227 228 /* Packed sRGB formats */ 229 FETCH_FUNCS(A8B8G8R8_SRGB), 230 FETCH_FUNCS(B8G8R8A8_SRGB), 231 FETCH_NULL(B8G8R8X8_SRGB), 232 FETCH_FUNCS(R8G8B8A8_SRGB), 233 FETCH_FUNCS(R8G8B8X8_SRGB), 234 FETCH_FUNCS(L8A8_SRGB), 235 236 /* Array sRGB formats */ 237 FETCH_FUNCS(L_SRGB8), 238 FETCH_FUNCS(BGR_SRGB8), 239 240 /* Packed float formats */ 241 FETCH_FUNCS(R9G9B9E5_FLOAT), 242 FETCH_FUNCS(R11G11B10_FLOAT), 243 FETCH_FUNCS(Z32_FLOAT_S8X24_UINT), 244 245 /* Array float formats */ 246 FETCH_FUNCS(A_FLOAT16), 247 FETCH_FUNCS(A_FLOAT32), 248 FETCH_FUNCS(L_FLOAT16), 249 FETCH_FUNCS(L_FLOAT32), 250 FETCH_FUNCS(LA_FLOAT16), 251 FETCH_FUNCS(LA_FLOAT32), 252 FETCH_FUNCS(I_FLOAT16), 253 FETCH_FUNCS(I_FLOAT32), 254 FETCH_FUNCS(R_FLOAT16), 255 FETCH_FUNCS(R_FLOAT32), 256 FETCH_FUNCS(RG_FLOAT16), 257 FETCH_FUNCS(RG_FLOAT32), 258 FETCH_FUNCS(RGB_FLOAT16), 259 FETCH_FUNCS(RGB_FLOAT32), 260 FETCH_FUNCS(RGBA_FLOAT16), 261 FETCH_FUNCS(RGBA_FLOAT32), 262 FETCH_FUNCS(RGBX_FLOAT16), 263 FETCH_FUNCS(RGBX_FLOAT32), 264 { 265 MESA_FORMAT_Z_FLOAT32, 266 fetch_texel_1d_R_FLOAT32, /* Reuse the R32F functions. */ 267 fetch_texel_2d_R_FLOAT32, 268 fetch_texel_3d_R_FLOAT32 269 }, 270 271 /* Packed signed/unsigned non-normalized integer formats */ 272 FETCH_NULL(B10G10R10A2_UINT), 273 FETCH_NULL(R10G10B10A2_UINT), 274 275 /* Array signed/unsigned non-normalized integer formats */ 276 FETCH_NULL(A_UINT8), 277 FETCH_NULL(A_UINT16), 278 FETCH_NULL(A_UINT32), 279 FETCH_NULL(A_SINT8), 280 FETCH_NULL(A_SINT16), 281 FETCH_NULL(A_SINT32), 282 FETCH_NULL(I_UINT8), 283 FETCH_NULL(I_UINT16), 284 FETCH_NULL(I_UINT32), 285 FETCH_NULL(I_SINT8), 286 FETCH_NULL(I_SINT16), 287 FETCH_NULL(I_SINT32), 288 FETCH_NULL(L_UINT8), 289 FETCH_NULL(L_UINT16), 290 FETCH_NULL(L_UINT32), 291 FETCH_NULL(L_SINT8), 292 FETCH_NULL(L_SINT16), 293 FETCH_NULL(L_SINT32), 294 FETCH_NULL(LA_UINT8), 295 FETCH_NULL(LA_UINT16), 296 FETCH_NULL(LA_UINT32), 297 FETCH_NULL(LA_SINT8), 298 FETCH_NULL(LA_SINT16), 299 FETCH_NULL(LA_SINT32), 300 FETCH_NULL(R_UINT8), 301 FETCH_NULL(R_UINT16), 302 FETCH_NULL(R_UINT32), 303 FETCH_NULL(R_SINT8), 304 FETCH_NULL(R_SINT16), 305 FETCH_NULL(R_SINT32), 306 FETCH_NULL(RG_UINT8), 307 FETCH_NULL(RG_UINT16), 308 FETCH_NULL(RG_UINT32), 309 FETCH_NULL(RG_SINT8), 310 FETCH_NULL(RG_SINT16), 311 FETCH_NULL(RG_SINT32), 312 FETCH_NULL(RGB_UINT8), 313 FETCH_NULL(RGB_UINT16), 314 FETCH_NULL(RGB_UINT32), 315 FETCH_NULL(RGB_SINT8), 316 FETCH_NULL(RGB_SINT16), 317 FETCH_NULL(RGB_SINT32), 318 FETCH_FUNCS(RGBA_UINT8), 319 FETCH_FUNCS(RGBA_UINT16), 320 FETCH_FUNCS(RGBA_UINT32), 321 FETCH_FUNCS(RGBA_SINT8), 322 FETCH_FUNCS(RGBA_SINT16), 323 FETCH_FUNCS(RGBA_SINT32), 324 FETCH_NULL(RGBX_UINT8), 325 FETCH_NULL(RGBX_UINT16), 326 FETCH_NULL(RGBX_UINT32), 327 FETCH_NULL(RGBX_SINT8), 328 FETCH_NULL(RGBX_SINT16), 329 FETCH_NULL(RGBX_SINT32), 330 331 /* DXT compressed formats */ 332 { 333 MESA_FORMAT_RGB_DXT1, 334 fetch_compressed, 335 fetch_compressed, 336 fetch_compressed 337 }, 338 { 339 MESA_FORMAT_RGBA_DXT1, 340 fetch_compressed, 341 fetch_compressed, 342 fetch_compressed 343 }, 344 { 345 MESA_FORMAT_RGBA_DXT3, 346 fetch_compressed, 347 fetch_compressed, 348 fetch_compressed 349 }, 350 { 351 MESA_FORMAT_RGBA_DXT5, 352 fetch_compressed, 353 fetch_compressed, 354 fetch_compressed 355 }, 356 357 /* DXT sRGB compressed formats */ 358 { 359 MESA_FORMAT_SRGB_DXT1, 360 fetch_compressed, 361 fetch_compressed, 362 fetch_compressed 363 }, 364 { 365 MESA_FORMAT_SRGBA_DXT1, 366 fetch_compressed, 367 fetch_compressed, 368 fetch_compressed 369 }, 370 { 371 MESA_FORMAT_SRGBA_DXT3, 372 fetch_compressed, 373 fetch_compressed, 374 fetch_compressed 375 }, 376 { 377 MESA_FORMAT_SRGBA_DXT5, 378 fetch_compressed, 379 fetch_compressed, 380 fetch_compressed 381 }, 382 383 /* FXT1 compressed formats */ 384 { 385 MESA_FORMAT_RGB_FXT1, 386 fetch_compressed, 387 fetch_compressed, 388 fetch_compressed 389 }, 390 { 391 MESA_FORMAT_RGBA_FXT1, 392 fetch_compressed, 393 fetch_compressed, 394 fetch_compressed 395 }, 396 397 /* RGTC compressed formats */ 398 { 399 MESA_FORMAT_R_RGTC1_UNORM, 400 fetch_compressed, 401 fetch_compressed, 402 fetch_compressed 403 }, 404 { 405 MESA_FORMAT_R_RGTC1_SNORM, 406 fetch_compressed, 407 fetch_compressed, 408 fetch_compressed 409 }, 410 { 411 MESA_FORMAT_RG_RGTC2_UNORM, 412 fetch_compressed, 413 fetch_compressed, 414 fetch_compressed 415 }, 416 { 417 MESA_FORMAT_RG_RGTC2_SNORM, 418 fetch_compressed, 419 fetch_compressed, 420 fetch_compressed 421 }, 422 423 /* LATC1/2 compressed formats */ 424 { 425 MESA_FORMAT_L_LATC1_UNORM, 426 fetch_compressed, 427 fetch_compressed, 428 fetch_compressed 429 }, 430 { 431 MESA_FORMAT_L_LATC1_SNORM, 432 fetch_compressed, 433 fetch_compressed, 434 fetch_compressed 435 }, 436 { 437 MESA_FORMAT_LA_LATC2_UNORM, 438 fetch_compressed, 439 fetch_compressed, 440 fetch_compressed 441 }, 442 { 443 MESA_FORMAT_LA_LATC2_SNORM, 444 fetch_compressed, 445 fetch_compressed, 446 fetch_compressed 447 }, 448 449 /* ETC1/2 compressed formats */ 450 { 451 MESA_FORMAT_ETC1_RGB8, 452 fetch_compressed, 453 fetch_compressed, 454 fetch_compressed 455 }, 456 { 457 MESA_FORMAT_ETC2_RGB8, 458 fetch_compressed, 459 fetch_compressed, 460 fetch_compressed 461 }, 462 { 463 MESA_FORMAT_ETC2_SRGB8, 464 fetch_compressed, 465 fetch_compressed, 466 fetch_compressed 467 }, 468 { 469 MESA_FORMAT_ETC2_RGBA8_EAC, 470 fetch_compressed, 471 fetch_compressed, 472 fetch_compressed 473 }, 474 { 475 MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC, 476 fetch_compressed, 477 fetch_compressed, 478 fetch_compressed 479 }, 480 { 481 MESA_FORMAT_ETC2_R11_EAC, 482 fetch_compressed, 483 fetch_compressed, 484 fetch_compressed 485 }, 486 { 487 MESA_FORMAT_ETC2_RG11_EAC, 488 fetch_compressed, 489 fetch_compressed, 490 fetch_compressed 491 }, 492 { 493 MESA_FORMAT_ETC2_SIGNED_R11_EAC, 494 fetch_compressed, 495 fetch_compressed, 496 fetch_compressed 497 }, 498 { 499 MESA_FORMAT_ETC2_SIGNED_RG11_EAC, 500 fetch_compressed, 501 fetch_compressed, 502 fetch_compressed 503 }, 504 { 505 MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1, 506 fetch_compressed, 507 fetch_compressed, 508 fetch_compressed 509 }, 510 { 511 MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1, 512 fetch_compressed, 513 fetch_compressed, 514 fetch_compressed 515 }, 516 { 517 MESA_FORMAT_BPTC_RGBA_UNORM, 518 fetch_compressed, 519 fetch_compressed, 520 fetch_compressed 521 }, 522 { 523 MESA_FORMAT_BPTC_SRGB_ALPHA_UNORM, 524 fetch_compressed, 525 fetch_compressed, 526 fetch_compressed 527 }, 528 { 529 MESA_FORMAT_BPTC_RGB_SIGNED_FLOAT, 530 fetch_compressed, 531 fetch_compressed, 532 fetch_compressed 533 }, 534 { 535 MESA_FORMAT_BPTC_RGB_UNSIGNED_FLOAT, 536 fetch_compressed, 537 fetch_compressed, 538 fetch_compressed 539 } 540}; 541 542 543/** 544 * Initialize the texture image's FetchTexel methods. 545 */ 546static void 547set_fetch_functions(const struct gl_sampler_object *samp, 548 struct swrast_texture_image *texImage, GLuint dims) 549{ 550 mesa_format format = texImage->Base.TexFormat; 551 552#ifdef DEBUG 553 /* check that the table entries are sorted by format name */ 554 mesa_format fmt; 555 for (fmt = 0; fmt < MESA_FORMAT_COUNT; fmt++) { 556 assert(texfetch_funcs[fmt].Name == fmt); 557 } 558#endif 559 560 STATIC_ASSERT(Elements(texfetch_funcs) == MESA_FORMAT_COUNT); 561 562 if (samp->sRGBDecode == GL_SKIP_DECODE_EXT && 563 _mesa_get_format_color_encoding(format) == GL_SRGB) { 564 format = _mesa_get_srgb_format_linear(format); 565 } 566 567 assert(format < MESA_FORMAT_COUNT); 568 569 switch (dims) { 570 case 1: 571 texImage->FetchTexel = texfetch_funcs[format].Fetch1D; 572 break; 573 case 2: 574 texImage->FetchTexel = texfetch_funcs[format].Fetch2D; 575 break; 576 case 3: 577 texImage->FetchTexel = texfetch_funcs[format].Fetch3D; 578 break; 579 default: 580 assert(!"Bad dims in set_fetch_functions()"); 581 } 582 583 texImage->FetchCompressedTexel = _mesa_get_compressed_fetch_func(format); 584 585 ASSERT(texImage->FetchTexel); 586} 587 588void 589_mesa_update_fetch_functions(struct gl_context *ctx, GLuint unit) 590{ 591 struct gl_texture_object *texObj = ctx->Texture.Unit[unit]._Current; 592 struct gl_sampler_object *samp; 593 GLuint face, i; 594 GLuint dims; 595 596 if (!texObj) 597 return; 598 599 samp = _mesa_get_samplerobj(ctx, unit); 600 601 dims = _mesa_get_texture_dimensions(texObj->Target); 602 603 for (face = 0; face < 6; face++) { 604 for (i = 0; i < MAX_TEXTURE_LEVELS; i++) { 605 if (texObj->Image[face][i]) { 606 set_fetch_functions(samp, 607 swrast_texture_image(texObj->Image[face][i]), 608 dims); 609 } 610 } 611 } 612} 613