summaryrefslogtreecommitdiffstats
path: root/src/mesa/main/stencil.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/main/stencil.c')
-rw-r--r--src/mesa/main/stencil.c289
1 files changed, 131 insertions, 158 deletions
diff --git a/src/mesa/main/stencil.c b/src/mesa/main/stencil.c
index ca7f6eaf88b..17464310b1a 100644
--- a/src/mesa/main/stencil.c
+++ b/src/mesa/main/stencil.c
@@ -1,8 +1,8 @@
/*
* Mesa 3-D graphics library
- * Version: 6.5.2
+ * Version: 7.1
*
- * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2007 Brian Paul 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"),
@@ -53,6 +53,48 @@
#include "mtypes.h"
+static GLboolean
+validate_stencil_op(GLcontext *ctx, GLenum op)
+{
+ switch (op) {
+ case GL_KEEP:
+ case GL_ZERO:
+ case GL_REPLACE:
+ case GL_INCR:
+ case GL_DECR:
+ case GL_INVERT:
+ return GL_TRUE;
+ case GL_INCR_WRAP_EXT:
+ case GL_DECR_WRAP_EXT:
+ if (ctx->Extensions.EXT_stencil_wrap) {
+ return GL_TRUE;
+ }
+ /* FALL-THROUGH */
+ default:
+ return GL_FALSE;
+ }
+}
+
+
+static GLboolean
+validate_stencil_func(GLcontext *ctx, GLenum func)
+{
+ switch (func) {
+ case GL_NEVER:
+ case GL_LESS:
+ case GL_LEQUAL:
+ case GL_GREATER:
+ case GL_GEQUAL:
+ case GL_EQUAL:
+ case GL_NOTEQUAL:
+ case GL_ALWAYS:
+ return GL_TRUE;
+ default:
+ return GL_FALSE;
+ }
+}
+
+
/**
* Set the clear value for the stencil buffer.
*
@@ -103,34 +145,15 @@ _mesa_StencilFuncSeparateATI( GLenum frontfunc, GLenum backfunc, GLint ref, GLui
const GLint stencilMax = (1 << ctx->DrawBuffer->Visual.stencilBits) - 1;
ASSERT_OUTSIDE_BEGIN_END(ctx);
- switch (frontfunc) {
- case GL_NEVER:
- case GL_LESS:
- case GL_LEQUAL:
- case GL_GREATER:
- case GL_GEQUAL:
- case GL_EQUAL:
- case GL_NOTEQUAL:
- case GL_ALWAYS:
- break;
- default:
- _mesa_error( ctx, GL_INVALID_ENUM, "glStencilFuncSeparateATI (0x%04x)", frontfunc );
- return;
+ if (!validate_stencil_func(ctx, frontfunc)) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glStencilFuncSeparateATI(frontfunc)");
+ return;
}
-
- switch (backfunc) {
- case GL_NEVER:
- case GL_LESS:
- case GL_LEQUAL:
- case GL_GREATER:
- case GL_GEQUAL:
- case GL_EQUAL:
- case GL_NOTEQUAL:
- case GL_ALWAYS:
- break;
- default:
- _mesa_error( ctx, GL_INVALID_ENUM, "glStencilFuncSeparateATI (0x%04x)", backfunc );
- return;
+ if (!validate_stencil_func(ctx, backfunc)) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glStencilFuncSeparateATI(backfunc)");
+ return;
}
ref = CLAMP( ref, 0, stencilMax );
@@ -157,6 +180,61 @@ _mesa_StencilFuncSeparateATI( GLenum frontfunc, GLenum backfunc, GLint ref, GLui
}
+void APIENTRY
+_mesa_StencilOpSeparateATI(GLenum face, GLenum sfail, GLenum zfail, GLenum zpass)
+{
+ GLboolean set = GL_FALSE;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (!validate_stencil_op(ctx, sfail)) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOpSeparateATI(sfail)");
+ return;
+ }
+ if (!validate_stencil_op(ctx, zfail)) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOpSeparateATI(zfail)");
+ return;
+ }
+ if (!validate_stencil_op(ctx, zpass)) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOpSeparateATI(zpass)");
+ return;
+ }
+ if (face != GL_FRONT && face != GL_BACK && face != GL_FRONT_AND_BACK) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOpSeparateATI(face)");
+ return;
+ }
+
+ if (face != GL_BACK) {
+ /* set front */
+ if (ctx->Stencil.ZFailFunc[0] != zfail ||
+ ctx->Stencil.ZPassFunc[0] != zpass ||
+ ctx->Stencil.FailFunc[0] != sfail){
+ FLUSH_VERTICES(ctx, _NEW_STENCIL);
+ ctx->Stencil.ZFailFunc[0] = zfail;
+ ctx->Stencil.ZPassFunc[0] = zpass;
+ ctx->Stencil.FailFunc[0] = sfail;
+ set = GL_TRUE;
+ }
+ }
+ if (face != GL_FRONT) {
+ /* set back */
+ if (ctx->Stencil.ZFailFunc[1] != zfail ||
+ ctx->Stencil.ZPassFunc[1] != zpass ||
+ ctx->Stencil.FailFunc[1] != sfail) {
+ FLUSH_VERTICES(ctx, _NEW_STENCIL);
+ ctx->Stencil.ZFailFunc[1] = zfail;
+ ctx->Stencil.ZPassFunc[1] = zpass;
+ ctx->Stencil.FailFunc[1] = sfail;
+ set = GL_TRUE;
+ }
+ }
+ if (set && ctx->Driver.StencilOpSeparate) {
+ ctx->Driver.StencilOpSeparate(ctx, face, sfail, zfail, zpass);
+ }
+}
+
+
+
/**
* Set the function and reference value for stencil testing.
*
@@ -177,19 +255,9 @@ _mesa_StencilFunc( GLenum func, GLint ref, GLuint mask )
const GLint stencilMax = (1 << ctx->DrawBuffer->Visual.stencilBits) - 1;
ASSERT_OUTSIDE_BEGIN_END(ctx);
- switch (func) {
- case GL_NEVER:
- case GL_LESS:
- case GL_LEQUAL:
- case GL_GREATER:
- case GL_GEQUAL:
- case GL_EQUAL:
- case GL_NOTEQUAL:
- case GL_ALWAYS:
- break;
- default:
- _mesa_error( ctx, GL_INVALID_ENUM, "glStencilFunc (0x%04x)", func );
- return;
+ if (!validate_stencil_func(ctx, func)) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glStencilFunc(func)");
+ return;
}
ref = CLAMP( ref, 0, stencilMax );
@@ -293,59 +361,17 @@ _mesa_StencilOp(GLenum fail, GLenum zfail, GLenum zpass)
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
- switch (fail) {
- case GL_KEEP:
- case GL_ZERO:
- case GL_REPLACE:
- case GL_INCR:
- case GL_DECR:
- case GL_INVERT:
- break;
- case GL_INCR_WRAP_EXT:
- case GL_DECR_WRAP_EXT:
- if (ctx->Extensions.EXT_stencil_wrap) {
- break;
- }
- /* FALL-THROUGH */
- default:
- _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOp");
- return;
+ if (!validate_stencil_op(ctx, fail)) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOp(sfail)");
+ return;
}
- switch (zfail) {
- case GL_KEEP:
- case GL_ZERO:
- case GL_REPLACE:
- case GL_INCR:
- case GL_DECR:
- case GL_INVERT:
- break;
- case GL_INCR_WRAP_EXT:
- case GL_DECR_WRAP_EXT:
- if (ctx->Extensions.EXT_stencil_wrap) {
- break;
- }
- /* FALL-THROUGH */
- default:
- _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOp");
- return;
+ if (!validate_stencil_op(ctx, zfail)) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOp(zfail)");
+ return;
}
- switch (zpass) {
- case GL_KEEP:
- case GL_ZERO:
- case GL_REPLACE:
- case GL_INCR:
- case GL_DECR:
- case GL_INVERT:
- break;
- case GL_INCR_WRAP_EXT:
- case GL_DECR_WRAP_EXT:
- if (ctx->Extensions.EXT_stencil_wrap) {
- break;
- }
- /* FALL-THROUGH */
- default:
- _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOp");
- return;
+ if (!validate_stencil_op(ctx, zpass)) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOp(zpass)");
+ return;
}
if (ctx->Extensions.ATI_separate_stencil) {
@@ -428,59 +454,17 @@ _mesa_StencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
return;
}
- switch (fail) {
- case GL_KEEP:
- case GL_ZERO:
- case GL_REPLACE:
- case GL_INCR:
- case GL_DECR:
- case GL_INVERT:
- break;
- case GL_INCR_WRAP_EXT:
- case GL_DECR_WRAP_EXT:
- if (ctx->Extensions.EXT_stencil_wrap) {
- break;
- }
- /* FALL-THROUGH */
- default:
- _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOpSeparate(fail)");
- return;
+ if (!validate_stencil_op(ctx, fail)) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOpSeparate(sfail)");
+ return;
}
- switch (zfail) {
- case GL_KEEP:
- case GL_ZERO:
- case GL_REPLACE:
- case GL_INCR:
- case GL_DECR:
- case GL_INVERT:
- break;
- case GL_INCR_WRAP_EXT:
- case GL_DECR_WRAP_EXT:
- if (ctx->Extensions.EXT_stencil_wrap) {
- break;
- }
- /* FALL-THROUGH */
- default:
- _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOpSeparate(zfail)");
- return;
+ if (!validate_stencil_op(ctx, zfail)) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOpSeparate(zfail)");
+ return;
}
- switch (zpass) {
- case GL_KEEP:
- case GL_ZERO:
- case GL_REPLACE:
- case GL_INCR:
- case GL_DECR:
- case GL_INVERT:
- break;
- case GL_INCR_WRAP_EXT:
- case GL_DECR_WRAP_EXT:
- if (ctx->Extensions.EXT_stencil_wrap) {
- break;
- }
- /* FALL-THROUGH */
- default:
- _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOpSeparate(zpass)");
- return;
+ if (!validate_stencil_op(ctx, zpass)) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOpSeparate(zpass)");
+ return;
}
FLUSH_VERTICES(ctx, _NEW_STENCIL);
@@ -513,20 +497,9 @@ _mesa_StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
_mesa_error(ctx, GL_INVALID_ENUM, "glStencilFuncSeparate(face)");
return;
}
-
- switch (func) {
- case GL_NEVER:
- case GL_LESS:
- case GL_LEQUAL:
- case GL_GREATER:
- case GL_GEQUAL:
- case GL_EQUAL:
- case GL_NOTEQUAL:
- case GL_ALWAYS:
- break;
- default:
- _mesa_error(ctx, GL_INVALID_ENUM, "glStencilFuncSeparate(func)");
- return;
+ if (!validate_stencil_func(ctx, func)) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glStencilFuncSeparate(func)");
+ return;
}
ref = CLAMP(ref, 0, stencilMax);