/* I'm almost certain I forgot something here */
#if 0 /* This should work now.. */
FALLBACK_IF(ctx->Color.AlphaEnabled); // GL_ALPHA_TEST
+ FALLBACK_IF(ctx->Color.BlendEnabled); // GL_BLEND
#endif
- //FALLBACK_IF(ctx->Color.BlendEnabled); // GL_BLEND
FALLBACK_IF(ctx->Fog.Enabled); // GL_FOG
FALLBACK_IF(ctx->Line.SmoothFlag); // GL_LINE_SMOOTH
FALLBACK_IF(ctx->Line.StippleFlag); // GL_LINE_STIPPLE
FALLBACK_IF(ctx->Polygon.OffsetFill); // GL_POLYGON_OFFSET_FILL
FALLBACK_IF(ctx->Polygon.SmoothFlag); // GL_POLYGON_SMOOTH
FALLBACK_IF(ctx->Polygon.StippleFlag); // GL_POLYGON_STIPPLE
- FALLBACK_IF(ctx->Stencil.Enabled); // GL_STENCIL_TEST
+ //FALLBACK_IF(ctx->Stencil.Enabled); // GL_STENCIL_TEST
FALLBACK_IF(ctx->Multisample.Enabled); // GL_MULTISAMPLE_ARB
/* One step at a time - let one texture pass.. */
- for (i = 2; i < ctx->Const.MaxTextureUnits; i++)
+ for (i = 1; i < ctx->Const.MaxTextureUnits; i++)
FALLBACK_IF(ctx->Texture.Unit[i].Enabled);
r300->hw.zs.cmd[R300_ZS_CNTL_0] = newval;
break;
+
+ case GL_STENCIL_TEST:
+ if (r300->state.hw_stencil) {
+ R300_STATECHANGE(r300, zs);
+ if (state) {
+ r300->hw.zs.cmd[R300_ZS_CNTL_0] |=
+ R300_STENCIL_ENABLE;
+ } else {
+ r300->hw.zs.cmd[R300_ZS_CNTL_0] &=
+ ~R300_STENCIL_ENABLE;
+ }
+ } else {
+ FALLBACK(&r300->radeon, RADEON_FALLBACK_STENCIL, state);
+ }
+ break;
case GL_CULL_FACE:
r300UpdateCulling(ctx);
break;
}
- fprintf(stderr, "ZS_CNTL_1=%08x\n", r300->hw.zs.cmd[R300_ZS_CNTL_1]);
}
R300_STATECHANGE(r300, vps);
r300->hw.vps.cmd[R300_VPS_POINTSIZE] = r300PackFloat32(1.0);
}
+/* =============================================================
+ * Stencil
+ */
+
+static void r300StencilFunc(GLcontext * ctx, GLenum func,
+ GLint ref, GLuint mask)
+{
+ r300ContextPtr rmesa = R300_CONTEXT(ctx);
+ GLuint refmask = ((ctx->Stencil.Ref[0] << R300_RB3D_ZS2_STENCIL_REF_SHIFT) |
+ (ctx->Stencil.
+ ValueMask[0] << R300_RB3D_ZS2_STENCIL_MASK_SHIFT));
+
+ R200_STATECHANGE(rmesa, zs);
+
+ rmesa->hw.zs.cmd[R300_ZS_CNTL_1] &= ~(R300_ZS_MASK << R300_RB3D_ZS1_STENCIL_FUNC_SHIFT);
+ rmesa->hw.zs.cmd[R300_ZS_CNTL_2] &= ~((R300_ZS_MASK << R300_RB3D_ZS2_STENCIL_REF_SHIFT) |
+ (R300_ZS_MASK << R300_RB3D_ZS2_STENCIL_MASK_SHIFT));
+
+ switch (ctx->Stencil.Function[0]) {
+ case GL_NEVER:
+ rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |=
+ R300_ZS_NEVER << R300_RB3D_ZS1_STENCIL_FUNC_SHIFT;
+ break;
+ case GL_LESS:
+ rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |=
+ R300_ZS_LESS << R300_RB3D_ZS1_STENCIL_FUNC_SHIFT;
+ break;
+ case GL_EQUAL:
+ rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |=
+ R300_ZS_EQUAL << R300_RB3D_ZS1_STENCIL_FUNC_SHIFT;
+ break;
+ case GL_LEQUAL:
+ rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |=
+ R300_ZS_LEQUAL << R300_RB3D_ZS1_STENCIL_FUNC_SHIFT;
+ break;
+ case GL_GREATER:
+ rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |=
+ R300_ZS_GREATER << R300_RB3D_ZS1_STENCIL_FUNC_SHIFT;
+ break;
+ case GL_NOTEQUAL:
+ rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |=
+ R300_ZS_NOTEQUAL << R300_RB3D_ZS1_STENCIL_FUNC_SHIFT;
+ break;
+ case GL_GEQUAL:
+ rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |=
+ R300_ZS_GEQUAL << R300_RB3D_ZS1_STENCIL_FUNC_SHIFT;
+ break;
+ case GL_ALWAYS:
+ rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |=
+ R300_ZS_ALWAYS << R300_RB3D_ZS1_STENCIL_FUNC_SHIFT;
+ break;
+ }
+
+ rmesa->hw.zs.cmd[R300_ZS_CNTL_2] |= refmask;
+}
+
+static void r300StencilMask(GLcontext * ctx, GLuint mask)
+{
+ r300ContextPtr rmesa = R300_CONTEXT(ctx);
+
+ R200_STATECHANGE(rmesa, zs);
+ rmesa->hw.zs.cmd[R300_ZS_CNTL_2] &= ~(R300_ZS_MASK << R300_RB3D_ZS2_STENCIL_WRITE_MASK_SHIFT);
+ rmesa->hw.zs.cmd[R300_ZS_CNTL_2] |= ctx->Stencil.WriteMask[0] << R300_RB3D_ZS2_STENCIL_WRITE_MASK_SHIFT;
+}
+
+static int translate_stencil_op(int op)
+{
+ switch (op) {
+ case GL_KEEP:
+ return R300_ZS_KEEP;
+ case GL_ZERO:
+ return R300_ZS_ZERO;
+ case GL_REPLACE:
+ return R300_ZS_REPLACE;
+ case GL_INCR:
+ return R300_ZS_INCR;
+ case GL_DECR:
+ return R300_ZS_DECR;
+ case GL_INCR_WRAP_EXT:
+ return R300_ZS_INCR_WRAP;
+ case GL_DECR_WRAP_EXT:
+ return R300_ZS_DECR_WRAP;
+ case GL_INVERT:
+ return R300_ZS_INVERT;
+ }
+}
+
+static void r300StencilOp(GLcontext * ctx, GLenum fail,
+ GLenum zfail, GLenum zpass)
+{
+ r300ContextPtr rmesa = R300_CONTEXT(ctx);
+
+ R200_STATECHANGE(rmesa, zs);
+ rmesa->hw.zs.cmd[R300_ZS_CNTL_1] &= ~((R300_ZS_MASK << R300_RB3D_ZS1_STENCIL_FAIL_OP_SHIFT)
+ | (R300_ZS_MASK << R300_RB3D_ZS1_STENCIL_ZPASS_OP_SHIFT)
+ | (R300_ZS_MASK << R300_RB3D_ZS1_STENCIL_ZFAIL_OP_SHIFT)
+ );
+
+ rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |=
+ (translate_stencil_op(ctx->Stencil.FailFunc[0]) << R300_RB3D_ZS1_STENCIL_FAIL_OP_SHIFT)
+ |(translate_stencil_op(ctx->Stencil.ZFailFunc[0]) << R300_RB3D_ZS1_STENCIL_ZFAIL_OP_SHIFT)
+ |(translate_stencil_op(ctx->Stencil.ZPassFunc[0]) << R300_RB3D_ZS1_STENCIL_ZPASS_OP_SHIFT);
+
+}
+
+static void r300ClearStencil(GLcontext * ctx, GLint s)
+{
+ r300ContextPtr rmesa = R300_CONTEXT(ctx);
+
+ /* Not sure whether this is correct.. */
+ R200_STATECHANGE(rmesa, zs);
+ rmesa->hw.zs.cmd[R300_ZS_CNTL_2] =
+ ((GLuint) ctx->Stencil.Clear |
+ (0xff << R200_STENCIL_MASK_SHIFT) |
+ (ctx->Stencil.WriteMask[0] << R200_STENCIL_WRITEMASK_SHIFT));
+}
/* =============================================================
* Window position and viewport transformation
exit(-1);
}
+ /* Only have hw stencil when depth buffer is 24 bits deep */
+ r300->state.hw_stencil = (ctx->Visual.stencilBits > 0 &&
+ ctx->Visual.depthBits == 24);
+
memset(&(r300->state.texture), 0, sizeof(r300->state.texture));
r300ResetHwState(r300);
functions->CullFace = r300CullFace;
functions->FrontFace = r300FrontFace;
+ /* Stencil related */
+ functions->ClearStencil = r300ClearStencil;
+ functions->StencilFunc = r300StencilFunc;
+ functions->StencilMask = r300StencilMask;
+ functions->StencilOp = r300StencilOp;
+
/* Viewport related */
functions->Viewport = r300Viewport;
functions->DepthRange = r300DepthRange;