Home | History | Annotate | Download | only in gallivm
      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