summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/dri/i915/i915_state.c
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2009-07-29 14:06:05 -0700
committerEric Anholt <eric@anholt.net>2009-07-29 21:25:39 -0700
commit246729162ccc7e2672aa6cc957053ce3a8975a2c (patch)
tree8558fc540b496800cf7173fcefbd06b276a94f57 /src/mesa/drivers/dri/i915/i915_state.c
parent92b9aa1646daa7d9e6470e9d1dbb3460eeae8941 (diff)
i915: Add support for EXT_stencil_two_side and ATI_separate_stencil.
Passes tests/stencil_twoside and glean/stencil2.
Diffstat (limited to 'src/mesa/drivers/dri/i915/i915_state.c')
-rw-r--r--src/mesa/drivers/dri/i915/i915_state.c151
1 files changed, 104 insertions, 47 deletions
diff --git a/src/mesa/drivers/dri/i915/i915_state.c b/src/mesa/drivers/dri/i915/i915_state.c
index 814fb59fd34..670451bc838 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;
}
{