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 
     46 struct pipe_resource;
     47 struct pipe_sampler_view;
     48 struct pipe_sampler_state;
     49 struct util_format_description;
     50 struct lp_type;
     51 struct lp_build_context;
     52 
     53 
     54 /**
     55  * Helper struct holding all derivatives needed for sampling
     56  */
     57 struct lp_derivatives
     58 {
     59    LLVMValueRef ddx_ddy[2];
     60 };
     61 
     62 
     63 /**
     64  * Sampler static state.
     65  *
     66  * These are the bits of state from pipe_resource and pipe_sampler_state that
     67  * are embedded in the generated code.
     68  */
     69 struct lp_sampler_static_state
     70 {
     71    /* pipe_sampler_view's state */
     72    enum pipe_format format;
     73    unsigned swizzle_r:3;     /**< PIPE_SWIZZLE_* */
     74    unsigned swizzle_g:3;
     75    unsigned swizzle_b:3;
     76    unsigned swizzle_a:3;
     77 
     78    /* pipe_texture's state */
     79    unsigned target:3;        /**< PIPE_TEXTURE_* */
     80    unsigned pot_width:1;     /**< is the width a power of two? */
     81    unsigned pot_height:1;
     82    unsigned pot_depth:1;
     83 
     84    /* pipe_sampler_state's state */
     85    unsigned wrap_s:3;
     86    unsigned wrap_t:3;
     87    unsigned wrap_r:3;
     88    unsigned min_img_filter:2;
     89    unsigned min_mip_filter:2;
     90    unsigned mag_img_filter:2;
     91    unsigned compare_mode:1;
     92    unsigned compare_func:3;
     93    unsigned normalized_coords:1;
     94    unsigned min_max_lod_equal:1;  /**< min_lod == max_lod ? */
     95    unsigned lod_bias_non_zero:1;
     96    unsigned apply_min_lod:1;  /**< min_lod > 0 ? */
     97    unsigned apply_max_lod:1;  /**< max_lod < last_level ? */
     98 
     99    /* Hacks */
    100    unsigned force_nearest_s:1;
    101    unsigned force_nearest_t:1;
    102 };
    103 
    104 
    105 /**
    106  * Sampler dynamic state.
    107  *
    108  * These are the bits of state from pipe_resource and pipe_sampler_state that
    109  * are computed in runtime.
    110  *
    111  * There are obtained through callbacks, as we don't want to tie the texture
    112  * sampling code generation logic to any particular texture layout or pipe
    113  * driver.
    114  */
    115 struct lp_sampler_dynamic_state
    116 {
    117 
    118    /** Obtain the base texture width (returns int32) */
    119    LLVMValueRef
    120    (*width)( const struct lp_sampler_dynamic_state *state,
    121              struct gallivm_state *gallivm,
    122              unsigned unit);
    123 
    124    /** Obtain the base texture height (returns int32) */
    125    LLVMValueRef
    126    (*height)( const struct lp_sampler_dynamic_state *state,
    127               struct gallivm_state *gallivm,
    128               unsigned unit);
    129 
    130    /** Obtain the base texture depth (returns int32) */
    131    LLVMValueRef
    132    (*depth)( const struct lp_sampler_dynamic_state *state,
    133              struct gallivm_state *gallivm,
    134              unsigned unit);
    135 
    136    /** Obtain the first mipmap level (base level) (returns int32) */
    137    LLVMValueRef
    138    (*first_level)( const struct lp_sampler_dynamic_state *state,
    139                    struct gallivm_state *gallivm,
    140                    unsigned unit);
    141 
    142    /** Obtain the number of mipmap levels minus one (returns int32) */
    143    LLVMValueRef
    144    (*last_level)( const struct lp_sampler_dynamic_state *state,
    145                   struct gallivm_state *gallivm,
    146                   unsigned unit);
    147 
    148    /** Obtain stride in bytes between image rows/blocks (returns int32) */
    149    LLVMValueRef
    150    (*row_stride)( const struct lp_sampler_dynamic_state *state,
    151                   struct gallivm_state *gallivm,
    152                   unsigned unit);
    153 
    154    /** Obtain stride in bytes between image slices (returns int32) */
    155    LLVMValueRef
    156    (*img_stride)( const struct lp_sampler_dynamic_state *state,
    157                   struct gallivm_state *gallivm,
    158                   unsigned unit);
    159 
    160    /** Obtain pointer to array of pointers to mimpap levels */
    161    LLVMValueRef
    162    (*data_ptr)( const struct lp_sampler_dynamic_state *state,
    163                 struct gallivm_state *gallivm,
    164                 unsigned unit);
    165 
    166    /** Obtain texture min lod (returns float) */
    167    LLVMValueRef
    168    (*min_lod)(const struct lp_sampler_dynamic_state *state,
    169               struct gallivm_state *gallivm, unsigned unit);
    170 
    171    /** Obtain texture max lod (returns float) */
    172    LLVMValueRef
    173    (*max_lod)(const struct lp_sampler_dynamic_state *state,
    174               struct gallivm_state *gallivm, unsigned unit);
    175 
    176    /** Obtain texture lod bias (returns float) */
    177    LLVMValueRef
    178    (*lod_bias)(const struct lp_sampler_dynamic_state *state,
    179                struct gallivm_state *gallivm, unsigned unit);
    180 
    181    /** Obtain texture border color (returns ptr to float[4]) */
    182    LLVMValueRef
    183    (*border_color)(const struct lp_sampler_dynamic_state *state,
    184                    struct gallivm_state *gallivm, unsigned unit);
    185 };
    186 
    187 
    188 /**
    189  * Keep all information for sampling code generation in a single place.
    190  */
    191 struct lp_build_sample_context
    192 {
    193    struct gallivm_state *gallivm;
    194 
    195    const struct lp_sampler_static_state *static_state;
    196 
    197    struct lp_sampler_dynamic_state *dynamic_state;
    198 
    199    const struct util_format_description *format_desc;
    200 
    201    /* See texture_dims() */
    202    unsigned dims;
    203 
    204    /** SIMD vector width */
    205    unsigned vector_width;
    206 
    207    /** regular scalar float type */
    208    struct lp_type float_type;
    209    struct lp_build_context float_bld;
    210 
    211    /** float vector type */
    212    struct lp_build_context float_vec_bld;
    213 
    214    /** regular scalar int type */
    215    struct lp_type int_type;
    216    struct lp_build_context int_bld;
    217 
    218    /** Incoming coordinates type and build context */
    219    struct lp_type coord_type;
    220    struct lp_build_context coord_bld;
    221 
    222    /** Signed integer coordinates */
    223    struct lp_type int_coord_type;
    224    struct lp_build_context int_coord_bld;
    225 
    226    /** Unsigned integer texture size */
    227    struct lp_type int_size_type;
    228    struct lp_build_context int_size_bld;
    229 
    230    /** Unsigned integer texture size */
    231    struct lp_type float_size_type;
    232    struct lp_build_context float_size_bld;
    233 
    234    /** Output texels type and build context */
    235    struct lp_type texel_type;
    236    struct lp_build_context texel_bld;
    237 
    238    /** Float per-quad type */
    239    struct lp_type perquadf_type;
    240    struct lp_build_context perquadf_bld;
    241 
    242    /** Int per-quad type */
    243    struct lp_type perquadi_type;
    244    struct lp_build_context perquadi_bld;
    245 
    246    /* Common dynamic state values */
    247    LLVMValueRef row_stride_array;
    248    LLVMValueRef img_stride_array;
    249    LLVMValueRef data_array;
    250 
    251    /** Integer vector with texture width, height, depth */
    252    LLVMValueRef int_size;
    253 };
    254 
    255 
    256 
    257 /**
    258  * We only support a few wrap modes in lp_build_sample_wrap_linear_int() at
    259  * this time.  Return whether the given mode is supported by that function.
    260  */
    261 static INLINE boolean
    262 lp_is_simple_wrap_mode(unsigned mode)
    263 {
    264    switch (mode) {
    265    case PIPE_TEX_WRAP_REPEAT:
    266    case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
    267       return TRUE;
    268    default:
    269       return FALSE;
    270    }
    271 }
    272 
    273 
    274 static INLINE void
    275 apply_sampler_swizzle(struct lp_build_sample_context *bld,
    276                       LLVMValueRef *texel)
    277 {
    278    unsigned char swizzles[4];
    279 
    280    swizzles[0] = bld->static_state->swizzle_r;
    281    swizzles[1] = bld->static_state->swizzle_g;
    282    swizzles[2] = bld->static_state->swizzle_b;
    283    swizzles[3] = bld->static_state->swizzle_a;
    284 
    285    lp_build_swizzle_soa_inplace(&bld->texel_bld, texel, swizzles);
    286 }
    287 
    288 
    289 static INLINE unsigned
    290 texture_dims(enum pipe_texture_target tex)
    291 {
    292    switch (tex) {
    293    case PIPE_TEXTURE_1D:
    294       return 1;
    295    case PIPE_TEXTURE_2D:
    296    case PIPE_TEXTURE_RECT:
    297    case PIPE_TEXTURE_CUBE:
    298       return 2;
    299    case PIPE_TEXTURE_3D:
    300       return 3;
    301    default:
    302       assert(0 && "bad texture target in texture_dims()");
    303       return 2;
    304    }
    305 }
    306 
    307 
    308 boolean
    309 lp_sampler_wrap_mode_uses_border_color(unsigned mode,
    310                                        unsigned min_img_filter,
    311                                        unsigned mag_img_filter);
    312 
    313 /**
    314  * Derive the sampler static state.
    315  */
    316 void
    317 lp_sampler_static_state(struct lp_sampler_static_state *state,
    318                         const struct pipe_sampler_view *view,
    319                         const struct pipe_sampler_state *sampler);
    320 
    321 
    322 void
    323 lp_build_lod_selector(struct lp_build_sample_context *bld,
    324                       unsigned unit,
    325                       const struct lp_derivatives *derivs,
    326                       LLVMValueRef lod_bias, /* optional */
    327                       LLVMValueRef explicit_lod, /* optional */
    328                       unsigned mip_filter,
    329                       LLVMValueRef *out_lod_ipart,
    330                       LLVMValueRef *out_lod_fpart);
    331 
    332 void
    333 lp_build_nearest_mip_level(struct lp_build_sample_context *bld,
    334                            unsigned unit,
    335                            LLVMValueRef lod,
    336                            LLVMValueRef *level_out);
    337 
    338 void
    339 lp_build_linear_mip_levels(struct lp_build_sample_context *bld,
    340                            unsigned unit,
    341                            LLVMValueRef lod_ipart,
    342                            LLVMValueRef *lod_fpart_inout,
    343                            LLVMValueRef *level0_out,
    344                            LLVMValueRef *level1_out);
    345 
    346 LLVMValueRef
    347 lp_build_get_mipmap_level(struct lp_build_sample_context *bld,
    348                           LLVMValueRef level);
    349 
    350 
    351 void
    352 lp_build_mipmap_level_sizes(struct lp_build_sample_context *bld,
    353                             LLVMValueRef ilevel,
    354                             LLVMValueRef *out_size_vec,
    355                             LLVMValueRef *row_stride_vec,
    356                             LLVMValueRef *img_stride_vec);
    357 
    358 
    359 void
    360 lp_build_extract_image_sizes(struct lp_build_sample_context *bld,
    361                              struct lp_type size_type,
    362                              struct lp_type coord_type,
    363                              LLVMValueRef size,
    364                              LLVMValueRef *out_width,
    365                              LLVMValueRef *out_height,
    366                              LLVMValueRef *out_depth);
    367 
    368 
    369 void
    370 lp_build_unnormalized_coords(struct lp_build_sample_context *bld,
    371                              LLVMValueRef flt_size,
    372                              LLVMValueRef *s,
    373                              LLVMValueRef *t,
    374                              LLVMValueRef *r);
    375 
    376 
    377 void
    378 lp_build_cube_lookup(struct lp_build_sample_context *bld,
    379                      LLVMValueRef s,
    380                      LLVMValueRef t,
    381                      LLVMValueRef r,
    382                      LLVMValueRef *face,
    383                      LLVMValueRef *face_s,
    384                      LLVMValueRef *face_t);
    385 
    386 
    387 void
    388 lp_build_sample_partial_offset(struct lp_build_context *bld,
    389                                unsigned block_length,
    390                                LLVMValueRef coord,
    391                                LLVMValueRef stride,
    392                                LLVMValueRef *out_offset,
    393                                LLVMValueRef *out_i);
    394 
    395 
    396 void
    397 lp_build_sample_offset(struct lp_build_context *bld,
    398                        const struct util_format_description *format_desc,
    399                        LLVMValueRef x,
    400                        LLVMValueRef y,
    401                        LLVMValueRef z,
    402                        LLVMValueRef y_stride,
    403                        LLVMValueRef z_stride,
    404                        LLVMValueRef *out_offset,
    405                        LLVMValueRef *out_i,
    406                        LLVMValueRef *out_j);
    407 
    408 
    409 void
    410 lp_build_sample_soa(struct gallivm_state *gallivm,
    411                     const struct lp_sampler_static_state *static_state,
    412                     struct lp_sampler_dynamic_state *dynamic_state,
    413                     struct lp_type fp_type,
    414                     unsigned unit,
    415                     unsigned num_coords,
    416                     const LLVMValueRef *coords,
    417                     const struct lp_derivatives *derivs,
    418                     LLVMValueRef lod_bias,
    419                     LLVMValueRef explicit_lod,
    420                     LLVMValueRef texel_out[4]);
    421 
    422 
    423 void
    424 lp_build_coord_repeat_npot_linear(struct lp_build_sample_context *bld,
    425                                   LLVMValueRef coord_f,
    426                                   LLVMValueRef length_i,
    427                                   LLVMValueRef length_f,
    428                                   LLVMValueRef *coord0_i,
    429                                   LLVMValueRef *weight_f);
    430 
    431 
    432 void
    433 lp_build_size_query_soa(struct gallivm_state *gallivm,
    434                         const struct lp_sampler_static_state *static_state,
    435                         struct lp_sampler_dynamic_state *dynamic_state,
    436                         struct lp_type int_type,
    437                         unsigned unit,
    438                         LLVMValueRef explicit_lod,
    439                         LLVMValueRef *sizes_out);
    440 
    441 void
    442 lp_build_sample_nop(struct gallivm_state *gallivm,
    443                     struct lp_type type,
    444                     unsigned num_coords,
    445                     const LLVMValueRef *coords,
    446                     LLVMValueRef texel_out[4]);
    447 
    448 
    449 LLVMValueRef
    450 lp_build_minify(struct lp_build_context *bld,
    451                 LLVMValueRef base_size,
    452                 LLVMValueRef level);
    453 
    454 
    455 #endif /* LP_BLD_SAMPLE_H */
    456