Mesa (master): i915: Add support for EXT_stencil_two_side and ATI_separate_stencil.

Eric Anholt anholt at kemper.freedesktop.org
Thu Jul 30 04:56:25 UTC 2009


Module: Mesa
Branch: master
Commit: 246729162ccc7e2672aa6cc957053ce3a8975a2c
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=246729162ccc7e2672aa6cc957053ce3a8975a2c

Author: Eric Anholt <eric at anholt.net>
Date:   Wed Jul 29 14:06:05 2009 -0700

i915: Add support for EXT_stencil_two_side and ATI_separate_stencil.

Passes tests/stencil_twoside and glean/stencil2.

---

 src/mesa/drivers/dri/i915/i915_context.c      |    2 +
 src/mesa/drivers/dri/i915/i915_context.h      |    5 +-
 src/mesa/drivers/dri/i915/i915_reg.h          |    2 +
 src/mesa/drivers/dri/i915/i915_state.c        |  151 +++++++++++++++++--------
 src/mesa/drivers/dri/i915/i915_vtbl.c         |    7 +-
 src/mesa/drivers/dri/intel/intel_extensions.c |    2 +
 6 files changed, 115 insertions(+), 54 deletions(-)

diff --git a/src/mesa/drivers/dri/i915/i915_context.c b/src/mesa/drivers/dri/i915/i915_context.c
index 367d2a3..5aa4133 100644
--- a/src/mesa/drivers/dri/i915/i915_context.c
+++ b/src/mesa/drivers/dri/i915/i915_context.c
@@ -75,6 +75,8 @@ i915InvalidateState(GLcontext * ctx, GLuint new_state)
 
    if (new_state & (_NEW_FOG | _NEW_HINT | _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS))
       i915_update_fog(ctx);
+   if (new_state & (_NEW_STENCIL | _NEW_BUFFERS | _NEW_POLYGON))
+      i915_update_stencil(ctx);
 }
 
 
diff --git a/src/mesa/drivers/dri/i915/i915_context.h b/src/mesa/drivers/dri/i915/i915_context.h
index 87bbf5f..c6b7377 100644
--- a/src/mesa/drivers/dri/i915/i915_context.h
+++ b/src/mesa/drivers/dri/i915/i915_context.h
@@ -82,7 +82,9 @@
 #define I915_CTXREG_IAB   	 	6
 #define I915_CTXREG_BLENDCOLOR0		7
 #define I915_CTXREG_BLENDCOLOR1		8
-#define I915_CTX_SETUP_SIZE		9
+#define I915_CTXREG_BF_STENCIL_OPS	9
+#define I915_CTXREG_BF_STENCIL_MASKS	10
+#define I915_CTX_SETUP_SIZE		11
 
 #define I915_FOGREG_COLOR		0
 #define I915_FOGREG_MODE0		1
@@ -321,6 +323,7 @@ extern void i915_print_ureg(const char *msg, GLuint ureg);
 extern void i915InitStateFunctions(struct dd_function_table *functions);
 extern void i915InitState(struct i915_context *i915);
 extern void i915_update_fog(GLcontext * ctx);
+extern void i915_update_stencil(GLcontext * ctx);
 
 
 /*======================================================================
diff --git a/src/mesa/drivers/dri/i915/i915_reg.h b/src/mesa/drivers/dri/i915/i915_reg.h
index 84db58e..80ec461 100644
--- a/src/mesa/drivers/dri/i915/i915_reg.h
+++ b/src/mesa/drivers/dri/i915/i915_reg.h
@@ -86,8 +86,10 @@
 #define BFM_ENABLE_STENCIL_WRITE_MASK     (1<<16)
 #define BFM_STENCIL_TEST_MASK_SHIFT       8
 #define BFM_STENCIL_TEST_MASK_MASK        (0xff<<8)
+#define BFM_STENCIL_TEST_MASK(x)	  (((x)&0xff) << 8)
 #define BFM_STENCIL_WRITE_MASK_SHIFT      0
 #define BFM_STENCIL_WRITE_MASK_MASK       (0xff<<0)
+#define BFM_STENCIL_WRITE_MASK(x)	  ((x)&0xff)
 
 
 
diff --git a/src/mesa/drivers/dri/i915/i915_state.c b/src/mesa/drivers/dri/i915/i915_state.c
index 814fb59..670451b 100644
--- a/src/mesa/drivers/dri/i915/i915_state.c
+++ b/src/mesa/drivers/dri/i915/i915_state.c
@@ -48,73 +48,119 @@
 
 #define FILE_DEBUG_FLAG DEBUG_STATE
 
-static void
-i915StencilFuncSeparate(GLcontext * ctx, GLenum face, GLenum func, GLint ref,
-                        GLuint mask)
+void
+i915_update_stencil(GLcontext * ctx)
 {
    struct i915_context *i915 = I915_CONTEXT(ctx);
-   int test = intel_translate_compare_func(func);
-
-   mask = mask & 0xff;
+   GLuint front_ref, front_writemask, front_mask;
+   GLenum front_func, front_fail, front_pass_z_fail, front_pass_z_pass;
+   GLuint back_ref, back_writemask, back_mask;
+   GLenum back_func, back_fail, back_pass_z_fail, back_pass_z_pass;
 
-   DBG("%s : func: %s, ref : 0x%x, mask: 0x%x\n", __FUNCTION__,
-       _mesa_lookup_enum_by_nr(func), ref, mask);
+   I915_STATECHANGE(i915, I915_UPLOAD_CTX);
 
+   /* The 915 considers CW to be "front" for two-sided stencil, so choose
+    * appropriately.
+    */
+   /* _NEW_POLYGON | _NEW_STENCIL */
+   if (ctx->Polygon.FrontFace == GL_CW) {
+      front_ref = ctx->Stencil.Ref[0];
+      front_mask = ctx->Stencil.ValueMask[0];
+      front_writemask = ctx->Stencil.WriteMask[0];
+      front_func = ctx->Stencil.Function[0];
+      front_fail = ctx->Stencil.FailFunc[0];
+      front_pass_z_fail = ctx->Stencil.ZFailFunc[0];
+      front_pass_z_pass = ctx->Stencil.ZPassFunc[0];
+      back_ref = ctx->Stencil.Ref[ctx->Stencil._BackFace];
+      back_mask = ctx->Stencil.ValueMask[ctx->Stencil._BackFace];
+      back_writemask = ctx->Stencil.WriteMask[ctx->Stencil._BackFace];
+      back_func = ctx->Stencil.Function[ctx->Stencil._BackFace];
+      back_fail = ctx->Stencil.FailFunc[ctx->Stencil._BackFace];
+      back_pass_z_fail = ctx->Stencil.ZFailFunc[ctx->Stencil._BackFace];
+      back_pass_z_pass = ctx->Stencil.ZPassFunc[ctx->Stencil._BackFace];
+   } else {
+      front_ref = ctx->Stencil.Ref[ctx->Stencil._BackFace];
+      front_mask = ctx->Stencil.ValueMask[ctx->Stencil._BackFace];
+      front_writemask = ctx->Stencil.WriteMask[ctx->Stencil._BackFace];
+      front_func = ctx->Stencil.Function[ctx->Stencil._BackFace];
+      front_fail = ctx->Stencil.FailFunc[ctx->Stencil._BackFace];
+      front_pass_z_fail = ctx->Stencil.ZFailFunc[ctx->Stencil._BackFace];
+      front_pass_z_pass = ctx->Stencil.ZPassFunc[ctx->Stencil._BackFace];
+      back_ref = ctx->Stencil.Ref[0];
+      back_mask = ctx->Stencil.ValueMask[0];
+      back_writemask = ctx->Stencil.WriteMask[0];
+      back_func = ctx->Stencil.Function[0];
+      back_fail = ctx->Stencil.FailFunc[0];
+      back_pass_z_fail = ctx->Stencil.ZFailFunc[0];
+      back_pass_z_pass = ctx->Stencil.ZPassFunc[0];
+   }
 
-   I915_STATECHANGE(i915, I915_UPLOAD_CTX);
-   i915->state.Ctx[I915_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_TEST_MASK;
+   /* Set front state. */
+   i915->state.Ctx[I915_CTXREG_STATE4] &= ~(MODE4_ENABLE_STENCIL_TEST_MASK |
+					    MODE4_ENABLE_STENCIL_WRITE_MASK);
    i915->state.Ctx[I915_CTXREG_STATE4] |= (ENABLE_STENCIL_TEST_MASK |
-                                           STENCIL_TEST_MASK(mask));
+					   ENABLE_STENCIL_WRITE_MASK |
+					   STENCIL_TEST_MASK(front_mask) |
+					   STENCIL_WRITE_MASK(front_writemask));
 
    i915->state.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_REF_MASK |
-                                          S5_STENCIL_TEST_FUNC_MASK);
+					  S5_STENCIL_TEST_FUNC_MASK |
+					  S5_STENCIL_FAIL_MASK |
+					  S5_STENCIL_PASS_Z_FAIL_MASK |
+					  S5_STENCIL_PASS_Z_PASS_MASK);
+
+   i915->state.Ctx[I915_CTXREG_LIS5] |=
+      (front_ref << S5_STENCIL_REF_SHIFT) |
+      (intel_translate_compare_func(front_func) << S5_STENCIL_TEST_FUNC_SHIFT) |
+      (intel_translate_stencil_op(front_fail) << S5_STENCIL_FAIL_SHIFT) |
+      (intel_translate_stencil_op(front_pass_z_fail) <<
+       S5_STENCIL_PASS_Z_FAIL_SHIFT) |
+      (intel_translate_stencil_op(front_pass_z_pass) <<
+       S5_STENCIL_PASS_Z_PASS_SHIFT);
+
+   /* Set back state if different from front. */
+   if (ctx->Stencil._TestTwoSide) {
+      i915->state.Ctx[I915_CTXREG_BF_STENCIL_OPS] &=
+	 ~(BFO_STENCIL_REF_MASK |
+	   BFO_STENCIL_TEST_MASK |
+	   BFO_STENCIL_FAIL_MASK |
+	   BFO_STENCIL_PASS_Z_FAIL_MASK |
+	   BFO_STENCIL_PASS_Z_PASS_MASK);
+      i915->state.Ctx[I915_CTXREG_BF_STENCIL_OPS] |= BFO_STENCIL_TWO_SIDE |
+	 (back_ref << BFO_STENCIL_REF_SHIFT) |
+	 (intel_translate_compare_func(back_func) << BFO_STENCIL_TEST_SHIFT) |
+	 (intel_translate_stencil_op(back_fail) << BFO_STENCIL_FAIL_SHIFT) |
+	 (intel_translate_stencil_op(back_pass_z_fail) <<
+	  BFO_STENCIL_PASS_Z_FAIL_SHIFT) |
+	 (intel_translate_stencil_op(back_pass_z_pass) <<
+	  BFO_STENCIL_PASS_Z_PASS_SHIFT);
+
+      i915->state.Ctx[I915_CTXREG_BF_STENCIL_MASKS] &=
+	 ~(BFM_STENCIL_TEST_MASK_MASK |
+	   BFM_STENCIL_WRITE_MASK_MASK);
+      i915->state.Ctx[I915_CTXREG_BF_STENCIL_MASKS] |=
+	 BFM_STENCIL_TEST_MASK(back_mask) |
+	 BFM_STENCIL_WRITE_MASK(back_writemask);
+   } else {
+      i915->state.Ctx[I915_CTXREG_BF_STENCIL_OPS] &= ~BFO_STENCIL_TWO_SIDE;
+   }
+}
 
-   i915->state.Ctx[I915_CTXREG_LIS5] |= ((ref << S5_STENCIL_REF_SHIFT) |
-                                         (test <<
-                                          S5_STENCIL_TEST_FUNC_SHIFT));
+static void
+i915StencilFuncSeparate(GLcontext * ctx, GLenum face, GLenum func, GLint ref,
+                        GLuint mask)
+{
 }
 
 static void
 i915StencilMaskSeparate(GLcontext * ctx, GLenum face, GLuint mask)
 {
-   struct i915_context *i915 = I915_CONTEXT(ctx);
-
-   DBG("%s : mask 0x%x\n", __FUNCTION__, mask);
-   
-   mask = mask & 0xff;
-
-   I915_STATECHANGE(i915, I915_UPLOAD_CTX);
-   i915->state.Ctx[I915_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_WRITE_MASK;
-   i915->state.Ctx[I915_CTXREG_STATE4] |= (ENABLE_STENCIL_WRITE_MASK |
-                                           STENCIL_WRITE_MASK(mask));
 }
 
-
 static void
 i915StencilOpSeparate(GLcontext * ctx, GLenum face, GLenum fail, GLenum zfail,
                       GLenum zpass)
 {
-   struct i915_context *i915 = I915_CONTEXT(ctx);
-   int fop = intel_translate_stencil_op(fail);
-   int dfop = intel_translate_stencil_op(zfail);
-   int dpop = intel_translate_stencil_op(zpass);
-
-
-   DBG("%s: fail : %s, zfail: %s, zpass : %s\n", __FUNCTION__,
-       _mesa_lookup_enum_by_nr(fail),
-       _mesa_lookup_enum_by_nr(zfail), _mesa_lookup_enum_by_nr(zpass));
-
-   I915_STATECHANGE(i915, I915_UPLOAD_CTX);
-
-   i915->state.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_FAIL_MASK |
-                                          S5_STENCIL_PASS_Z_FAIL_MASK |
-                                          S5_STENCIL_PASS_Z_PASS_MASK);
-
-   i915->state.Ctx[I915_CTXREG_LIS5] |= ((fop << S5_STENCIL_FAIL_SHIFT) |
-                                         (dfop <<
-                                          S5_STENCIL_PASS_Z_FAIL_SHIFT) |
-                                         (dpop <<
-                                          S5_STENCIL_PASS_Z_PASS_SHIFT));
 }
 
 static void
@@ -945,6 +991,17 @@ i915_init_packets(struct i915_context *i915)
          _3DSTATE_CONST_BLEND_COLOR_CMD;
       i915->state.Ctx[I915_CTXREG_BLENDCOLOR1] = 0;
 
+      i915->state.Ctx[I915_CTXREG_BF_STENCIL_MASKS] =
+	 _3DSTATE_BACKFACE_STENCIL_MASKS |
+	 BFM_ENABLE_STENCIL_TEST_MASK |
+	 BFM_ENABLE_STENCIL_WRITE_MASK |
+	 (0xff << BFM_STENCIL_WRITE_MASK_SHIFT) |
+	 (0xff << BFM_STENCIL_TEST_MASK_SHIFT);
+      i915->state.Ctx[I915_CTXREG_BF_STENCIL_OPS] =
+	 _3DSTATE_BACKFACE_STENCIL_OPS |
+	 BFO_ENABLE_STENCIL_REF |
+	 BFO_ENABLE_STENCIL_FUNCS |
+	 BFO_ENABLE_STENCIL_TWO_SIDE;
    }
 
    {
diff --git a/src/mesa/drivers/dri/i915/i915_vtbl.c b/src/mesa/drivers/dri/i915/i915_vtbl.c
index fe1be93..707864e 100644
--- a/src/mesa/drivers/dri/i915/i915_vtbl.c
+++ b/src/mesa/drivers/dri/i915/i915_vtbl.c
@@ -176,7 +176,7 @@ i915_emit_invarient_state(struct intel_context *intel)
 {
    BATCH_LOCALS;
 
-   BEGIN_BATCH(20, IGNORE_CLIPRECTS);
+   BEGIN_BATCH(18, IGNORE_CLIPRECTS);
 
    OUT_BATCH(_3DSTATE_AA_CMD |
              AA_LINE_ECAAR_WIDTH_ENABLE |
@@ -225,11 +225,6 @@ i915_emit_invarient_state(struct intel_context *intel)
    OUT_BATCH(_3DSTATE_LOAD_INDIRECT | 0);       /* disable indirect state */
    OUT_BATCH(0);
 
-
-   /* Don't support twosided stencil yet */
-   OUT_BATCH(_3DSTATE_BACKFACE_STENCIL_OPS | BFO_ENABLE_STENCIL_TWO_SIDE | 0);
-   OUT_BATCH(0);
-
    ADVANCE_BATCH();
 }
 
diff --git a/src/mesa/drivers/dri/intel/intel_extensions.c b/src/mesa/drivers/dri/intel/intel_extensions.c
index 3a09a53..6a68021 100644
--- a/src/mesa/drivers/dri/intel/intel_extensions.c
+++ b/src/mesa/drivers/dri/intel/intel_extensions.c
@@ -120,8 +120,10 @@ static const struct dri_extension i915_extensions[] = {
    { "GL_ARB_fragment_program",           NULL },
    { "GL_ARB_shadow",                     NULL },
    { "GL_ARB_texture_non_power_of_two",   NULL },
+   { "GL_ATI_separate_stencil",           GL_ATI_separate_stencil_functions },
    { "GL_ATI_texture_env_combine3",       NULL },
    { "GL_EXT_shadow_funcs",               NULL },
+   { "GL_EXT_stencil_two_side",           GL_EXT_stencil_two_side_functions },
    { "GL_NV_texture_env_combine4",        NULL },
    { NULL,                                NULL }
 };




More information about the mesa-commit mailing list