Redo the cso cache to map driver data in a lot more pleasing way.
authorZack Rusin <zack@tungstengraphics.com>
Wed, 19 Sep 2007 16:35:29 +0000 (12:35 -0400)
committerZack Rusin <zack@tungstengraphics.com>
Wed, 19 Sep 2007 17:12:09 +0000 (13:12 -0400)
Drivers can now create whatever they want from the state template. We
use cso_state object to store the template (necessary during lookups),
and the driver data. Convert blend state to the new semantics.

14 files changed:
src/mesa/pipe/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_state.c
src/mesa/pipe/p_context.h
src/mesa/pipe/softpipe/sp_state.h
src/mesa/pipe/softpipe/sp_state_blend.c
src/mesa/state_tracker/st_atom_blend.c
src/mesa/state_tracker/st_cache.c
src/mesa/state_tracker/st_cache.h
src/mesa/state_tracker/st_cb_clear.c
src/mesa/state_tracker/st_cb_drawpixels.c
src/mesa/state_tracker/st_context.h

index 352e1a6..7ac5908 100644 (file)
@@ -48,6 +48,11 @@ struct cso_cache {
    struct cso_hash *vs_hash;
 };
 
+struct cso_blend {
+   struct pipe_blend_state state;
+   void   *data;
+};
+
 enum cso_cache_type {
    CSO_BLEND,
    CSO_SAMPLER,
index 9556a17..ea7fb10 100644 (file)
 #define FO_HW 0
 #define FO_SW 1
 
+struct fo_state {
+   void *sw_state;
+   void *hw_state;
+};
 struct failover_context {     
    struct pipe_context pipe;  /**< base class */
 
 
    /* The most recent drawing state as set by the driver:
     */
-   const struct pipe_blend_state         *blend;
+   const struct fo_state                 *blend;
    const struct pipe_sampler_state       *sampler[PIPE_MAX_SAMPLERS];
    const struct pipe_depth_stencil_state *depth_stencil;
    const struct pipe_rasterizer_state    *rasterizer;
index 04ebd33..ba110a6 100644 (file)
@@ -57,17 +57,43 @@ failover_set_alpha_test_state(struct pipe_context *pipe,
 }
 
 
-static void 
+static void *
+failover_create_blend_state( struct pipe_context *pipe,
+                             const struct pipe_blend_state *blend )
+{
+   struct fo_state *state = malloc(sizeof(struct fo_state));
+   struct failover_context *failover = failover_context(pipe);
+
+   state->sw_state = failover->sw->create_blend_state(pipe, blend);
+   state->hw_state = failover->hw->create_blend_state(pipe, blend);
+
+   return state;
+}
+
+static void
 failover_bind_blend_state( struct pipe_context *pipe,
-                         const struct pipe_blend_state *blend )
+                           void *blend )
 {
    struct failover_context *failover = failover_context(pipe);
 
-   failover->blend = blend;
+   failover->blend = (struct fo_state *)blend;
    failover->dirty |= FO_NEW_BLEND;
    failover->hw->bind_blend_state( failover->hw, blend );
 }
 
+static void
+failover_delete_blend_state( struct pipe_context *pipe,
+                             void *blend )
+{
+   struct fo_state *state = (struct fo_state*)blend;
+   struct failover_context *failover = failover_context(pipe);
+
+   failover->sw->delete_blend_state(pipe, state->sw_state);
+   failover->hw->delete_blend_state(pipe, state->hw_state);
+   state->sw_state = 0;
+   state->hw_state = 0;
+   free(state);
+}
 
 static void 
 failover_set_blend_color( struct pipe_context *pipe,
@@ -253,7 +279,9 @@ failover_set_vertex_element(struct pipe_context *pipe,
 void
 failover_init_state_functions( struct failover_context *failover )
 {
+   failover->pipe.create_blend_state = failover_create_blend_state;
    failover->pipe.bind_blend_state = failover_bind_blend_state;
+   failover->pipe.delete_blend_state = failover_delete_blend_state;
    failover->pipe.bind_sampler_state = failover_bind_sampler_state;
    failover->pipe.bind_depth_stencil_state = failover_bind_depth_stencil_state;
    failover->pipe.bind_rasterizer_state = failover_bind_rasterizer_state;
index 9d30407..72697c0 100644 (file)
@@ -59,7 +59,8 @@ failover_state_emit( struct failover_context *failover )
       failover->sw->set_alpha_test_state( failover->sw, &failover->alpha_test );
 
    if (failover->dirty & FO_NEW_BLEND)
-      failover->sw->bind_blend_state( failover->sw, failover->blend );
+      failover->sw->bind_blend_state( failover->sw,
+                                      failover->blend->sw_state );
 
    if (failover->dirty & FO_NEW_BLEND_COLOR)
       failover->sw->set_blend_color( failover->sw, &failover->blend_color );
index aaf2ccf..86c1089 100644 (file)
@@ -38,7 +38,7 @@
 /* None of this state is actually used for anything yet.
  */
 
-static const struct pipe_blend_state *
+static void *
 i915_create_blend_state(struct pipe_context *pipe,
                         const struct pipe_blend_state *blend)
 {
@@ -49,20 +49,20 @@ i915_create_blend_state(struct pipe_context *pipe,
 }
 
 static void i915_bind_blend_state( struct pipe_context *pipe,
-                            const struct pipe_blend_state *blend )
+                                   void *blend )
 {
    struct i915_context *i915 = i915_context(pipe);
 
-   i915->blend = blend;
+   i915->blend = (struct pipe_blend_state *)blend;
 
    i915->dirty |= I915_NEW_BLEND;
 }
 
 
 static void i915_delete_blend_state( struct pipe_context *pipe,
-                                     const struct pipe_blend_state *blend )
+                                     void *blend )
 {
-   free((void*)blend);
+   free(blend);
 }
 
 static void i915_set_blend_color( struct pipe_context *pipe,
index 5766b2b..adca661 100644 (file)
@@ -85,12 +85,10 @@ struct pipe_context {
    /*
     * State functions
     */
-   const struct pipe_blend_state * (*create_blend_state)(struct pipe_context *,
-                                                         const struct pipe_blend_state *);
-   void (*bind_blend_state)(struct pipe_context *,
-                            const struct pipe_blend_state *);
-   void (*delete_blend_state)(struct pipe_context *,
-                              const struct pipe_blend_state *);
+   void * (*create_blend_state)(struct pipe_context *,
+                                const struct pipe_blend_state *);
+   void (*bind_blend_state)(struct pipe_context *, void *);
+   void (*delete_blend_state)(struct pipe_context *, void  *);
 
    const struct pipe_sampler_state * (*create_sampler_state)(
       struct pipe_context *,
index 04cc743..8e7776a 100644 (file)
 
 #include "pipe/p_state.h"
 
-const struct pipe_blend_state *
+void *
 softpipe_create_blend_state(struct pipe_context *,
                             const struct pipe_blend_state *);
 void softpipe_bind_blend_state(struct pipe_context *,
-                               const struct pipe_blend_state *);
+                               void *);
 void softpipe_delete_blend_state(struct pipe_context *,
-                                 const struct pipe_blend_state *);
+                                 void *);
 
 const struct pipe_sampler_state *
 softpipe_create_sampler_state(struct pipe_context *,
index 83f456d..7a94e82 100644 (file)
@@ -30,7 +30,7 @@
 #include "sp_context.h"
 #include "sp_state.h"
 
-const struct pipe_blend_state *
+void *
 softpipe_create_blend_state(struct pipe_context *pipe,
                             const struct pipe_blend_state *blend)
 {
@@ -41,19 +41,19 @@ softpipe_create_blend_state(struct pipe_context *pipe,
 }
 
 void softpipe_bind_blend_state( struct pipe_context *pipe,
-                            const struct pipe_blend_state *blend )
+                                void *blend )
 {
    struct softpipe_context *softpipe = softpipe_context(pipe);
 
-   softpipe->blend = blend;
+   softpipe->blend = (const struct pipe_blend_state *)blend;
 
    softpipe->dirty |= SP_NEW_BLEND;
 }
 
 void softpipe_delete_blend_state(struct pipe_context *pipe,
-                                 const struct pipe_blend_state *blend )
+                                 void *blend )
 {
-   free((struct pipe_blend_state *)blend);
+   free(blend);
 }
 
 
index d94beb6..d5eadc3 100644 (file)
@@ -211,14 +211,14 @@ update_blend( struct st_context *st )
    if (st->ctx->Color.DitherFlag)
       blend.dither = 1;
 
-   struct pipe_blend_state *real_blend =
+   const struct cso_blend *cso =
       st_cached_blend_state(st, &blend);
 
-   if (st->state.blend != real_blend) {
+   if (st->state.blend != cso) {
       /* state has changed */
-      st->state.blend = real_blend;
+      st->state.blend = cso;
       /* bind new state */
-      st->pipe->bind_blend_state(st->pipe, real_blend);
+      st->pipe->bind_blend_state(st->pipe, cso->data);
    }
 
    if (memcmp(st->ctx->Color.BlendColor, &st->state.blend_color, 4 * sizeof(GLfloat)) != 0) {
index d84a396..bd6c63b 100644 (file)
  * in the cache or it will create a new state state from the given
  * template, will insert it in the cache and return it.
  */
-struct pipe_blend_state * st_cached_blend_state(
-   struct st_context *st,
-   const struct pipe_blend_state *blend)
+const struct cso_blend * st_cached_blend_state(struct st_context *st,
+                                               const struct pipe_blend_state *templ)
 {
-   unsigned hash_key = cso_construct_key((void*)blend, sizeof(struct pipe_blend_state));
+   unsigned hash_key = cso_construct_key((void*)templ, sizeof(struct pipe_blend_state));
    struct cso_hash_iter iter = cso_find_state_template(st->cache,
                                                        hash_key, CSO_BLEND,
-                                                       (void*)blend);
+                                                       (void*)templ);
    if (cso_hash_iter_is_null(iter)) {
-      const struct pipe_blend_state *created_state = st->pipe->create_blend_state(
-         st->pipe, blend);
-      iter = cso_insert_state(st->cache, hash_key, CSO_BLEND,
-                              (void*)created_state);
+      struct cso_blend *cso = malloc(sizeof(struct cso_blend));
+      memcpy(&cso->state, templ, sizeof(struct pipe_blend_state));
+      cso->data = st->pipe->create_blend_state(st->pipe, templ);
+      if (!cso->data)
+         cso->data = &cso->state;
+      iter = cso_insert_state(st->cache, hash_key, CSO_BLEND, cso);
    }
-   return (struct pipe_blend_state*)(cso_hash_iter_data(iter));
+   return ((struct cso_blend *)cso_hash_iter_data(iter));
 }
 
 struct pipe_sampler_state * st_cached_sampler_state(
index bcbe19b..fb0ff0d 100644 (file)
 #ifndef ST_CACHE_H
 #define ST_CACHE_H
 
+#include "pipe/cso_cache/cso_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);
+const struct cso_blend *
+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);
+struct pipe_sampler_state *
+st_cached_sampler_state(struct st_context *st,
+                        const struct pipe_sampler_state *sampler);
 
 struct pipe_depth_stencil_state *st_cached_depth_stencil_state(
    struct st_context *st,
index 7c669ab..3a69917 100644 (file)
@@ -298,7 +298,7 @@ clear_with_quad(GLcontext *ctx,
    /* blend state: RGBA masking */
    {
       struct pipe_blend_state blend;
-      const struct pipe_blend_state *state;
+      const struct cso_blend *cso;
       memset(&blend, 0, sizeof(blend));
       if (color) {
          if (ctx->Color.ColorMask[0])
@@ -312,8 +312,8 @@ clear_with_quad(GLcontext *ctx,
          if (st->ctx->Color.DitherFlag)
             blend.dither = 1;
       }
-      state = st_cached_blend_state(st, &blend);
-      pipe->bind_blend_state(pipe, state);
+      cso = st_cached_blend_state(st, &blend);
+      pipe->bind_blend_state(pipe, cso->data);
    }
 
    /* depth_stencil state: always pass/set to ref value */
@@ -411,7 +411,7 @@ clear_with_quad(GLcontext *ctx,
 
    /* Restore pipe state */
    pipe->set_alpha_test_state(pipe, &st->state.alpha_test);
-   pipe->bind_blend_state(pipe, st->state.blend);
+   pipe->bind_blend_state(pipe, st->state.blend->data);
    pipe->bind_depth_stencil_state(pipe, st->state.depth_stencil);
    pipe->bind_fs_state(pipe, st->state.fs);
    pipe->bind_vs_state(pipe, st->state.vs);
index 67de781..4a554cd 100644 (file)
@@ -493,8 +493,8 @@ static GLboolean
 any_fragment_ops(const struct st_context *st)
 {
    if (st->state.alpha_test.enabled ||
-       st->state.blend->blend_enable ||
-       st->state.blend->logicop_enable ||
+       st->state.blend->state.blend_enable ||
+       st->state.blend->state.logicop_enable ||
        st->state.depth_stencil->depth.enabled)
       /* XXX more checks */
       return GL_TRUE;
index a8ae5d9..966574b 100644 (file)
@@ -40,6 +40,7 @@ struct st_fragment_program;
 struct draw_context;
 struct draw_stage;
 struct cso_cache;
+struct cso_blend;
 
 #define ST_NEW_MESA                    0x1 /* Mesa state has changed */
 #define ST_NEW_FRAGMENT_PROGRAM        0x2
@@ -74,7 +75,7 @@ struct st_context
     * though, we just shove random objects across the interface.  
     */
    struct {
-      const struct pipe_blend_state   *blend;
+      const struct cso_blend *blend;
       const struct pipe_sampler_state *sampler[PIPE_MAX_SAMPLERS];
       const struct pipe_depth_stencil_state *depth_stencil;
       const struct pipe_rasterizer_state  *rasterizer;