Make sampler an immutable state object.
authorZack Rusin <zack@tungstengraphics.com>
Mon, 17 Sep 2007 13:47:41 +0000 (09:47 -0400)
committerZack Rusin <zack@tungstengraphics.com>
Tue, 18 Sep 2007 10:31:22 +0000 (06:31 -0400)
Switch the sample to be an immutable state object.

18 files changed:
src/mesa/cso_cache/cso_cache.c
src/mesa/cso_cache/cso_cache.h
src/mesa/pipe/failover/fo_context.h
src/mesa/pipe/failover/fo_state.c
src/mesa/pipe/failover/fo_state_emit.c
src/mesa/pipe/i915simple/i915_context.h
src/mesa/pipe/i915simple/i915_state.c
src/mesa/pipe/i915simple/i915_state_sampler.c
src/mesa/pipe/p_context.h
src/mesa/pipe/softpipe/sp_context.c
src/mesa/pipe/softpipe/sp_context.h
src/mesa/pipe/softpipe/sp_state.h
src/mesa/pipe/softpipe/sp_state_sampler.c
src/mesa/state_tracker/st_atom_sampler.c
src/mesa/state_tracker/st_cache.c
src/mesa/state_tracker/st_cache.h
src/mesa/state_tracker/st_cb_drawpixels.c
src/mesa/state_tracker/st_context.h

index 784d1f9..61da590 100644 (file)
@@ -74,6 +74,8 @@ static struct cso_hash *_cso_hash_for_type(struct cso_cache *sc, enum cso_cache_
    switch(type) {
    case CSO_BLEND:
       hash = sc->blend_hash;
+   case CSO_SAMPLER:
+      hash = sc->sampler_hash;
    }
 
    return hash;
@@ -84,6 +86,8 @@ static int _cso_size_for_type(enum cso_cache_type type)
    switch(type) {
    case CSO_BLEND:
       return sizeof(struct pipe_blend_state);
+   case CSO_SAMPLER:
+      return sizeof(struct pipe_sampler_state);
    }
    return 0;
 }
@@ -133,6 +137,7 @@ struct cso_cache *cso_cache_create(void)
    struct cso_cache *sc = malloc(sizeof(struct cso_cache));
 
    sc->blend_hash = cso_hash_create();
+   sc->sampler_hash = cso_hash_create();
 
    return sc;
 }
@@ -140,8 +145,8 @@ struct cso_cache *cso_cache_create(void)
 void cso_cache_delete(struct cso_cache *sc)
 {
    assert(sc);
-   assert(sc->blend_hash);
    cso_hash_delete(sc->blend_hash);
+   cso_hash_delete(sc->sampler_hash);
    free(sc);
 }
 
index c022b98..05a4cfc 100644 (file)
@@ -41,10 +41,12 @@ struct cso_hash;
 
 struct cso_cache {
    struct cso_hash *blend_hash;
+   struct cso_hash *sampler_hash;
 };
 
 enum cso_cache_type {
    CSO_BLEND,
+   CSO_SAMPLER
 };
 
 unsigned cso_construct_key(void *item, int item_size);
index b065aa8..fa33619 100644 (file)
@@ -68,6 +68,7 @@ struct failover_context {
    /* The most recent drawing state as set by the driver:
     */
    const struct pipe_blend_state *blend;
+   const struct pipe_sampler_state *sampler[PIPE_MAX_SAMPLERS];
 
    struct pipe_alpha_test_state alpha_test;
    struct pipe_blend_color blend_color;
@@ -79,7 +80,6 @@ struct failover_context {
    struct pipe_shader_state vertex_shader;
    struct pipe_poly_stipple poly_stipple;
    struct pipe_scissor_state scissor;
-   struct pipe_sampler_state sampler[PIPE_MAX_SAMPLERS];
    struct pipe_setup_state setup;
    struct pipe_stencil_state stencil;
    struct pipe_mipmap_tree *texture[PIPE_MAX_SAMPLERS];
index 2357d7e..f3a99e4 100644 (file)
@@ -196,16 +196,16 @@ failover_set_stencil_state(struct pipe_context *pipe,
 
 
 static void
-failover_set_sampler_state(struct pipe_context *pipe,
+failover_bind_sampler_state(struct pipe_context *pipe,
                           unsigned unit,
                            const struct pipe_sampler_state *sampler)
 {
    struct failover_context *failover = failover_context(pipe);
 
-   failover->sampler[unit] = *sampler;
+   failover->sampler[unit] = sampler;
    failover->dirty |= FO_NEW_SAMPLER;
    failover->dirty_sampler |= (1<<unit);
-   failover->hw->set_sampler_state( failover->hw, unit, sampler );
+   failover->hw->bind_sampler_state( failover->hw, unit, sampler );
 }
 
 
@@ -267,6 +267,7 @@ void
 failover_init_state_functions( struct failover_context *failover )
 {
    failover->pipe.bind_blend_state = failover_bind_blend_state;
+   failover->pipe.bind_sampler_state = failover_bind_sampler_state;
 
    failover->pipe.set_alpha_test_state = failover_set_alpha_test_state;
    failover->pipe.set_blend_color = failover_set_blend_color;
@@ -277,7 +278,6 @@ failover_init_state_functions( struct failover_context *failover )
    failover->pipe.set_fs_state = failover_set_fs_state;
    failover->pipe.set_vs_state = failover_set_vs_state;
    failover->pipe.set_polygon_stipple = failover_set_polygon_stipple;
-   failover->pipe.set_sampler_state = failover_set_sampler_state;
    failover->pipe.set_scissor_state = failover_set_scissor_state;
    failover->pipe.set_setup_state = failover_set_setup_state;
    failover->pipe.set_stencil_state = failover_set_stencil_state;
index 77413d1..9d46267 100644 (file)
@@ -100,8 +100,8 @@ failover_state_emit( struct failover_context *failover )
    if (failover->dirty & FO_NEW_SAMPLER) {
       for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
         if (failover->dirty_sampler & (1<<i)) {
-           failover->sw->set_sampler_state( failover->sw, i, 
-                                            &failover->sampler[i] );
+           failover->sw->bind_sampler_state( failover->sw, i,
+                                              failover->sampler[i] );
         }
       }
    }
index 215c529..51baa28 100644 (file)
@@ -123,7 +123,8 @@ struct i915_context
 
    /* The most recent drawing state as set by the driver:
     */
-   const struct pipe_blend_state *blend;
+   const struct pipe_blend_state   *blend;
+   const struct pipe_sampler_state *sampler[PIPE_MAX_SAMPLERS];
 
    struct pipe_alpha_test_state alpha_test;
    struct pipe_blend_color blend_color;
@@ -135,7 +136,6 @@ struct i915_context
    struct pipe_shader_state fs;
    struct pipe_poly_stipple poly_stipple;
    struct pipe_scissor_state scissor;
-   struct pipe_sampler_state sampler[PIPE_MAX_SAMPLERS];
    struct pipe_setup_state setup;
    struct pipe_stencil_state stencil;
    struct pipe_mipmap_tree *texture[PIPE_MAX_SAMPLERS];
index 478988f..10060b4 100644 (file)
@@ -42,8 +42,6 @@ static const struct pipe_blend_state *
 i915_create_blend_state(struct pipe_context *pipe,
                         const struct pipe_blend_state *blend)
 {
-   /*struct i915_context *i915 = i915_context(pipe);*/
-
    struct pipe_blend_state *new_blend = malloc(sizeof(struct pipe_blend_state));
    memcpy(new_blend, blend, sizeof(struct pipe_blend_state));
 
@@ -62,10 +60,9 @@ static void i915_bind_blend_state( struct pipe_context *pipe,
 
 
 static void i915_delete_blend_state( struct pipe_context *pipe,
-                            const struct pipe_blend_state *blend )
+                                     const struct pipe_blend_state *blend )
 {
-   /*struct i915_context *i915 = i915_context(pipe);*/
-   free(blend);
+   free((void*)blend);
 }
 
 static void i915_set_blend_color( struct pipe_context *pipe,
@@ -78,6 +75,34 @@ static void i915_set_blend_color( struct pipe_context *pipe,
    i915->dirty |= I915_NEW_BLEND;
 }
 
+static const struct pipe_sampler_state *
+i915_create_sampler_state(struct pipe_context *pipe,
+                          const struct pipe_sampler_state *sampler)
+{
+   struct pipe_sampler_state *new_sampler = malloc(sizeof(struct pipe_sampler_state));
+   memcpy(new_sampler, sampler, sizeof(struct pipe_sampler_state));
+
+   return new_sampler;
+}
+
+static void i915_bind_sampler_state(struct pipe_context *pipe,
+                                    unsigned unit,
+                                    const struct pipe_sampler_state *sampler)
+{
+   struct i915_context *i915 = i915_context(pipe);
+
+   assert(unit < PIPE_MAX_SAMPLERS);
+   i915->sampler[unit] = sampler;
+
+   i915->dirty |= I915_NEW_SAMPLER;
+}
+
+static void i915_delete_sampler_state(struct pipe_context *pipe,
+                                      const struct pipe_sampler_state *sampler)
+{
+   free((struct pipe_sampler_state*)sampler);
+}
+
 
 /** XXX move someday?  Or consolidate all these simple state setters
  * into one file.
@@ -189,19 +214,6 @@ static void i915_set_constant_buffer(struct pipe_context *pipe,
 }
 
 
-static void i915_set_sampler_state(struct pipe_context *pipe,
-                           unsigned unit,
-                           const struct pipe_sampler_state *sampler)
-{
-   struct i915_context *i915 = i915_context(pipe);
-
-   assert(unit < PIPE_MAX_SAMPLERS);
-   i915->sampler[unit] = *sampler;
-
-   i915->dirty |= I915_NEW_SAMPLER;
-}
-
-
 static void i915_set_texture_state(struct pipe_context *pipe,
                                   unsigned unit,
                                   struct pipe_mipmap_tree *texture)
@@ -293,7 +305,6 @@ static void i915_set_vertex_buffer( struct pipe_context *pipe,
    /* pass-through to draw module */
    draw_set_vertex_buffer(i915->draw, index, buffer);
 }
-   
 
 static void i915_set_vertex_element( struct pipe_context *pipe,
                                      unsigned index,
@@ -313,6 +324,10 @@ i915_init_state_functions( struct i915_context *i915 )
    i915->pipe.bind_blend_state = i915_bind_blend_state;
    i915->pipe.delete_blend_state = i915_delete_blend_state;
 
+   i915->pipe.create_sampler_state = i915_create_sampler_state;
+   i915->pipe.bind_sampler_state = i915_bind_sampler_state;
+   i915->pipe.delete_sampler_state = i915_delete_sampler_state;
+
    i915->pipe.set_alpha_test_state = i915_set_alpha_test_state;
    i915->pipe.set_blend_color = i915_set_blend_color;
    i915->pipe.set_clip_state = i915_set_clip_state;
@@ -323,7 +338,6 @@ i915_init_state_functions( struct i915_context *i915 )
    i915->pipe.set_fs_state = i915_set_fs_state;
    i915->pipe.set_vs_state = i915_set_vs_state;
    i915->pipe.set_polygon_stipple = i915_set_polygon_stipple;
-   i915->pipe.set_sampler_state = i915_set_sampler_state;
    i915->pipe.set_scissor_state = i915_set_scissor_state;
    i915->pipe.set_setup_state = i915_set_setup_state;
    i915->pipe.set_stencil_state = i915_set_stencil_state;
index 7a595d1..419a156 100644 (file)
@@ -269,7 +269,7 @@ void i915_update_samplers( struct i915_context *i915 )
       if (i915->texture[unit]) {
         update_sampler( i915,
                          unit,
-                         i915->sampler + unit,       /* sampler state */
+                         i915->sampler[unit],       /* sampler state */
                          i915->texture[unit],        /* mipmap tree */
                         i915->current.sampler[unit] /* the result */
                          );
index b9af69f..0913e49 100644 (file)
@@ -92,6 +92,15 @@ struct pipe_context {
    void (*delete_blend_state)(struct pipe_context *,
                               const struct pipe_blend_state *);
 
+   const struct pipe_sampler_state * (*create_sampler_state)(
+      struct pipe_context *,
+      const struct pipe_sampler_state *);
+   void (*bind_sampler_state)(struct pipe_context *,
+                              unsigned unit,
+                              const struct pipe_sampler_state *);
+   void (*delete_sampler_state)(struct pipe_context *,
+                                const struct pipe_sampler_state *);
+
    void (*set_alpha_test_state)( struct pipe_context *,
                                  const struct pipe_alpha_test_state * );
 
@@ -135,10 +144,6 @@ struct pipe_context {
    void (*set_stencil_state)( struct pipe_context *,
                               const struct pipe_stencil_state * );
 
-   void (*set_sampler_state)( struct pipe_context *,
-                              unsigned unit,
-                              const struct pipe_sampler_state * );
-
    void (*set_texture_state)( struct pipe_context *,
                               unsigned unit,
                               struct pipe_mipmap_tree * );
index b9c7013..bab7985 100644 (file)
@@ -253,6 +253,9 @@ struct pipe_context *softpipe_create( struct pipe_winsys *pipe_winsys,
    softpipe->pipe.create_blend_state = softpipe_create_blend_state;
    softpipe->pipe.bind_blend_state = softpipe_bind_blend_state;
    softpipe->pipe.delete_blend_state = softpipe_delete_blend_state;
+   softpipe->pipe.create_sampler_state = softpipe_create_sampler_state;
+   softpipe->pipe.bind_sampler_state = softpipe_bind_sampler_state;
+   softpipe->pipe.delete_sampler_state = softpipe_delete_sampler_state;
 
    softpipe->pipe.set_alpha_test_state = softpipe_set_alpha_test_state;
    softpipe->pipe.set_blend_color = softpipe_set_blend_color;
@@ -265,7 +268,6 @@ struct pipe_context *softpipe_create( struct pipe_winsys *pipe_winsys,
    softpipe->pipe.set_fs_state = softpipe_set_fs_state;
    softpipe->pipe.set_vs_state = softpipe_set_vs_state;
    softpipe->pipe.set_polygon_stipple = softpipe_set_polygon_stipple;
-   softpipe->pipe.set_sampler_state = softpipe_set_sampler_state;
    softpipe->pipe.set_scissor_state = softpipe_set_scissor_state;
    softpipe->pipe.set_setup_state = softpipe_set_setup_state;
    softpipe->pipe.set_stencil_state = softpipe_set_stencil_state;
index 7fecf29..5cee1a3 100644 (file)
@@ -71,7 +71,8 @@ struct softpipe_context {
 
    /* The most recent drawing state as set by the driver:
     */
-   const struct pipe_blend_state *blend;
+   const struct pipe_blend_state   *blend;
+   const struct pipe_sampler_state *sampler[PIPE_MAX_SAMPLERS];
 
    struct pipe_alpha_test_state alpha_test;
    struct pipe_blend_color blend_color;
@@ -85,7 +86,6 @@ struct softpipe_context {
    struct pipe_shader_state vs;
    struct pipe_poly_stipple poly_stipple;
    struct pipe_scissor_state scissor;
-   struct pipe_sampler_state sampler[PIPE_MAX_SAMPLERS];
    struct pipe_setup_state setup;
    struct pipe_stencil_state stencil;
    struct pipe_mipmap_tree *texture[PIPE_MAX_SAMPLERS];
index e2b1a2a..c8c9370 100644 (file)
@@ -41,6 +41,15 @@ void softpipe_bind_blend_state(struct pipe_context *,
 void softpipe_delete_blend_state(struct pipe_context *,
                                  const struct pipe_blend_state *);
 
+const struct pipe_sampler_state *
+softpipe_create_sampler_state(struct pipe_context *,
+                              const struct pipe_sampler_state *);
+void softpipe_bind_sampler_state(struct pipe_context *,
+                                 unsigned,
+                                 const struct pipe_sampler_state *);
+void softpipe_delete_sampler_state(struct pipe_context *,
+                                   const struct pipe_sampler_state *);
+
 void softpipe_set_framebuffer_state( struct pipe_context *,
                             const struct pipe_framebuffer_state * );
 
@@ -81,10 +90,6 @@ void softpipe_set_scissor_state( struct pipe_context *,
 void softpipe_set_setup_state( struct pipe_context *,
                              const struct pipe_setup_state * );
 
-void softpipe_set_sampler_state( struct pipe_context *,
-                                 unsigned unit,
-                                 const struct pipe_sampler_state * );
-
 void softpipe_set_stencil_state( struct pipe_context *,
                                  const struct pipe_stencil_state * );
 
index 2e3d0c3..09898eb 100644 (file)
 
 
 
+const struct pipe_sampler_state *
+softpipe_create_sampler_state(struct pipe_context *pipe,
+                              const struct pipe_sampler_state *sampler)
+{
+   struct pipe_sampler_state *new_sampler = malloc(sizeof(struct pipe_sampler_state));
+   memcpy(new_sampler, sampler, sizeof(struct pipe_sampler_state));
+
+   return new_sampler;
+}
+
 void
-softpipe_set_sampler_state(struct pipe_context *pipe,
-                           unsigned unit,
-                           const struct pipe_sampler_state *sampler)
+softpipe_bind_sampler_state(struct pipe_context *pipe,
+                            unsigned unit,
+                            const struct pipe_sampler_state *sampler)
 {
    struct softpipe_context *softpipe = softpipe_context(pipe);
 
    assert(unit < PIPE_MAX_SAMPLERS);
-   softpipe->sampler[unit] = *sampler;
+   softpipe->sampler[unit] = sampler;
 
    softpipe->dirty |= SP_NEW_SAMPLER;
 }
 
 
 void
+softpipe_delete_sampler_state(struct pipe_context *pipe,
+                              const struct pipe_sampler_state *sampler)
+{
+   free((struct pipe_sampler_state*)sampler);
+}
+
+
+void
 softpipe_set_texture_state(struct pipe_context *pipe,
                            unsigned unit,
                            struct pipe_mipmap_tree *texture)
index d65565f..9a728e2 100644 (file)
@@ -33,6 +33,7 @@
  
 
 #include "st_context.h"
+#include "st_cache.h"
 #include "st_atom.h"
 #include "pipe/p_context.h"
 #include "pipe/p_defines.h"
@@ -142,10 +143,13 @@ update_samplers(struct st_context *st)
          /* XXX more sampler state here */
       }
 
-      if (memcmp(&sampler, &st->state.sampler[u], sizeof(sampler)) != 0) {
+      const struct pipe_sampler_state *cached_sampler =
+         st_cached_sampler_state(st, &sampler);
+
+      if (cached_sampler == st->state.sampler[u]) {
          /* state has changed */
-         st->state.sampler[u] = sampler;
-         st->pipe->set_sampler_state(st->pipe, u, &sampler);
+         st->state.sampler[u] = cached_sampler;
+         st->pipe->bind_sampler_state(st->pipe, u, cached_sampler);
       }
    }
 }
index 0205b1c..99fb45f 100644 (file)
@@ -59,3 +59,20 @@ struct pipe_blend_state * st_cached_blend_state(
    }
    return (struct pipe_blend_state*)(cso_hash_iter_data(iter));
 }
+
+struct pipe_sampler_state * st_cached_sampler_state(
+   struct st_context *st,
+   const struct pipe_sampler_state *sampler)
+{
+   unsigned hash_key = cso_construct_key((void*)sampler, sizeof(struct pipe_sampler_state));
+   struct cso_hash_iter iter = cso_find_state_template(st->cache,
+                                                       hash_key, CSO_SAMPLER,
+                                                       (void*)sampler);
+   if (cso_hash_iter_is_null(iter)) {
+      const struct pipe_sampler_state *created_state = st->pipe->create_sampler_state(
+         st->pipe, sampler);
+      iter = cso_insert_state(st->cache, hash_key, CSO_SAMPLER,
+                              (void*)created_state);
+   }
+   return (struct pipe_sampler_state*)(cso_hash_iter_data(iter));
+}
index 29b1d00..9275851 100644 (file)
 #define ST_CACHE_H
 
 struct pipe_blend_state;
+struct pipe_sampler_state;
 struct st_context;
 
 struct pipe_blend_state * st_cached_blend_state(
    struct st_context *st,
    const struct pipe_blend_state *blend);
 
+struct pipe_sampler_state * st_cached_sampler_state(
+   struct st_context *st,
+   const struct pipe_sampler_state *sampler);
+
+
 #endif
index c2d231c..31a37e5 100644 (file)
@@ -34,6 +34,7 @@
 
 #include "st_context.h"
 #include "st_atom.h"
+#include "st_cache.h"
 #include "st_draw.h"
 #include "st_program.h"
 #include "st_cb_drawpixels.h"
@@ -359,7 +360,8 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
       sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST;
       sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
       sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
-      pipe->set_sampler_state(pipe, unit, &sampler);
+      const struct pipe_sampler_state *state = st_cached_sampler_state(ctx->st, &sampler);
+      pipe->bind_sampler_state(pipe, unit, state);
    }
 
    /* viewport state: viewport matching window dims */
@@ -402,7 +404,7 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
    pipe->set_fs_state(pipe, &ctx->st->state.fs);
    pipe->set_vs_state(pipe, &ctx->st->state.vs);
    pipe->set_texture_state(pipe, unit, ctx->st->state.texture[unit]);
-   pipe->set_sampler_state(pipe, unit, &ctx->st->state.sampler[unit]);
+   pipe->bind_sampler_state(pipe, unit, ctx->st->state.sampler[unit]);
    pipe->set_viewport_state(pipe, &ctx->st->state.viewport);
 
    free_mipmap_tree(pipe, mt);
index bd2efdb..13526ff 100644 (file)
@@ -74,7 +74,8 @@ struct st_context
     * though, we just shove random objects across the interface.  
     */
    struct {
-      const struct pipe_blend_state  *blend;
+      const struct pipe_blend_state   *blend;
+      const struct pipe_sampler_state *sampler[PIPE_MAX_SAMPLERS];
 
       struct pipe_alpha_test_state  alpha_test;
       struct pipe_blend_color  blend_color;
@@ -86,7 +87,6 @@ struct st_context
       struct pipe_framebuffer_state framebuffer;
       struct pipe_mipmap_tree *texture[PIPE_MAX_SAMPLERS];
       struct pipe_poly_stipple poly_stipple;
-      struct pipe_sampler_state sampler[PIPE_MAX_SAMPLERS];
       struct pipe_scissor_state scissor;
       struct pipe_setup_state  setup;
       struct pipe_shader_state fs;