Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

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