Combing depth and stencil objects and making them immutable.
authorZack Rusin <zack@tungstengraphics.com>
Mon, 17 Sep 2007 15:55:18 +0000 (11:55 -0400)
committerZack Rusin <zack@tungstengraphics.com>
Tue, 18 Sep 2007 10:31:22 +0000 (06:31 -0400)
Converting depth and stencil objects into a single state object
(d3d10 like) and making it immutable.

30 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_dynamic.c
src/mesa/pipe/i915simple/i915_state_immediate.c
src/mesa/pipe/p_context.h
src/mesa/pipe/p_state.h
src/mesa/pipe/softpipe/sp_context.c
src/mesa/pipe/softpipe/sp_context.h
src/mesa/pipe/softpipe/sp_quad.c
src/mesa/pipe/softpipe/sp_quad_depth_test.c
src/mesa/pipe/softpipe/sp_quad_fs.c
src/mesa/pipe/softpipe/sp_quad_stencil.c
src/mesa/pipe/softpipe/sp_state.h
src/mesa/pipe/softpipe/sp_state_blend.c
src/mesa/pipe/softpipe/sp_state_derived.c
src/mesa/sources
src/mesa/state_tracker/st_atom.c
src/mesa/state_tracker/st_atom.h
src/mesa/state_tracker/st_atom_depth.c
src/mesa/state_tracker/st_atom_stencil.c [deleted file]
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 61da590..a473039 100644 (file)
@@ -76,6 +76,8 @@ static struct cso_hash *_cso_hash_for_type(struct cso_cache *sc, enum cso_cache_
       hash = sc->blend_hash;
    case CSO_SAMPLER:
       hash = sc->sampler_hash;
+   case CSO_DEPTH_STENCIL:
+      hash = sc->depth_stencil_hash;
    }
 
    return hash;
@@ -88,6 +90,8 @@ static int _cso_size_for_type(enum cso_cache_type type)
       return sizeof(struct pipe_blend_state);
    case CSO_SAMPLER:
       return sizeof(struct pipe_sampler_state);
+   case CSO_DEPTH_STENCIL:
+      return sizeof(struct pipe_depth_stencil_state);
    }
    return 0;
 }
@@ -138,6 +142,7 @@ struct cso_cache *cso_cache_create(void)
 
    sc->blend_hash = cso_hash_create();
    sc->sampler_hash = cso_hash_create();
+   sc->depth_stencil_hash = cso_hash_create();
 
    return sc;
 }
@@ -147,6 +152,7 @@ void cso_cache_delete(struct cso_cache *sc)
    assert(sc);
    cso_hash_delete(sc->blend_hash);
    cso_hash_delete(sc->sampler_hash);
+   cso_hash_delete(sc->depth_stencil_hash);
    free(sc);
 }
 
index 05a4cfc..c340cf7 100644 (file)
@@ -42,11 +42,13 @@ struct cso_hash;
 struct cso_cache {
    struct cso_hash *blend_hash;
    struct cso_hash *sampler_hash;
+   struct cso_hash *depth_stencil_hash;
 };
 
 enum cso_cache_type {
    CSO_BLEND,
-   CSO_SAMPLER
+   CSO_SAMPLER,
+   CSO_DEPTH_STENCIL
 };
 
 unsigned cso_construct_key(void *item, int item_size);
index fa33619..63ec723 100644 (file)
 
 
 
-#define FO_NEW_VIEWPORT      0x1
-#define FO_NEW_SETUP         0x2
-#define FO_NEW_FRAGMENT_SHADER            0x4
-#define FO_NEW_BLEND         0x8
-#define FO_NEW_CLIP         0x10
-#define FO_NEW_SCISSOR      0x20
-#define FO_NEW_STIPPLE      0x40
-#define FO_NEW_FRAMEBUFFER  0x80
-#define FO_NEW_ALPHA_TEST  0x100
-#define FO_NEW_DEPTH_TEST  0x200
-#define FO_NEW_SAMPLER     0x400
-#define FO_NEW_TEXTURE     0x800
-#define FO_NEW_STENCIL    0x1000
-#define FO_NEW_VERTEX     0x2000
-#define FO_NEW_VERTEX_SHADER        0x4000
-#define FO_NEW_BLEND_COLOR    0x8000
-#define FO_NEW_CLEAR_COLOR    0x10000
-#define FO_NEW_VERTEX_BUFFER  0x20000
-#define FO_NEW_VERTEX_ELEMENT 0x40000
+#define FO_NEW_VIEWPORT        0x1
+#define FO_NEW_SETUP           0x2
+#define FO_NEW_FRAGMENT_SHADER 0x4
+#define FO_NEW_BLEND           0x8
+#define FO_NEW_CLIP            0x10
+#define FO_NEW_SCISSOR         0x20
+#define FO_NEW_STIPPLE         0x40
+#define FO_NEW_FRAMEBUFFER     0x80
+#define FO_NEW_ALPHA_TEST      0x100
+#define FO_NEW_DEPTH_STENCIL   0x200
+#define FO_NEW_SAMPLER         0x400
+#define FO_NEW_TEXTURE         0x800
+#define FO_NEW_VERTEX          0x2000
+#define FO_NEW_VERTEX_SHADER   0x4000
+#define FO_NEW_BLEND_COLOR     0x8000
+#define FO_NEW_CLEAR_COLOR     0x10000
+#define FO_NEW_VERTEX_BUFFER   0x20000
+#define FO_NEW_VERTEX_ELEMENT  0x40000
 
 
 
@@ -69,19 +68,18 @@ struct failover_context {
     */
    const struct pipe_blend_state *blend;
    const struct pipe_sampler_state *sampler[PIPE_MAX_SAMPLERS];
+   const struct pipe_depth_stencil_state *depth_stencil;
 
    struct pipe_alpha_test_state alpha_test;
    struct pipe_blend_color blend_color;
    struct pipe_clear_color_state clear_color;
    struct pipe_clip_state clip;
-   struct pipe_depth_state depth_test;
    struct pipe_framebuffer_state framebuffer;
    struct pipe_shader_state fragment_shader;
    struct pipe_shader_state vertex_shader;
    struct pipe_poly_stipple poly_stipple;
    struct pipe_scissor_state scissor;
    struct pipe_setup_state setup;
-   struct pipe_stencil_state stencil;
    struct pipe_mipmap_tree *texture[PIPE_MAX_SAMPLERS];
    struct pipe_viewport_state viewport;
    struct pipe_vertex_buffer vertex_buffer[PIPE_ATTRIB_MAX];
index f3a99e4..43b9757 100644 (file)
@@ -103,14 +103,14 @@ failover_set_clear_color_state( struct pipe_context *pipe,
 }
 
 static void
-failover_set_depth_test_state(struct pipe_context *pipe,
-                              const struct pipe_depth_state *depth)
+failover_bind_depth_stencil_state(struct pipe_context *pipe,
+                          const struct pipe_depth_stencil_state *depth_stencil)
 {
    struct failover_context *failover = failover_context(pipe);
 
-   failover->depth_test = *depth;
-   failover->dirty |= FO_NEW_DEPTH_TEST;
-   failover->hw->set_depth_state( failover->hw, depth );
+   failover->depth_stencil = depth_stencil;
+   failover->dirty |= FO_NEW_DEPTH_STENCIL;
+   failover->hw->bind_depth_stencil_state( failover->hw, depth_stencil );
 }
 
 static void
@@ -184,18 +184,6 @@ failover_set_scissor_state( struct pipe_context *pipe,
 }
 
 static void
-failover_set_stencil_state(struct pipe_context *pipe,
-                           const struct pipe_stencil_state *stencil)
-{
-   struct failover_context *failover = failover_context(pipe);
-
-   failover->stencil = *stencil;
-   failover->dirty |= FO_NEW_STENCIL;
-   failover->hw->set_stencil_state( failover->hw, stencil );
-}
-
-
-static void
 failover_bind_sampler_state(struct pipe_context *pipe,
                           unsigned unit,
                            const struct pipe_sampler_state *sampler)
@@ -268,19 +256,18 @@ 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.bind_depth_stencil_state = failover_bind_depth_stencil_state;
 
    failover->pipe.set_alpha_test_state = failover_set_alpha_test_state;
    failover->pipe.set_blend_color = failover_set_blend_color;
    failover->pipe.set_clip_state = failover_set_clip_state;
    failover->pipe.set_clear_color_state = failover_set_clear_color_state;
-   failover->pipe.set_depth_state = failover_set_depth_test_state;
    failover->pipe.set_framebuffer_state = failover_set_framebuffer_state;
    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_scissor_state = failover_set_scissor_state;
    failover->pipe.set_setup_state = failover_set_setup_state;
-   failover->pipe.set_stencil_state = failover_set_stencil_state;
    failover->pipe.set_texture_state = failover_set_texture_state;
    failover->pipe.set_viewport_state = failover_set_viewport_state;
    failover->pipe.set_vertex_buffer = failover_set_vertex_buffer;
index 9d46267..3a1865d 100644 (file)
@@ -70,8 +70,8 @@ failover_state_emit( struct failover_context *failover )
    if (failover->dirty & FO_NEW_CLEAR_COLOR)
       failover->sw->set_clear_color_state( failover->sw, &failover->clear_color );
 
-   if (failover->dirty & FO_NEW_DEPTH_TEST)
-      failover->sw->set_depth_state( failover->sw, &failover->depth_test );
+   if (failover->dirty & FO_NEW_DEPTH_STENCIL)
+      failover->sw->bind_depth_stencil_state( failover->sw, failover->depth_stencil );
 
    if (failover->dirty & FO_NEW_FRAMEBUFFER)
       failover->sw->set_framebuffer_state( failover->sw, &failover->framebuffer );
@@ -91,9 +91,6 @@ failover_state_emit( struct failover_context *failover )
    if (failover->dirty & FO_NEW_SCISSOR)
       failover->sw->set_scissor_state( failover->sw, &failover->scissor );
 
-   if (failover->dirty & FO_NEW_STENCIL)
-      failover->sw->set_stencil_state( failover->sw, &failover->stencil );
-
    if (failover->dirty & FO_NEW_VIEWPORT)
       failover->sw->set_viewport_state( failover->sw, &failover->viewport );
 
index 51baa28..518f780 100644 (file)
@@ -125,19 +125,18 @@ struct i915_context
     */
    const struct pipe_blend_state   *blend;
    const struct pipe_sampler_state *sampler[PIPE_MAX_SAMPLERS];
+   const struct pipe_depth_stencil_state   *depth_stencil;
 
    struct pipe_alpha_test_state alpha_test;
    struct pipe_blend_color blend_color;
    struct pipe_clear_color_state clear_color;
    struct pipe_clip_state clip;
    struct pipe_constant_buffer constants[PIPE_SHADER_TYPES];
-   struct pipe_depth_state depth_test;
    struct pipe_framebuffer_state framebuffer;
    struct pipe_shader_state fs;
    struct pipe_poly_stipple poly_stipple;
    struct pipe_scissor_state scissor;
    struct pipe_setup_state setup;
-   struct pipe_stencil_state stencil;
    struct pipe_mipmap_tree *texture[PIPE_MAX_SAMPLERS];
    struct pipe_viewport_state viewport;
    struct pipe_vertex_buffer vertex_buffer[PIPE_ATTRIB_MAX];
@@ -163,16 +162,15 @@ struct i915_context
 #define I915_NEW_SETUP         0x2
 #define I915_NEW_FS            0x4
 #define I915_NEW_BLEND         0x8
-#define I915_NEW_CLIP         0x10
-#define I915_NEW_SCISSOR      0x20
-#define I915_NEW_STIPPLE      0x40
-#define I915_NEW_FRAMEBUFFER  0x80
-#define I915_NEW_ALPHA_TEST  0x100
-#define I915_NEW_DEPTH_TEST  0x200
-#define I915_NEW_SAMPLER     0x400
-#define I915_NEW_TEXTURE     0x800
-#define I915_NEW_STENCIL    0x1000
-#define I915_NEW_CONSTANTS  0x2000
+#define I915_NEW_CLIP          0x10
+#define I915_NEW_SCISSOR       0x20
+#define I915_NEW_STIPPLE       0x40
+#define I915_NEW_FRAMEBUFFER   0x80
+#define I915_NEW_ALPHA_TEST    0x100
+#define I915_NEW_DEPTH_STENCIL 0x200
+#define I915_NEW_SAMPLER       0x400
+#define I915_NEW_TEXTURE       0x800
+#define I915_NEW_CONSTANTS     0x1000
 
 
 /* Driver's internally generated state flags:
index 10060b4..5ac2e27 100644 (file)
@@ -107,38 +107,44 @@ static void i915_delete_sampler_state(struct pipe_context *pipe,
 /** XXX move someday?  Or consolidate all these simple state setters
  * into one file.
  */
-static void i915_set_depth_test_state(struct pipe_context *pipe,
-                              const struct pipe_depth_state *depth)
-{
-   struct i915_context *i915 = i915_context(pipe);
 
-   i915->depth_test = *depth;
+static const struct pipe_depth_stencil_state *
+i915_create_depth_stencil_state(struct pipe_context *pipe,
+                           const struct pipe_depth_stencil_state *depth_stencil)
+{
+   struct pipe_depth_stencil_state *new_ds =
+      malloc(sizeof(struct pipe_depth_stencil_state));
+   memcpy(new_ds, depth_stencil, sizeof(struct pipe_depth_stencil_state));
 
-   i915->dirty |= I915_NEW_DEPTH_TEST;
+   return new_ds;
 }
 
-static void i915_set_alpha_test_state(struct pipe_context *pipe,
-                              const struct pipe_alpha_test_state *alpha)
+static void i915_bind_depth_stencil_state(struct pipe_context *pipe,
+                           const struct pipe_depth_stencil_state *depth_stencil)
 {
    struct i915_context *i915 = i915_context(pipe);
 
-   i915->alpha_test = *alpha;
+   i915->depth_stencil = depth_stencil;
 
-   i915->dirty |= I915_NEW_ALPHA_TEST;
+   i915->dirty |= I915_NEW_DEPTH_STENCIL;
 }
 
-static void i915_set_stencil_state(struct pipe_context *pipe,
-                           const struct pipe_stencil_state *stencil)
+static void i915_delete_depth_stencil_state(struct pipe_context *pipe,
+                           const struct pipe_depth_stencil_state *depth_stencil)
+{
+   free((struct pipe_depth_stencil_state *)depth_stencil);
+}
+
+static void i915_set_alpha_test_state(struct pipe_context *pipe,
+                              const struct pipe_alpha_test_state *alpha)
 {
    struct i915_context *i915 = i915_context(pipe);
 
-   i915->stencil = *stencil;
+   i915->alpha_test = *alpha;
 
-   i915->dirty |= I915_NEW_STENCIL;
+   i915->dirty |= I915_NEW_ALPHA_TEST;
 }
 
-
-
 static void i915_set_scissor_state( struct pipe_context *pipe,
                                  const struct pipe_scissor_state *scissor )
 {
@@ -328,19 +334,21 @@ i915_init_state_functions( struct i915_context *i915 )
    i915->pipe.bind_sampler_state = i915_bind_sampler_state;
    i915->pipe.delete_sampler_state = i915_delete_sampler_state;
 
+   i915->pipe.create_depth_stencil_state = i915_create_depth_stencil_state;
+   i915->pipe.bind_depth_stencil_state = i915_bind_depth_stencil_state;
+   i915->pipe.delete_depth_stencil_state = i915_delete_depth_stencil_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;
    i915->pipe.set_clear_color_state = i915_set_clear_color_state;
    i915->pipe.set_constant_buffer = i915_set_constant_buffer;
-   i915->pipe.set_depth_state = i915_set_depth_test_state;
    i915->pipe.set_framebuffer_state = i915_set_framebuffer_state;
    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_scissor_state = i915_set_scissor_state;
    i915->pipe.set_setup_state = i915_set_setup_state;
-   i915->pipe.set_stencil_state = i915_set_stencil_state;
    i915->pipe.set_texture_state = i915_set_texture_state;
    i915->pipe.set_viewport_state = i915_set_viewport_state;
    i915->pipe.set_vertex_buffer = i915_set_vertex_buffer;
index 49a30fa..9140eee 100644 (file)
@@ -68,8 +68,8 @@ static void upload_MODES4( struct i915_context *i915 )
 
    /* I915_NEW_STENCIL */
    {
-      int testmask = i915->stencil.value_mask[0] & 0xff;
-      int writemask = i915->stencil.write_mask[0] & 0xff;
+      int testmask = i915->depth_stencil->stencil.value_mask[0] & 0xff;
+      int writemask = i915->depth_stencil->stencil.write_mask[0] & 0xff;
 
       modes4 |= (_3DSTATE_MODES_4_CMD |
                 ENABLE_STENCIL_TEST_MASK |
@@ -94,7 +94,7 @@ static void upload_MODES4( struct i915_context *i915 )
 }
 
 const struct i915_tracked_state i915_upload_MODES4 = {
-   .dirty = I915_NEW_BLEND | I915_NEW_STENCIL,
+   .dirty = I915_NEW_BLEND | I915_NEW_DEPTH_STENCIL,
    .update = upload_MODES4
 };
 
@@ -112,14 +112,14 @@ static void upload_BFO( struct i915_context *i915 )
 
    /* _NEW_STENCIL 
     */
-   if (i915->stencil.back_enabled) {
-      int test  = i915_translate_compare_func(i915->stencil.back_func);
-      int fop   = i915_translate_stencil_op(i915->stencil.back_fail_op);
-      int dfop  = i915_translate_stencil_op(i915->stencil.back_zfail_op);
-      int dpop  = i915_translate_stencil_op(i915->stencil.back_zpass_op);
-      int ref   = i915->stencil.ref_value[1] & 0xff;
-      int tmask = i915->stencil.value_mask[1] & 0xff;
-      int wmask = i915->stencil.write_mask[1] & 0xff;
+   if (i915->depth_stencil->stencil.back_enabled) {
+      int test  = i915_translate_compare_func(i915->depth_stencil->stencil.back_func);
+      int fop   = i915_translate_stencil_op(i915->depth_stencil->stencil.back_fail_op);
+      int dfop  = i915_translate_stencil_op(i915->depth_stencil->stencil.back_zfail_op);
+      int dpop  = i915_translate_stencil_op(i915->depth_stencil->stencil.back_zpass_op);
+      int ref   = i915->depth_stencil->stencil.ref_value[1] & 0xff;
+      int tmask = i915->depth_stencil->stencil.value_mask[1] & 0xff;
+      int wmask = i915->depth_stencil->stencil.write_mask[1] & 0xff;
       
       bf[0] = (_3DSTATE_BACKFACE_STENCIL_OPS |
               BFO_ENABLE_STENCIL_FUNCS |
@@ -157,7 +157,7 @@ static void upload_BFO( struct i915_context *i915 )
 }
 
 const struct i915_tracked_state i915_upload_BFO = {
-   .dirty = I915_NEW_STENCIL,
+   .dirty = I915_NEW_DEPTH_STENCIL,
    .update = upload_BFO
 };
 
index aaca534..484913d 100644 (file)
@@ -128,12 +128,12 @@ static void upload_S5( struct i915_context *i915 )
    unsigned LIS5 = 0;
 
    /* I915_NEW_STENCIL */
-   if (i915->stencil.front_enabled) {
-      int test = i915_translate_compare_func(i915->stencil.front_func);
-      int fop = i915_translate_stencil_op(i915->stencil.front_fail_op);
-      int dfop = i915_translate_stencil_op(i915->stencil.front_zfail_op);
-      int dpop = i915_translate_stencil_op(i915->stencil.front_zpass_op);
-      int ref = i915->stencil.ref_value[0] & 0xff;
+   if (i915->depth_stencil->stencil.front_enabled) {
+      int test = i915_translate_compare_func(i915->depth_stencil->stencil.front_func);
+      int fop = i915_translate_stencil_op(i915->depth_stencil->stencil.front_fail_op);
+      int dfop = i915_translate_stencil_op(i915->depth_stencil->stencil.front_zfail_op);
+      int dpop = i915_translate_stencil_op(i915->depth_stencil->stencil.front_zpass_op);
+      int ref = i915->depth_stencil->stencil.ref_value[0] & 0xff;
       
       LIS5 |= (S5_STENCIL_TEST_ENABLE |
               S5_STENCIL_WRITE_ENABLE |
@@ -179,7 +179,7 @@ static void upload_S5( struct i915_context *i915 )
 }
 
 const struct i915_tracked_state i915_upload_S5 = {
-   .dirty = (I915_NEW_STENCIL | I915_NEW_BLEND | I915_NEW_SETUP),
+   .dirty = (I915_NEW_DEPTH_STENCIL | I915_NEW_BLEND | I915_NEW_SETUP),
    .update = upload_S5
 };
 
@@ -219,13 +219,13 @@ static void upload_S6( struct i915_context *i915 )
 
    /* I915_NEW_DEPTH 
     */
-   if (i915->depth_test.enabled) {
-      int func = i915_translate_compare_func(i915->depth_test.func);
+   if (i915->depth_stencil->depth.enabled) {
+      int func = i915_translate_compare_func(i915->depth_stencil->depth.func);
 
       LIS6 |= (S6_DEPTH_TEST_ENABLE |
               (func << S6_DEPTH_TEST_FUNC_SHIFT));
 
-      if (i915->depth_test.writemask)
+      if (i915->depth_stencil->depth.writemask)
         LIS6 |= S6_DEPTH_WRITE_ENABLE;
    }
 
@@ -236,7 +236,7 @@ static void upload_S6( struct i915_context *i915 )
 }
 
 const struct i915_tracked_state i915_upload_S6 = {
-   .dirty = I915_NEW_ALPHA_TEST | I915_NEW_BLEND | I915_NEW_DEPTH_TEST,
+   .dirty = I915_NEW_ALPHA_TEST | I915_NEW_BLEND | I915_NEW_DEPTH_STENCIL,
    .update = upload_S6
 };
 
index 0913e49..488f002 100644 (file)
@@ -101,6 +101,14 @@ struct pipe_context {
    void (*delete_sampler_state)(struct pipe_context *,
                                 const struct pipe_sampler_state *);
 
+   const struct pipe_depth_stencil_state * (*create_depth_stencil_state)(
+      struct pipe_context *,
+      const struct pipe_depth_stencil_state *);
+   void (*bind_depth_stencil_state)(struct pipe_context *,
+                                    const struct pipe_depth_stencil_state *);
+   void (*delete_depth_stencil_state)(struct pipe_context *,
+                                      const struct pipe_depth_stencil_state *);
+
    void (*set_alpha_test_state)( struct pipe_context *,
                                  const struct pipe_alpha_test_state * );
 
@@ -116,9 +124,6 @@ struct pipe_context {
    void (*set_constant_buffer)( struct pipe_context *,
                                 uint shader, uint index,
                                 const struct pipe_constant_buffer *buf );
-                              
-   void (*set_depth_state)( struct pipe_context *,
-                            const struct pipe_depth_state * );
 
    void (*set_feedback_state)( struct pipe_context *,
                                const struct pipe_feedback_state *);
@@ -141,9 +146,6 @@ struct pipe_context {
    void (*set_scissor_state)( struct pipe_context *,
                               const struct pipe_scissor_state * );
 
-   void (*set_stencil_state)( struct pipe_context *,
-                              const struct pipe_stencil_state * );
-
    void (*set_texture_state)( struct pipe_context *,
                               unsigned unit,
                               struct pipe_mipmap_tree * );
index b994d17..30e559b 100644 (file)
@@ -146,13 +146,31 @@ struct pipe_shader_state {
    void *executable;
 };
 
-struct pipe_depth_state
+struct pipe_depth_stencil_state
 {
-   unsigned enabled:1;   /**< depth test enabled? */
-   unsigned writemask:1; /**< allow depth buffer writes? */
-   unsigned func:3;      /**< depth test func (PIPE_FUNC_x) */
-   unsigned occlusion_count:1; /**< XXX move this elsewhere? */
-   float clear;      /**< Clear value in [0,1] (XXX correct place?) */
+   struct {
+      unsigned enabled:1;   /**< depth test enabled? */
+      unsigned writemask:1; /**< allow depth buffer writes? */
+      unsigned func:3;      /**< depth test func (PIPE_FUNC_x) */
+      unsigned occlusion_count:1; /**< XXX move this elsewhere? */
+      float clear;      /**< Clear value in [0,1] (XXX correct place?) */
+   } depth;
+   struct {
+      unsigned front_enabled:1;
+      unsigned front_func:3;     /**< PIPE_FUNC_x */
+      unsigned front_fail_op:3;  /**< PIPE_STENCIL_OP_x */
+      unsigned front_zpass_op:3; /**< PIPE_STENCIL_OP_x */
+      unsigned front_zfail_op:3; /**< PIPE_STENCIL_OP_x */
+      unsigned back_enabled:1;
+      unsigned back_func:3;      /**< PIPE_FUNC_x */
+      unsigned back_fail_op:3;   /**< PIPE_STENCIL_OP_x */
+      unsigned back_zpass_op:3;  /**< PIPE_STENCIL_OP_x */
+      unsigned back_zfail_op:3;  /**< PIPE_STENCIL_OP_x */
+      ubyte ref_value[2];    /**< [0] = front, [1] = back */
+      ubyte value_mask[2];
+      ubyte write_mask[2];
+      ubyte clear_value;
+   } stencil;
 };
 
 struct pipe_alpha_test_state {
@@ -188,24 +206,6 @@ struct pipe_clear_color_state
    float color[4];
 };
 
-struct pipe_stencil_state {
-   unsigned front_enabled:1;
-   unsigned front_func:3;     /**< PIPE_FUNC_x */
-   unsigned front_fail_op:3;  /**< PIPE_STENCIL_OP_x */
-   unsigned front_zpass_op:3; /**< PIPE_STENCIL_OP_x */
-   unsigned front_zfail_op:3; /**< PIPE_STENCIL_OP_x */
-   unsigned back_enabled:1;
-   unsigned back_func:3;      /**< PIPE_FUNC_x */
-   unsigned back_fail_op:3;   /**< PIPE_STENCIL_OP_x */
-   unsigned back_zpass_op:3;  /**< PIPE_STENCIL_OP_x */
-   unsigned back_zfail_op:3;  /**< PIPE_STENCIL_OP_x */
-   ubyte ref_value[2];    /**< [0] = front, [1] = back */
-   ubyte value_mask[2];
-   ubyte write_mask[2];
-   ubyte clear_value;
-};
-
-
 struct pipe_framebuffer_state
 {
    /** multiple colorbuffers for multiple render targets */
index bab7985..9a8b55b 100644 (file)
@@ -256,13 +256,15 @@ struct pipe_context *softpipe_create( struct pipe_winsys *pipe_winsys,
    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.create_depth_stencil_state = softpipe_create_depth_stencil_state;
+   softpipe->pipe.bind_depth_stencil_state = softpipe_bind_depth_stencil_state;
+   softpipe->pipe.delete_depth_stencil_state = softpipe_delete_depth_stencil_state;
 
    softpipe->pipe.set_alpha_test_state = softpipe_set_alpha_test_state;
    softpipe->pipe.set_blend_color = softpipe_set_blend_color;
    softpipe->pipe.set_clip_state = softpipe_set_clip_state;
    softpipe->pipe.set_clear_color_state = softpipe_set_clear_color_state;
    softpipe->pipe.set_constant_buffer = softpipe_set_constant_buffer;
-   softpipe->pipe.set_depth_state = softpipe_set_depth_test_state;
    softpipe->pipe.set_feedback_state = softpipe_set_feedback_state;
    softpipe->pipe.set_framebuffer_state = softpipe_set_framebuffer_state;
    softpipe->pipe.set_fs_state = softpipe_set_fs_state;
@@ -270,7 +272,6 @@ struct pipe_context *softpipe_create( struct pipe_winsys *pipe_winsys,
    softpipe->pipe.set_polygon_stipple = softpipe_set_polygon_stipple;
    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;
    softpipe->pipe.set_texture_state = softpipe_set_texture_state;
    softpipe->pipe.set_viewport_state = softpipe_set_viewport_state;
 
index 5cee1a3..4cbb0f8 100644 (file)
@@ -50,18 +50,17 @@ struct draw_stage;
 #define SP_NEW_SETUP         0x2
 #define SP_NEW_FS            0x4
 #define SP_NEW_BLEND         0x8
-#define SP_NEW_CLIP         0x10
-#define SP_NEW_SCISSOR      0x20
-#define SP_NEW_STIPPLE      0x40
-#define SP_NEW_FRAMEBUFFER  0x80
-#define SP_NEW_ALPHA_TEST  0x100
-#define SP_NEW_DEPTH_TEST  0x200
-#define SP_NEW_SAMPLER     0x400
-#define SP_NEW_TEXTURE     0x800
-#define SP_NEW_STENCIL    0x1000
-#define SP_NEW_VERTEX     0x2000
-#define SP_NEW_VS         0x4000
-#define SP_NEW_CONSTANTS  0x8000
+#define SP_NEW_CLIP          0x10
+#define SP_NEW_SCISSOR       0x20
+#define SP_NEW_STIPPLE       0x40
+#define SP_NEW_FRAMEBUFFER   0x80
+#define SP_NEW_ALPHA_TEST    0x100
+#define SP_NEW_DEPTH_STENCIL 0x200
+#define SP_NEW_SAMPLER       0x400
+#define SP_NEW_TEXTURE       0x800
+#define SP_NEW_VERTEX        0x1000
+#define SP_NEW_VS            0x2000
+#define SP_NEW_CONSTANTS     0x4000
 
 
 struct softpipe_context {     
@@ -73,13 +72,13 @@ struct softpipe_context {
     */
    const struct pipe_blend_state   *blend;
    const struct pipe_sampler_state *sampler[PIPE_MAX_SAMPLERS];
+   const struct pipe_depth_stencil_state   *depth_stencil;
 
    struct pipe_alpha_test_state alpha_test;
    struct pipe_blend_color blend_color;
    struct pipe_clear_color_state clear_color;
    struct pipe_clip_state clip;
    struct pipe_constant_buffer constants[2];
-   struct pipe_depth_state depth_test;
    struct pipe_feedback_state feedback;
    struct pipe_framebuffer_state framebuffer;
    struct pipe_shader_state fs;
@@ -87,7 +86,6 @@ struct softpipe_context {
    struct pipe_poly_stipple poly_stipple;
    struct pipe_scissor_state scissor;
    struct pipe_setup_state setup;
-   struct pipe_stencil_state stencil;
    struct pipe_mipmap_tree *texture[PIPE_MAX_SAMPLERS];
    struct pipe_viewport_state viewport;
    struct pipe_vertex_buffer vertex_buffer[PIPE_ATTRIB_MAX];
index 2fcbea1..1f45776 100644 (file)
@@ -31,7 +31,7 @@ sp_build_quad_pipeline(struct softpipe_context *sp)
       sp->quad.first = sp->quad.bufloop;
    }
 
-   if (sp->depth_test.occlusion_count) {
+   if (sp->depth_stencil->depth.occlusion_count) {
       sp->quad.occlusion->next = sp->quad.first;
       sp->quad.first = sp->quad.occlusion;
    }
@@ -43,12 +43,12 @@ sp_build_quad_pipeline(struct softpipe_context *sp)
       sp->quad.first = sp->quad.coverage;
    }
 
-   if (   sp->stencil.front_enabled
-       || sp->stencil.front_enabled) {
+   if (   sp->depth_stencil->stencil.front_enabled
+       || sp->depth_stencil->stencil.back_enabled) {
       sp->quad.stencil_test->next = sp->quad.first;
       sp->quad.first = sp->quad.stencil_test;
    }
-   else if (sp->depth_test.enabled &&
+   else if (sp->depth_stencil->depth.enabled &&
             sp->framebuffer.zbuf) {
       sp->quad.depth_test->next = sp->quad.first;
       sp->quad.first = sp->quad.depth_test;
index 5d46e70..ff1d84a 100644 (file)
@@ -77,7 +77,7 @@ sp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad)
    /* get zquad from zbuffer */
    sps->read_quad_z(sps, quad->x0, quad->y0, bzzzz);
 
-   switch (softpipe->depth_test.func) {
+   switch (softpipe->depth_stencil->depth.func) {
    case PIPE_FUNC_NEVER:
       /* zmask = 0 */
       break;
@@ -129,7 +129,7 @@ sp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad)
 
    quad->mask &= zmask;
 
-   if (softpipe->depth_test.writemask) {
+   if (softpipe->depth_stencil->depth.writemask) {
       
       /* This is also efficient with sse / spe instructions: 
        */
index cb0b6d8..46ad08a 100755 (executable)
@@ -179,7 +179,7 @@ static void shade_begin(struct quad_stage *qs)
    unsigned i, entry;
 
    for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
-      qss->samplers[i].state = &softpipe->sampler[i];
+      qss->samplers[i].state = softpipe->sampler[i];
       qss->samplers[i].texture = softpipe->texture[i];
       qss->samplers[i].get_samples = sp_get_samples;
       qss->samplers[i].pipe = &softpipe->pipe;
index 47b3b4f..56cc690 100644 (file)
@@ -207,23 +207,23 @@ stencil_test_quad(struct quad_stage *qs, struct quad_header *quad)
 
    /* choose front or back face function, operator, etc */
    /* XXX we could do these initializations once per primitive */
-   if (softpipe->stencil.back_enabled && quad->facing) {
-      func = softpipe->stencil.back_func;
-      failOp = softpipe->stencil.back_fail_op;
-      zFailOp = softpipe->stencil.back_zfail_op;
-      zPassOp = softpipe->stencil.back_zpass_op;
-      ref = softpipe->stencil.ref_value[1];
-      wrtMask = softpipe->stencil.write_mask[1];
-      valMask = softpipe->stencil.value_mask[1];
+   if (softpipe->depth_stencil->stencil.back_enabled && quad->facing) {
+      func = softpipe->depth_stencil->stencil.back_func;
+      failOp = softpipe->depth_stencil->stencil.back_fail_op;
+      zFailOp = softpipe->depth_stencil->stencil.back_zfail_op;
+      zPassOp = softpipe->depth_stencil->stencil.back_zpass_op;
+      ref = softpipe->depth_stencil->stencil.ref_value[1];
+      wrtMask = softpipe->depth_stencil->stencil.write_mask[1];
+      valMask = softpipe->depth_stencil->stencil.value_mask[1];
    }
    else {
-      func = softpipe->stencil.front_func;
-      failOp = softpipe->stencil.front_fail_op;
-      zFailOp = softpipe->stencil.front_zfail_op;
-      zPassOp = softpipe->stencil.front_zpass_op;
-      ref = softpipe->stencil.ref_value[0];
-      wrtMask = softpipe->stencil.write_mask[0];
-      valMask = softpipe->stencil.value_mask[0];
+      func = softpipe->depth_stencil->stencil.front_func;
+      failOp = softpipe->depth_stencil->stencil.front_fail_op;
+      zFailOp = softpipe->depth_stencil->stencil.front_zfail_op;
+      zPassOp = softpipe->depth_stencil->stencil.front_zpass_op;
+      ref = softpipe->depth_stencil->stencil.ref_value[0];
+      wrtMask = softpipe->depth_stencil->stencil.write_mask[0];
+      valMask = softpipe->depth_stencil->stencil.value_mask[0];
    }
 
    assert(s_surf); /* shouldn't get here if there's no stencil buffer */
@@ -244,7 +244,7 @@ stencil_test_quad(struct quad_stage *qs, struct quad_header *quad)
    if (quad->mask) {
 
       /* now the pixels that passed the stencil test are depth tested */
-      if (softpipe->depth_test.enabled) {
+      if (softpipe->depth_stencil->depth.enabled) {
          const unsigned origMask = quad->mask;
 
          sp_depth_test_quad(qs, quad);  /* quad->mask is updated */
index c8c9370..caec3b4 100644 (file)
@@ -50,6 +50,15 @@ void softpipe_bind_sampler_state(struct pipe_context *,
 void softpipe_delete_sampler_state(struct pipe_context *,
                                    const struct pipe_sampler_state *);
 
+
+const struct pipe_depth_stencil_state *
+softpipe_create_depth_stencil_state(struct pipe_context *,
+                                    const struct pipe_depth_stencil_state *);
+void softpipe_bind_depth_stencil_state(struct pipe_context *,
+                                       const struct pipe_depth_stencil_state *);
+void softpipe_delete_depth_stencil_state(struct pipe_context *,
+                                         const struct pipe_depth_stencil_state *);
+
 void softpipe_set_framebuffer_state( struct pipe_context *,
                             const struct pipe_framebuffer_state * );
 
@@ -69,9 +78,6 @@ void softpipe_set_constant_buffer(struct pipe_context *,
                                   uint shader, uint index,
                                   const struct pipe_constant_buffer *buf);
 
-void softpipe_set_depth_test_state( struct pipe_context *,
-                                    const struct pipe_depth_state * );
-
 void softpipe_set_feedback_state( struct pipe_context *,
                                   const struct pipe_feedback_state * );
 
@@ -90,9 +96,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_stencil_state( struct pipe_context *,
-                                 const struct pipe_stencil_state * );
-
 void softpipe_set_texture_state( struct pipe_context *,
                                  unsigned unit,
                                  struct pipe_mipmap_tree * );
index 34da613..83f456d 100644 (file)
@@ -71,16 +71,6 @@ void softpipe_set_blend_color( struct pipe_context *pipe,
 /** XXX move someday?  Or consolidate all these simple state setters
  * into one file.
  */
-void
-softpipe_set_depth_test_state(struct pipe_context *pipe,
-                              const struct pipe_depth_state *depth)
-{
-   struct softpipe_context *softpipe = softpipe_context(pipe);
-
-   softpipe->depth_test = *depth;
-
-   softpipe->dirty |= SP_NEW_DEPTH_TEST;
-}
 
 void
 softpipe_set_alpha_test_state(struct pipe_context *pipe,
@@ -93,14 +83,30 @@ softpipe_set_alpha_test_state(struct pipe_context *pipe,
    softpipe->dirty |= SP_NEW_ALPHA_TEST;
 }
 
+const struct pipe_depth_stencil_state *
+softpipe_create_depth_stencil_state(struct pipe_context *pipe,
+                              const struct pipe_depth_stencil_state *depth_stencil)
+{
+   struct pipe_depth_stencil_state *new_ds = malloc(sizeof(struct pipe_depth_stencil_state));
+   memcpy(new_ds, depth_stencil, sizeof(struct pipe_depth_stencil_state));
+
+   return new_ds;
+}
+
 void
-softpipe_set_stencil_state(struct pipe_context *pipe,
-                           const struct pipe_stencil_state *stencil)
+softpipe_bind_depth_stencil_state(struct pipe_context *pipe,
+                              const struct pipe_depth_stencil_state *depth_stencil)
 {
    struct softpipe_context *softpipe = softpipe_context(pipe);
 
-   softpipe->stencil = *stencil;
+   softpipe->depth_stencil = depth_stencil;
 
-   softpipe->dirty |= SP_NEW_STENCIL;
+   softpipe->dirty |= SP_NEW_DEPTH_STENCIL;
 }
 
+void
+softpipe_delete_depth_stencil_state(struct pipe_context *pipe,
+                                    const struct pipe_depth_stencil_state *depth)
+{
+   free((struct pipe_depth_stencil_state*)depth);
+}
index e08ed50..47743e1 100644 (file)
@@ -55,7 +55,7 @@ static void calculate_vertex_layout( struct softpipe_context *softpipe )
    /* Need Z if depth test is enabled or the fragment program uses the
     * fragment position (XYZW).
     */
-   if (softpipe->depth_test.enabled ||
+   if (softpipe->depth_stencil->depth.enabled ||
        (inputsRead & (1 << TGSI_ATTRIB_POS)))
       softpipe->need_z = TRUE;
    else
@@ -186,15 +186,14 @@ void softpipe_update_derived( struct softpipe_context *softpipe )
       calculate_vertex_layout( softpipe );
 
    if (softpipe->dirty & (SP_NEW_SCISSOR |
-                          SP_NEW_STENCIL |
+                          SP_NEW_DEPTH_STENCIL |
                           SP_NEW_FRAMEBUFFER))
       compute_cliprect(softpipe);
 
    if (softpipe->dirty & (SP_NEW_BLEND |
-                          SP_NEW_DEPTH_TEST |
+                          SP_NEW_DEPTH_STENCIL |
                           SP_NEW_ALPHA_TEST |
                           SP_NEW_FRAMEBUFFER |
-                          SP_NEW_STENCIL |
                           SP_NEW_SETUP |
                           SP_NEW_FS))
       sp_build_quad_pipeline(softpipe);
index 90fa5c6..22b592d 100644 (file)
@@ -204,7 +204,6 @@ STATETRACKER_SOURCES = \
        state_tracker/st_atom_sampler.c \
        state_tracker/st_atom_scissor.c \
        state_tracker/st_atom_setup.c \
-       state_tracker/st_atom_stencil.c \
        state_tracker/st_atom_stipple.c \
        state_tracker/st_atom_texture.c \
        state_tracker/st_atom_viewport.c \
index 66ab5d7..99d0bcb 100644 (file)
@@ -46,7 +46,7 @@ static const struct st_tracked_state *atoms[] =
 {
    &st_update_framebuffer,
    &st_update_clear_color,
-   &st_update_depth,
+   &st_update_depth_stencil,
    &st_update_clip,
 
    &st_update_tnl,
@@ -58,7 +58,6 @@ static const struct st_tracked_state *atoms[] =
    &st_update_viewport,
    &st_update_scissor,
    &st_update_blend,
-   &st_update_stencil,
    &st_update_sampler,
    &st_update_texture,
    &st_update_vs_constants,
index 447430b..0e362b1 100644 (file)
@@ -47,7 +47,7 @@ void st_validate_state( struct st_context *st );
 const struct st_tracked_state st_update_framebuffer;
 const struct st_tracked_state st_update_clip;
 const struct st_tracked_state st_update_clear_color;
-const struct st_tracked_state st_update_depth;
+const struct st_tracked_state st_update_depth_stencil;
 const struct st_tracked_state st_update_tnl;
 const struct st_tracked_state st_update_fs;
 const struct st_tracked_state st_update_vs;
@@ -56,7 +56,6 @@ const struct st_tracked_state st_update_polygon_stipple;
 const struct st_tracked_state st_update_viewport;
 const struct st_tracked_state st_update_scissor;
 const struct st_tracked_state st_update_blend;
-const struct st_tracked_state st_update_stencil;
 const struct st_tracked_state st_update_sampler;
 const struct st_tracked_state st_update_texture;
 const struct st_tracked_state st_update_fs_constants;
index df05c79..4067732 100644 (file)
   * Authors:
   *   Keith Whitwell <keith@tungstengraphics.com>
   *   Brian Paul
+  *   Zack  Rusin
   */
  
 
 #include "st_context.h"
+#include "st_cache.h"
 #include "st_atom.h"
 #include "pipe/p_context.h"
 #include "pipe/p_defines.h"
 
 
 /**
+ * Convert GLenum stencil func tokens to pipe tokens.
+ */
+static GLuint
+gl_stencil_func_to_sp(GLenum func)
+{
+   /* Same values, just biased */
+   assert(PIPE_FUNC_NEVER == GL_NEVER - GL_NEVER);
+   assert(PIPE_FUNC_LESS == GL_LESS - GL_NEVER);
+   assert(PIPE_FUNC_EQUAL == GL_EQUAL - GL_NEVER);
+   assert(PIPE_FUNC_LEQUAL == GL_LEQUAL - GL_NEVER);
+   assert(PIPE_FUNC_GREATER == GL_GREATER - GL_NEVER);
+   assert(PIPE_FUNC_NOTEQUAL == GL_NOTEQUAL - GL_NEVER);
+   assert(PIPE_FUNC_GEQUAL == GL_GEQUAL - GL_NEVER);
+   assert(PIPE_FUNC_ALWAYS == GL_ALWAYS - GL_NEVER);
+   assert(func >= GL_NEVER);
+   assert(func <= GL_ALWAYS);
+   return func - GL_NEVER;
+}
+
+
+/**
+ * Convert GLenum stencil op tokens to pipe tokens.
+ */
+static GLuint
+gl_stencil_op_to_sp(GLenum func)
+{
+   switch (func) {
+   case GL_KEEP:
+      return PIPE_STENCIL_OP_KEEP;
+   case GL_ZERO:
+      return PIPE_STENCIL_OP_ZERO;
+   case GL_REPLACE:
+      return PIPE_STENCIL_OP_REPLACE;
+   case GL_INCR:
+      return PIPE_STENCIL_OP_INCR;
+   case GL_DECR:
+      return PIPE_STENCIL_OP_DECR;
+   case GL_INCR_WRAP:
+      return PIPE_STENCIL_OP_INCR_WRAP;
+   case GL_DECR_WRAP:
+      return PIPE_STENCIL_OP_DECR_WRAP;
+   case GL_INVERT:
+      return PIPE_STENCIL_OP_INVERT;
+   default:
+      assert("invalid GL token in gl_stencil_op_to_sp()" == NULL);
+      return 0;
+   }
+}
+
+/**
  * Convert GLenum depth func tokens to pipe tokens.
  */
 static GLuint
@@ -59,35 +111,59 @@ gl_depth_func_to_sp(GLenum func)
 }
 
 
-static void 
-update_depth( struct st_context *st )
+static void
+update_depth_stencil(struct st_context *st)
 {
-   struct pipe_depth_state depth;
+   struct pipe_depth_stencil_state depth_stencil;
 
-   memset(&depth, 0, sizeof(depth));
+   memset(&depth_stencil, 0, sizeof(depth_stencil));
 
-   depth.enabled = st->ctx->Depth.Test;
-   depth.writemask = st->ctx->Depth.Mask;
-   depth.func = gl_depth_func_to_sp(st->ctx->Depth.Func);
-   depth.clear = st->ctx->Depth.Clear;
+   depth_stencil.depth.enabled = st->ctx->Depth.Test;
+   depth_stencil.depth.writemask = st->ctx->Depth.Mask;
+   depth_stencil.depth.func = gl_depth_func_to_sp(st->ctx->Depth.Func);
+   depth_stencil.depth.clear = st->ctx->Depth.Clear;
 
    if (st->ctx->Query.CurrentOcclusionObject &&
        st->ctx->Query.CurrentOcclusionObject->Active)
-      depth.occlusion_count = 1;
+      depth_stencil.depth.occlusion_count = 1;
+
+   if (st->ctx->Stencil.Enabled) {
+      depth_stencil.stencil.front_enabled = 1;
+      depth_stencil.stencil.front_func = gl_stencil_func_to_sp(st->ctx->Stencil.Function[0]);
+      depth_stencil.stencil.front_fail_op = gl_stencil_op_to_sp(st->ctx->Stencil.FailFunc[0]);
+      depth_stencil.stencil.front_zfail_op = gl_stencil_op_to_sp(st->ctx->Stencil.ZFailFunc[0]);
+      depth_stencil.stencil.front_zpass_op = gl_stencil_op_to_sp(st->ctx->Stencil.ZPassFunc[0]);
+      depth_stencil.stencil.ref_value[0] = st->ctx->Stencil.Ref[0] & 0xff;
+      depth_stencil.stencil.value_mask[0] = st->ctx->Stencil.ValueMask[0] & 0xff;
+      depth_stencil.stencil.write_mask[0] = st->ctx->Stencil.WriteMask[0] & 0xff;
+      if (st->ctx->Stencil.TestTwoSide) {
+         depth_stencil.stencil.back_enabled = 1;
+         depth_stencil.stencil.back_func = gl_stencil_func_to_sp(st->ctx->Stencil.Function[1]);
+         depth_stencil.stencil.back_fail_op = gl_stencil_op_to_sp(st->ctx->Stencil.FailFunc[1]);
+         depth_stencil.stencil.back_zfail_op = gl_stencil_op_to_sp(st->ctx->Stencil.ZFailFunc[1]);
+         depth_stencil.stencil.back_zpass_op = gl_stencil_op_to_sp(st->ctx->Stencil.ZPassFunc[1]);
+         depth_stencil.stencil.ref_value[1] = st->ctx->Stencil.Ref[1] & 0xff;
+         depth_stencil.stencil.value_mask[1] = st->ctx->Stencil.ValueMask[1] & 0xff;
+         depth_stencil.stencil.write_mask[1] = st->ctx->Stencil.WriteMask[1] & 0xff;
+      }
+      depth_stencil.stencil.clear_value = st->ctx->Stencil.Clear & 0xff;
+   }
 
-   if (memcmp(&depth, &st->state.depth, sizeof(depth)) != 0) {
+   struct pipe_depth_stencil_state *cached_state =
+      st_cached_depth_stencil_state(st, &depth_stencil);
+   if (st->state.depth_stencil != cached_state) {
       /* state has changed */
-      st->state.depth = depth;  /* struct copy */
-      st->pipe->set_depth_state(st->pipe, &depth); /* set new state */
+      st->state.depth_stencil = cached_state;
+      st->pipe->bind_depth_stencil_state(st->pipe, cached_state); /* set new state */
    }
 }
 
 
-const struct st_tracked_state st_update_depth = {
-   .name = "st_update_depth",
+const struct st_tracked_state st_update_depth_stencil = {
+   .name = "st_update_depth_stencil",
    .dirty = {
-      .mesa = (_NEW_DEPTH),
+      .mesa = (_NEW_DEPTH|_NEW_STENCIL),
       .st  = 0,
    },
-   .update = update_depth
+   .update = update_depth_stencil
 };
diff --git a/src/mesa/state_tracker/st_atom_stencil.c b/src/mesa/state_tracker/st_atom_stencil.c
deleted file mode 100644 (file)
index b8aec0b..0000000
+++ /dev/null
@@ -1,141 +0,0 @@
-/**************************************************************************
- * 
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
- **************************************************************************/
-
- /*
-  * Authors:
-  *   Keith Whitwell <keith@tungstengraphics.com>
-  *   Brian Paul
-  */
-
-#include "st_context.h"
-#include "st_atom.h"
-#include "pipe/p_context.h"
-#include "pipe/p_defines.h"
-
-
-/**
- * Convert GLenum stencil func tokens to pipe tokens.
- */
-static GLuint
-gl_stencil_func_to_sp(GLenum func)
-{
-   /* Same values, just biased */
-   assert(PIPE_FUNC_NEVER == GL_NEVER - GL_NEVER);
-   assert(PIPE_FUNC_LESS == GL_LESS - GL_NEVER);
-   assert(PIPE_FUNC_EQUAL == GL_EQUAL - GL_NEVER);
-   assert(PIPE_FUNC_LEQUAL == GL_LEQUAL - GL_NEVER);
-   assert(PIPE_FUNC_GREATER == GL_GREATER - GL_NEVER);
-   assert(PIPE_FUNC_NOTEQUAL == GL_NOTEQUAL - GL_NEVER);
-   assert(PIPE_FUNC_GEQUAL == GL_GEQUAL - GL_NEVER);
-   assert(PIPE_FUNC_ALWAYS == GL_ALWAYS - GL_NEVER);
-   assert(func >= GL_NEVER);
-   assert(func <= GL_ALWAYS);
-   return func - GL_NEVER;
-}
-
-
-/**
- * Convert GLenum stencil op tokens to pipe tokens.
- */
-static GLuint
-gl_stencil_op_to_sp(GLenum func)
-{
-   switch (func) {
-   case GL_KEEP:
-      return PIPE_STENCIL_OP_KEEP;
-   case GL_ZERO:
-      return PIPE_STENCIL_OP_ZERO;
-   case GL_REPLACE:
-      return PIPE_STENCIL_OP_REPLACE;
-   case GL_INCR:
-      return PIPE_STENCIL_OP_INCR;
-   case GL_DECR:
-      return PIPE_STENCIL_OP_DECR;
-   case GL_INCR_WRAP:
-      return PIPE_STENCIL_OP_INCR_WRAP;
-   case GL_DECR_WRAP:
-      return PIPE_STENCIL_OP_DECR_WRAP;
-   case GL_INVERT:
-      return PIPE_STENCIL_OP_INVERT;
-   default:
-      assert("invalid GL token in gl_stencil_op_to_sp()" == NULL);
-      return 0;
-   }
-}
-
-
-static void 
-update_stencil( struct st_context *st )
-{
-   struct pipe_stencil_state stencil;
-
-   memset(&stencil, 0, sizeof(stencil));
-
-   if (st->ctx->Stencil.Enabled) {
-      stencil.front_enabled = 1;
-      stencil.front_func = gl_stencil_func_to_sp(st->ctx->Stencil.Function[0]);
-      stencil.front_fail_op = gl_stencil_op_to_sp(st->ctx->Stencil.FailFunc[0]);
-      stencil.front_zfail_op = gl_stencil_op_to_sp(st->ctx->Stencil.ZFailFunc[0]);
-      stencil.front_zpass_op = gl_stencil_op_to_sp(st->ctx->Stencil.ZPassFunc[0]);
-      stencil.ref_value[0] = st->ctx->Stencil.Ref[0] & 0xff;
-      stencil.value_mask[0] = st->ctx->Stencil.ValueMask[0] & 0xff;
-      stencil.write_mask[0] = st->ctx->Stencil.WriteMask[0] & 0xff;
-      if (st->ctx->Stencil.TestTwoSide) {
-         stencil.back_enabled = 1;
-         stencil.back_func = gl_stencil_func_to_sp(st->ctx->Stencil.Function[1]);
-         stencil.back_fail_op = gl_stencil_op_to_sp(st->ctx->Stencil.FailFunc[1]);
-         stencil.back_zfail_op = gl_stencil_op_to_sp(st->ctx->Stencil.ZFailFunc[1]);
-         stencil.back_zpass_op = gl_stencil_op_to_sp(st->ctx->Stencil.ZPassFunc[1]);
-         stencil.ref_value[1] = st->ctx->Stencil.Ref[1] & 0xff;
-         stencil.value_mask[1] = st->ctx->Stencil.ValueMask[1] & 0xff;
-         stencil.write_mask[1] = st->ctx->Stencil.WriteMask[1] & 0xff;
-      }
-      stencil.clear_value = st->ctx->Stencil.Clear & 0xff;
-   }
-
-   if (memcmp(&stencil, &st->state.stencil, sizeof(stencil)) != 0) {
-      /* state has changed */
-      st->state.stencil = stencil;  /* struct copy */
-      st->pipe->set_stencil_state(st->pipe, &stencil); /* set new state */
-   }
-}
-
-
-const struct st_tracked_state st_update_stencil = {
-   .name = "st_update_stencil",
-   .dirty = {
-      .mesa = (_NEW_STENCIL),
-      .st  = 0,
-   },
-   .update = update_stencil
-};
-
-
-
-
-
index 99fb45f..64c03be 100644 (file)
@@ -76,3 +76,20 @@ struct pipe_sampler_state * st_cached_sampler_state(
    }
    return (struct pipe_sampler_state*)(cso_hash_iter_data(iter));
 }
+
+struct pipe_depth_stencil_state * st_cached_depth_stencil_state(
+   struct st_context *st,
+   const struct pipe_depth_stencil_state *depth_stencil)
+{
+   unsigned hash_key = cso_construct_key((void*)depth_stencil, sizeof(struct pipe_depth_stencil_state));
+   struct cso_hash_iter iter = cso_find_state_template(st->cache,
+                                                       hash_key, CSO_DEPTH_STENCIL,
+                                                       (void*)depth_stencil);
+   if (cso_hash_iter_is_null(iter)) {
+      const struct pipe_depth_stencil_state *created_state = st->pipe->create_depth_stencil_state(
+         st->pipe, depth_stencil);
+      iter = cso_insert_state(st->cache, hash_key, CSO_DEPTH_STENCIL,
+                              (void*)created_state);
+   }
+   return (struct pipe_depth_stencil_state*)(cso_hash_iter_data(iter));
+}
index 9275851..78cb2e7 100644 (file)
@@ -45,5 +45,8 @@ 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,
+   const struct pipe_depth_stencil_state *sampler);
 
 #endif
index 55e03f6..e9aabd1 100644 (file)
@@ -283,6 +283,7 @@ clear_with_quad(GLcontext *ctx,
    /* blend state: RGBA masking */
    {
       struct pipe_blend_state blend;
+      const struct pipe_blend_state *state;
       memset(&blend, 0, sizeof(blend));
       if (color) {
          if (ctx->Color.ColorMask[0])
@@ -296,20 +297,34 @@ clear_with_quad(GLcontext *ctx,
          if (st->ctx->Color.DitherFlag)
             blend.dither = 1;
       }
-      const struct pipe_blend_state *state = st_cached_blend_state(st, &blend);
+      state = st_cached_blend_state(st, &blend);
       pipe->bind_blend_state(pipe, state);
    }
 
-   /* depth state: always pass */
+   /* depth_stencil state: always pass/set to ref value */
    {
-      struct pipe_depth_state depth_test;
-      memset(&depth_test, 0, sizeof(depth_test));
+      struct pipe_depth_stencil_state depth_stencil;
+      struct pipe_depth_stencil_state *cached;
+      memset(&depth_stencil, 0, sizeof(depth_stencil));
       if (depth) {
-         depth_test.enabled = 1;
-         depth_test.writemask = 1;
-         depth_test.func = PIPE_FUNC_ALWAYS;
+         depth_stencil.depth.enabled = 1;
+         depth_stencil.depth.writemask = 1;
+         depth_stencil.depth.func = PIPE_FUNC_ALWAYS;
       }
-      pipe->set_depth_state(pipe, &depth_test);
+
+      if (stencil) {
+         depth_stencil.stencil.front_enabled = 1;
+         depth_stencil.stencil.front_func = PIPE_FUNC_ALWAYS;
+         depth_stencil.stencil.front_fail_op = PIPE_STENCIL_OP_REPLACE;
+         depth_stencil.stencil.front_zpass_op = PIPE_STENCIL_OP_REPLACE;
+         depth_stencil.stencil.front_zfail_op = PIPE_STENCIL_OP_REPLACE;
+         depth_stencil.stencil.ref_value[0] = ctx->Stencil.Clear;
+         depth_stencil.stencil.value_mask[0] = 0xff;
+         depth_stencil.stencil.write_mask[0] = ctx->Stencil.WriteMask[0] & 0xff;
+      }
+      cached =
+         st_cached_depth_stencil_state(ctx->st, &depth_stencil);
+      pipe->bind_depth_stencil_state(pipe, cached);
    }
 
    /* setup state: nothing */
@@ -326,23 +341,6 @@ clear_with_quad(GLcontext *ctx,
       pipe->set_setup_state(pipe, &setup);
    }
 
-   /* stencil state: always set to ref value */
-   {
-      struct pipe_stencil_state stencil_test;
-      memset(&stencil_test, 0, sizeof(stencil_test));
-      if (stencil) {
-         stencil_test.front_enabled = 1;
-         stencil_test.front_func = PIPE_FUNC_ALWAYS;
-         stencil_test.front_fail_op = PIPE_STENCIL_OP_REPLACE;
-         stencil_test.front_zpass_op = PIPE_STENCIL_OP_REPLACE;
-         stencil_test.front_zfail_op = PIPE_STENCIL_OP_REPLACE;
-         stencil_test.ref_value[0] = ctx->Stencil.Clear;
-         stencil_test.value_mask[0] = 0xff;
-         stencil_test.write_mask[0] = ctx->Stencil.WriteMask[0] & 0xff;
-      }
-      pipe->set_stencil_state(pipe, &stencil_test);
-   }
-
    /* fragment shader state: color pass-through program */
    {
       static struct st_fragment_program *stfp = NULL;
@@ -393,11 +391,10 @@ 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->set_depth_state(pipe, &st->state.depth);
+   pipe->bind_depth_stencil_state(pipe, st->state.depth_stencil);
    pipe->set_fs_state(pipe, &st->state.fs);
    pipe->set_vs_state(pipe, &st->state.vs);
    pipe->set_setup_state(pipe, &st->state.setup);
-   pipe->set_stencil_state(pipe, &st->state.stencil);
    pipe->set_viewport_state(pipe, &ctx->st->state.viewport);
    /* OR:
    st_invalidate_state(ctx, _NEW_COLOR | _NEW_DEPTH | _NEW_STENCIL);
index 31a37e5..a0012e3 100644 (file)
@@ -478,7 +478,7 @@ 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.depth.enabled)
+       st->state.depth_stencil->depth.enabled)
       /* XXX more checks */
       return GL_TRUE;
    else
index 13526ff..7c887d0 100644 (file)
@@ -76,13 +76,13 @@ struct st_context
    struct {
       const struct pipe_blend_state   *blend;
       const struct pipe_sampler_state *sampler[PIPE_MAX_SAMPLERS];
+      const struct pipe_depth_stencil_state *depth_stencil;
 
       struct pipe_alpha_test_state  alpha_test;
       struct pipe_blend_color  blend_color;
       struct pipe_clear_color_state clear_color;
       struct pipe_clip_state clip;
       struct pipe_constant_buffer constants[2];
-      struct pipe_depth_state depth;
       struct pipe_feedback_state feedback;
       struct pipe_framebuffer_state framebuffer;
       struct pipe_mipmap_tree *texture[PIPE_MAX_SAMPLERS];
@@ -91,7 +91,6 @@ struct st_context
       struct pipe_setup_state  setup;
       struct pipe_shader_state fs;
       struct pipe_shader_state vs;
-      struct pipe_stencil_state stencil;
       struct pipe_viewport_state viewport;
    } state;