#include "sis_context.h"
#include "sis_state.h"
#include "sis_stencil.h"
static void
sisDDStencilFunc( GLcontext * ctx, GLenum func, GLint ref, GLuint mask )
{
sisContextPtr smesa = SIS_CONTEXT(ctx);
__GLSiSHardware *prev = &smesa->prev;
__GLSiSHardware *current = &smesa->current;
current->hwStSetting = STENCIL_FORMAT_8 | (ctx->Stencil.Ref[0] << 8) |
ctx->Stencil.ValueMask[0];
switch (func)
{
case GL_NEVER:
current->hwStSetting |= SiS_STENCIL_NEVER;
break;
case GL_LESS:
current->hwStSetting |= SiS_STENCIL_LESS;
break;
case GL_EQUAL:
current->hwStSetting |= SiS_STENCIL_EQUAL;
break;
case GL_LEQUAL:
current->hwStSetting |= SiS_STENCIL_LEQUAL;
break;
case GL_GREATER:
current->hwStSetting |= SiS_STENCIL_GREATER;
break;
case GL_NOTEQUAL:
current->hwStSetting |= SiS_STENCIL_NOTEQUAL;
break;
case GL_GEQUAL:
current->hwStSetting |= SiS_STENCIL_GEQUAL;
break;
case GL_ALWAYS:
current->hwStSetting |= SiS_STENCIL_ALWAYS;
break;
}
if (current->hwStSetting != prev->hwStSetting)
{
prev->hwStSetting = current->hwStSetting;
smesa->GlobalFlag |= GFLAG_STENCILSETTING;
}
}
static void
sisDDStencilMask( GLcontext * ctx, GLuint mask )
{
if (!ctx->Visual.stencilBits)
return;
sisDDDepthMask (ctx, ctx->Depth.Mask);
}
static void
sisDDStencilOp( GLcontext * ctx, GLenum fail, GLenum zfail, GLenum zpass )
{
sisContextPtr smesa = SIS_CONTEXT(ctx);
__GLSiSHardware *prev = &smesa->prev;
__GLSiSHardware *current = &smesa->current;
current->hwStSetting2 &= ~(MASK_StencilZPassOp | MASK_StencilZFailOp |
MASK_StencilFailOp);
switch (fail)
{
case GL_KEEP:
current->hwStSetting2 |= SiS_SFAIL_KEEP;
break;
case GL_ZERO:
current->hwStSetting2 |= SiS_SFAIL_ZERO;
break;
case GL_REPLACE:
current->hwStSetting2 |= SiS_SFAIL_REPLACE;
break;
case GL_INVERT:
current->hwStSetting2 |= SiS_SFAIL_INVERT;
break;
case GL_INCR:
current->hwStSetting2 |= SiS_SFAIL_INCR;
break;
case GL_DECR:
current->hwStSetting2 |= SiS_SFAIL_DECR;
break;
}
switch (zfail)
{
case GL_KEEP:
current->hwStSetting2 |= SiS_SPASS_ZFAIL_KEEP;
break;
case GL_ZERO:
current->hwStSetting2 |= SiS_SPASS_ZFAIL_ZERO;
break;
case GL_REPLACE:
current->hwStSetting2 |= SiS_SPASS_ZFAIL_REPLACE;
break;
case GL_INVERT:
current->hwStSetting2 |= SiS_SPASS_ZFAIL_INVERT;
break;
case GL_INCR:
current->hwStSetting2 |= SiS_SPASS_ZFAIL_INCR;
break;
case GL_DECR:
current->hwStSetting2 |= SiS_SPASS_ZFAIL_DECR;
break;
}
switch (zpass)
{
case GL_KEEP:
current->hwStSetting2 |= SiS_SPASS_ZPASS_KEEP;
break;
case GL_ZERO:
current->hwStSetting2 |= SiS_SPASS_ZPASS_ZERO;
break;
case GL_REPLACE:
current->hwStSetting2 |= SiS_SPASS_ZPASS_REPLACE;
break;
case GL_INVERT:
current->hwStSetting2 |= SiS_SPASS_ZPASS_INVERT;
break;
case GL_INCR:
current->hwStSetting2 |= SiS_SPASS_ZPASS_INCR;
break;
case GL_DECR:
current->hwStSetting2 |= SiS_SPASS_ZPASS_DECR;
break;
}
if (current->hwStSetting2 != prev->hwStSetting2)
{
prev->hwStSetting2 = current->hwStSetting2;
smesa->GlobalFlag |= GFLAG_STENCILSETTING;
}
}
void
sisDDInitStencilFuncs( GLcontext *ctx )
{
ctx->Driver.StencilFunc = sisDDStencilFunc;
ctx->Driver.StencilMask = sisDDStencilMask;
ctx->Driver.StencilOp = sisDDStencilOp;
}