[965] Convert sampler state to use a cache key instead of brw_cache_data.
authorEric Anholt <eric@anholt.net>
Wed, 2 Jan 2008 19:33:55 +0000 (11:33 -0800)
committerEric Anholt <eric@anholt.net>
Wed, 2 Jan 2008 23:51:43 +0000 (15:51 -0800)
src/mesa/drivers/dri/i965/brw_context.h
src/mesa/drivers/dri/i965/brw_wm_sampler_state.c

index a5ef058..fd18fcd 100644 (file)
@@ -582,12 +582,6 @@ struct brw_context
        */
       GLuint input_size_masks[4];
 
-
-      /**
-       * Array of sampler state uploaded at sampler_bo of BRW_SAMPLER
-       * cache
-       */
-      struct brw_sampler_state sampler[BRW_MAX_TEX_UNIT];
       /** Array of surface default colors (texture border color) */
       dri_bo *sdc_bo[BRW_MAX_TEX_UNIT];
 
index d410b1e..0f59584 100644 (file)
@@ -91,16 +91,31 @@ static dri_bo *upload_default_color( struct brw_context *brw,
 }
 
 
-/*
+struct wm_sampler_key {
+   int sampler_count;
+
+   struct wm_sampler_entry {
+      GLenum wrap_r, wrap_s, wrap_t;
+      float maxlod, minlod;
+      float lod_bias;
+      float max_aniso;
+      GLenum minfilter, magfilter;
+      GLenum comparemode;
+      dri_bo *sdc_bo;
+   } sampler[BRW_MAX_TEX_UNIT];
+};
+
+/**
+ * Sets the sampler state for a single unit based off of the sampler key
+ * entry.
  */
-static void brw_update_sampler_state( struct gl_texture_unit *texUnit,
-                                     struct gl_texture_object *texObj,
-                                     dri_bo *sdc_bo,
-                                     struct brw_sampler_state *sampler)
-{   
+static void brw_update_sampler_state(struct wm_sampler_entry *key,
+                                    dri_bo *sdc_bo,
+                                    struct brw_sampler_state *sampler)
+{
    _mesa_memset(sampler, 0, sizeof(*sampler));
 
-   switch (texObj->MinFilter) {
+   switch (key->minfilter) {
    case GL_NEAREST:
       sampler->ss0.min_filter = BRW_MAPFILTER_NEAREST;
       sampler->ss0.mip_filter = BRW_MIPFILTER_NONE;
@@ -131,17 +146,17 @@ static void brw_update_sampler_state( struct gl_texture_unit *texUnit,
 
    /* Set Anisotropy: 
     */
-   if ( texObj->MaxAnisotropy > 1.0 ) {
+   if (key->max_aniso > 1.0) {
       sampler->ss0.min_filter = BRW_MAPFILTER_ANISOTROPIC; 
       sampler->ss0.mag_filter = BRW_MAPFILTER_ANISOTROPIC;
 
-      if (texObj->MaxAnisotropy > 2.0) {
-        sampler->ss3.max_aniso = MAX2((texObj->MaxAnisotropy - 2) / 2,
+      if (key->max_aniso > 2.0) {
+        sampler->ss3.max_aniso = MAX2((key->max_aniso - 2) / 2,
                                       BRW_ANISORATIO_16);
       }
    }
    else {
-      switch (texObj->MagFilter) {
+      switch (key->magfilter) {
       case GL_NEAREST:
         sampler->ss0.mag_filter = BRW_MAPFILTER_NEAREST;
         break;
@@ -153,9 +168,9 @@ static void brw_update_sampler_state( struct gl_texture_unit *texUnit,
       }  
    }
 
-   sampler->ss1.r_wrap_mode = translate_wrap_mode(texObj->WrapR);
-   sampler->ss1.s_wrap_mode = translate_wrap_mode(texObj->WrapS);
-   sampler->ss1.t_wrap_mode = translate_wrap_mode(texObj->WrapT);
+   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:
     */
@@ -169,17 +184,18 @@ static void brw_update_sampler_state( struct gl_texture_unit *texUnit,
 
    /* Set shadow function: 
     */
-   if (texObj->CompareMode == GL_COMPARE_R_TO_TEXTURE_ARB) {
+   if (key->comparemode == GL_COMPARE_R_TO_TEXTURE_ARB) {
       /* Shadowing is "enabled" by emitting a particular sampler
        * message (sample_c).  So need to recompile WM program when
        * shadow comparison is enabled on each/any texture unit.
        */
-      sampler->ss0.shadow_function = intel_translate_shadow_compare_func(texObj->CompareFunc);
+      sampler->ss0.shadow_function =
+        intel_translate_shadow_compare_func(key->comparemode);
    }
 
    /* Set LOD bias: 
     */
-   sampler->ss0.lod_bias = S_FIXED(CLAMP(texUnit->LodBias + texObj->LodBias, -16, 15), 6);
+   sampler->ss0.lod_bias = S_FIXED(CLAMP(key->lod_bias, -16, 15), 6);
 
    sampler->ss0.lod_preclamp = 1; /* OpenGL mode */
    sampler->ss0.default_color_mode = 0; /* OpenGL/DX10 mode */
@@ -193,61 +209,93 @@ static void brw_update_sampler_state( struct gl_texture_unit *texUnit,
     */
    sampler->ss0.base_level = U_FIXED(0, 1);
 
-   sampler->ss1.max_lod = U_FIXED(MIN2(MAX2(texObj->MaxLod, 0), 13), 6);
-   sampler->ss1.min_lod = U_FIXED(MIN2(MAX2(texObj->MinLod, 0), 13), 6);
+   sampler->ss1.max_lod = U_FIXED(MIN2(MAX2(key->maxlod, 0), 13), 6);
+   sampler->ss1.min_lod = U_FIXED(MIN2(MAX2(key->minlod, 0), 13), 6);
    
    sampler->ss2.default_color_pointer = sdc_bo->offset >> 5; /* reloc */
 }
 
-
-
-/* All samplers must be uploaded in a single contiguous array, which
- * complicates various things.  However, this is still too confusing -
- * FIXME: simplify all the different new texture state flags.
- */
-static void upload_wm_samplers( struct brw_context *brw )
+/** 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)
 {
-   GLuint unit;
-   GLuint sampler_count = 0;
-   dri_bo *reloc_bufs[BRW_MAX_TEX_UNIT];
+   int unit;
+
+   memset(key, 0, sizeof(*key));
 
-   /* _NEW_TEXTURE */
    for (unit = 0; unit < BRW_MAX_TEX_UNIT; unit++) {
-      if (brw->attribs.Texture->Unit[unit]._ReallyEnabled) {    
+      if (brw->attribs.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_object *texObj = texUnit->_Current;
 
-        dri_bo_unreference(brw->wm.sdc_bo[unit]);
-        brw->wm.sdc_bo[unit] = upload_default_color(brw, texObj->BorderColor);
+        entry->wrap_r = texObj->WrapR;
+        entry->wrap_s = texObj->WrapS;
+        entry->wrap_t = texObj->WrapT;
 
-        brw_update_sampler_state(texUnit,
-                                 texObj,
-                                 brw->wm.sdc_bo[unit],
-                                 &brw->wm.sampler[unit]);
+        entry->maxlod = texObj->MaxLod;
+        entry->minlod = texObj->MinLod;
+        entry->lod_bias = texUnit->LodBias + texObj->LodBias;
+        entry->max_aniso = texObj->MaxAnisotropy;
+        entry->minfilter = texObj->MinFilter;
+        entry->magfilter = texObj->MagFilter;
+        entry->comparemode = texObj->CompareMode;
 
-        sampler_count = unit + 1;
-      } else {
         dri_bo_unreference(brw->wm.sdc_bo[unit]);
-        brw->wm.sdc_bo[unit] = NULL;
+        brw->wm.sdc_bo[unit] = upload_default_color(brw, texObj->BorderColor);
+
+        key->sampler_count = unit + 1;
       }
-      reloc_bufs[unit] = brw->wm.sdc_bo[unit];
    }
-   
-   if (brw->wm.sampler_count != sampler_count) {
-      brw->wm.sampler_count = sampler_count;
+}
+
+/* All samplers must be uploaded in a single contiguous array, which
+ * complicates various things.  However, this is still too confusing -
+ * FIXME: simplify all the different new texture state flags.
+ */
+static void upload_wm_samplers( struct brw_context *brw )
+{
+   struct wm_sampler_key key;
+   int i;
+
+   brw_wm_sampler_populate_key(brw, &key);
+
+   if (brw->wm.sampler_count != key.sampler_count) {
+      brw->wm.sampler_count = key.sampler_count;
       brw->state.dirty.cache |= CACHE_NEW_SAMPLER;
    }
 
    dri_bo_unreference(brw->wm.sampler_bo);
-   if (brw->wm.sampler_count) {
-      brw->wm.sampler_bo =
-        brw_cache_data_sz(&brw->cache, BRW_SAMPLER,
-                          brw->wm.sampler,
-                          sizeof(struct brw_sampler_state) *
-                          brw->wm.sampler_count,
-                          reloc_bufs, BRW_MAX_TEX_UNIT);
-   } else {
-      brw->wm.sampler_bo = NULL;
+   brw->wm.sampler_bo = NULL;
+   if (brw->wm.sampler_count == 0)
+      return;
+
+   brw->wm.sampler_bo = brw_search_cache(&brw->cache, BRW_SAMPLER,
+                                        &key, sizeof(key),
+                                        brw->wm.sdc_bo, key.sampler_count,
+                                        NULL);
+
+   /* If we didnt find it in the cache, compute the state and put it in the
+    * cache.
+    */
+   if (brw->wm.sampler_bo == NULL) {
+      struct brw_sampler_state sampler[BRW_MAX_TEX_UNIT];
+
+      memset(sampler, 0, sizeof(sampler));
+      for (i = 0; i < key.sampler_count; i++) {
+        if (brw->wm.sdc_bo[i] == NULL)
+           continue;
+
+        brw_update_sampler_state(&key.sampler[i], brw->wm.sdc_bo[i],
+                                 &sampler[i]);
+      }
+
+      brw->wm.sampler_bo = brw_upload_cache(&brw->cache, BRW_SAMPLER,
+                                           &key, sizeof(key),
+                                           brw->wm.sdc_bo, key.sampler_count,
+                                           &sampler, sizeof(sampler),
+                                           NULL, NULL);
    }
 }