Merge remote branch 'origin/master' into gallium_draw_llvm
[mesa.git] / src / gallium / auxiliary / gallivm / lp_bld_sample.c
index 9003e108c1cd2be8fe6eb37391be22ab49f336c7..2f74aa5e00a1f4d3fab3412f003d362b0721ed2f 100644 (file)
 #include "lp_bld_sample.h"
 
 
+/**
+ * Initialize lp_sampler_static_state object with the gallium sampler
+ * and texture state.
+ * The former is considered to be static and the later dynamic.
+ */
 void
 lp_sampler_static_state(struct lp_sampler_static_state *state,
                         const struct pipe_texture *texture,
@@ -57,6 +62,18 @@ lp_sampler_static_state(struct lp_sampler_static_state *state,
    if(!sampler)
       return;
 
+   /*
+    * We don't copy sampler state over unless it is actually enabled, to avoid
+    * spurious recompiles, as the sampler static state is part of the shader
+    * key.
+    *
+    * Ideally the state tracker or cso_cache module would make all state
+    * canonical, but until that happens it's better to be safe than sorry here.
+    *
+    * XXX: Actually there's much more than can be done here, especially
+    * regarding 1D/2D/3D/CUBE textures, wrap modes, etc.
+    */
+
    state->format            = texture->format;
    state->target            = texture->target;
    state->pot_width         = util_is_pot(texture->width0);
@@ -67,14 +84,26 @@ lp_sampler_static_state(struct lp_sampler_static_state *state,
    state->wrap_t            = sampler->wrap_t;
    state->wrap_r            = sampler->wrap_r;
    state->min_img_filter    = sampler->min_img_filter;
-   state->min_mip_filter    = sampler->min_mip_filter;
    state->mag_img_filter    = sampler->mag_img_filter;
+   if (texture->last_level) {
+      state->min_mip_filter = sampler->min_mip_filter;
+   } else {
+      state->min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
+   }
+
    state->compare_mode      = sampler->compare_mode;
-   if(sampler->compare_mode != PIPE_TEX_COMPARE_NONE) {
-      state->compare_func      = sampler->compare_func;
+   if (sampler->compare_mode != PIPE_TEX_COMPARE_NONE) {
+      state->compare_func   = sampler->compare_func;
    }
+
    state->normalized_coords = sampler->normalized_coords;
-   state->prefilter         = sampler->prefilter;
+   state->lod_bias          = sampler->lod_bias;
+   state->min_lod           = sampler->min_lod;
+   state->max_lod           = sampler->max_lod;
+   state->border_color[0]   = sampler->border_color[0];
+   state->border_color[1]   = sampler->border_color[1];
+   state->border_color[2]   = sampler->border_color[2];
+   state->border_color[3]   = sampler->border_color[3];
 }
 
 
@@ -130,15 +159,16 @@ lp_build_gather(LLVMBuilderRef builder,
 /**
  * Compute the offset of a pixel.
  *
- * x, y, y_stride are vectors
+ * x, y, z, y_stride, z_stride are vectors
  */
 LLVMValueRef
 lp_build_sample_offset(struct lp_build_context *bld,
                        const struct util_format_description *format_desc,
                        LLVMValueRef x,
                        LLVMValueRef y,
+                       LLVMValueRef z,
                        LLVMValueRef y_stride,
-                       LLVMValueRef data_ptr)
+                       LLVMValueRef z_stride)
 {
    LLVMValueRef x_stride;
    LLVMValueRef offset;
@@ -154,6 +184,10 @@ lp_build_sample_offset(struct lp_build_context *bld,
       LLVMValueRef y_offset_lo, y_offset_hi;
       LLVMValueRef offset_lo, offset_hi;
 
+      /* XXX 1D & 3D addressing not done yet */
+      assert(!z);
+      assert(!z_stride);
+
       x_lo = LLVMBuildAnd(bld->builder, x, bld->one, "");
       y_lo = LLVMBuildAnd(bld->builder, y, bld->one, "");
 
@@ -177,13 +211,17 @@ lp_build_sample_offset(struct lp_build_context *bld,
       offset = lp_build_add(bld, offset_hi, offset_lo);
    }
    else {
-      LLVMValueRef x_offset;
-      LLVMValueRef y_offset;
+      offset = lp_build_mul(bld, x, x_stride);
 
-      x_offset = lp_build_mul(bld, x, x_stride);
-      y_offset = lp_build_mul(bld, y, y_stride);
+      if (y && y_stride) {
+         LLVMValueRef y_offset = lp_build_mul(bld, y, y_stride);
+         offset = lp_build_add(bld, offset, y_offset);
+      }
 
-      offset = lp_build_add(bld, x_offset, y_offset);
+      if (z && z_stride) {
+         LLVMValueRef z_offset = lp_build_mul(bld, z, z_stride);
+         offset = lp_build_add(bld, offset, z_offset);
+      }
    }
 
    return offset;