From 91a04617c40a740ade27e2f60e78a761a297a1d3 Mon Sep 17 00:00:00 2001 From: Daniel Borca Date: Tue, 21 Dec 2004 08:21:52 +0000 Subject: [PATCH] added GL_EXT_stencil_two_side (yes, it works) --- src/mesa/drivers/glide/fxdd.c | 1 + src/mesa/drivers/glide/fxdrv.h | 3 +- src/mesa/drivers/glide/fxsetup.c | 54 +++++++++- src/mesa/drivers/glide/fxtris.c | 225 ++++++++++++++++++++++++++++++++++++--- 4 files changed, 263 insertions(+), 20 deletions(-) diff --git a/src/mesa/drivers/glide/fxdd.c b/src/mesa/drivers/glide/fxdd.c index dedd7da..f0f4e03 100644 --- a/src/mesa/drivers/glide/fxdd.c +++ b/src/mesa/drivers/glide/fxdd.c @@ -1857,6 +1857,7 @@ fxDDInitExtensions(GLcontext * ctx) _mesa_enable_extension(ctx, "GL_EXT_blend_func_separate"); _mesa_enable_extension(ctx, "GL_EXT_texture_env_add"); _mesa_enable_extension(ctx, "GL_EXT_stencil_wrap"); + _mesa_enable_extension(ctx, "GL_EXT_stencil_two_side"); if (fxMesa->haveTwoTMUs) { _mesa_enable_extension(ctx, "GL_ARB_multitexture"); diff --git a/src/mesa/drivers/glide/fxdrv.h b/src/mesa/drivers/glide/fxdrv.h index 9cc6d15..984092d 100644 --- a/src/mesa/drivers/glide/fxdrv.h +++ b/src/mesa/drivers/glide/fxdrv.h @@ -447,7 +447,7 @@ struct tfxMesaContext tfxUnitsState unitsState; tfxUnitsState restoreUnitsState; /* saved during multipass */ - + GLboolean multipass; /* true when drawing intermediate pass */ GLuint new_state; GLuint new_gl_state; @@ -715,6 +715,7 @@ void fxSetupBlend (GLcontext *ctx); void fxSetupDepthTest (GLcontext *ctx); void fxSetupTexture (GLcontext *ctx); void fxSetupStencil (GLcontext *ctx); +void fxSetupStencilFace (GLcontext *ctx, GLint face); /* Flags for software fallback cases */ #define FX_FALLBACK_TEXTURE_MAP 0x0001 diff --git a/src/mesa/drivers/glide/fxsetup.c b/src/mesa/drivers/glide/fxsetup.c index dd8a383..ee945dc 100644 --- a/src/mesa/drivers/glide/fxsetup.c +++ b/src/mesa/drivers/glide/fxsetup.c @@ -1686,6 +1686,10 @@ fxDDStencilFunc (GLcontext *ctx, GLenum func, GLint ref, GLuint mask) fxMesaContext fxMesa = FX_CONTEXT(ctx); tfxUnitsState *us = &fxMesa->unitsState; + if (ctx->Stencil.ActiveFace) { + return; + } + if ( (us->stencilFunction != func) || @@ -1706,6 +1710,10 @@ fxDDStencilMask (GLcontext *ctx, GLuint mask) fxMesaContext fxMesa = FX_CONTEXT(ctx); tfxUnitsState *us = &fxMesa->unitsState; + if (ctx->Stencil.ActiveFace) { + return; + } + if (us->stencilWriteMask != mask) { us->stencilWriteMask = mask; fxMesa->new_state |= FX_NEW_STENCIL; @@ -1718,6 +1726,10 @@ fxDDStencilOp (GLcontext *ctx, GLenum sfail, GLenum zfail, GLenum zpass) fxMesaContext fxMesa = FX_CONTEXT(ctx); tfxUnitsState *us = &fxMesa->unitsState; + if (ctx->Stencil.ActiveFace) { + return; + } + if ( (us->stencilFailFunc != sfail) || @@ -1739,10 +1751,18 @@ fxSetupStencil (GLcontext * ctx) tfxUnitsState *us = &fxMesa->unitsState; if (us->stencilEnabled) { + GrCmpFnc_t stencilFailFunc = GR_STENCILOP_KEEP; + GrCmpFnc_t stencilZFailFunc = GR_STENCILOP_KEEP; + GrCmpFnc_t stencilZPassFunc = GR_STENCILOP_KEEP; + if (!fxMesa->multipass) { + stencilFailFunc = convertGLStencilOp(us->stencilFailFunc); + stencilZFailFunc = convertGLStencilOp(us->stencilZFailFunc); + stencilZPassFunc = convertGLStencilOp(us->stencilZPassFunc); + } grEnable(GR_STENCIL_MODE_EXT); - fxMesa->Glide.grStencilOpExt(convertGLStencilOp(us->stencilFailFunc), - convertGLStencilOp(us->stencilZFailFunc), - convertGLStencilOp(us->stencilZPassFunc)); + fxMesa->Glide.grStencilOpExt(stencilFailFunc, + stencilZFailFunc, + stencilZPassFunc); fxMesa->Glide.grStencilFuncExt(us->stencilFunction - GL_NEVER + GR_CMP_NEVER, us->stencilRefValue, us->stencilValueMask); @@ -1752,6 +1772,34 @@ fxSetupStencil (GLcontext * ctx) } } +void +fxSetupStencilFace (GLcontext * ctx, GLint face) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + tfxUnitsState *us = &fxMesa->unitsState; + + if (us->stencilEnabled) { + GrCmpFnc_t stencilFailFunc = GR_STENCILOP_KEEP; + GrCmpFnc_t stencilZFailFunc = GR_STENCILOP_KEEP; + GrCmpFnc_t stencilZPassFunc = GR_STENCILOP_KEEP; + if (!fxMesa->multipass) { + stencilFailFunc = convertGLStencilOp(ctx->Stencil.FailFunc[face]); + stencilZFailFunc = convertGLStencilOp(ctx->Stencil.ZFailFunc[face]); + stencilZPassFunc = convertGLStencilOp(ctx->Stencil.ZPassFunc[face]); + } + grEnable(GR_STENCIL_MODE_EXT); + fxMesa->Glide.grStencilOpExt(stencilFailFunc, + stencilZFailFunc, + stencilZPassFunc); + fxMesa->Glide.grStencilFuncExt(ctx->Stencil.Function[face] - GL_NEVER + GR_CMP_NEVER, + ctx->Stencil.Ref[face], + ctx->Stencil.ValueMask[face]); + fxMesa->Glide.grStencilMaskExt(ctx->Stencil.WriteMask[face]); + } else { + grDisable(GR_STENCIL_MODE_EXT); + } +} + /************************************************************************/ /**************************** Color Mask SetUp **************************/ /************************************************************************/ diff --git a/src/mesa/drivers/glide/fxtris.c b/src/mesa/drivers/glide/fxtris.c index 04b0ebe..f722c5c 100644 --- a/src/mesa/drivers/glide/fxtris.c +++ b/src/mesa/drivers/glide/fxtris.c @@ -499,8 +499,9 @@ static void fx_draw_point_wide_aa ( fxMesaContext fxMesa, #define FX_OFFSET_BIT 0x2 #define FX_TWOSIDE_BIT 0x4 #define FX_FLAT_BIT 0x8 -#define FX_FALLBACK_BIT 0x10 -#define FX_MAX_TRIFUNC 0x20 +#define FX_TWOSTENCIL_BIT 0x10 +#define FX_FALLBACK_BIT 0x20 +#define FX_MAX_TRIFUNC 0x40 static struct { tnl_points_func points; @@ -514,6 +515,7 @@ static struct { #define DO_UNFILLED (IND & FX_UNFILLED_BIT) #define DO_TWOSIDE (IND & FX_TWOSIDE_BIT) #define DO_FLAT (IND & FX_FLAT_BIT) +#define DO_TWOSTENCIL (IND & FX_TWOSTENCIL_BIT) #define DO_TRI 1 #define DO_QUAD 1 #define DO_LINE 1 @@ -652,6 +654,12 @@ do { \ #endif /* !FX_PACKEDCOLOR */ +/*********************************************************************** + * Twoside stencil * + ***********************************************************************/ +#define SETUP_STENCIL(f) if (f) fxSetupStencilFace(ctx, f) +#define UNSET_STENCIL(f) if (f) fxSetupStencil(ctx) + /*********************************************************************** * Functions to draw basic unfilled primitives * @@ -803,6 +811,142 @@ do { \ #include "tnl_dd/t_dd_tritmp.h" +/* 2-sided stencil begin */ +#define IND (FX_TWOSTENCIL_BIT) +#define TAG(x) x##_twostencil +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_OFFSET_BIT|FX_TWOSTENCIL_BIT) +#define TAG(x) x##_offset_twostencil +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_TWOSIDE_BIT|FX_TWOSTENCIL_BIT) +#define TAG(x) x##_twoside_twostencil +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_TWOSTENCIL_BIT) +#define TAG(x) x##_twoside_offset_twostencil +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_UNFILLED_BIT|FX_TWOSTENCIL_BIT) +#define TAG(x) x##_unfilled_twostencil +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_OFFSET_BIT|FX_UNFILLED_BIT|FX_TWOSTENCIL_BIT) +#define TAG(x) x##_offset_unfilled_twostencil +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_TWOSIDE_BIT|FX_UNFILLED_BIT|FX_TWOSTENCIL_BIT) +#define TAG(x) x##_twoside_unfilled_twostencil +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_UNFILLED_BIT|FX_TWOSTENCIL_BIT) +#define TAG(x) x##_twoside_offset_unfilled_twostencil +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_FALLBACK_BIT|FX_TWOSTENCIL_BIT) +#define TAG(x) x##_fallback_twostencil +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_OFFSET_BIT|FX_FALLBACK_BIT|FX_TWOSTENCIL_BIT) +#define TAG(x) x##_offset_fallback_twostencil +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_TWOSIDE_BIT|FX_FALLBACK_BIT|FX_TWOSTENCIL_BIT) +#define TAG(x) x##_twoside_fallback_twostencil +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_FALLBACK_BIT|FX_TWOSTENCIL_BIT) +#define TAG(x) x##_twoside_offset_fallback_twostencil +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_UNFILLED_BIT|FX_FALLBACK_BIT|FX_TWOSTENCIL_BIT) +#define TAG(x) x##_unfilled_fallback_twostencil +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_OFFSET_BIT|FX_UNFILLED_BIT|FX_FALLBACK_BIT|FX_TWOSTENCIL_BIT) +#define TAG(x) x##_offset_unfilled_fallback_twostencil +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_TWOSIDE_BIT|FX_UNFILLED_BIT|FX_FALLBACK_BIT|FX_TWOSTENCIL_BIT) +#define TAG(x) x##_twoside_unfilled_fallback_twostencil +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_UNFILLED_BIT| \ + FX_FALLBACK_BIT|FX_TWOSTENCIL_BIT) +#define TAG(x) x##_twoside_offset_unfilled_fallback_twostencil +#include "tnl_dd/t_dd_tritmp.h" + + +/* Fx doesn't support provoking-vertex flat-shading? + */ +#define IND (FX_FLAT_BIT|FX_TWOSTENCIL_BIT) +#define TAG(x) x##_flat_twostencil +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_OFFSET_BIT|FX_FLAT_BIT|FX_TWOSTENCIL_BIT) +#define TAG(x) x##_offset_flat_twostencil +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_TWOSIDE_BIT|FX_FLAT_BIT|FX_TWOSTENCIL_BIT) +#define TAG(x) x##_twoside_flat_twostencil +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_FLAT_BIT|FX_TWOSTENCIL_BIT) +#define TAG(x) x##_twoside_offset_flat_twostencil +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_UNFILLED_BIT|FX_FLAT_BIT|FX_TWOSTENCIL_BIT) +#define TAG(x) x##_unfilled_flat_twostencil +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_OFFSET_BIT|FX_UNFILLED_BIT|FX_FLAT_BIT|FX_TWOSTENCIL_BIT) +#define TAG(x) x##_offset_unfilled_flat_twostencil +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_TWOSIDE_BIT|FX_UNFILLED_BIT|FX_FLAT_BIT|FX_TWOSTENCIL_BIT) +#define TAG(x) x##_twoside_unfilled_flat_twostencil +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_UNFILLED_BIT|FX_FLAT_BIT|FX_TWOSTENCIL_BIT) +#define TAG(x) x##_twoside_offset_unfilled_flat_twostencil +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_FALLBACK_BIT|FX_FLAT_BIT|FX_TWOSTENCIL_BIT) +#define TAG(x) x##_fallback_flat_twostencil +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_OFFSET_BIT|FX_FALLBACK_BIT|FX_FLAT_BIT|FX_TWOSTENCIL_BIT) +#define TAG(x) x##_offset_fallback_flat_twostencil +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_TWOSIDE_BIT|FX_FALLBACK_BIT|FX_FLAT_BIT|FX_TWOSTENCIL_BIT) +#define TAG(x) x##_twoside_fallback_flat_twostencil +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_FALLBACK_BIT|FX_FLAT_BIT|FX_TWOSTENCIL_BIT) +#define TAG(x) x##_twoside_offset_fallback_flat_twostencil +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_UNFILLED_BIT|FX_FALLBACK_BIT|FX_FLAT_BIT|FX_TWOSTENCIL_BIT) +#define TAG(x) x##_unfilled_fallback_flat_twostencil +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_OFFSET_BIT|FX_UNFILLED_BIT|FX_FALLBACK_BIT|FX_FLAT_BIT|FX_TWOSTENCIL_BIT) +#define TAG(x) x##_offset_unfilled_fallback_flat_twostencil +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_TWOSIDE_BIT|FX_UNFILLED_BIT|FX_FALLBACK_BIT|FX_FLAT_BIT|FX_TWOSTENCIL_BIT) +#define TAG(x) x##_twoside_unfilled_fallback_flat_twostencil +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_UNFILLED_BIT| \ + FX_FALLBACK_BIT|FX_FLAT_BIT|FX_TWOSTENCIL_BIT) +#define TAG(x) x##_twoside_offset_unfilled_fallback_flat_twostencil +#include "tnl_dd/t_dd_tritmp.h" +/* 2-sided stencil end */ + + static void init_rast_tab( void ) { init(); @@ -838,6 +982,42 @@ static void init_rast_tab( void ) init_offset_unfilled_fallback_flat(); init_twoside_unfilled_fallback_flat(); init_twoside_offset_unfilled_fallback_flat(); + + /* 2-sided stencil begin */ + init_twostencil(); + init_offset_twostencil(); + init_twoside_twostencil(); + init_twoside_offset_twostencil(); + init_unfilled_twostencil(); + init_offset_unfilled_twostencil(); + init_twoside_unfilled_twostencil(); + init_twoside_offset_unfilled_twostencil(); + init_fallback_twostencil(); + init_offset_fallback_twostencil(); + init_twoside_fallback_twostencil(); + init_twoside_offset_fallback_twostencil(); + init_unfilled_fallback_twostencil(); + init_offset_unfilled_fallback_twostencil(); + init_twoside_unfilled_fallback_twostencil(); + init_twoside_offset_unfilled_fallback_twostencil(); + + init_flat_twostencil(); + init_offset_flat_twostencil(); + init_twoside_flat_twostencil(); + init_twoside_offset_flat_twostencil(); + init_unfilled_flat_twostencil(); + init_offset_unfilled_flat_twostencil(); + init_twoside_unfilled_flat_twostencil(); + init_twoside_offset_unfilled_flat_twostencil(); + init_fallback_flat_twostencil(); + init_offset_fallback_flat_twostencil(); + init_twoside_fallback_flat_twostencil(); + init_twoside_offset_fallback_flat_twostencil(); + init_unfilled_fallback_flat_twostencil(); + init_offset_unfilled_fallback_flat_twostencil(); + init_twoside_unfilled_fallback_flat_twostencil(); + init_twoside_offset_unfilled_fallback_flat_twostencil(); + /* 2-sided stencil end */ } @@ -1271,7 +1451,7 @@ static void fxFastRenderClippedPoly( GLcontext *ctx, const GLuint *elts, #define TRI_FALLBACK (DD_TRI_SMOOTH | DD_TRI_STIPPLE) #define ANY_FALLBACK_FLAGS (POINT_FALLBACK | LINE_FALLBACK | TRI_FALLBACK) #define ANY_RASTER_FLAGS (DD_FLATSHADE | DD_TRI_LIGHT_TWOSIDE | DD_TRI_OFFSET \ - | DD_TRI_UNFILLED) + | DD_TRI_UNFILLED | DD_TRI_TWOSTENCIL) @@ -1284,6 +1464,7 @@ void fxDDChooseRenderState(GLcontext *ctx) if (flags & (ANY_FALLBACK_FLAGS|ANY_RASTER_FLAGS)) { if (flags & ANY_RASTER_FLAGS) { + if (flags & DD_TRI_TWOSTENCIL) index |= FX_TWOSTENCIL_BIT; if (flags & DD_TRI_LIGHT_TWOSIDE) index |= FX_TWOSIDE_BIT; if (flags & DD_TRI_OFFSET) index |= FX_OFFSET_BIT; if (flags & DD_TRI_UNFILLED) index |= FX_UNFILLED_BIT; @@ -1527,7 +1708,15 @@ void fxCheckIsInHardware( GLcontext *ctx ) fprintf(stderr, "Voodoo ! leave SW 0x%08x %s\n", oldfallback, getFallbackString(oldfallback)); } } - tnl->Driver.Render.Multipass = (HAVE_SPEC && NEED_SECONDARY_COLOR(ctx)) ? fxMultipass_ColorSum : NULL; + tnl->Driver.Render.Multipass = NULL; + if (HAVE_SPEC && NEED_SECONDARY_COLOR(ctx)) { + tnl->Driver.Render.Multipass = fxMultipass_ColorSum; + /* obey stencil, but do not change it */ + fxMesa->multipass = GL_TRUE; + if (fxMesa->unitsState.stencilEnabled) { + fxMesa->new_state |= FX_NEW_STENCIL; + } + } } } @@ -1559,19 +1748,24 @@ void fxDDInitTriFuncs( GLcontext *ctx ) /* [dBorca] Hack alert: * doesn't work with blending. - * XXX todo - need to take care of stencil. */ GLboolean fxMultipass_ColorSum (GLcontext *ctx, GLuint pass) { fxMesaContext fxMesa = FX_CONTEXT(ctx); + tfxUnitsState *us = &fxMesa->unitsState; static int t0 = 0; static int t1 = 0; switch (pass) { case 1: /* first pass: the TEXTURED triangles are drawn */ + /* set stencil's real values */ + fxMesa->multipass = GL_FALSE; + if (us->stencilEnabled) { + fxSetupStencil(ctx); + } /* save per-pass data */ - fxMesa->restoreUnitsState = fxMesa->unitsState; + fxMesa->restoreUnitsState = *us; /* turn off texturing */ t0 = ctx->Texture.Unit[0]._ReallyEnabled; t1 = ctx->Texture.Unit[1]._ReallyEnabled; @@ -1582,16 +1776,15 @@ GLboolean fxMultipass_ColorSum (GLcontext *ctx, GLuint pass) fxDDBlendFuncSeparate(ctx, GL_ONE, GL_ONE, GL_ZERO, GL_ONE); fxDDEnable(ctx, GL_BLEND, GL_TRUE); /* make sure we draw only where we want to */ - if (ctx->Depth.Mask) { - switch (ctx->Depth.Func) { - case GL_NEVER: - case GL_ALWAYS: - break; - default: - fxDDDepthFunc( ctx, GL_EQUAL ); - break; + if (us->depthTestEnabled) { + switch (us->depthTestFunc) { + default: + fxDDDepthFunc(ctx, GL_EQUAL); + case GL_NEVER: + case GL_ALWAYS: + ; } - fxDDDepthMask( ctx, GL_FALSE ); + fxDDDepthMask(ctx, GL_FALSE); } /* switch to secondary colors */ #if FX_PACKEDCOLOR @@ -1604,7 +1797,7 @@ GLboolean fxMultipass_ColorSum (GLcontext *ctx, GLuint pass) break; case 2: /* 2nd pass (last): the secondary color is summed over texture */ /* restore original state */ - fxMesa->unitsState = fxMesa->restoreUnitsState; + *us = fxMesa->restoreUnitsState; /* restore texturing */ ctx->Texture.Unit[0]._ReallyEnabled = t0; ctx->Texture.Unit[1]._ReallyEnabled = t1; -- 2.7.4