Mesa (master): gallivm: simplify sampler interface

Roland Scheidegger sroland at kemper.freedesktop.org
Tue Mar 31 15:24:05 UTC 2015


Module: Mesa
Branch: master
Commit: 1863ed21ffbb3ab7fd9875dc25e32ececea79d50
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=1863ed21ffbb3ab7fd9875dc25e32ececea79d50

Author: Roland Scheidegger <sroland at vmware.com>
Date:   Sat Mar 28 20:51:23 2015 +0100

gallivm: simplify sampler interface

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.

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

---

 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;




More information about the mesa-commit mailing list