summaryrefslogtreecommitdiffstats
path: root/src/mesa/main
diff options
context:
space:
mode:
authorBrian Paul <[email protected]>2005-01-12 04:01:08 +0000
committerBrian Paul <[email protected]>2005-01-12 04:01:08 +0000
commita9e34c68ac0538699a144f67d3ce83ccb8f49be9 (patch)
treeae9f6d8f3dd361ecc4303e7e19dbe6c9330ee726 /src/mesa/main
parent591b72b6a9718e908b11c7c2fd3bbf9e5b432677 (diff)
Some initial work for OpenGL 2.0: glStencilFunc/Op/MaskSeparate() functions.
Diffstat (limited to 'src/mesa/main')
-rw-r--r--src/mesa/main/dd.h11
-rw-r--r--src/mesa/main/dlist.c80
-rw-r--r--src/mesa/main/state.c5
-rw-r--r--src/mesa/main/stencil.c174
-rw-r--r--src/mesa/main/stencil.h16
5 files changed, 280 insertions, 6 deletions
diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h
index 2b1131bc414..f7f7eacf060 100644
--- a/src/mesa/main/dd.h
+++ b/src/mesa/main/dd.h
@@ -7,7 +7,7 @@
* Mesa 3-D graphics library
* Version: 6.3
*
- * Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2005 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"),
@@ -676,7 +676,16 @@ struct dd_function_table {
void (*StencilMask)(GLcontext *ctx, GLuint mask);
/** Set stencil test actions */
void (*StencilOp)(GLcontext *ctx, GLenum fail, GLenum zfail, GLenum zpass);
+ /** Set active stencil face (GL_EXT_stencil_two_side) */
void (*ActiveStencilFace)(GLcontext *ctx, GLuint face);
+ /** OpenGL 2.0 two-sided StencilFunc */
+ void (*StencilFuncSeparate)(GLcontext *ctx, GLenum face, GLenum func,
+ GLint ref, GLuint mask);
+ /** OpenGL 2.0 two-sided StencilMask */
+ void (*StencilMaskSeparate)(GLcontext *ctx, GLenum face, GLuint mask);
+ /** OpenGL 2.0 two-sided StencilOp */
+ void (*StencilOpSeparate)(GLcontext *ctx, GLenum face, GLenum fail,
+ GLenum zfail, GLenum zpass);
/** Control the generation of texture coordinates */
void (*TexGen)(GLcontext *ctx, GLenum coord, GLenum pname,
const GLfloat *params);
diff --git a/src/mesa/main/dlist.c b/src/mesa/main/dlist.c
index 8ef5269cd89..beacf5b1f99 100644
--- a/src/mesa/main/dlist.c
+++ b/src/mesa/main/dlist.c
@@ -322,6 +322,10 @@ typedef enum {
/* GL_ATI_fragment_shader */
OPCODE_BIND_FRAGMENT_SHADER_ATI,
OPCODE_SET_FRAGMENT_SHADER_CONSTANTS_ATI,
+ /* OpenGL 2.0 */
+ OPCODE_STENCIL_FUNC_SEPARATE,
+ OPCODE_STENCIL_OP_SEPARATE,
+ OPCODE_STENCIL_MASK_SEPARATE,
/* Vertex attributes -- fallback for when optimized display
* list build isn't active.
@@ -799,6 +803,11 @@ _mesa_init_lists( void )
InstSize[OPCODE_BIND_FRAGMENT_SHADER_ATI] = 2;
InstSize[OPCODE_SET_FRAGMENT_SHADER_CONSTANTS_ATI] = 6;
#endif
+ /* OpenGL 2.0 */
+ InstSize[OPCODE_STENCIL_FUNC_SEPARATE] = 5;
+ InstSize[OPCODE_STENCIL_MASK_SEPARATE] = 3;
+ InstSize[OPCODE_STENCIL_OP_SEPARATE] = 5;
+
InstSize[OPCODE_ATTR_1F_NV] = 3;
InstSize[OPCODE_ATTR_2F_NV] = 4;
InstSize[OPCODE_ATTR_3F_NV] = 5;
@@ -3259,6 +3268,61 @@ static void GLAPIENTRY save_StencilOp( GLenum fail, GLenum zfail, GLenum zpass )
}
+static void GLAPIENTRY
+save_StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_STENCIL_FUNC_SEPARATE, 4);
+ if (n) {
+ n[1].e = face;
+ n[2].e = func;
+ n[3].i = ref;
+ n[4].ui = mask;
+ }
+ if (ctx->ExecuteFlag) {
+ ctx->Exec->StencilFuncSeparate(face, func, ref, mask);
+ }
+}
+
+
+static void GLAPIENTRY
+save_StencilMaskSeparate(GLenum face, GLuint mask)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_STENCIL_MASK_SEPARATE, 2);
+ if (n) {
+ n[1].e = face;
+ n[2].ui = mask;
+ }
+ if (ctx->ExecuteFlag) {
+ ctx->Exec->StencilMaskSeparate(face, mask);
+ }
+}
+
+
+static void GLAPIENTRY
+save_StencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION( ctx, OPCODE_STENCIL_OP_SEPARATE, 4 );
+ if (n) {
+ n[1].e = face;
+ n[2].e = fail;
+ n[3].e = zfail;
+ n[4].e = zpass;
+ }
+ if (ctx->ExecuteFlag) {
+ ctx->Exec->StencilOpSeparate(face, fail, zfail, zpass);
+ }
+}
+
+
static void GLAPIENTRY save_TexEnvfv( GLenum target, GLenum pname, const GLfloat *params )
{
GET_CURRENT_CONTEXT(ctx);
@@ -4567,7 +4631,7 @@ static void GLAPIENTRY save_DepthBoundsEXT( GLclampd zmin, GLclampd zmax )
GET_CURRENT_CONTEXT(ctx);
Node *n;
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- n = ALLOC_INSTRUCTION( ctx, OPCODE_ACTIVE_STENCIL_FACE_EXT, 2 );
+ n = ALLOC_INSTRUCTION( ctx, OPCODE_DEPTH_BOUNDS_EXT, 2 );
if (n) {
n[1].f = (GLfloat) zmin;
n[2].f = (GLfloat) zmax;
@@ -6052,6 +6116,15 @@ execute_list( GLcontext *ctx, GLuint list )
case OPCODE_STENCIL_OP:
(*ctx->Exec->StencilOp)( n[1].e, n[2].e, n[3].e );
break;
+ case OPCODE_STENCIL_FUNC_SEPARATE:
+ ctx->Exec->StencilFuncSeparate( n[1].e, n[2].e, n[3].i, n[4].ui );
+ break;
+ case OPCODE_STENCIL_MASK_SEPARATE:
+ ctx->Exec->StencilMaskSeparate( n[1].e, n[2].ui );
+ break;
+ case OPCODE_STENCIL_OP_SEPARATE:
+ ctx->Exec->StencilOpSeparate( n[1].e, n[2].e, n[3].e, n[4].e );
+ break;
case OPCODE_TEXENV:
{
GLfloat params[4];
@@ -7628,6 +7701,11 @@ _mesa_init_dlist_table( struct _glapi_table *table )
table->TexImage3D = save_TexImage3D;
table->TexSubImage3D = save_TexSubImage3D;
+ /* GL 2.0 */
+ table->StencilFuncSeparate = save_StencilFuncSeparate;
+ table->StencilMaskSeparate = save_StencilMaskSeparate;
+ table->StencilOpSeparate = save_StencilOpSeparate;
+
/* GL_ARB_imaging */
/* Not all are supported */
table->BlendColor = save_BlendColor;
diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c
index 64bb02cf01e..886a571eb8d 100644
--- a/src/mesa/main/state.c
+++ b/src/mesa/main/state.c
@@ -382,6 +382,11 @@ _mesa_init_exec_table(struct _glapi_table *exec)
exec->SeparableFilter2D = _mesa_SeparableFilter2D;
#endif
+ /* OpenGL 2.0 */
+ exec->StencilFuncSeparate = _mesa_StencilFuncSeparate;
+ exec->StencilMaskSeparate = _mesa_StencilMaskSeparate;
+ exec->StencilOpSeparate = _mesa_StencilOpSeparate;
+
/* 2. GL_EXT_blend_color */
#if 0
/* exec->BlendColorEXT = _mesa_BlendColorEXT; */
diff --git a/src/mesa/main/stencil.c b/src/mesa/main/stencil.c
index 8c89e8cc13c..dfda4aa8fda 100644
--- a/src/mesa/main/stencil.c
+++ b/src/mesa/main/stencil.c
@@ -5,9 +5,9 @@
/*
* Mesa 3-D graphics library
- * Version: 4.1
+ * Version: 6.3
*
- * Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2005 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"),
@@ -244,6 +244,7 @@ _mesa_StencilOp(GLenum fail, GLenum zfail, GLenum zpass)
}
+
#if _HAVE_FULL_GL
/* GL_EXT_stencil_two_side */
void GLAPIENTRY
@@ -264,6 +265,175 @@ _mesa_ActiveStencilFaceEXT(GLenum face)
#endif
+
+/**
+ * OpenGL 2.0 function.
+ * \todo Make StencilOp() call this function. And eventually remove the
+ * ctx->Driver.StencilOp function and use ctx->Driver.StencilOpSeparate
+ * instead.
+ */
+void GLAPIENTRY
+_mesa_StencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (face != GL_FRONT && face != GL_BACK && face != GL_FRONT_AND_BACK) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOpSeparate(face)");
+ 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;
+ }
+ 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;
+ }
+ 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;
+ }
+
+ FLUSH_VERTICES(ctx, _NEW_STENCIL);
+
+ if (face == GL_FRONT || face == GL_FRONT_AND_BACK) {
+ ctx->Stencil.FailFunc[0] = fail;
+ ctx->Stencil.ZFailFunc[0] = zfail;
+ ctx->Stencil.ZPassFunc[0] = zpass;
+ }
+ if (face == GL_BACK || face == GL_FRONT_AND_BACK) {
+ ctx->Stencil.FailFunc[1] = fail;
+ ctx->Stencil.ZFailFunc[1] = zfail;
+ ctx->Stencil.ZPassFunc[1] = zpass;
+ }
+
+ if (ctx->Driver.StencilOpSeparate) {
+ ctx->Driver.StencilOpSeparate(ctx, face, fail, zfail, zpass);
+ }
+}
+
+
+/* OpenGL 2.0 */
+void GLAPIENTRY
+_mesa_StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLint maxref;
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (face != GL_FRONT && face != GL_BACK && face != GL_FRONT_AND_BACK) {
+ _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;
+ }
+
+ maxref = (1 << STENCIL_BITS) - 1;
+ ref = (GLstencil) CLAMP(ref, 0, maxref);
+
+ FLUSH_VERTICES(ctx, _NEW_STENCIL);
+
+ if (face == GL_FRONT || face == GL_FRONT_AND_BACK) {
+ ctx->Stencil.Function[0] = func;
+ ctx->Stencil.Ref[0] = ref;
+ ctx->Stencil.ValueMask[0] = (GLstencil) mask;
+ }
+ if (face == GL_BACK || face == GL_FRONT_AND_BACK) {
+ ctx->Stencil.Function[1] = func;
+ ctx->Stencil.Ref[1] = ref;
+ ctx->Stencil.ValueMask[1] = (GLstencil) mask;
+ }
+
+ if (ctx->Driver.StencilFuncSeparate) {
+ ctx->Driver.StencilFuncSeparate(ctx, face, func, ref, mask);
+ }
+}
+
+
+/* OpenGL 2.0 */
+void GLAPIENTRY
+_mesa_StencilMaskSeparate(GLenum face, GLuint mask)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (face != GL_FRONT && face != GL_BACK && face != GL_FRONT_AND_BACK) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glStencilaMaskSeparate(face)");
+ return;
+ }
+
+ FLUSH_VERTICES(ctx, _NEW_STENCIL);
+
+ if (face == GL_FRONT || face == GL_FRONT_AND_BACK) {
+ ctx->Stencil.WriteMask[0] = (GLstencil) mask;
+ }
+ if (face == GL_BACK || face == GL_FRONT_AND_BACK) {
+ ctx->Stencil.WriteMask[1] = (GLstencil) mask;
+ }
+
+ if (ctx->Driver.StencilMaskSeparate) {
+ ctx->Driver.StencilMaskSeparate(ctx, face, mask);
+ }
+}
+
+
/**
* Initialize the context stipple state.
*
diff --git a/src/mesa/main/stencil.h b/src/mesa/main/stencil.h
index 5620d14c730..ec2927cfd20 100644
--- a/src/mesa/main/stencil.h
+++ b/src/mesa/main/stencil.h
@@ -5,9 +5,9 @@
/*
* Mesa 3-D graphics library
- * Version: 4.1
+ * Version: 6.3
*
- * Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2005 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"),
@@ -55,6 +55,18 @@ extern void GLAPIENTRY
_mesa_ActiveStencilFaceEXT(GLenum face);
+extern void GLAPIENTRY
+_mesa_StencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass);
+
+
+extern void GLAPIENTRY
+_mesa_StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask);
+
+
+extern void GLAPIENTRY
+_mesa_StencilMaskSeparate(GLenum face, GLuint mask);
+
+
extern void
_mesa_init_stencil( GLcontext * ctx );