Merge branch 'mesa_7_5_branch'
[mesa.git] / src / mesa / drivers / dri / i965 / brw_wm_sampler_state.c
index 0f59584c6e332623ad6cb74cadcebb0e742d8a07..3fc18ff1f3a3cfbc2de60736a96bb59c90d52839 100644 (file)
@@ -34,7 +34,7 @@
 #include "brw_state.h"
 #include "brw_defines.h"
 
-#include "macros.h"
+#include "main/macros.h"
 
 
 
@@ -95,12 +95,13 @@ struct wm_sampler_key {
    int sampler_count;
 
    struct wm_sampler_entry {
+      GLenum tex_target;
       GLenum wrap_r, wrap_s, wrap_t;
       float maxlod, minlod;
       float lod_bias;
       float max_aniso;
       GLenum minfilter, magfilter;
-      GLenum comparemode;
+      GLenum comparemode, comparefunc;
       dri_bo *sdc_bo;
    } sampler[BRW_MAX_TEX_UNIT];
 };
@@ -151,7 +152,7 @@ static void brw_update_sampler_state(struct wm_sampler_entry *key,
       sampler->ss0.mag_filter = BRW_MAPFILTER_ANISOTROPIC;
 
       if (key->max_aniso > 2.0) {
-        sampler->ss3.max_aniso = MAX2((key->max_aniso - 2) / 2,
+        sampler->ss3.max_aniso = MIN2((key->max_aniso - 2) / 2,
                                       BRW_ANISORATIO_16);
       }
    }
@@ -168,19 +169,30 @@ static void brw_update_sampler_state(struct wm_sampler_entry *key,
       }  
    }
 
-   sampler->ss1.r_wrap_mode = translate_wrap_mode(key->wrap_r);
-   sampler->ss1.s_wrap_mode = translate_wrap_mode(key->wrap_s);
-   sampler->ss1.t_wrap_mode = translate_wrap_mode(key->wrap_t);
-
-   /* Fulsim complains if I don't do this.  Hardware doesn't mind:
-    */
-#if 0
-   if (texObj->Target == GL_TEXTURE_CUBE_MAP_ARB) {
+   if (key->tex_target == GL_TEXTURE_CUBE_MAP &&
+       (key->minfilter != GL_NEAREST || key->magfilter != GL_NEAREST)) {
+      /* If we're using anything but nearest sampling for a cube map, we
+       * need to set this wrap mode to avoid GPU lock-ups.
+       */
       sampler->ss1.r_wrap_mode = BRW_TEXCOORDMODE_CUBE;
       sampler->ss1.s_wrap_mode = BRW_TEXCOORDMODE_CUBE;
       sampler->ss1.t_wrap_mode = BRW_TEXCOORDMODE_CUBE;
    }
-#endif
+   else if (key->tex_target == GL_TEXTURE_1D) {
+      /* There's a bug in 1D texture sampling - it actually pays
+       * attention to the wrap_t value, though it should not.
+       * Override the wrap_t value here to GL_REPEAT to keep
+       * any nonexistent border pixels from floating in.
+       */
+      sampler->ss1.r_wrap_mode = translate_wrap_mode(key->wrap_r);
+      sampler->ss1.s_wrap_mode = translate_wrap_mode(key->wrap_s);
+      sampler->ss1.t_wrap_mode = BRW_TEXCOORDMODE_WRAP;
+   }
+   else {
+      sampler->ss1.r_wrap_mode = translate_wrap_mode(key->wrap_r);
+      sampler->ss1.s_wrap_mode = translate_wrap_mode(key->wrap_s);
+      sampler->ss1.t_wrap_mode = translate_wrap_mode(key->wrap_t);
+   }
 
    /* Set shadow function: 
     */
@@ -190,7 +202,7 @@ static void brw_update_sampler_state(struct wm_sampler_entry *key,
        * shadow comparison is enabled on each/any texture unit.
        */
       sampler->ss0.shadow_function =
-        intel_translate_shadow_compare_func(key->comparemode);
+        intel_translate_shadow_compare_func(key->comparefunc);
    }
 
    /* Set LOD bias: 
@@ -215,20 +227,27 @@ static void brw_update_sampler_state(struct wm_sampler_entry *key,
    sampler->ss2.default_color_pointer = sdc_bo->offset >> 5; /* reloc */
 }
 
+
 /** Sets up the cache key for sampler state for all texture units */
 static void
 brw_wm_sampler_populate_key(struct brw_context *brw,
                            struct wm_sampler_key *key)
 {
+   GLcontext *ctx = &brw->intel.ctx;
    int unit;
 
    memset(key, 0, sizeof(*key));
 
    for (unit = 0; unit < BRW_MAX_TEX_UNIT; unit++) {
-      if (brw->attribs.Texture->Unit[unit]._ReallyEnabled) {
+      if (ctx->Texture.Unit[unit]._ReallyEnabled) {
         struct wm_sampler_entry *entry = &key->sampler[unit];
-        struct gl_texture_unit *texUnit = &brw->attribs.Texture->Unit[unit];
+        struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
         struct gl_texture_object *texObj = texUnit->_Current;
+        struct intel_texture_object *intelObj = intel_texture_object(texObj);
+        struct gl_texture_image *firstImage =
+           texObj->Image[0][intelObj->firstLevel];
+
+         entry->tex_target = texObj->Target;
 
         entry->wrap_r = texObj->WrapR;
         entry->wrap_s = texObj->WrapS;
@@ -241,10 +260,25 @@ brw_wm_sampler_populate_key(struct brw_context *brw,
         entry->minfilter = texObj->MinFilter;
         entry->magfilter = texObj->MagFilter;
         entry->comparemode = texObj->CompareMode;
+         entry->comparefunc = texObj->CompareFunc;
 
         dri_bo_unreference(brw->wm.sdc_bo[unit]);
-        brw->wm.sdc_bo[unit] = upload_default_color(brw, texObj->BorderColor);
-
+        if (firstImage->_BaseFormat == GL_DEPTH_COMPONENT) {
+           float bordercolor[4] = {
+              texObj->BorderColor[0],
+              texObj->BorderColor[0],
+              texObj->BorderColor[0],
+              texObj->BorderColor[0]
+           };
+           /* GL specs that border color for depth textures is taken from the
+            * R channel, while the hardware uses A.  Spam R into all the
+            * channels for safety.
+            */
+           brw->wm.sdc_bo[unit] = upload_default_color(brw, bordercolor);
+        } else {
+           brw->wm.sdc_bo[unit] = upload_default_color(brw,
+                                                       texObj->BorderColor);
+        }
         key->sampler_count = unit + 1;
       }
    }
@@ -256,6 +290,7 @@ brw_wm_sampler_populate_key(struct brw_context *brw,
  */
 static void upload_wm_samplers( struct brw_context *brw )
 {
+   GLcontext *ctx = &brw->intel.ctx;
    struct wm_sampler_key key;
    int i;
 
@@ -296,27 +331,19 @@ static void upload_wm_samplers( struct brw_context *brw )
                                            brw->wm.sdc_bo, key.sampler_count,
                                            &sampler, sizeof(sampler),
                                            NULL, NULL);
-   }
-}
 
-static void emit_reloc_wm_samplers(struct brw_context *brw)
-{
-   GLuint unit;
-
-   if (brw->wm.sampler_count == 0)
-      return;
+      /* Emit SDC relocations */
+      for (i = 0; i < BRW_MAX_TEX_UNIT; i++) {
+        if (!ctx->Texture.Unit[i]._ReallyEnabled)
+           continue;
 
-   /* Emit SDC relocations */
-   for (unit = 0; unit < BRW_MAX_TEX_UNIT; unit++) {
-      if (!brw->attribs.Texture->Unit[unit]._ReallyEnabled)
-        continue;
-
-      dri_emit_reloc(brw->wm.sampler_bo,
-                    DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ,
-                    0,
-                    unit * sizeof(struct brw_sampler_state) +
-                    offsetof(struct brw_sampler_state, ss2),
-                    brw->wm.sdc_bo[unit]);
+        dri_bo_emit_reloc(brw->wm.sampler_bo,
+                          I915_GEM_DOMAIN_SAMPLER, 0,
+                          0,
+                          i * sizeof(struct brw_sampler_state) +
+                          offsetof(struct brw_sampler_state, ss2),
+                          brw->wm.sdc_bo[i]);
+      }
    }
 }
 
@@ -326,8 +353,7 @@ const struct brw_tracked_state brw_wm_samplers = {
       .brw = 0,
       .cache = 0
    },
-   .update = upload_wm_samplers,
-  .emit_reloc = emit_reloc_wm_samplers,
+   .prepare = upload_wm_samplers,
 };