mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-08 19:58:09 +02:00
Track two sets of back-face stencil state
Track separate back-face stencil state for OpenGL 2.0 /
GL_ATI_separate_stencil and GL_EXT_stencil_two_side. This allows all
three to be enabled in a driver. One set of state is set via the 2.0
or ATI functions and is used when STENCIL_TEST_TWO_SIDE_EXT is
disabled. The other is set by StencilFunc and StencilOp when the
active stencil face is set to BACK. The GL_EXT_stencil_two_side spec has
more details.
http://opengl.org/registry/specs/EXT/stencil_two_side.txt
(cherry picked from commit dde7cb9628)
This commit is contained in:
parent
a6f7e909a7
commit
842b5164d2
9 changed files with 128 additions and 104 deletions
|
|
@ -84,6 +84,7 @@ static void
|
|||
cc_unit_populate_key(struct brw_context *brw, struct brw_cc_unit_key *key)
|
||||
{
|
||||
struct gl_stencil_attrib *stencil = brw->attribs.Stencil;
|
||||
const unsigned back = stencil->_BackFace;
|
||||
|
||||
memset(key, 0, sizeof(*key));
|
||||
|
||||
|
|
@ -100,13 +101,13 @@ cc_unit_populate_key(struct brw_context *brw, struct brw_cc_unit_key *key)
|
|||
key->stencil_test_mask[0] = stencil->ValueMask[0];
|
||||
}
|
||||
if (key->stencil_two_side) {
|
||||
key->stencil_func[1] = stencil->Function[1];
|
||||
key->stencil_fail_op[1] = stencil->FailFunc[1];
|
||||
key->stencil_pass_depth_fail_op[1] = stencil->ZFailFunc[1];
|
||||
key->stencil_pass_depth_pass_op[1] = stencil->ZPassFunc[1];
|
||||
key->stencil_ref[1] = stencil->Ref[1];
|
||||
key->stencil_write_mask[1] = stencil->WriteMask[1];
|
||||
key->stencil_test_mask[1] = stencil->ValueMask[1];
|
||||
key->stencil_func[1] = stencil->Function[back];
|
||||
key->stencil_fail_op[1] = stencil->FailFunc[back];
|
||||
key->stencil_pass_depth_fail_op[1] = stencil->ZFailFunc[back];
|
||||
key->stencil_pass_depth_pass_op[1] = stencil->ZPassFunc[back];
|
||||
key->stencil_ref[1] = stencil->Ref[back];
|
||||
key->stencil_write_mask[1] = stencil->WriteMask[back];
|
||||
key->stencil_test_mask[1] = stencil->ValueMask[back];
|
||||
}
|
||||
|
||||
if (brw->attribs.Color->_LogicOpEnabled)
|
||||
|
|
|
|||
|
|
@ -189,8 +189,7 @@ static void brw_wm_populate_key( struct brw_context *brw,
|
|||
lookup |= IZ_STENCIL_TEST_ENABLE_BIT;
|
||||
|
||||
if (brw->attribs.Stencil->WriteMask[0] ||
|
||||
(brw->attribs.Stencil->_TestTwoSide &&
|
||||
brw->attribs.Stencil->WriteMask[1]))
|
||||
brw->attribs.Stencil->WriteMask[brw->attribs.Stencil->_BackFace])
|
||||
lookup |= IZ_STENCIL_WRITE_ENABLE_BIT;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -347,6 +347,8 @@ static GLboolean r300RunRender(GLcontext * ctx,
|
|||
static int r300Fallback(GLcontext * ctx)
|
||||
{
|
||||
r300ContextPtr r300 = R300_CONTEXT(ctx);
|
||||
const unsigned back = ctx->Stencil._BackFace;
|
||||
|
||||
/* Do we need to use new-style shaders?
|
||||
* Also is there a better way to do this? */
|
||||
if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) {
|
||||
|
|
@ -371,12 +373,14 @@ static int r300Fallback(GLcontext * ctx)
|
|||
|
||||
FALLBACK_IF(ctx->RenderMode != GL_RENDER);
|
||||
|
||||
FALLBACK_IF(ctx->Stencil._TestTwoSide
|
||||
&& (ctx->Stencil.Ref[0] != ctx->Stencil.Ref[1]
|
||||
|| ctx->Stencil.ValueMask[0] !=
|
||||
ctx->Stencil.ValueMask[1]
|
||||
|| ctx->Stencil.WriteMask[0] !=
|
||||
ctx->Stencil.WriteMask[1]));
|
||||
/* If GL_EXT_stencil_two_side is disabled, this fallback check can
|
||||
* be removed.
|
||||
*/
|
||||
FALLBACK_IF(ctx->Stencil.Ref[0] != ctx->Stencil.Ref[back]
|
||||
|| ctx->Stencil.ValueMask[0] !=
|
||||
ctx->Stencil.ValueMask[back]
|
||||
|| ctx->Stencil.WriteMask[0] !=
|
||||
ctx->Stencil.WriteMask[back]);
|
||||
|
||||
if (ctx->Extensions.NV_point_sprite || ctx->Extensions.ARB_point_sprite)
|
||||
FALLBACK_IF(ctx->Point.PointSprite);
|
||||
|
|
|
|||
|
|
@ -974,15 +974,9 @@ static void r300StencilFuncSeparate(GLcontext * ctx, GLenum face,
|
|||
{
|
||||
r300ContextPtr rmesa = R300_CONTEXT(ctx);
|
||||
GLuint refmask =
|
||||
(((ctx->Stencil.
|
||||
Ref[0] & 0xff) << R300_STENCILREF_SHIFT) | ((ctx->
|
||||
Stencil.
|
||||
ValueMask
|
||||
[0] &
|
||||
0xff)
|
||||
<<
|
||||
R300_STENCILMASK_SHIFT));
|
||||
|
||||
((ctx->Stencil.Ref[0] & 0xff) << R300_STENCILREF_SHIFT)
|
||||
| ((ctx->Stencil.ValueMask[0] & 0xff) << R300_STENCILMASK_SHIFT);
|
||||
const unsigned back = ctx->Stencil._BackFace;
|
||||
GLuint flag;
|
||||
|
||||
R300_STATECHANGE(rmesa, zs);
|
||||
|
|
@ -1000,8 +994,7 @@ static void r300StencilFuncSeparate(GLcontext * ctx, GLenum face,
|
|||
rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |=
|
||||
(flag << R300_S_FRONT_FUNC_SHIFT);
|
||||
|
||||
if (ctx->Stencil._TestTwoSide)
|
||||
flag = translate_func(ctx->Stencil.Function[1]);
|
||||
flag = translate_func(ctx->Stencil.Function[back]);
|
||||
|
||||
rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |=
|
||||
(flag << R300_S_BACK_FUNC_SHIFT);
|
||||
|
|
@ -1026,6 +1019,7 @@ static void r300StencilOpSeparate(GLcontext * ctx, GLenum face,
|
|||
GLenum fail, GLenum zfail, GLenum zpass)
|
||||
{
|
||||
r300ContextPtr rmesa = R300_CONTEXT(ctx);
|
||||
const unsigned back = ctx->Stencil._BackFace;
|
||||
|
||||
R300_STATECHANGE(rmesa, zs);
|
||||
/* It is easier to mask what's left.. */
|
||||
|
|
@ -1042,23 +1036,13 @@ static void r300StencilOpSeparate(GLcontext * ctx, GLenum face,
|
|||
| (translate_stencil_op(ctx->Stencil.ZPassFunc[0]) <<
|
||||
R300_S_FRONT_ZPASS_OP_SHIFT);
|
||||
|
||||
if (ctx->Stencil._TestTwoSide) {
|
||||
rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |=
|
||||
(translate_stencil_op(ctx->Stencil.FailFunc[1]) <<
|
||||
R300_S_BACK_SFAIL_OP_SHIFT)
|
||||
| (translate_stencil_op(ctx->Stencil.ZFailFunc[1]) <<
|
||||
R300_S_BACK_ZFAIL_OP_SHIFT)
|
||||
| (translate_stencil_op(ctx->Stencil.ZPassFunc[1]) <<
|
||||
R300_S_BACK_ZPASS_OP_SHIFT);
|
||||
} else {
|
||||
rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |=
|
||||
(translate_stencil_op(ctx->Stencil.FailFunc[0]) <<
|
||||
R300_S_BACK_SFAIL_OP_SHIFT)
|
||||
| (translate_stencil_op(ctx->Stencil.ZFailFunc[0]) <<
|
||||
R300_S_BACK_ZFAIL_OP_SHIFT)
|
||||
| (translate_stencil_op(ctx->Stencil.ZPassFunc[0]) <<
|
||||
R300_S_BACK_ZPASS_OP_SHIFT);
|
||||
}
|
||||
rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |=
|
||||
(translate_stencil_op(ctx->Stencil.FailFunc[back]) <<
|
||||
R300_S_BACK_SFAIL_OP_SHIFT)
|
||||
| (translate_stencil_op(ctx->Stencil.ZFailFunc[back]) <<
|
||||
R300_S_BACK_ZFAIL_OP_SHIFT)
|
||||
| (translate_stencil_op(ctx->Stencil.ZPassFunc[back]) <<
|
||||
R300_S_BACK_ZPASS_OP_SHIFT);
|
||||
}
|
||||
|
||||
/* =============================================================
|
||||
|
|
|
|||
|
|
@ -922,10 +922,13 @@ _mesa_set_enable(GLcontext *ctx, GLenum cap, GLboolean state)
|
|||
return;
|
||||
FLUSH_VERTICES(ctx, _NEW_STENCIL);
|
||||
ctx->Stencil.TestTwoSide = state;
|
||||
if (state)
|
||||
if (state) {
|
||||
ctx->Stencil._BackFace = 2;
|
||||
ctx->_TriangleCaps |= DD_TRI_TWOSTENCIL;
|
||||
else
|
||||
} else {
|
||||
ctx->Stencil._BackFace = 1;
|
||||
ctx->_TriangleCaps &= ~DD_TRI_TWOSTENCIL;
|
||||
}
|
||||
break;
|
||||
|
||||
#if FEATURE_ARB_fragment_program
|
||||
|
|
|
|||
|
|
@ -82,7 +82,16 @@ compute_version(const GLcontext *ctx)
|
|||
ctx->Extensions.ARB_vertex_shader &&
|
||||
ctx->Extensions.ARB_fragment_shader &&
|
||||
ctx->Extensions.ARB_texture_non_power_of_two &&
|
||||
ctx->Extensions.EXT_blend_equation_separate);
|
||||
ctx->Extensions.EXT_blend_equation_separate &&
|
||||
|
||||
/* Technically, 2.0 requires the functionality
|
||||
* of the EXT version. Enable 2.0 if either
|
||||
* extension is available, and assume that a
|
||||
* driver that only exposes the ATI extension
|
||||
* will fallback to software when necessary.
|
||||
*/
|
||||
(ctx->Extensions.EXT_stencil_two_side
|
||||
|| ctx->Extensions.ATI_separate_stencil));
|
||||
const GLboolean ver_2_1 = (ver_2_0 &&
|
||||
ctx->Extensions.ARB_shading_language_120 &&
|
||||
ctx->Extensions.EXT_pixel_buffer_object &&
|
||||
|
|
|
|||
|
|
@ -1108,20 +1108,34 @@ struct gl_scissor_attrib
|
|||
|
||||
/**
|
||||
* Stencil attribute group (GL_STENCIL_BUFFER_BIT).
|
||||
*
|
||||
* Three sets of stencil data are tracked so that OpenGL 2.0,
|
||||
* GL_EXT_stencil_two_side, and GL_ATI_separate_stencil can all be supported
|
||||
* simultaneously. In each of the stencil state arrays, element 0 corresponds
|
||||
* to GL_FRONT. Element 1 corresponds to the OpenGL 2.0 /
|
||||
* GL_ATI_separate_stencil GL_BACK state. Element 2 corresponds to the
|
||||
* GL_EXT_stencil_two_side GL_BACK state.
|
||||
*
|
||||
* The derived value \c _BackFace is either 1 or 2 depending on whether or
|
||||
* not GL_STENCIL_TEST_TWO_SIDE_EXT is enabled.
|
||||
*
|
||||
* The derived value \c _TestTwoSide is set when the front-face and back-face
|
||||
* stencil state are different.
|
||||
*/
|
||||
struct gl_stencil_attrib
|
||||
{
|
||||
GLboolean Enabled; /**< Enabled flag */
|
||||
GLboolean TestTwoSide; /**< GL_EXT_stencil_two_side */
|
||||
GLubyte ActiveFace; /**< GL_EXT_stencil_two_side (0 or 1) */
|
||||
GLubyte ActiveFace; /**< GL_EXT_stencil_two_side (0 or 2) */
|
||||
GLboolean _TestTwoSide;
|
||||
GLenum Function[2]; /**< Stencil function */
|
||||
GLenum FailFunc[2]; /**< Fail function */
|
||||
GLenum ZPassFunc[2]; /**< Depth buffer pass function */
|
||||
GLenum ZFailFunc[2]; /**< Depth buffer fail function */
|
||||
GLint Ref[2]; /**< Reference value */
|
||||
GLuint ValueMask[2]; /**< Value mask */
|
||||
GLuint WriteMask[2]; /**< Write mask */
|
||||
GLubyte _BackFace;
|
||||
GLenum Function[3]; /**< Stencil function */
|
||||
GLenum FailFunc[3]; /**< Fail function */
|
||||
GLenum ZPassFunc[3]; /**< Depth buffer pass function */
|
||||
GLenum ZFailFunc[3]; /**< Depth buffer fail function */
|
||||
GLint Ref[3]; /**< Reference value */
|
||||
GLuint ValueMask[3]; /**< Value mask */
|
||||
GLuint WriteMask[3]; /**< Write mask */
|
||||
GLuint Clear; /**< Clear value */
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -27,21 +27,6 @@
|
|||
* \file stencil.c
|
||||
* Stencil operations.
|
||||
*
|
||||
* Note: There's an incompatibility between GL_EXT_stencil_two_side and
|
||||
* OpenGL 2.0's two-sided stencil feature.
|
||||
*
|
||||
* With GL_EXT_stencil_two_side, calling glStencilOp/Func/Mask() only the
|
||||
* front OR back face state (as set by glActiveStencilFaceEXT) is set.
|
||||
*
|
||||
* But with OpenGL 2.0, calling glStencilOp/Func/Mask() sets BOTH the
|
||||
* front AND back state.
|
||||
*
|
||||
* So either we advertise the GL_EXT_stencil_two_side extension, or OpenGL
|
||||
* 2.0, but not both.
|
||||
*
|
||||
* Also, note that GL_ATI_separate_stencil is different as well:
|
||||
* glStencilFuncSeparateATI(GLenum frontfunc, GLenum backfunc, ...) vs.
|
||||
* glStencilFuncSeparate(GLenum face, GLenum func, ...).
|
||||
*/
|
||||
|
||||
|
||||
|
|
@ -198,6 +183,7 @@ _mesa_StencilFunc( GLenum func, GLint ref, GLuint mask )
|
|||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
const GLint stencilMax = (1 << ctx->DrawBuffer->Visual.stencilBits) - 1;
|
||||
const GLint face = ctx->Stencil.ActiveFace;
|
||||
ASSERT_OUTSIDE_BEGIN_END(ctx);
|
||||
|
||||
if (!validate_stencil_func(ctx, func)) {
|
||||
|
|
@ -207,9 +193,7 @@ _mesa_StencilFunc( GLenum func, GLint ref, GLuint mask )
|
|||
|
||||
ref = CLAMP( ref, 0, stencilMax );
|
||||
|
||||
if (ctx->Extensions.EXT_stencil_two_side) {
|
||||
/* only set active face state */
|
||||
const GLint face = ctx->Stencil.ActiveFace;
|
||||
if (face != 0) {
|
||||
if (ctx->Stencil.Function[face] == func &&
|
||||
ctx->Stencil.ValueMask[face] == mask &&
|
||||
ctx->Stencil.Ref[face] == ref)
|
||||
|
|
@ -218,9 +202,12 @@ _mesa_StencilFunc( GLenum func, GLint ref, GLuint mask )
|
|||
ctx->Stencil.Function[face] = func;
|
||||
ctx->Stencil.Ref[face] = ref;
|
||||
ctx->Stencil.ValueMask[face] = mask;
|
||||
if (ctx->Driver.StencilFuncSeparate) {
|
||||
ctx->Driver.StencilFuncSeparate(ctx, face ? GL_BACK : GL_FRONT,
|
||||
func, ref, mask);
|
||||
|
||||
/* Only propagate the change to the driver if EXT_stencil_two_side
|
||||
* is enabled.
|
||||
*/
|
||||
if (ctx->Driver.StencilFuncSeparate && ctx->Stencil.TestTwoSide) {
|
||||
ctx->Driver.StencilFuncSeparate(ctx, GL_BACK, func, ref, mask);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
@ -237,7 +224,9 @@ _mesa_StencilFunc( GLenum func, GLint ref, GLuint mask )
|
|||
ctx->Stencil.Ref[0] = ctx->Stencil.Ref[1] = ref;
|
||||
ctx->Stencil.ValueMask[0] = ctx->Stencil.ValueMask[1] = mask;
|
||||
if (ctx->Driver.StencilFuncSeparate) {
|
||||
ctx->Driver.StencilFuncSeparate(ctx, GL_FRONT_AND_BACK,
|
||||
ctx->Driver.StencilFuncSeparate(ctx,
|
||||
((ctx->Stencil.TestTwoSide)
|
||||
? GL_FRONT : GL_FRONT_AND_BACK),
|
||||
func, ref, mask);
|
||||
}
|
||||
}
|
||||
|
|
@ -259,17 +248,23 @@ void GLAPIENTRY
|
|||
_mesa_StencilMask( GLuint mask )
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
const GLint face = ctx->Stencil.ActiveFace;
|
||||
|
||||
ASSERT_OUTSIDE_BEGIN_END(ctx);
|
||||
|
||||
if (ctx->Extensions.EXT_stencil_two_side) {
|
||||
/* only set active face state */
|
||||
const GLint face = ctx->Stencil.ActiveFace;
|
||||
if (face != 0) {
|
||||
/* Only modify the EXT_stencil_two_side back-face state.
|
||||
*/
|
||||
if (ctx->Stencil.WriteMask[face] == mask)
|
||||
return;
|
||||
FLUSH_VERTICES(ctx, _NEW_STENCIL);
|
||||
ctx->Stencil.WriteMask[face] = mask;
|
||||
if (ctx->Driver.StencilMaskSeparate) {
|
||||
ctx->Driver.StencilMaskSeparate(ctx, face ? GL_BACK : GL_FRONT, mask);
|
||||
|
||||
/* Only propagate the change to the driver if EXT_stencil_two_side
|
||||
* is enabled.
|
||||
*/
|
||||
if (ctx->Driver.StencilMaskSeparate && ctx->Stencil.TestTwoSide) {
|
||||
ctx->Driver.StencilMaskSeparate(ctx, GL_BACK, mask);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
@ -280,7 +275,10 @@ _mesa_StencilMask( GLuint mask )
|
|||
FLUSH_VERTICES(ctx, _NEW_STENCIL);
|
||||
ctx->Stencil.WriteMask[0] = ctx->Stencil.WriteMask[1] = mask;
|
||||
if (ctx->Driver.StencilMaskSeparate) {
|
||||
ctx->Driver.StencilMaskSeparate(ctx, GL_FRONT_AND_BACK, mask);
|
||||
ctx->Driver.StencilMaskSeparate(ctx,
|
||||
((ctx->Stencil.TestTwoSide)
|
||||
? GL_FRONT : GL_FRONT_AND_BACK),
|
||||
mask);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -304,6 +302,8 @@ void GLAPIENTRY
|
|||
_mesa_StencilOp(GLenum fail, GLenum zfail, GLenum zpass)
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
const GLint face = ctx->Stencil.ActiveFace;
|
||||
|
||||
ASSERT_OUTSIDE_BEGIN_END(ctx);
|
||||
|
||||
if (!validate_stencil_op(ctx, fail)) {
|
||||
|
|
@ -319,9 +319,8 @@ _mesa_StencilOp(GLenum fail, GLenum zfail, GLenum zpass)
|
|||
return;
|
||||
}
|
||||
|
||||
if (ctx->Extensions.EXT_stencil_two_side) {
|
||||
if (face != 0) {
|
||||
/* only set active face state */
|
||||
const GLint face = ctx->Stencil.ActiveFace;
|
||||
if (ctx->Stencil.ZFailFunc[face] == zfail &&
|
||||
ctx->Stencil.ZPassFunc[face] == zpass &&
|
||||
ctx->Stencil.FailFunc[face] == fail)
|
||||
|
|
@ -330,9 +329,12 @@ _mesa_StencilOp(GLenum fail, GLenum zfail, GLenum zpass)
|
|||
ctx->Stencil.ZFailFunc[face] = zfail;
|
||||
ctx->Stencil.ZPassFunc[face] = zpass;
|
||||
ctx->Stencil.FailFunc[face] = fail;
|
||||
if (ctx->Driver.StencilOpSeparate) {
|
||||
ctx->Driver.StencilOpSeparate(ctx, face ? GL_BACK : GL_FRONT,
|
||||
fail, zfail, zpass);
|
||||
|
||||
/* Only propagate the change to the driver if EXT_stencil_two_side
|
||||
* is enabled.
|
||||
*/
|
||||
if (ctx->Driver.StencilOpSeparate && ctx->Stencil.TestTwoSide) {
|
||||
ctx->Driver.StencilOpSeparate(ctx, GL_BACK, fail, zfail, zpass);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
@ -349,7 +351,9 @@ _mesa_StencilOp(GLenum fail, GLenum zfail, GLenum zpass)
|
|||
ctx->Stencil.ZPassFunc[0] = ctx->Stencil.ZPassFunc[1] = zpass;
|
||||
ctx->Stencil.FailFunc[0] = ctx->Stencil.FailFunc[1] = fail;
|
||||
if (ctx->Driver.StencilOpSeparate) {
|
||||
ctx->Driver.StencilOpSeparate(ctx, GL_FRONT_AND_BACK,
|
||||
ctx->Driver.StencilOpSeparate(ctx,
|
||||
((ctx->Stencil.TestTwoSide)
|
||||
? GL_FRONT : GL_FRONT_AND_BACK),
|
||||
fail, zfail, zpass);
|
||||
}
|
||||
}
|
||||
|
|
@ -372,7 +376,7 @@ _mesa_ActiveStencilFaceEXT(GLenum face)
|
|||
|
||||
if (face == GL_FRONT || face == GL_BACK) {
|
||||
FLUSH_VERTICES(ctx, _NEW_STENCIL);
|
||||
ctx->Stencil.ActiveFace = (face == GL_FRONT) ? 0 : 1;
|
||||
ctx->Stencil.ActiveFace = (face == GL_FRONT) ? 0 : 2;
|
||||
}
|
||||
else {
|
||||
_mesa_error(ctx, GL_INVALID_ENUM, "glActiveStencilFaceEXT(face)");
|
||||
|
|
@ -513,19 +517,16 @@ _mesa_StencilMaskSeparate(GLenum face, GLuint mask)
|
|||
void
|
||||
_mesa_update_stencil(GLcontext *ctx)
|
||||
{
|
||||
if (ctx->Extensions.EXT_stencil_two_side) {
|
||||
ctx->Stencil._TestTwoSide = ctx->Stencil.TestTwoSide;
|
||||
}
|
||||
else {
|
||||
ctx->Stencil._TestTwoSide =
|
||||
(ctx->Stencil.Function[0] != ctx->Stencil.Function[1] ||
|
||||
ctx->Stencil.FailFunc[0] != ctx->Stencil.FailFunc[1] ||
|
||||
ctx->Stencil.ZPassFunc[0] != ctx->Stencil.ZPassFunc[1] ||
|
||||
ctx->Stencil.ZFailFunc[0] != ctx->Stencil.ZFailFunc[1] ||
|
||||
ctx->Stencil.Ref[0] != ctx->Stencil.Ref[1] ||
|
||||
ctx->Stencil.ValueMask[0] != ctx->Stencil.ValueMask[1] ||
|
||||
ctx->Stencil.WriteMask[0] != ctx->Stencil.WriteMask[1]);
|
||||
}
|
||||
const GLint face = ctx->Stencil._BackFace;
|
||||
|
||||
ctx->Stencil._TestTwoSide =
|
||||
(ctx->Stencil.Function[0] != ctx->Stencil.Function[face] ||
|
||||
ctx->Stencil.FailFunc[0] != ctx->Stencil.FailFunc[face] ||
|
||||
ctx->Stencil.ZPassFunc[0] != ctx->Stencil.ZPassFunc[face] ||
|
||||
ctx->Stencil.ZFailFunc[0] != ctx->Stencil.ZFailFunc[face] ||
|
||||
ctx->Stencil.Ref[0] != ctx->Stencil.Ref[face] ||
|
||||
ctx->Stencil.ValueMask[0] != ctx->Stencil.ValueMask[face] ||
|
||||
ctx->Stencil.WriteMask[0] != ctx->Stencil.WriteMask[face]);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -544,17 +545,24 @@ _mesa_init_stencil(GLcontext *ctx)
|
|||
ctx->Stencil.ActiveFace = 0; /* 0 = GL_FRONT, 1 = GL_BACK */
|
||||
ctx->Stencil.Function[0] = GL_ALWAYS;
|
||||
ctx->Stencil.Function[1] = GL_ALWAYS;
|
||||
ctx->Stencil.Function[2] = GL_ALWAYS;
|
||||
ctx->Stencil.FailFunc[0] = GL_KEEP;
|
||||
ctx->Stencil.FailFunc[1] = GL_KEEP;
|
||||
ctx->Stencil.FailFunc[2] = GL_KEEP;
|
||||
ctx->Stencil.ZPassFunc[0] = GL_KEEP;
|
||||
ctx->Stencil.ZPassFunc[1] = GL_KEEP;
|
||||
ctx->Stencil.ZPassFunc[2] = GL_KEEP;
|
||||
ctx->Stencil.ZFailFunc[0] = GL_KEEP;
|
||||
ctx->Stencil.ZFailFunc[1] = GL_KEEP;
|
||||
ctx->Stencil.ZFailFunc[2] = GL_KEEP;
|
||||
ctx->Stencil.Ref[0] = 0;
|
||||
ctx->Stencil.Ref[1] = 0;
|
||||
ctx->Stencil.Ref[2] = 0;
|
||||
ctx->Stencil.ValueMask[0] = ~0U;
|
||||
ctx->Stencil.ValueMask[1] = ~0U;
|
||||
ctx->Stencil.ValueMask[2] = ~0U;
|
||||
ctx->Stencil.WriteMask[0] = ~0U;
|
||||
ctx->Stencil.WriteMask[1] = ~0U;
|
||||
ctx->Stencil.WriteMask[2] = ~0U;
|
||||
ctx->Stencil.Clear = 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -997,10 +997,12 @@ stencil_and_ztest_pixels( GLcontext *ctx, SWspan *span, GLuint face )
|
|||
GLboolean
|
||||
_swrast_stencil_and_ztest_span(GLcontext *ctx, SWspan *span)
|
||||
{
|
||||
const GLuint face = (span->facing == 0) ? 0 : ctx->Stencil._BackFace;
|
||||
|
||||
if (span->arrayMask & SPAN_XY)
|
||||
return stencil_and_ztest_pixels(ctx, span, span->facing);
|
||||
return stencil_and_ztest_pixels(ctx, span, face);
|
||||
else
|
||||
return stencil_and_ztest_span(ctx, span, span->facing);
|
||||
return stencil_and_ztest_span(ctx, span, face);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue