1 /************************************************************************** 2 * 3 * Copyright 2009 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 above copyright notice and this permission notice (including the 15 * next paragraph) shall be included in all copies or substantial portions 16 * of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 * 26 **************************************************************************/ 27 28 /** 29 * @file 30 * Texture sampling. 31 * 32 * @author Jose Fonseca <jfonseca (at) vmware.com> 33 */ 34 35 #ifndef LP_BLD_SAMPLE_H 36 #define LP_BLD_SAMPLE_H 37 38 39 #include "pipe/p_format.h" 40 #include "util/u_debug.h" 41 #include "gallivm/lp_bld.h" 42 #include "gallivm/lp_bld_type.h" 43 #include "gallivm/lp_bld_swizzle.h" 44 45 #ifdef __cplusplus 46 extern "C" { 47 #endif 48 49 struct pipe_resource; 50 struct pipe_sampler_view; 51 struct pipe_sampler_state; 52 struct util_format_description; 53 struct lp_type; 54 struct lp_build_context; 55 56 57 /** 58 * Helper struct holding all derivatives needed for sampling 59 */ 60 struct lp_derivatives 61 { 62 LLVMValueRef ddx[3]; 63 LLVMValueRef ddy[3]; 64 }; 65 66 67 enum lp_sampler_lod_property { 68 LP_SAMPLER_LOD_SCALAR, 69 LP_SAMPLER_LOD_PER_ELEMENT, 70 LP_SAMPLER_LOD_PER_QUAD 71 }; 72 73 74 enum lp_sampler_lod_control { 75 LP_SAMPLER_LOD_IMPLICIT, 76 LP_SAMPLER_LOD_BIAS, 77 LP_SAMPLER_LOD_EXPLICIT, 78 LP_SAMPLER_LOD_DERIVATIVES, 79 }; 80 81 82 enum lp_sampler_op_type { 83 LP_SAMPLER_OP_TEXTURE, 84 LP_SAMPLER_OP_FETCH, 85 LP_SAMPLER_OP_GATHER, 86 LP_SAMPLER_OP_LODQ 87 }; 88 89 90 #define LP_SAMPLER_SHADOW (1 << 0) 91 #define LP_SAMPLER_OFFSETS (1 << 1) 92 #define LP_SAMPLER_OP_TYPE_SHIFT 2 93 #define LP_SAMPLER_OP_TYPE_MASK (3 << 2) 94 #define LP_SAMPLER_LOD_CONTROL_SHIFT 4 95 #define LP_SAMPLER_LOD_CONTROL_MASK (3 << 4) 96 #define LP_SAMPLER_LOD_PROPERTY_SHIFT 6 97 #define LP_SAMPLER_LOD_PROPERTY_MASK (3 << 6) 98 99 struct lp_sampler_params 100 { 101 struct lp_type type; 102 unsigned texture_index; 103 unsigned sampler_index; 104 unsigned sample_key; 105 LLVMValueRef context_ptr; 106 LLVMValueRef thread_data_ptr; 107 const LLVMValueRef *coords; 108 const LLVMValueRef *offsets; 109 LLVMValueRef lod; 110 const struct lp_derivatives *derivs; 111 LLVMValueRef *texel; 112 }; 113 114 struct lp_sampler_size_query_params 115 { 116 struct lp_type int_type; 117 unsigned texture_unit; 118 unsigned target; 119 LLVMValueRef context_ptr; 120 boolean is_sviewinfo; 121 enum lp_sampler_lod_property lod_property; 122 LLVMValueRef explicit_lod; 123 LLVMValueRef *sizes_out; 124 }; 125 /** 126 * Texture static state. 127 * 128 * These are the bits of state from pipe_resource/pipe_sampler_view that 129 * are embedded in the generated code. 130 */ 131 struct lp_static_texture_state 132 { 133 /* pipe_sampler_view's state */ 134 enum pipe_format format; 135 unsigned swizzle_r:3; /**< PIPE_SWIZZLE_* */ 136 unsigned swizzle_g:3; 137 unsigned swizzle_b:3; 138 unsigned swizzle_a:3; 139 140 /* pipe_texture's state */ 141 unsigned target:4; /**< PIPE_TEXTURE_* */ 142 unsigned pot_width:1; /**< is the width a power of two? */ 143 unsigned pot_height:1; 144 unsigned pot_depth:1; 145 unsigned level_zero_only:1; 146 }; 147 148 149 /** 150 * Sampler static state. 151 * 152 * These are the bits of state from pipe_sampler_state that 153 * are embedded in the generated code. 154 */ 155 struct lp_static_sampler_state 156 { 157 /* pipe_sampler_state's state */ 158 unsigned wrap_s:3; 159 unsigned wrap_t:3; 160 unsigned wrap_r:3; 161 unsigned min_img_filter:2; 162 unsigned min_mip_filter:2; 163 unsigned mag_img_filter:2; 164 unsigned compare_mode:1; 165 unsigned compare_func:3; 166 unsigned normalized_coords:1; 167 unsigned min_max_lod_equal:1; /**< min_lod == max_lod ? */ 168 unsigned lod_bias_non_zero:1; 169 unsigned max_lod_pos:1; 170 unsigned apply_min_lod:1; /**< min_lod > 0 ? */ 171 unsigned apply_max_lod:1; /**< max_lod < last_level ? */ 172 unsigned seamless_cube_map:1; 173 174 /* Hacks */ 175 unsigned force_nearest_s:1; 176 unsigned force_nearest_t:1; 177 }; 178 179 180 /** 181 * Sampler dynamic state. 182 * 183 * These are the bits of state from pipe_resource/pipe_sampler_view 184 * as well as from sampler state that are computed at runtime. 185 * 186 * There are obtained through callbacks, as we don't want to tie the texture 187 * sampling code generation logic to any particular texture layout or pipe 188 * driver. 189 */ 190 struct lp_sampler_dynamic_state 191 { 192 /* First callbacks for sampler view state */ 193 194 /** Obtain the base texture width (or number of elements) (returns int32) */ 195 LLVMValueRef 196 (*width)(const struct lp_sampler_dynamic_state *state, 197 struct gallivm_state *gallivm, 198 LLVMValueRef context_ptr, 199 unsigned texture_unit); 200 201 /** Obtain the base texture height (returns int32) */ 202 LLVMValueRef 203 (*height)(const struct lp_sampler_dynamic_state *state, 204 struct gallivm_state *gallivm, 205 LLVMValueRef context_ptr, 206 unsigned texture_unit); 207 208 /** Obtain the base texture depth (or array size) (returns int32) */ 209 LLVMValueRef 210 (*depth)(const struct lp_sampler_dynamic_state *state, 211 struct gallivm_state *gallivm, 212 LLVMValueRef context_ptr, 213 unsigned texture_unit); 214 215 /** Obtain the first mipmap level (base level) (returns int32) */ 216 LLVMValueRef 217 (*first_level)(const struct lp_sampler_dynamic_state *state, 218 struct gallivm_state *gallivm, 219 LLVMValueRef context_ptr, 220 unsigned texture_unit); 221 222 /** Obtain the number of mipmap levels minus one (returns int32) */ 223 LLVMValueRef 224 (*last_level)(const struct lp_sampler_dynamic_state *state, 225 struct gallivm_state *gallivm, 226 LLVMValueRef context_ptr, 227 unsigned texture_unit); 228 229 /** Obtain stride in bytes between image rows/blocks (returns int32) */ 230 LLVMValueRef 231 (*row_stride)(const struct lp_sampler_dynamic_state *state, 232 struct gallivm_state *gallivm, 233 LLVMValueRef context_ptr, 234 unsigned texture_unit); 235 236 /** Obtain stride in bytes between image slices (returns int32) */ 237 LLVMValueRef 238 (*img_stride)(const struct lp_sampler_dynamic_state *state, 239 struct gallivm_state *gallivm, 240 LLVMValueRef context_ptr, 241 unsigned texture_unit); 242 243 /** Obtain pointer to base of texture */ 244 LLVMValueRef 245 (*base_ptr)(const struct lp_sampler_dynamic_state *state, 246 struct gallivm_state *gallivm, 247 LLVMValueRef context_ptr, 248 unsigned texture_unit); 249 250 /** Obtain pointer to array of mipmap offsets */ 251 LLVMValueRef 252 (*mip_offsets)(const struct lp_sampler_dynamic_state *state, 253 struct gallivm_state *gallivm, 254 LLVMValueRef context_ptr, 255 unsigned texture_unit); 256 257 /* These are callbacks for sampler state */ 258 259 /** Obtain texture min lod (returns float) */ 260 LLVMValueRef 261 (*min_lod)(const struct lp_sampler_dynamic_state *state, 262 struct gallivm_state *gallivm, 263 LLVMValueRef context_ptr, 264 unsigned sampler_unit); 265 266 /** Obtain texture max lod (returns float) */ 267 LLVMValueRef 268 (*max_lod)(const struct lp_sampler_dynamic_state *state, 269 struct gallivm_state *gallivm, 270 LLVMValueRef context_ptr, 271 unsigned sampler_unit); 272 273 /** Obtain texture lod bias (returns float) */ 274 LLVMValueRef 275 (*lod_bias)(const struct lp_sampler_dynamic_state *state, 276 struct gallivm_state *gallivm, 277 LLVMValueRef context_ptr, 278 unsigned sampler_unit); 279 280 /** Obtain texture border color (returns ptr to float[4]) */ 281 LLVMValueRef 282 (*border_color)(const struct lp_sampler_dynamic_state *state, 283 struct gallivm_state *gallivm, 284 LLVMValueRef context_ptr, 285 unsigned sampler_unit); 286 287 /** 288 * Obtain texture cache (returns ptr to lp_build_format_cache). 289 * 290 * It's optional: no caching will be done if it's NULL. 291 */ 292 LLVMValueRef 293 (*cache_ptr)(const struct lp_sampler_dynamic_state *state, 294 struct gallivm_state *gallivm, 295 LLVMValueRef thread_data_ptr, 296 unsigned unit); 297 }; 298 299 300 /** 301 * Keep all information for sampling code generation in a single place. 302 */ 303 struct lp_build_sample_context 304 { 305 struct gallivm_state *gallivm; 306 307 const struct lp_static_texture_state *static_texture_state; 308 const struct lp_static_sampler_state *static_sampler_state; 309 310 struct lp_sampler_dynamic_state *dynamic_state; 311 312 const struct util_format_description *format_desc; 313 314 /* See texture_dims() */ 315 unsigned dims; 316 317 /** SIMD vector width */ 318 unsigned vector_width; 319 320 /** number of mipmaps (valid are 1, length/4, length) */ 321 unsigned num_mips; 322 323 /** number of lod values (valid are 1, length/4, length) */ 324 unsigned num_lods; 325 326 boolean no_quad_lod; 327 boolean no_brilinear; 328 boolean no_rho_approx; 329 330 /** regular scalar float type */ 331 struct lp_type float_type; 332 struct lp_build_context float_bld; 333 334 /** float vector type */ 335 struct lp_build_context float_vec_bld; 336 337 /** regular scalar int type */ 338 struct lp_type int_type; 339 struct lp_build_context int_bld; 340 341 /** Incoming coordinates type and build context */ 342 struct lp_type coord_type; 343 struct lp_build_context coord_bld; 344 345 /** Signed integer coordinates */ 346 struct lp_type int_coord_type; 347 struct lp_build_context int_coord_bld; 348 349 /** Unsigned integer texture size */ 350 struct lp_type int_size_in_type; 351 struct lp_build_context int_size_in_bld; 352 353 /** Float incoming texture size */ 354 struct lp_type float_size_in_type; 355 struct lp_build_context float_size_in_bld; 356 357 /** Unsigned integer texture size (might be per quad) */ 358 struct lp_type int_size_type; 359 struct lp_build_context int_size_bld; 360 361 /** Float texture size (might be per quad) */ 362 struct lp_type float_size_type; 363 struct lp_build_context float_size_bld; 364 365 /** Output texels type and build context */ 366 struct lp_type texel_type; 367 struct lp_build_context texel_bld; 368 369 /** Float level type */ 370 struct lp_type levelf_type; 371 struct lp_build_context levelf_bld; 372 373 /** Int level type */ 374 struct lp_type leveli_type; 375 struct lp_build_context leveli_bld; 376 377 /** Float lod type */ 378 struct lp_type lodf_type; 379 struct lp_build_context lodf_bld; 380 381 /** Int lod type */ 382 struct lp_type lodi_type; 383 struct lp_build_context lodi_bld; 384 385 /* Common dynamic state values */ 386 LLVMValueRef row_stride_array; 387 LLVMValueRef img_stride_array; 388 LLVMValueRef base_ptr; 389 LLVMValueRef mip_offsets; 390 LLVMValueRef cache; 391 392 /** Integer vector with texture width, height, depth */ 393 LLVMValueRef int_size; 394 395 LLVMValueRef border_color_clamped; 396 397 LLVMValueRef context_ptr; 398 }; 399 400 401 402 /** 403 * We only support a few wrap modes in lp_build_sample_wrap_linear_int() at 404 * this time. Return whether the given mode is supported by that function. 405 */ 406 static inline boolean 407 lp_is_simple_wrap_mode(unsigned mode) 408 { 409 switch (mode) { 410 case PIPE_TEX_WRAP_REPEAT: 411 case PIPE_TEX_WRAP_CLAMP_TO_EDGE: 412 return TRUE; 413 default: 414 return FALSE; 415 } 416 } 417 418 419 static inline void 420 apply_sampler_swizzle(struct lp_build_sample_context *bld, 421 LLVMValueRef *texel) 422 { 423 unsigned char swizzles[4]; 424 425 swizzles[0] = bld->static_texture_state->swizzle_r; 426 swizzles[1] = bld->static_texture_state->swizzle_g; 427 swizzles[2] = bld->static_texture_state->swizzle_b; 428 swizzles[3] = bld->static_texture_state->swizzle_a; 429 430 lp_build_swizzle_soa_inplace(&bld->texel_bld, texel, swizzles); 431 } 432 433 /* 434 * not really dimension as such, this indicates the amount of 435 * "normal" texture coords subject to minification, wrapping etc. 436 */ 437 static inline unsigned 438 texture_dims(enum pipe_texture_target tex) 439 { 440 switch (tex) { 441 case PIPE_TEXTURE_1D: 442 case PIPE_TEXTURE_1D_ARRAY: 443 case PIPE_BUFFER: 444 return 1; 445 case PIPE_TEXTURE_2D: 446 case PIPE_TEXTURE_2D_ARRAY: 447 case PIPE_TEXTURE_RECT: 448 case PIPE_TEXTURE_CUBE: 449 case PIPE_TEXTURE_CUBE_ARRAY: 450 return 2; 451 case PIPE_TEXTURE_3D: 452 return 3; 453 default: 454 assert(0 && "bad texture target in texture_dims()"); 455 return 2; 456 } 457 } 458 459 static inline boolean 460 has_layer_coord(enum pipe_texture_target tex) 461 { 462 switch (tex) { 463 case PIPE_TEXTURE_1D_ARRAY: 464 case PIPE_TEXTURE_2D_ARRAY: 465 /* cube is not layered but 3rd coord (after cube mapping) behaves the same */ 466 case PIPE_TEXTURE_CUBE: 467 case PIPE_TEXTURE_CUBE_ARRAY: 468 return TRUE; 469 default: 470 return FALSE; 471 } 472 } 473 474 475 boolean 476 lp_sampler_wrap_mode_uses_border_color(unsigned mode, 477 unsigned min_img_filter, 478 unsigned mag_img_filter); 479 480 /** 481 * Derive the sampler static state. 482 */ 483 void 484 lp_sampler_static_sampler_state(struct lp_static_sampler_state *state, 485 const struct pipe_sampler_state *sampler); 486 487 488 void 489 lp_sampler_static_texture_state(struct lp_static_texture_state *state, 490 const struct pipe_sampler_view *view); 491 492 493 void 494 lp_build_lod_selector(struct lp_build_sample_context *bld, 495 boolean is_lodq, 496 unsigned texture_index, 497 unsigned sampler_index, 498 LLVMValueRef s, 499 LLVMValueRef t, 500 LLVMValueRef r, 501 LLVMValueRef cube_rho, 502 const struct lp_derivatives *derivs, 503 LLVMValueRef lod_bias, /* optional */ 504 LLVMValueRef explicit_lod, /* optional */ 505 unsigned mip_filter, 506 LLVMValueRef *out_lod, 507 LLVMValueRef *out_lod_ipart, 508 LLVMValueRef *out_lod_fpart, 509 LLVMValueRef *out_lod_positive); 510 511 void 512 lp_build_nearest_mip_level(struct lp_build_sample_context *bld, 513 unsigned texture_unit, 514 LLVMValueRef lod, 515 LLVMValueRef *level_out, 516 LLVMValueRef *out_of_bounds); 517 518 void 519 lp_build_linear_mip_levels(struct lp_build_sample_context *bld, 520 unsigned texture_unit, 521 LLVMValueRef lod_ipart, 522 LLVMValueRef *lod_fpart_inout, 523 LLVMValueRef *level0_out, 524 LLVMValueRef *level1_out); 525 526 LLVMValueRef 527 lp_build_get_mipmap_level(struct lp_build_sample_context *bld, 528 LLVMValueRef level); 529 530 531 LLVMValueRef 532 lp_build_get_mip_offsets(struct lp_build_sample_context *bld, 533 LLVMValueRef level); 534 535 536 void 537 lp_build_mipmap_level_sizes(struct lp_build_sample_context *bld, 538 LLVMValueRef ilevel, 539 LLVMValueRef *out_size_vec, 540 LLVMValueRef *row_stride_vec, 541 LLVMValueRef *img_stride_vec); 542 543 544 void 545 lp_build_extract_image_sizes(struct lp_build_sample_context *bld, 546 struct lp_build_context *size_bld, 547 struct lp_type coord_type, 548 LLVMValueRef size, 549 LLVMValueRef *out_width, 550 LLVMValueRef *out_height, 551 LLVMValueRef *out_depth); 552 553 554 void 555 lp_build_unnormalized_coords(struct lp_build_sample_context *bld, 556 LLVMValueRef flt_size, 557 LLVMValueRef *s, 558 LLVMValueRef *t, 559 LLVMValueRef *r); 560 561 562 void 563 lp_build_cube_lookup(struct lp_build_sample_context *bld, 564 LLVMValueRef *coords, 565 const struct lp_derivatives *derivs_in, /* optional */ 566 LLVMValueRef *rho, 567 struct lp_derivatives *derivs_out, /* optional */ 568 boolean need_derivs); 569 570 571 void 572 lp_build_cube_new_coords(struct lp_build_context *ivec_bld, 573 LLVMValueRef face, 574 LLVMValueRef x0, 575 LLVMValueRef x1, 576 LLVMValueRef y0, 577 LLVMValueRef y1, 578 LLVMValueRef max_coord, 579 LLVMValueRef new_faces[4], 580 LLVMValueRef new_xcoords[4][2], 581 LLVMValueRef new_ycoords[4][2]); 582 583 584 void 585 lp_build_sample_partial_offset(struct lp_build_context *bld, 586 unsigned block_length, 587 LLVMValueRef coord, 588 LLVMValueRef stride, 589 LLVMValueRef *out_offset, 590 LLVMValueRef *out_i); 591 592 593 void 594 lp_build_sample_offset(struct lp_build_context *bld, 595 const struct util_format_description *format_desc, 596 LLVMValueRef x, 597 LLVMValueRef y, 598 LLVMValueRef z, 599 LLVMValueRef y_stride, 600 LLVMValueRef z_stride, 601 LLVMValueRef *out_offset, 602 LLVMValueRef *out_i, 603 LLVMValueRef *out_j); 604 605 606 void 607 lp_build_sample_soa(const struct lp_static_texture_state *static_texture_state, 608 const struct lp_static_sampler_state *static_sampler_state, 609 struct lp_sampler_dynamic_state *dynamic_texture_state, 610 struct gallivm_state *gallivm, 611 const struct lp_sampler_params *params); 612 613 614 void 615 lp_build_coord_repeat_npot_linear(struct lp_build_sample_context *bld, 616 LLVMValueRef coord_f, 617 LLVMValueRef length_i, 618 LLVMValueRef length_f, 619 LLVMValueRef *coord0_i, 620 LLVMValueRef *weight_f); 621 622 623 void 624 lp_build_size_query_soa(struct gallivm_state *gallivm, 625 const struct lp_static_texture_state *static_state, 626 struct lp_sampler_dynamic_state *dynamic_state, 627 const struct lp_sampler_size_query_params *params); 628 629 void 630 lp_build_sample_nop(struct gallivm_state *gallivm, 631 struct lp_type type, 632 const LLVMValueRef *coords, 633 LLVMValueRef texel_out[4]); 634 635 636 LLVMValueRef 637 lp_build_minify(struct lp_build_context *bld, 638 LLVMValueRef base_size, 639 LLVMValueRef level, 640 boolean lod_scalar); 641 642 #ifdef __cplusplus 643 } 644 #endif 645 646 #endif /* LP_BLD_SAMPLE_H */ 647