gallium: don't put stencil ref value in pipe_depth_stencil_alpha_state
authorRoland Scheidegger <sroland@vmware.com>
Tue, 9 Feb 2010 20:23:27 +0000 (21:23 +0100)
committerRoland Scheidegger <sroland@vmware.com>
Tue, 9 Feb 2010 20:23:27 +0000 (21:23 +0100)
This will make driver's life a bit harder, however it makes sense that stencil
reference value is not part of the pipe_depth_stencil_alpha_state, because
it often (there are some algorithms which require this) changes more frequently
than the rest of the dsa state. This is also encouraged by some graphic APIs.
Treat it similar to pipe_blend_color.

src/gallium/auxiliary/cso_cache/cso_context.c
src/gallium/auxiliary/cso_cache/cso_context.h
src/gallium/auxiliary/util/u_blitter.c
src/gallium/include/pipe/p_context.h
src/gallium/include/pipe/p_state.h
src/mesa/state_tracker/st_atom_depth.c

index c638239e80b44185b7c9621e22bde48da797e1b8..47867e888a460ccf283dab01916f9ceada8f1376 100644 (file)
@@ -93,6 +93,7 @@ struct cso_context {
    struct pipe_framebuffer_state fb, fb_saved;
    struct pipe_viewport_state vp, vp_saved;
    struct pipe_blend_color blend_color;
+   struct pipe_stencil_ref stencil_ref;
 };
 
 
@@ -1069,6 +1070,16 @@ enum pipe_error cso_set_blend_color(struct cso_context *ctx,
    return PIPE_OK;
 }
 
+enum pipe_error cso_set_stencil_ref(struct cso_context *ctx,
+                                    const struct pipe_stencil_ref *sr)
+{
+   if (memcmp(&ctx->stencil_ref, sr, sizeof(ctx->stencil_ref))) {
+      ctx->stencil_ref = *sr;
+      ctx->pipe->set_stencil_ref(ctx->pipe, sr);
+   }
+   return PIPE_OK;
+}
+
 enum pipe_error cso_set_geometry_shader_handle(struct cso_context *ctx,
                                                void *handle)
 {
index d2089b1c8839a02514fcd5bc1f98a1dbbc8c59e6..3a6fff21e210302f8b3b891320a86a79752d0e59 100644 (file)
@@ -174,6 +174,10 @@ enum pipe_error cso_set_blend_color(struct cso_context *cso,
                                     const struct pipe_blend_color *bc);
 
 
+enum pipe_error cso_set_stencil_ref(struct cso_context *cso,
+                                    const struct pipe_stencil_ref *sr);
+
+
 #ifdef __cplusplus
 }
 #endif
index f3b4491d17542a1eceef051d9a3f35af70438c0e..0504538258da29b55111804c8b1522aaeffccbc6 100644 (file)
@@ -60,13 +60,12 @@ struct blitter_context_priv
    float vertices[4][2][4];   /**< {pos, color} or {pos, texcoord} */
 
    /* Templates for various state objects. */
-   struct pipe_depth_stencil_alpha_state template_dsa;
    struct pipe_sampler_state template_sampler_state;
 
    /* Constant state objects. */
    /* Vertex shaders. */
    void *vs_col; /**< Vertex shader which passes {pos, color} to the output */
-   void *vs_tex; /**<Vertex shader which passes {pos, texcoord} to the output.*/
+   void *vs_tex; /**< Vertex shader which passes {pos, texcoord} to the output.*/
 
    /* Fragment shaders. */
    /* FS which outputs a color to multiple color buffers. */
@@ -85,7 +84,7 @@ struct blitter_context_priv
    void *blend_keep_color;    /**< blend state with writemask of 0 */
 
    /* Depth stencil alpha state. */
-   void *dsa_write_depth_stencil[0xff]; /**< indices are stencil clear values */
+   void *dsa_write_depth_stencil;
    void *dsa_write_depth_keep_stencil;
    void *dsa_keep_depth_stencil;
 
@@ -100,7 +99,7 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe)
 {
    struct blitter_context_priv *ctx;
    struct pipe_blend_state blend;
-   struct pipe_depth_stencil_alpha_state *dsa;
+   struct pipe_depth_stencil_alpha_state dsa;
    struct pipe_rasterizer_state rs_state;
    struct pipe_sampler_state *sampler_state;
    unsigned i;
@@ -129,23 +128,24 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe)
    ctx->blend_write_color = pipe->create_blend_state(pipe, &blend);
 
    /* depth stencil alpha state objects */
-   dsa = &ctx->template_dsa;
    ctx->dsa_keep_depth_stencil =
-      pipe->create_depth_stencil_alpha_state(pipe, dsa);
+      pipe->create_depth_stencil_alpha_state(pipe, &dsa);
 
-   dsa->depth.enabled = 1;
-   dsa->depth.writemask = 1;
-   dsa->depth.func = PIPE_FUNC_ALWAYS;
+   dsa.depth.enabled = 1;
+   dsa.depth.writemask = 1;
+   dsa.depth.func = PIPE_FUNC_ALWAYS;
    ctx->dsa_write_depth_keep_stencil =
-      pipe->create_depth_stencil_alpha_state(pipe, dsa);
-
-   dsa->stencil[0].enabled = 1;
-   dsa->stencil[0].func = PIPE_FUNC_ALWAYS;
-   dsa->stencil[0].fail_op = PIPE_STENCIL_OP_REPLACE;
-   dsa->stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE;
-   dsa->stencil[0].zfail_op = PIPE_STENCIL_OP_REPLACE;
-   dsa->stencil[0].valuemask = 0xff;
-   dsa->stencil[0].writemask = 0xff;
+      pipe->create_depth_stencil_alpha_state(pipe, &dsa);
+
+   dsa.stencil[0].enabled = 1;
+   dsa.stencil[0].func = PIPE_FUNC_ALWAYS;
+   dsa.stencil[0].fail_op = PIPE_STENCIL_OP_REPLACE;
+   dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE;
+   dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_REPLACE;
+   dsa.stencil[0].valuemask = 0xff;
+   dsa.stencil[0].writemask = 0xff;
+   ctx->dsa_write_depth_stencil =
+      pipe->create_depth_stencil_alpha_state(pipe, &dsa);
    /* The DSA state objects which write depth and stencil are created
     * on-demand. */
 
@@ -210,12 +210,8 @@ void util_blitter_destroy(struct blitter_context *blitter)
    pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
    pipe->delete_depth_stencil_alpha_state(pipe,
                                           ctx->dsa_write_depth_keep_stencil);
-
-   for (i = 0; i < 0xff; i++)
-      if (ctx->dsa_write_depth_stencil[i])
-         pipe->delete_depth_stencil_alpha_state(pipe,
-            ctx->dsa_write_depth_stencil[i]);
-
+   pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_stencil);
    pipe->delete_rasterizer_state(pipe, ctx->rs_state);
    pipe->delete_vs_state(pipe, ctx->vs_col);
    pipe->delete_vs_state(pipe, ctx->vs_tex);
@@ -412,26 +408,6 @@ static void blitter_draw_quad(struct blitter_context_priv *ctx)
                            2); /* attribs/vert */
 }
 
-static INLINE
-void *blitter_get_state_write_depth_stencil(
-               struct blitter_context_priv *ctx,
-               unsigned stencil)
-{
-   struct pipe_context *pipe = ctx->pipe;
-
-   stencil &= 0xff;
-
-   /* Create the DSA state on-demand. */
-   if (!ctx->dsa_write_depth_stencil[stencil]) {
-      ctx->template_dsa.stencil[0].ref_value = stencil;
-
-      ctx->dsa_write_depth_stencil[stencil] =
-         pipe->create_depth_stencil_alpha_state(pipe, &ctx->template_dsa);
-   }
-
-   return ctx->dsa_write_depth_stencil[stencil];
-}
-
 static INLINE
 void **blitter_get_sampler_state(struct blitter_context_priv *ctx,
                                  int miplevel)
@@ -559,9 +535,13 @@ void util_blitter_clear(struct blitter_context *blitter,
    else
       pipe->bind_blend_state(pipe, ctx->blend_keep_color);
 
-   if (clear_buffers & PIPE_CLEAR_DEPTHSTENCIL)
-      pipe->bind_depth_stencil_alpha_state(pipe,
-         blitter_get_state_write_depth_stencil(ctx, stencil));
+   if (clear_buffers & PIPE_CLEAR_DEPTHSTENCIL) {
+      struct pipe_stencil_ref sr;
+      memset (&sr, 0, sizeof(sr));
+      sr.ref_value[0] = stencil & 0xff;
+      pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_stencil);
+      pipe->set_stencil_ref(pipe, &sr);
+   }
    else
       pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
 
@@ -573,6 +553,7 @@ void util_blitter_clear(struct blitter_context *blitter,
    blitter_set_rectangle(ctx, 0, 0, width, height, depth);
    blitter_draw_quad(ctx);
    blitter_restore_CSOs(ctx);
+   /* XXX driver's responsibility to restore stencil refs? */
 }
 
 static boolean
index f1e6a60e0416cc86a0f5a6486ca9cbeb1258020a..f82b77903e93674a316a1a1142de34e2407a3685 100644 (file)
@@ -186,8 +186,11 @@ struct pipe_context {
    void (*set_blend_color)( struct pipe_context *,
                             const struct pipe_blend_color * );
 
+   void (*set_stencil_ref)( struct pipe_context *,
+                            const struct pipe_stencil_ref * );
+
    void (*set_clip_state)( struct pipe_context *,
-                          const struct pipe_clip_state * );
+                            const struct pipe_clip_state * );
 
    void (*set_constant_buffer)( struct pipe_context *,
                                 uint shader, uint index,
index 68369570b95aac83e4c91906677e011198b3a5ab..80e02ae70e335672e725980f4e27bc83b38f435d 100644 (file)
@@ -199,7 +199,6 @@ struct pipe_stencil_state
    unsigned fail_op:3;  /**< PIPE_STENCIL_OP_x */
    unsigned zpass_op:3; /**< PIPE_STENCIL_OP_x */
    unsigned zfail_op:3; /**< PIPE_STENCIL_OP_x */
-   ubyte ref_value;
    ubyte valuemask;
    ubyte writemask;
 };
@@ -251,6 +250,10 @@ struct pipe_blend_color
    float color[4];
 };
 
+struct pipe_stencil_ref
+{
+   ubyte ref_value[2];
+};
 
 struct pipe_framebuffer_state
 {
index 88b80a07fc98402fd89a6c7022eb7995ecb6910c..4395c68209384b5b99c5143717f073fdadd42a5b 100644 (file)
@@ -94,9 +94,11 @@ static void
 update_depth_stencil_alpha(struct st_context *st)
 {
    struct pipe_depth_stencil_alpha_state *dsa = &st->state.depth_stencil;
+   struct pipe_stencil_ref sr;
    GLcontext *ctx = st->ctx;
 
    memset(dsa, 0, sizeof(*dsa));
+   memset(&sr, 0, sizeof(sr));
 
    if (ctx->Depth.Test && ctx->DrawBuffer->Visual.depthBits > 0) {
       dsa->depth.enabled = 1;
@@ -110,9 +112,9 @@ update_depth_stencil_alpha(struct st_context *st)
       dsa->stencil[0].fail_op = gl_stencil_op_to_pipe(ctx->Stencil.FailFunc[0]);
       dsa->stencil[0].zfail_op = gl_stencil_op_to_pipe(ctx->Stencil.ZFailFunc[0]);
       dsa->stencil[0].zpass_op = gl_stencil_op_to_pipe(ctx->Stencil.ZPassFunc[0]);
-      dsa->stencil[0].ref_value = ctx->Stencil.Ref[0] & 0xff;
       dsa->stencil[0].valuemask = ctx->Stencil.ValueMask[0] & 0xff;
       dsa->stencil[0].writemask = ctx->Stencil.WriteMask[0] & 0xff;
+      sr.ref_value[0] = ctx->Stencil.Ref[0] & 0xff;
 
       if (ctx->Stencil._TestTwoSide) {
          const GLuint back = ctx->Stencil._BackFace;
@@ -124,10 +126,15 @@ update_depth_stencil_alpha(struct st_context *st)
          dsa->stencil[1].ref_value = ctx->Stencil.Ref[back] & 0xff;
          dsa->stencil[1].valuemask = ctx->Stencil.ValueMask[back] & 0xff;
          dsa->stencil[1].writemask = ctx->Stencil.WriteMask[back] & 0xff;
+         sr.ref_value[1] = ctx->Stencil.Ref[back] & 0xff;
       }
       else {
+         /* This should be unnecessary. Drivers must not expect this to
+          * contain valid data, except the enabled bit
+          */
          dsa->stencil[1] = dsa->stencil[0];
          dsa->stencil[1].enabled = 0;
+         sr.ref_value[1] = sr.ref_value[0];
       }
    }
 
@@ -138,6 +145,7 @@ update_depth_stencil_alpha(struct st_context *st)
    }
 
    cso_set_depth_stencil_alpha(st->cso_context, dsa);
+   cso_set_stencil_ref(st->cso_context, &sr);
 }