[Mesa-dev] [PATCH] gallivm: simplify sampler interface

Jose Fonseca jfonseca at vmware.com
Mon Mar 30 06:10:45 PDT 2015


On 28/03/15 19:53, sroland at vmware.com wrote:
> From: Roland Scheidegger <sroland at vmware.com>
>
> This has got a bit out of control with more and more parameters added.
> Worse, whenever something in there changes all callees have to be updated
> for that, even though they don't really do much with any parameter in there
> except pass it on to the actual sampling function.
> Hence simply put almost everything into a struct. Also instead of relying
> on some arguments being NULL, be explicit and set this in a key (which is
> just reused for function generation for simplicity). (The code still relies
> on them being NULL in the end for now.)
> Technically there is a minimal functional change here for shadow sampling:
> if shadow sampling is done is now determined explicitly by the texture
> function (either sample_c or the gl-style tex func inherit this from target)
> instead of the static texture state. These two should always match, however.
> Otherwise, it should generate all the same code.
> ---
>   src/gallium/auxiliary/draw/draw_llvm_sample.c     |  31 +--
>   src/gallium/auxiliary/gallivm/lp_bld_sample.h     |  48 +++--
>   src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c | 227 +++++++++-------------
>   src/gallium/auxiliary/gallivm/lp_bld_tgsi.h       |  17 +-
>   src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c   | 133 +++++++------
>   src/gallium/drivers/llvmpipe/lp_tex_sample.c      |  33 +---
>   6 files changed, 218 insertions(+), 271 deletions(-)
>
> diff --git a/src/gallium/auxiliary/draw/draw_llvm_sample.c b/src/gallium/auxiliary/draw/draw_llvm_sample.c
> index 16d075c..32cad59 100644
> --- a/src/gallium/auxiliary/draw/draw_llvm_sample.c
> +++ b/src/gallium/auxiliary/draw/draw_llvm_sample.c
> @@ -229,38 +229,19 @@ draw_llvm_sampler_soa_destroy(struct lp_build_sampler_soa *sampler)
>   static void
>   draw_llvm_sampler_soa_emit_fetch_texel(const struct lp_build_sampler_soa *base,
>                                          struct gallivm_state *gallivm,
> -                                       struct lp_type type,
> -                                       boolean is_fetch,
> -                                       unsigned texture_index,
> -                                       unsigned sampler_index,
> -                                       LLVMValueRef context_ptr,
> -                                       const LLVMValueRef *coords,
> -                                       const LLVMValueRef *offsets,
> -                                       const struct lp_derivatives *derivs,
> -                                       LLVMValueRef lod_bias, /* optional */
> -                                       LLVMValueRef explicit_lod, /* optional */
> -                                       enum lp_sampler_lod_property lod_property,
> -                                       LLVMValueRef *texel)
> +                                       const struct lp_sampler_params *params)
>   {
>      struct draw_llvm_sampler_soa *sampler = (struct draw_llvm_sampler_soa *)base;
> +   unsigned texture_index = params->texture_index;
> +   unsigned sampler_index = params->sampler_index;
>
>      assert(texture_index < PIPE_MAX_SHADER_SAMPLER_VIEWS);
>      assert(sampler_index < PIPE_MAX_SAMPLERS);
>
> -   lp_build_sample_soa(gallivm,
> -                       &sampler->dynamic_state.static_state[texture_index].texture_state,
> +   lp_build_sample_soa(&sampler->dynamic_state.static_state[texture_index].texture_state,
>                          &sampler->dynamic_state.static_state[sampler_index].sampler_state,
>                          &sampler->dynamic_state.base,
> -                       type,
> -                       is_fetch,
> -                       texture_index,
> -                       sampler_index,
> -                       context_ptr,
> -                       coords,
> -                       offsets,
> -                       derivs,
> -                       lod_bias, explicit_lod, lod_property,
> -                       texel);
> +                       gallivm, params);
>   }
>
>
> @@ -306,7 +287,7 @@ draw_llvm_sampler_soa_create(const struct draw_sampler_static_state *static_stat
>         return NULL;
>
>      sampler->base.destroy = draw_llvm_sampler_soa_destroy;
> -   sampler->base.emit_fetch_texel = draw_llvm_sampler_soa_emit_fetch_texel;
> +   sampler->base.emit_tex_sample = draw_llvm_sampler_soa_emit_fetch_texel;
>      sampler->base.emit_size_query = draw_llvm_sampler_soa_emit_size_query;
>      sampler->dynamic_state.base.width = draw_llvm_texture_width;
>      sampler->dynamic_state.base.height = draw_llvm_texture_height;
> diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample.h b/src/gallium/auxiliary/gallivm/lp_bld_sample.h
> index be41ca0..b95ee6f 100644
> --- a/src/gallium/auxiliary/gallivm/lp_bld_sample.h
> +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample.h
> @@ -68,6 +68,37 @@ enum lp_sampler_lod_property {
>   };
>
>
> +enum lp_sampler_lod_control {
> +   LP_SAMPLER_LOD_IMPLICIT,
> +   LP_SAMPLER_LOD_BIAS,
> +   LP_SAMPLER_LOD_EXPLICIT,
> +   LP_SAMPLER_LOD_DERIVATIVES,
> +};
> +
> +
> +#define LP_SAMPLER_SHADOW             (1 << 0)
> +#define LP_SAMPLER_OFFSETS            (1 << 1)
> +#define LP_SAMPLER_FETCH              (1 << 2)
> +#define LP_SAMPLER_LOD_CONTROL_SHIFT        3
> +#define LP_SAMPLER_LOD_CONTROL_MASK   (3 << 3)
> +#define LP_SAMPLER_LOD_PROPERTY_SHIFT       5
> +#define LP_SAMPLER_LOD_PROPERTY_MASK  (3 << 5)
> +
> +struct lp_sampler_params
> +{
> +   struct lp_type type;
> +   unsigned texture_index;
> +   unsigned sampler_index;
> +   unsigned sample_key;
> +   LLVMValueRef context_ptr;
> +   const LLVMValueRef *coords;
> +   const LLVMValueRef *offsets;
> +   LLVMValueRef lod;
> +   const struct lp_derivatives *derivs;
> +   LLVMValueRef *texel;
> +};
> +
> +
>   /**
>    * Texture static state.
>    *
> @@ -531,22 +562,11 @@ lp_build_sample_offset(struct lp_build_context *bld,
>
>
>   void
> -lp_build_sample_soa(struct gallivm_state *gallivm,
> -                    const struct lp_static_texture_state *static_texture_state,
> +lp_build_sample_soa(const struct lp_static_texture_state *static_texture_state,
>                       const struct lp_static_sampler_state *static_sampler_state,
>                       struct lp_sampler_dynamic_state *dynamic_texture_state,
> -                    struct lp_type fp_type,
> -                    boolean is_fetch,
> -                    unsigned texture_index,
> -                    unsigned sampler_index,
> -                    LLVMValueRef context_ptr,
> -                    const LLVMValueRef *coords,
> -                    const LLVMValueRef *offsets,
> -                    const struct lp_derivatives *derivs,
> -                    LLVMValueRef lod_bias,
> -                    LLVMValueRef explicit_lod,
> -                    enum lp_sampler_lod_property lod_property,
> -                    LLVMValueRef texel_out[4]);
> +                    struct gallivm_state *gallivm,
> +                    const struct lp_sampler_params *params);
>
>
>   void
> diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
> index 598d5fc..82ef359 100644
> --- a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
> +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
> @@ -2361,7 +2361,7 @@ lp_build_sample_nop(struct gallivm_state *gallivm,
>    * 'texel' will return a vector of four LLVMValueRefs corresponding to
>    * R, G, B, A.
>    * \param type  vector float type to use for coords, etc.
> - * \param is_fetch  if this is a texel fetch instruction.
> + * \param sample_key
>    * \param derivs  partial derivatives of (s,t,r,q) with respect to x and y
>    */
>   static void
> @@ -2370,16 +2370,14 @@ lp_build_sample_soa_code(struct gallivm_state *gallivm,
>                            const struct lp_static_sampler_state *static_sampler_state,
>                            struct lp_sampler_dynamic_state *dynamic_state,
>                            struct lp_type type,
> -                         boolean is_fetch,
> +                         unsigned sample_key,
>                            unsigned texture_index,
>                            unsigned sampler_index,
>                            LLVMValueRef context_ptr,
>                            const LLVMValueRef *coords,
>                            const LLVMValueRef *offsets,
>                            const struct lp_derivatives *derivs, /* optional */
> -                         LLVMValueRef lod_bias, /* optional */
> -                         LLVMValueRef explicit_lod, /* optional */
> -                         enum lp_sampler_lod_property lod_property,
> +                         LLVMValueRef lod, /* optional */
>                            LLVMValueRef texel_out[4])
>   {
>      unsigned target = static_texture_state->target;
> @@ -2391,12 +2389,41 @@ lp_build_sample_soa_code(struct gallivm_state *gallivm,
>      LLVMTypeRef i32t = LLVMInt32TypeInContext(gallivm->context);
>      LLVMBuilderRef builder = gallivm->builder;
>      LLVMValueRef tex_width, newcoords[5];
> +   enum lp_sampler_lod_property lod_property;
> +   enum lp_sampler_lod_control lod_control;
> +   LLVMValueRef lod_bias = NULL;
> +   LLVMValueRef explicit_lod = NULL;
> +   boolean is_fetch = !!(sample_key & LP_SAMPLER_FETCH);
>
>      if (0) {
>         enum pipe_format fmt = static_texture_state->format;
>         debug_printf("Sample from %s\n", util_format_name(fmt));
>      }
>
> +   lod_property = (sample_key & LP_SAMPLER_LOD_PROPERTY_MASK) >>
> +                     LP_SAMPLER_LOD_PROPERTY_SHIFT;
> +   lod_control = (sample_key & LP_SAMPLER_LOD_CONTROL_MASK) >>
> +                    LP_SAMPLER_LOD_CONTROL_SHIFT;
> +
> +   if (lod_control == LP_SAMPLER_LOD_BIAS) {
> +      lod_bias = lod;
> +      assert(lod);
> +      assert(derivs == NULL);
> +   }
> +   else if (lod_control == LP_SAMPLER_LOD_EXPLICIT) {
> +      explicit_lod = lod;
> +      assert(lod);
> +      assert(derivs == NULL);
> +   }
> +   else if (lod_control == LP_SAMPLER_LOD_DERIVATIVES) {
> +      assert(derivs);
> +      assert(lod == NULL);
> +   }
> +   else {
> +      assert(derivs == NULL);
> +      assert(lod == NULL);
> +   }
> +
>      if (static_texture_state->format == PIPE_FORMAT_NONE) {
>         /*
>          * If there's nothing bound, format is NONE, and we must return
> @@ -2633,7 +2660,7 @@ lp_build_sample_soa_code(struct gallivm_state *gallivm,
>
>      else if (is_fetch) {
>         lp_build_fetch_texel(&bld, texture_index, newcoords,
> -                           explicit_lod, offsets,
> +                           lod, offsets,
>                              texel_out);
>      }
>
> @@ -2895,15 +2922,6 @@ lp_build_sample_soa_code(struct gallivm_state *gallivm,
>
>   #define LP_MAX_TEX_FUNC_ARGS 32
>
> -#define LP_SAMPLER_FUNC_LOD_BIAS        (1 << 0)
> -#define LP_SAMPLER_FUNC_LOD_EXPLICIT    (1 << 1)
> -#define LP_SAMPLER_FUNC_EXPLICITDERIVS  (1 << 2)
> -#define LP_SAMPLER_FUNC_SHADOW          (1 << 3)
> -#define LP_SAMPLER_FUNC_OFFSETS         (1 << 4)
> -#define LP_SAMPLER_FUNC_FETCH           (1 << 5)
> -#define LP_SAMPLER_FUNC_LOD_PROPERTY_SHIFT 6
> -
> -
>   static inline void
>   get_target_info(enum pipe_texture_target target,
>                   unsigned *num_coords, unsigned *num_derivs,
> @@ -2935,27 +2953,27 @@ lp_build_sample_gen_func(struct gallivm_state *gallivm,
>                            const struct lp_static_sampler_state *static_sampler_state,
>                            struct lp_sampler_dynamic_state *dynamic_state,
>                            struct lp_type type,
> -                         boolean is_fetch,
>                            unsigned texture_index,
>                            unsigned sampler_index,
>                            LLVMValueRef function,
>                            unsigned num_args,
> -                         unsigned sampler_bits,
> -                         enum lp_sampler_lod_property lod_property)
> +                         unsigned sample_key)
>   {
> -
>      LLVMBuilderRef old_builder;
>      LLVMBasicBlockRef block;
>      LLVMValueRef coords[5];
>      LLVMValueRef offsets[3] = { NULL };
> -   LLVMValueRef lod_bias = NULL;
> -   LLVMValueRef explicit_lod = NULL;
> +   LLVMValueRef lod = NULL;
>      LLVMValueRef context_ptr;
>      LLVMValueRef texel_out[4];
>      struct lp_derivatives derivs;
>      struct lp_derivatives *deriv_ptr = NULL;
>      unsigned num_param = 0;
>      unsigned i, num_coords, num_derivs, num_offsets, layer;
> +   enum lp_sampler_lod_control lod_control;
> +
> +   lod_control = (sample_key & LP_SAMPLER_LOD_CONTROL_MASK) >>
> +                    LP_SAMPLER_LOD_CONTROL_SHIFT;
>
>      get_target_info(static_texture_state->target,
>                      &num_coords, &num_derivs, &num_offsets, &layer);
> @@ -2972,21 +2990,19 @@ lp_build_sample_gen_func(struct gallivm_state *gallivm,
>      if (layer) {
>         coords[layer] = LLVMGetParam(function, num_param++);
>      }
> -   if (sampler_bits & LP_SAMPLER_FUNC_SHADOW) {
> +   if (sample_key & LP_SAMPLER_SHADOW) {
>         coords[4] = LLVMGetParam(function, num_param++);
>      }
> -   if (sampler_bits & LP_SAMPLER_FUNC_OFFSETS) {
> +   if (sample_key & LP_SAMPLER_OFFSETS) {
>         for (i = 0; i < num_offsets; i++) {
>            offsets[i] = LLVMGetParam(function, num_param++);
>         }
>      }
> -   if (sampler_bits & LP_SAMPLER_FUNC_LOD_BIAS) {
> -      lod_bias = LLVMGetParam(function, num_param++);
> -   }
> -   else if (sampler_bits & LP_SAMPLER_FUNC_LOD_EXPLICIT) {
> -      explicit_lod = LLVMGetParam(function, num_param++);
> +   if (lod_control == LP_SAMPLER_LOD_BIAS ||
> +       lod_control == LP_SAMPLER_LOD_EXPLICIT) {
> +      lod = LLVMGetParam(function, num_param++);
>      }
> -   else if (sampler_bits & LP_SAMPLER_FUNC_EXPLICITDERIVS) {
> +   else if (lod_control == LP_SAMPLER_LOD_DERIVATIVES) {
>         for (i = 0; i < num_derivs; i++) {
>            derivs.ddx[i] = LLVMGetParam(function, num_param++);
>            derivs.ddy[i] = LLVMGetParam(function, num_param++);
> @@ -3010,16 +3026,14 @@ lp_build_sample_gen_func(struct gallivm_state *gallivm,
>                               static_sampler_state,
>                               dynamic_state,
>                               type,
> -                            is_fetch,
> +                            sample_key,
>                               texture_index,
>                               sampler_index,
>                               context_ptr,
>                               coords,
>                               offsets,
>                               deriv_ptr,
> -                            lod_bias,
> -                            explicit_lod,
> -                            lod_property,
> +                            lod,
>                               texel_out);
>
>      LLVMBuildAggregateRet(gallivm->builder, texel_out, 4);
> @@ -3040,18 +3054,7 @@ lp_build_sample_soa_func(struct gallivm_state *gallivm,
>                            const struct lp_static_texture_state *static_texture_state,
>                            const struct lp_static_sampler_state *static_sampler_state,
>                            struct lp_sampler_dynamic_state *dynamic_state,
> -                         struct lp_type type,
> -                         boolean is_fetch,
> -                         unsigned texture_index,
> -                         unsigned sampler_index,
> -                         LLVMValueRef context_ptr,
> -                         const LLVMValueRef *coords,
> -                         const LLVMValueRef *offsets,
> -                         const struct lp_derivatives *derivs, /* optional */
> -                         LLVMValueRef lod_bias, /* optional */
> -                         LLVMValueRef explicit_lod, /* optional */
> -                         enum lp_sampler_lod_property lod_property,
> -                         LLVMValueRef texel_out[4])
> +                         const struct lp_sampler_params *params)
>   {
>      LLVMBuilderRef builder = gallivm->builder;
>      LLVMModuleRef module = LLVMGetGlobalParent(LLVMGetBasicBlockParent(
> @@ -3061,9 +3064,18 @@ lp_build_sample_soa_func(struct gallivm_state *gallivm,
>      LLVMBasicBlockRef bb;
>      LLVMValueRef tex_ret;
>      unsigned num_args = 0;
> -   unsigned sampler_bits = 0;
>      char func_name[64];
>      unsigned i, num_coords, num_derivs, num_offsets, layer;
> +   unsigned texture_index = params->texture_index;
> +   unsigned sampler_index = params->sampler_index;
> +   unsigned sample_key = params->sample_key;
> +   const LLVMValueRef *coords = params->coords;
> +   const LLVMValueRef *offsets = params->offsets;
> +   const struct lp_derivatives *derivs = params->derivs;
> +   enum lp_sampler_lod_control lod_control;
> +
> +   lod_control = (sample_key & LP_SAMPLER_LOD_CONTROL_MASK) >>
> +                    LP_SAMPLER_LOD_CONTROL_SHIFT;
>
>      get_target_info(static_texture_state->target,
>                      &num_coords, &num_derivs, &num_offsets, &layer);
> @@ -3071,34 +3083,13 @@ lp_build_sample_soa_func(struct gallivm_state *gallivm,
>      /*
>       * texture function matches are found by name.
>       * Thus the name has to include both the texture and sampler unit
> -    * (which covers all static state) plus the actual texture functions
> -    * (which is determined here somewhat awkwardly by presence of the
> -    * corresponding LLVMValueRefs). Additionally, lod_property also
> -    * has to be included (it could change if the lod for instance comes
> -    * from a shader uniform or a temp reg).
> +    * (which covers all static state) plus the actual texture function
> +    * (including things like offsets, shadow coord, lod control).
> +    * Additionally lod_property has to be included too.
>       */
> -   if (static_sampler_state->compare_mode != PIPE_TEX_COMPARE_NONE) {
> -      sampler_bits |= LP_SAMPLER_FUNC_SHADOW;
> -   }
> -   if (offsets[0]) {
> -      sampler_bits |= LP_SAMPLER_FUNC_OFFSETS;
> -   }
> -   if (lod_bias) {
> -      sampler_bits |= LP_SAMPLER_FUNC_LOD_BIAS;
> -   }
> -   else if (explicit_lod) {
> -      sampler_bits |= LP_SAMPLER_FUNC_LOD_EXPLICIT;
> -   }
> -   else if (derivs) {
> -      sampler_bits |= LP_SAMPLER_FUNC_EXPLICITDERIVS;
> -   }
> -   if (is_fetch) {
> -      sampler_bits |= LP_SAMPLER_FUNC_FETCH;
> -   }
> -   sampler_bits |= lod_property << LP_SAMPLER_FUNC_LOD_PROPERTY_SHIFT;
>
>      util_snprintf(func_name, sizeof(func_name), "texfunc_res_%d_sam_%d_%x",
> -                 texture_index, sampler_index, sampler_bits);
> +                 texture_index, sampler_index, sample_key);
>
>      function = LLVMGetNamedFunction(module, func_name);
>
> @@ -3113,7 +3104,7 @@ lp_build_sample_soa_func(struct gallivm_state *gallivm,
>          * Generate the function prototype.
>          */
>
> -      arg_types[num_param++] = LLVMTypeOf(context_ptr);
> +      arg_types[num_param++] = LLVMTypeOf(params->context_ptr);
>         for (i = 0; i < num_coords; i++) {
>            arg_types[num_param++] = LLVMTypeOf(coords[0]);
>            assert(LLVMTypeOf(coords[0]) == LLVMTypeOf(coords[i]));
> @@ -3122,22 +3113,20 @@ lp_build_sample_soa_func(struct gallivm_state *gallivm,
>            arg_types[num_param++] = LLVMTypeOf(coords[layer]);
>            assert(LLVMTypeOf(coords[0]) == LLVMTypeOf(coords[layer]));
>         }
> -      if (sampler_bits & LP_SAMPLER_FUNC_SHADOW) {
> +      if (sample_key & LP_SAMPLER_SHADOW) {
>            arg_types[num_param++] = LLVMTypeOf(coords[0]);
>         }
> -      if (sampler_bits & LP_SAMPLER_FUNC_OFFSETS) {
> +      if (sample_key & LP_SAMPLER_OFFSETS) {
>            for (i = 0; i < num_offsets; i++) {
>               arg_types[num_param++] = LLVMTypeOf(offsets[0]);
>               assert(LLVMTypeOf(offsets[0]) == LLVMTypeOf(offsets[i]));
>            }
>         }
> -      if (sampler_bits & LP_SAMPLER_FUNC_LOD_BIAS) {
> -         arg_types[num_param++] = LLVMTypeOf(lod_bias);
> -      }
> -      else if (sampler_bits & LP_SAMPLER_FUNC_LOD_EXPLICIT) {
> -         arg_types[num_param++] = LLVMTypeOf(explicit_lod);
> +      if (lod_control == LP_SAMPLER_LOD_BIAS ||
> +          lod_control == LP_SAMPLER_LOD_EXPLICIT) {
> +         arg_types[num_param++] = LLVMTypeOf(params->lod);
>         }
> -      else if (sampler_bits & LP_SAMPLER_FUNC_EXPLICITDERIVS) {
> +      else if (lod_control == LP_SAMPLER_LOD_DERIVATIVES) {
>            for (i = 0; i < num_derivs; i++) {
>               arg_types[num_param++] = LLVMTypeOf(derivs->ddx[i]);
>               arg_types[num_param++] = LLVMTypeOf(derivs->ddy[i]);
> @@ -3147,7 +3136,7 @@ lp_build_sample_soa_func(struct gallivm_state *gallivm,
>         }
>
>         val_type[0] = val_type[1] = val_type[2] = val_type[3] =
> -         lp_build_vec_type(gallivm, type);
> +         lp_build_vec_type(gallivm, params->type);
>         ret_type = LLVMStructTypeInContext(gallivm->context, val_type, 4, 0);
>         function_type = LLVMFunctionType(ret_type, arg_types, num_param, 0);
>         function = LLVMAddFunction(module, func_name, function_type);
> @@ -3165,39 +3154,35 @@ lp_build_sample_soa_func(struct gallivm_state *gallivm,
>                                  static_texture_state,
>                                  static_sampler_state,
>                                  dynamic_state,
> -                               type,
> -                               is_fetch,
> +                               params->type,
>                                  texture_index,
>                                  sampler_index,
>                                  function,
>                                  num_param,
> -                               sampler_bits,
> -                               lod_property);
> +                               sample_key);
>      }
>
>      num_args = 0;
> -   args[num_args++] = context_ptr;
> +   args[num_args++] = params->context_ptr;
>      for (i = 0; i < num_coords; i++) {
>         args[num_args++] = coords[i];
>      }
>      if (layer) {
>         args[num_args++] = coords[layer];
>      }
> -   if (sampler_bits & LP_SAMPLER_FUNC_SHADOW) {
> +   if (sample_key & LP_SAMPLER_SHADOW) {
>         args[num_args++] = coords[4];
>      }
> -   if (sampler_bits & LP_SAMPLER_FUNC_OFFSETS) {
> +   if (sample_key & LP_SAMPLER_OFFSETS) {
>         for (i = 0; i < num_offsets; i++) {
>            args[num_args++] = offsets[i];
>         }
>      }
> -   if (sampler_bits & LP_SAMPLER_FUNC_LOD_BIAS) {
> -      args[num_args++] = lod_bias;
> -   }
> -   else if (sampler_bits & LP_SAMPLER_FUNC_LOD_EXPLICIT) {
> -      args[num_args++] = explicit_lod;
> +   if (lod_control == LP_SAMPLER_LOD_BIAS ||
> +       lod_control == LP_SAMPLER_LOD_EXPLICIT) {
> +      args[num_args++] = params->lod;
>      }
> -   else if (sampler_bits & LP_SAMPLER_FUNC_EXPLICITDERIVS) {
> +   else if (lod_control == LP_SAMPLER_LOD_DERIVATIVES) {
>         for (i = 0; i < num_derivs; i++) {
>            args[num_args++] = derivs->ddx[i];
>            args[num_args++] = derivs->ddy[i];
> @@ -3212,7 +3197,7 @@ lp_build_sample_soa_func(struct gallivm_state *gallivm,
>      LLVMSetInstructionCallConv(inst, LLVMFastCallConv);
>
>      for (i = 0; i < 4; i++) {
> -      texel_out[i] = LLVMBuildExtractValue(gallivm->builder, tex_ret, i, "");
> +      params->texel[i] = LLVMBuildExtractValue(gallivm->builder, tex_ret, i, "");
>      }
>   }
>
> @@ -3222,58 +3207,34 @@ lp_build_sample_soa_func(struct gallivm_state *gallivm,
>    * Either via a function call or inline it directly.
>    */
>   void
> -lp_build_sample_soa(struct gallivm_state *gallivm,
> -                    const struct lp_static_texture_state *static_texture_state,
> +lp_build_sample_soa(const struct lp_static_texture_state *static_texture_state,
>                       const struct lp_static_sampler_state *static_sampler_state,
>                       struct lp_sampler_dynamic_state *dynamic_state,
> -                    struct lp_type type,
> -                    boolean is_fetch,
> -                    unsigned texture_index,
> -                    unsigned sampler_index,
> -                    LLVMValueRef context_ptr,
> -                    const LLVMValueRef *coords,
> -                    const LLVMValueRef *offsets,
> -                    const struct lp_derivatives *derivs, /* optional */
> -                    LLVMValueRef lod_bias, /* optional */
> -                    LLVMValueRef explicit_lod, /* optional */
> -                    enum lp_sampler_lod_property lod_property,
> -                    LLVMValueRef texel_out[4])
> +                    struct gallivm_state *gallivm,
> +                    const struct lp_sampler_params *params)
>   {
>      if (USE_TEX_FUNC_CALL) {
>         lp_build_sample_soa_func(gallivm,
>                                  static_texture_state,
>                                  static_sampler_state,
>                                  dynamic_state,
> -                               type,
> -                               is_fetch,
> -                               texture_index,
> -                               sampler_index,
> -                               context_ptr,
> -                               coords,
> -                               offsets,
> -                               derivs,
> -                               lod_bias,
> -                               explicit_lod,
> -                               lod_property,
> -                               texel_out);
> +                               params);
>      }
>      else {
>         lp_build_sample_soa_code(gallivm,
>                                  static_texture_state,
>                                  static_sampler_state,
>                                  dynamic_state,
> -                               type,
> -                               is_fetch,
> -                               texture_index,
> -                               sampler_index,
> -                               context_ptr,
> -                               coords,
> -                               offsets,
> -                               derivs,
> -                               lod_bias,
> -                               explicit_lod,
> -                               lod_property,
> -                               texel_out);
> +                               params->type,
> +                               params->sample_key,
> +                               params->texture_index,
> +                               params->sampler_index,
> +                               params->context_ptr,
> +                               params->coords,
> +                               params->offsets,
> +                               params->derivs,
> +                               params->lod,
> +                               params->texel);
>      }
>   }
>
> diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h
> index 8d53607..3f76b79 100644
> --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h
> +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h
> @@ -182,20 +182,9 @@ struct lp_build_sampler_soa
>      (*destroy)( struct lp_build_sampler_soa *sampler );
>
>      void
> -   (*emit_fetch_texel)( const struct lp_build_sampler_soa *sampler,
> -                        struct gallivm_state *gallivm,
> -                        struct lp_type type,
> -                        boolean is_fetch,
> -                        unsigned texture_index,
> -                        unsigned sampler_index,
> -                        LLVMValueRef context_ptr,
> -                        const LLVMValueRef *coords,
> -                        const LLVMValueRef *offsets,
> -                        const struct lp_derivatives *derivs,
> -                        LLVMValueRef lod_bias, /* optional */
> -                        LLVMValueRef explicit_lod, /* optional */
> -                        enum lp_sampler_lod_property,
> -                        LLVMValueRef *texel);
> +   (*emit_tex_sample)(const struct lp_build_sampler_soa *sampler,
> +                      struct gallivm_state *gallivm,
> +                      const struct lp_sampler_params *params);
>
>      void
>      (*emit_size_query)( const struct lp_build_sampler_soa *sampler,
> diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
> index 3e82036..6a71da6 100644
> --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
> +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
> @@ -1964,16 +1964,19 @@ emit_tex( struct lp_build_tgsi_soa_context *bld,
>             unsigned sampler_reg)
>   {
>      unsigned unit = inst->Src[sampler_reg].Register.Index;
> -   LLVMValueRef lod_bias, explicit_lod;
>      LLVMValueRef oow = NULL;
> +   LLVMValueRef lod = NULL;
>      LLVMValueRef coords[5];
>      LLVMValueRef offsets[3] = { NULL };
>      struct lp_derivatives derivs;
> -   struct lp_derivatives *deriv_ptr = NULL;
> +   struct lp_sampler_params params;
>      enum lp_sampler_lod_property lod_property = LP_SAMPLER_LOD_SCALAR;
>      unsigned num_derivs, num_offsets, i;
>      unsigned shadow_coord = 0;
>      unsigned layer_coord = 0;
> +   unsigned sample_key = 0;
> +
> +   memset(&params, 0, sizeof(params));
>
>      if (!bld->sampler) {
>         _debug_printf("warning: found texture instruction but no sampler generator supplied\n");
> @@ -2053,7 +2056,6 @@ emit_tex( struct lp_build_tgsi_soa_context *bld,
>      /* Note lod and especially projected are illegal in a LOT of cases */
>      if (modifier == LP_BLD_TEX_MODIFIER_LOD_BIAS ||
>          modifier == LP_BLD_TEX_MODIFIER_EXPLICIT_LOD) {
> -      LLVMValueRef lod;
>         if (inst->Texture.Texture == TGSI_TEXTURE_SHADOWCUBE ||
>             inst->Texture.Texture == TGSI_TEXTURE_CUBE_ARRAY) {
>            /* note that shadow cube array with bias/explicit lod does not exist */
> @@ -2063,19 +2065,13 @@ emit_tex( struct lp_build_tgsi_soa_context *bld,
>            lod = lp_build_emit_fetch(&bld->bld_base, inst, 0, 3);
>         }
>         if (modifier == LP_BLD_TEX_MODIFIER_LOD_BIAS) {
> -         lod_bias = lod;
> -         explicit_lod = NULL;
> +         sample_key |= LP_SAMPLER_LOD_BIAS << LP_SAMPLER_LOD_CONTROL_SHIFT;
>         }
>         else if (modifier == LP_BLD_TEX_MODIFIER_EXPLICIT_LOD) {
> -         lod_bias = NULL;
> -         explicit_lod = lod;
> +         sample_key |= LP_SAMPLER_LOD_EXPLICIT << LP_SAMPLER_LOD_CONTROL_SHIFT;
>         }
>         lod_property = lp_build_lod_property(&bld->bld_base, inst, 0);
>      }
> -   else {
> -      lod_bias = NULL;
> -      explicit_lod = NULL;
> -   }
>
>      if (modifier == LP_BLD_TEX_MODIFIER_PROJECTED) {
>         oow = lp_build_emit_fetch(&bld->bld_base, inst, 0, 3);
> @@ -2104,6 +2100,7 @@ emit_tex( struct lp_build_tgsi_soa_context *bld,
>      }
>      /* Shadow coord occupies always 5th slot. */
>      if (shadow_coord) {
> +      sample_key |= LP_SAMPLER_SHADOW;
>         if (shadow_coord == 4) {
>            coords[4] = lp_build_emit_fetch(&bld->bld_base, inst, 1, 0);
>         }
> @@ -2116,11 +2113,12 @@ emit_tex( struct lp_build_tgsi_soa_context *bld,
>
>      if (modifier == LP_BLD_TEX_MODIFIER_EXPLICIT_DERIV) {
>         unsigned dim;
> +      sample_key |= LP_SAMPLER_LOD_DERIVATIVES << LP_SAMPLER_LOD_CONTROL_SHIFT;
>         for (dim = 0; dim < num_derivs; ++dim) {
>            derivs.ddx[dim] = lp_build_emit_fetch(&bld->bld_base, inst, 1, dim);
>            derivs.ddy[dim] = lp_build_emit_fetch(&bld->bld_base, inst, 2, dim);
>         }
> -      deriv_ptr = &derivs;
> +      params.derivs = &derivs;
>         /*
>          * could also check all src regs if constant but I doubt such
>          * cases exist in practice.
> @@ -2137,26 +2135,30 @@ emit_tex( struct lp_build_tgsi_soa_context *bld,
>            lod_property = LP_SAMPLER_LOD_PER_ELEMENT;
>         }
>      }
> +   sample_key |= lod_property << LP_SAMPLER_LOD_PROPERTY_SHIFT;
>
>      /* some advanced gather instructions (txgo) would require 4 offsets */
>      if (inst->Texture.NumOffsets == 1) {
>         unsigned dim;
> +      sample_key |= LP_SAMPLER_OFFSETS;
>         for (dim = 0; dim < num_offsets; dim++) {
>            offsets[dim] = lp_build_emit_fetch_texoffset(&bld->bld_base, inst, 0, dim);
>         }
>      }
>
> -   bld->sampler->emit_fetch_texel(bld->sampler,
> -                                  bld->bld_base.base.gallivm,
> -                                  bld->bld_base.base.type,
> -                                  FALSE,
> -                                  unit, unit,
> -                                  bld->context_ptr,
> -                                  coords,
> -                                  offsets,
> -                                  deriv_ptr,
> -                                  lod_bias, explicit_lod, lod_property,
> -                                  texel);
> +   params.type = bld->bld_base.base.type;
> +   params.sample_key = sample_key;
> +   params.texture_index = unit;
> +   params.sampler_index = unit;
> +   params.context_ptr = bld->context_ptr;
> +   params.coords = coords;
> +   params.offsets = offsets;
> +   params.lod = lod;
> +   params.texel = texel;
> +
> +   bld->sampler->emit_tex_sample(bld->sampler,
> +                                 bld->bld_base.base.gallivm,
> +                                 &params);
>   }
>
>   static void
> @@ -2168,15 +2170,18 @@ emit_sample(struct lp_build_tgsi_soa_context *bld,
>   {
>      struct gallivm_state *gallivm = bld->bld_base.base.gallivm;
>      unsigned texture_unit, sampler_unit;
> -   LLVMValueRef lod_bias, explicit_lod;
> +   LLVMValueRef lod = NULL;
>      LLVMValueRef coords[5];
>      LLVMValueRef offsets[3] = { NULL };
>      struct lp_derivatives derivs;
> -   struct lp_derivatives *deriv_ptr = NULL;
> +   struct lp_sampler_params params;
>      enum lp_sampler_lod_property lod_property = LP_SAMPLER_LOD_SCALAR;
>
>      unsigned num_offsets, num_derivs, i;
>      unsigned layer_coord = 0;
> +   unsigned sample_key = 0;
> +
> +   memset(&params, 0, sizeof(params));
>
>      if (!bld->sampler) {
>         _debug_printf("warning: found texture instruction but no sampler generator supplied\n");
> @@ -2238,25 +2243,19 @@ emit_sample(struct lp_build_tgsi_soa_context *bld,
>
>      if (modifier == LP_BLD_TEX_MODIFIER_LOD_BIAS ||
>          modifier == LP_BLD_TEX_MODIFIER_EXPLICIT_LOD) {
> -      LLVMValueRef lod = lp_build_emit_fetch(&bld->bld_base, inst, 3, 0);
> +      lod = lp_build_emit_fetch(&bld->bld_base, inst, 3, 0);
>         if (modifier == LP_BLD_TEX_MODIFIER_LOD_BIAS) {
> -         lod_bias = lod;
> -         explicit_lod = NULL;
> +         sample_key |= LP_SAMPLER_LOD_BIAS << LP_SAMPLER_LOD_CONTROL_SHIFT;
>         }
>         else if (modifier == LP_BLD_TEX_MODIFIER_EXPLICIT_LOD) {
> -         lod_bias = NULL;
> -         explicit_lod = lod;
> +         sample_key |= LP_SAMPLER_LOD_EXPLICIT << LP_SAMPLER_LOD_CONTROL_SHIFT;
>         }
>         lod_property = lp_build_lod_property(&bld->bld_base, inst, 0);
>      }
>      else if (modifier == LP_BLD_TEX_MODIFIER_LOD_ZERO) {
> -      lod_bias = NULL;
>         /* XXX might be better to explicitly pass the level zero information */
> -      explicit_lod = lp_build_const_vec(gallivm, bld->bld_base.base.type, 0.0F);
> -   }
> -   else {
> -      lod_bias = NULL;
> -      explicit_lod = NULL;
> +      sample_key |= LP_SAMPLER_LOD_EXPLICIT << LP_SAMPLER_LOD_CONTROL_SHIFT;
> +      lod = lp_build_const_vec(gallivm, bld->bld_base.base.type, 0.0F);
>      }
>
>      for (i = 0; i < num_derivs; i++) {
> @@ -2275,16 +2274,18 @@ emit_sample(struct lp_build_tgsi_soa_context *bld,
>      }
>      /* Shadow coord occupies always 5th slot. */
>      if (compare) {
> +      sample_key |= LP_SAMPLER_SHADOW;
>         coords[4] = lp_build_emit_fetch(&bld->bld_base, inst, 3, 0);
>      }
>
>      if (modifier == LP_BLD_TEX_MODIFIER_EXPLICIT_DERIV) {
>         unsigned dim;
> +      sample_key |= LP_SAMPLER_LOD_DERIVATIVES << LP_SAMPLER_LOD_CONTROL_SHIFT;
>         for (dim = 0; dim < num_derivs; ++dim) {
>            derivs.ddx[dim] = lp_build_emit_fetch(&bld->bld_base, inst, 3, dim);
>            derivs.ddy[dim] = lp_build_emit_fetch(&bld->bld_base, inst, 4, dim);
>         }
> -      deriv_ptr = &derivs;
> +      params.derivs = &derivs;
>         /*
>          * could also check all src regs if constant but I doubt such
>          * cases exist in practice.
> @@ -2305,22 +2306,26 @@ emit_sample(struct lp_build_tgsi_soa_context *bld,
>      /* some advanced gather instructions (txgo) would require 4 offsets */
>      if (inst->Texture.NumOffsets == 1) {
>         unsigned dim;
> +      sample_key |= LP_SAMPLER_OFFSETS;
>         for (dim = 0; dim < num_offsets; dim++) {
>            offsets[dim] = lp_build_emit_fetch_texoffset(&bld->bld_base, inst, 0, dim);
>         }
>      }
> +   sample_key |= lod_property << LP_SAMPLER_LOD_PROPERTY_SHIFT;
>
> -   bld->sampler->emit_fetch_texel(bld->sampler,
> -                                  bld->bld_base.base.gallivm,
> -                                  bld->bld_base.base.type,
> -                                  FALSE,
> -                                  texture_unit, sampler_unit,
> -                                  bld->context_ptr,
> -                                  coords,
> -                                  offsets,
> -                                  deriv_ptr,
> -                                  lod_bias, explicit_lod, lod_property,
> -                                  texel);
> +   params.type = bld->bld_base.base.type;
> +   params.sample_key = sample_key;
> +   params.texture_index = texture_unit;
> +   params.sampler_index = sampler_unit;
> +   params.context_ptr = bld->context_ptr;
> +   params.coords = coords;
> +   params.offsets = offsets;
> +   params.lod = lod;
> +   params.texel = texel;
> +
> +   bld->sampler->emit_tex_sample(bld->sampler,
> +                                 bld->bld_base.base.gallivm,
> +                                 &params);
>
>      if (inst->Src[1].Register.SwizzleX != PIPE_SWIZZLE_RED ||
>          inst->Src[1].Register.SwizzleY != PIPE_SWIZZLE_GREEN ||
> @@ -2347,9 +2352,13 @@ emit_fetch_texels( struct lp_build_tgsi_soa_context *bld,
>      LLVMValueRef explicit_lod = NULL;
>      LLVMValueRef coords[5];
>      LLVMValueRef offsets[3] = { NULL };
> +   struct lp_sampler_params params;
>      enum lp_sampler_lod_property lod_property = LP_SAMPLER_LOD_SCALAR;
>      unsigned dims, i;
>      unsigned layer_coord = 0;
> +   unsigned sample_key = LP_SAMPLER_FETCH;
> +
> +   memset(&params, 0, sizeof(params));
>
>      if (!bld->sampler) {
>         _debug_printf("warning: found texture instruction but no sampler generator supplied\n");
> @@ -2399,6 +2408,7 @@ emit_fetch_texels( struct lp_build_tgsi_soa_context *bld,
>      if (target != TGSI_TEXTURE_BUFFER &&
>          target != TGSI_TEXTURE_2D_MSAA &&
>          target != TGSI_TEXTURE_2D_ARRAY_MSAA) {
> +      sample_key |= LP_SAMPLER_LOD_EXPLICIT << LP_SAMPLER_LOD_CONTROL_SHIFT;
>         explicit_lod = lp_build_emit_fetch(&bld->bld_base, inst, 0, 3);
>         lod_property = lp_build_lod_property(&bld->bld_base, inst, 0);
>      }
> @@ -2416,22 +2426,27 @@ emit_fetch_texels( struct lp_build_tgsi_soa_context *bld,
>
>      if (inst->Texture.NumOffsets == 1) {
>         unsigned dim;
> +      sample_key |= LP_SAMPLER_OFFSETS;
>         for (dim = 0; dim < dims; dim++) {
>            offsets[dim] = lp_build_emit_fetch_texoffset(&bld->bld_base, inst, 0, dim);
>         }
>      }
> +   sample_key |= lod_property << LP_SAMPLER_LOD_PROPERTY_SHIFT;
>
> -   bld->sampler->emit_fetch_texel(bld->sampler,
> -                                  bld->bld_base.base.gallivm,
> -                                  bld->bld_base.base.type,
> -                                  TRUE,
> -                                  unit, unit,
> -                                  bld->context_ptr,
> -                                  coords,
> -                                  offsets,
> -                                  NULL,
> -                                  NULL, explicit_lod, lod_property,
> -                                  texel);
> +   params.type = bld->bld_base.base.type;
> +   params.sample_key = sample_key;
> +   params.texture_index = unit;
> +   params.sampler_index = unit;
> +   params.context_ptr = bld->context_ptr;
> +   params.coords = coords;
> +   params.offsets = offsets;
> +   params.derivs = NULL;
> +   params.lod = explicit_lod;
> +   params.texel = texel;
> +
> +   bld->sampler->emit_tex_sample(bld->sampler,
> +                                 bld->bld_base.base.gallivm,
> +                                 &params);
>
>      if (is_samplei &&
>          (inst->Src[1].Register.SwizzleX != PIPE_SWIZZLE_RED ||
> diff --git a/src/gallium/drivers/llvmpipe/lp_tex_sample.c b/src/gallium/drivers/llvmpipe/lp_tex_sample.c
> index 1828069..316d1c5 100644
> --- a/src/gallium/drivers/llvmpipe/lp_tex_sample.c
> +++ b/src/gallium/drivers/llvmpipe/lp_tex_sample.c
> @@ -235,43 +235,24 @@ lp_llvm_sampler_soa_destroy(struct lp_build_sampler_soa *sampler)
>   static void
>   lp_llvm_sampler_soa_emit_fetch_texel(const struct lp_build_sampler_soa *base,
>                                        struct gallivm_state *gallivm,
> -                                     struct lp_type type,
> -                                     boolean is_fetch,
> -                                     unsigned texture_index,
> -                                     unsigned sampler_index,
> -                                     LLVMValueRef context_ptr,
> -                                     const LLVMValueRef *coords,
> -                                     const LLVMValueRef *offsets,
> -                                     const struct lp_derivatives *derivs,
> -                                     LLVMValueRef lod_bias, /* optional */
> -                                     LLVMValueRef explicit_lod, /* optional */
> -                                     enum lp_sampler_lod_property lod_property,
> -                                     LLVMValueRef *texel)
> +                                     const struct lp_sampler_params *params)
>   {
>      struct lp_llvm_sampler_soa *sampler = (struct lp_llvm_sampler_soa *)base;
> +   unsigned texture_index = params->texture_index;
> +   unsigned sampler_index = params->sampler_index;
>
>      assert(sampler_index < PIPE_MAX_SAMPLERS);
>      assert(texture_index < PIPE_MAX_SHADER_SAMPLER_VIEWS);
>
>      if (LP_PERF & PERF_NO_TEX) {
> -      lp_build_sample_nop(gallivm, type, coords, texel);
> +      lp_build_sample_nop(gallivm, params->type, params->coords, params->texel);
>         return;
>      }
>
> -   lp_build_sample_soa(gallivm,
> -                       &sampler->dynamic_state.static_state[texture_index].texture_state,
> +   lp_build_sample_soa(&sampler->dynamic_state.static_state[texture_index].texture_state,
>                          &sampler->dynamic_state.static_state[sampler_index].sampler_state,
>                          &sampler->dynamic_state.base,
> -                       type,
> -                       is_fetch,
> -                       texture_index,
> -                       sampler_index,
> -                       context_ptr,
> -                       coords,
> -                       offsets,
> -                       derivs,
> -                       lod_bias, explicit_lod, lod_property,
> -                       texel);
> +                       gallivm, params);
>   }
>
>   /**
> @@ -317,7 +298,7 @@ lp_llvm_sampler_soa_create(const struct lp_sampler_static_state *static_state)
>         return NULL;
>
>      sampler->base.destroy = lp_llvm_sampler_soa_destroy;
> -   sampler->base.emit_fetch_texel = lp_llvm_sampler_soa_emit_fetch_texel;
> +   sampler->base.emit_tex_sample = lp_llvm_sampler_soa_emit_fetch_texel;
>      sampler->base.emit_size_query = lp_llvm_sampler_soa_emit_size_query;
>      sampler->dynamic_state.base.width = lp_llvm_texture_width;
>      sampler->dynamic_state.base.height = lp_llvm_texture_height;
>

Reviewed-by: Jose Fonseca <jfonseca at vmware.com>


More information about the mesa-dev mailing list