From e2e4a5c992c7655cdd4374b962d339ec62bb5f5c Mon Sep 17 00:00:00 2001 From: Peter Zubaj Date: Mon, 14 Mar 2005 20:35:00 +0000 Subject: [PATCH] Stencil support Reflex from mesa demos doesn't work TODO - double side stencil I hope that I didn't break anything --- src/mesa/drivers/dri/r300/r300_context.h | 10 ++++- src/mesa/drivers/dri/r300/r300_ioctl.c | 35 ++++++++++++++-- src/mesa/drivers/dri/r300/r300_reg.h | 3 +- src/mesa/drivers/dri/r300/r300_state.c | 70 +++++++++++++++++++------------- 4 files changed, 84 insertions(+), 34 deletions(-) diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h index d956848..75aeb3e 100644 --- a/src/mesa/drivers/dri/r300/r300_context.h +++ b/src/mesa/drivers/dri/r300/r300_context.h @@ -500,6 +500,12 @@ struct r300_depthbuffer_state { GLfloat scale; }; +struct r300_stencilbuffer_state { + GLuint clear; + GLboolean hw_stencil; + +}; + struct r300_vap_reg_state { /* input register assigments */ int i_coords; @@ -678,7 +684,9 @@ struct r300_state { struct { int transform_offset; /* Transform matrix offset, -1 if none */ } vap_param; /* vertex processor parameter allocation - tells where to write parameters */ - int hw_stencil; + + struct r300_stencilbuffer_state stencil; + }; diff --git a/src/mesa/drivers/dri/r300/r300_ioctl.c b/src/mesa/drivers/dri/r300/r300_ioctl.c index 45cff5b..31515c0 100644 --- a/src/mesa/drivers/dri/r300/r300_ioctl.c +++ b/src/mesa/drivers/dri/r300/r300_ioctl.c @@ -58,6 +58,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define CLEARBUFFER_COLOR 0x1 #define CLEARBUFFER_DEPTH 0x2 +#define CLEARBUFFER_STENCIL 0x4 static void r300ClearBuffer(r300ContextPtr r300, int flags, int buffer) { @@ -205,8 +206,10 @@ static void r300ClearBuffer(r300ContextPtr r300, int flags, int buffer) R300_STATECHANGE(r300, zs); if (flags & CLEARBUFFER_DEPTH) { - r300->hw.zs.cmd[R300_ZS_CNTL_0] = 0x6; // test and write - r300->hw.zs.cmd[R300_ZS_CNTL_1] = (R300_ZS_ALWAYS<hw.zs.cmd[R300_ZS_CNTL_0] &= R300_RB3D_STENCIL_ENABLE; + r300->hw.zs.cmd[R300_ZS_CNTL_0] |= 0x6; // test and write + r300->hw.zs.cmd[R300_ZS_CNTL_1] &= ~(R300_ZS_MASK << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT); + r300->hw.zs.cmd[R300_ZS_CNTL_1] |= (R300_ZS_ALWAYS<hw.zb.cmd[R300_ZB_OFFSET] = @@ -217,8 +220,27 @@ static void r300ClearBuffer(r300ContextPtr r300, int flags, int buffer) r300->radeon.radeonScreen->depthPitch; */ } else { - r300->hw.zs.cmd[R300_ZS_CNTL_0] = 0; // disable - r300->hw.zs.cmd[R300_ZS_CNTL_1] = 0; + r300->hw.zs.cmd[R300_ZS_CNTL_0] &= R300_RB3D_STENCIL_ENABLE; + r300->hw.zs.cmd[R300_ZS_CNTL_0] |= R300_RB3D_Z_DISABLED_1; // disable + r300->hw.zs.cmd[R300_ZS_CNTL_1] &= ~(R300_ZS_MASK << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT); + } + + R300_STATECHANGE(r300, zs); + if (flags & CLEARBUFFER_STENCIL) { + r300->hw.zs.cmd[R300_ZS_CNTL_0] &= ~R300_RB3D_STENCIL_ENABLE; + r300->hw.zs.cmd[R300_ZS_CNTL_0] |= R300_RB3D_STENCIL_ENABLE; + r300->hw.zs.cmd[R300_ZS_CNTL_1] &= + ~((R300_ZS_MASK << R300_RB3D_ZS1_FRONT_FUNC_SHIFT) | (R300_ZS_MASK << R300_RB3D_ZS1_BACK_FUNC_SHIFT)); + r300->hw.zs.cmd[R300_ZS_CNTL_1] |= + (R300_ZS_ALWAYS<hw.zs.cmd[R300_ZS_CNTL_2] = r300->state.stencil.clear; } /* Make sure we have enough space */ @@ -314,6 +336,11 @@ static void r300Clear(GLcontext * ctx, GLbitfield mask, GLboolean all, bits |= CLEARBUFFER_DEPTH; mask &= ~DD_DEPTH_BIT; } + + if ( (mask & DD_STENCIL_BIT) && r300->state.stencil.hw_stencil) { + bits |= CLEARBUFFER_STENCIL; + mask &= ~DD_STENCIL_BIT; + } if (mask) { if (RADEON_DEBUG & DEBUG_FALLBACKS) diff --git a/src/mesa/drivers/dri/r300/r300_reg.h b/src/mesa/drivers/dri/r300/r300_reg.h index f98e9b3..a9cb88c 100644 --- a/src/mesa/drivers/dri/r300/r300_reg.h +++ b/src/mesa/drivers/dri/r300/r300_reg.h @@ -1109,7 +1109,7 @@ I am fairly certain that they are correct unless stated otherwise in comments. # define R300_RB3D_Z_TEST 0x00000012 # define R300_RB3D_Z_TEST_AND_WRITE 0x00000016 # define R300_RB3D_Z_WRITE_ONLY 0x00000006 -# define R300_RB3D_STENCIL_ENABLE (0<<1) /* UNKNOWN yet.. */ +# define R300_RB3D_STENCIL_ENABLE 0x00000001 #define R300_RB3D_ZSTENCIL_CNTL_1 0x4F04 /* functions */ @@ -1148,6 +1148,7 @@ I am fairly certain that they are correct unless stated otherwise in comments. #define R300_RB3D_ZSTENCIL_CNTL_2 0x4F08 # define R300_RB3D_ZS2_STENCIL_REF_SHIFT 0 +# define R300_RB3D_ZS2_STENCIL_MASK 0xFF # define R300_RB3D_ZS2_STENCIL_MASK_SHIFT 8 # define R300_RB3D_ZS2_STENCIL_WRITE_MASK_SHIFT 16 diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index 874bd85..c3c0120 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -483,17 +483,15 @@ static void r300Enable(GLcontext* ctx, GLenum cap, GLboolean state) else newval = R300_RB3D_Z_TEST; } else - newval = 0; + newval = R300_RB3D_Z_DISABLED_1; - r300->hw.zs.cmd[R300_ZS_CNTL_0] = newval; + r300->hw.zs.cmd[R300_ZS_CNTL_0] &= R300_RB3D_STENCIL_ENABLE; + r300->hw.zs.cmd[R300_ZS_CNTL_0] |= newval; break; case GL_STENCIL_TEST: - - WARN_ONCE("Do not know how to enable stencil. Help me !\n"); - - if (r300->state.hw_stencil) { - //fprintf(stderr, "Stencil %s\n", state ? "enabled" : "disabled"); + WARN_ONCE("TODO - double side stencil !\n"); + if (r300->state.stencil.hw_stencil) { R300_STATECHANGE(r300, zs); if (state) { r300->hw.zs.cmd[R300_ZS_CNTL_0] |= @@ -609,7 +607,6 @@ static void r300DepthFunc(GLcontext* ctx, GLenum func) r300->hw.zs.cmd[R300_ZS_CNTL_1] |= R300_ZS_ALWAYS << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT; break; } - } @@ -626,8 +623,9 @@ static void r300DepthMask(GLcontext* ctx, GLboolean mask) return; R300_STATECHANGE(r300, zs); - r300->hw.zs.cmd[R300_ZS_CNTL_0] = mask - ? R300_RB3D_Z_TEST_AND_WRITE : R300_RB3D_Z_TEST; + r300->hw.zs.cmd[R300_ZS_CNTL_0] &= R300_RB3D_STENCIL_ENABLE; + r300->hw.zs.cmd[R300_ZS_CNTL_0] |= mask + ? R300_RB3D_Z_TEST_AND_WRITE : R300_RB3D_Z_TEST; } @@ -866,8 +864,8 @@ static void r300StencilFunc(GLcontext * ctx, GLenum func, { r300ContextPtr rmesa = R300_CONTEXT(ctx); GLuint refmask = ((ctx->Stencil.Ref[0] << R300_RB3D_ZS2_STENCIL_REF_SHIFT) | - (ctx->Stencil. - ValueMask[0] << R300_RB3D_ZS2_STENCIL_MASK_SHIFT)); + (ctx->Stencil.ValueMask[0] << R300_RB3D_ZS2_STENCIL_MASK_SHIFT)); + GLuint flag; R300_STATECHANGE(rmesa, zs); @@ -875,9 +873,10 @@ static void r300StencilFunc(GLcontext * ctx, GLenum func, rmesa->hw.zs.cmd[R300_ZS_CNTL_1] &= ~( (R300_ZS_MASK << R300_RB3D_ZS1_FRONT_FUNC_SHIFT) | (R300_ZS_MASK << R300_RB3D_ZS1_BACK_FUNC_SHIFT)); - rmesa->hw.zs.cmd[R300_ZS_CNTL_2] &= ~((R300_ZS_MASK << R300_RB3D_ZS2_STENCIL_REF_SHIFT) | - (R300_ZS_MASK << R300_RB3D_ZS2_STENCIL_MASK_SHIFT)); - + + rmesa->hw.zs.cmd[R300_ZS_CNTL_2] &= ~((R300_RB3D_ZS2_STENCIL_MASK << R300_RB3D_ZS2_STENCIL_REF_SHIFT) | + (R300_RB3D_ZS2_STENCIL_MASK << R300_RB3D_ZS2_STENCIL_MASK_SHIFT)); + flag = translate_stencil_func(ctx->Stencil.Function[0]); rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |= (flag << R300_RB3D_ZS1_FRONT_FUNC_SHIFT) @@ -890,7 +889,7 @@ static void r300StencilMask(GLcontext * ctx, GLuint mask) r300ContextPtr rmesa = R300_CONTEXT(ctx); R300_STATECHANGE(rmesa, zs); - rmesa->hw.zs.cmd[R300_ZS_CNTL_2] &= ~(R300_ZS_MASK << R300_RB3D_ZS2_STENCIL_WRITE_MASK_SHIFT); + rmesa->hw.zs.cmd[R300_ZS_CNTL_2] &= ~(R300_RB3D_ZS2_STENCIL_MASK << R300_RB3D_ZS2_STENCIL_WRITE_MASK_SHIFT); rmesa->hw.zs.cmd[R300_ZS_CNTL_2] |= ctx->Stencil.WriteMask[0] << R300_RB3D_ZS2_STENCIL_WRITE_MASK_SHIFT; } @@ -902,7 +901,10 @@ static void r300StencilOp(GLcontext * ctx, GLenum fail, R300_STATECHANGE(rmesa, zs); /* It is easier to mask what's left.. */ - rmesa->hw.zs.cmd[R300_ZS_CNTL_1] &= (R300_ZS_MASK << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT); + rmesa->hw.zs.cmd[R300_ZS_CNTL_1] &= + (R300_ZS_MASK << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT) | + (R300_ZS_MASK << R300_RB3D_ZS1_FRONT_FUNC_SHIFT) | + (R300_ZS_MASK << R300_RB3D_ZS1_BACK_FUNC_SHIFT); rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |= (translate_stencil_op(ctx->Stencil.FailFunc[0]) << R300_RB3D_ZS1_FRONT_FAIL_OP_SHIFT) @@ -911,19 +913,16 @@ static void r300StencilOp(GLcontext * ctx, GLenum fail, |(translate_stencil_op(ctx->Stencil.FailFunc[0]) << R300_RB3D_ZS1_BACK_FAIL_OP_SHIFT) |(translate_stencil_op(ctx->Stencil.ZFailFunc[0]) << R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT) |(translate_stencil_op(ctx->Stencil.ZPassFunc[0]) << R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT); - } static void r300ClearStencil(GLcontext * ctx, GLint s) { r300ContextPtr rmesa = R300_CONTEXT(ctx); - /* Not sure whether this is correct.. */ - R300_STATECHANGE(rmesa, zs); - rmesa->hw.zs.cmd[R300_ZS_CNTL_2] = + rmesa->state.stencil.clear = ((GLuint) ctx->Stencil.Clear | - (0xff << R200_STENCIL_MASK_SHIFT) | - (ctx->Stencil.WriteMask[0] << R200_STENCIL_WRITEMASK_SHIFT)); + (R300_RB3D_ZS2_STENCIL_MASK << R300_RB3D_ZS2_STENCIL_MASK_SHIFT) | + (ctx->Stencil.WriteMask[0] << R300_RB3D_ZS2_STENCIL_WRITE_MASK_SHIFT)); } /* ============================================================= @@ -1978,9 +1977,18 @@ void r300ResetHwState(r300ContextPtr r300) have bitfields accessed by different functions and not all bits are used */ #if 0 + /* initialize similiar to r200 */ r300->hw.zs.cmd[R300_ZS_CNTL_0] = 0; - r300->hw.zs.cmd[R300_ZS_CNTL_1] = 0; - r300->hw.zs.cmd[R300_ZS_CNTL_2] = 0xffff00; + r300->hw.zs.cmd[R300_ZS_CNTL_1] = + (R300_ZS_ALWAYS << R300_RB3D_ZS1_FRONT_FUNC_SHIFT) | + (R300_ZS_KEEP << R300_RB3D_ZS1_FRONT_FAIL_OP_SHIFT) | + (R300_ZS_KEEP << R300_RB3D_ZS1_FRONT_ZPASS_OP_SHIFT) | + (R300_ZS_KEEP << R300_RB3D_ZS1_FRONT_ZFAIL_OP_SHIFT) | + (R300_ZS_ALWAYS << R300_RB3D_ZS1_BACK_FUNC_SHIFT) | + (R300_ZS_KEEP << R300_RB3D_ZS1_BACK_FAIL_OP_SHIFT) | + (R300_ZS_KEEP << R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT) | + (R300_ZS_KEEP << R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT); + r300->hw.zs.cmd[R300_ZS_CNTL_2] = 0x00ffff00; #endif /* go and compute register values from GL state */ @@ -1996,6 +2004,12 @@ void r300ResetHwState(r300ContextPtr r300) r300Enable(ctx, GL_DEPTH_TEST, ctx->Depth.Test); r300DepthMask(ctx, ctx->Depth.Mask); r300DepthFunc(ctx, ctx->Depth.Func); + + /* stencil */ + r300Enable(ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled); + r300StencilMask(ctx, ctx->Stencil.WriteMask[0]); + r300StencilFunc(ctx, ctx->Stencil.Function[0], ctx->Stencil.Ref[0], ctx->Stencil.ValueMask[0]); + r300StencilOp(ctx, ctx->Stencil.FailFunc[0], ctx->Stencil.ZFailFunc[0], ctx->Stencil.ZPassFunc[0]); r300UpdateCulling(ctx); @@ -2293,12 +2307,12 @@ void r300InitState(r300ContextPtr r300) case 16: r300->state.depth.scale = 1.0 / (GLfloat) 0xffff; depth_fmt = R200_DEPTH_FORMAT_16BIT_INT_Z; - //r300->state.stencil.clear = 0x00000000; + r300->state.stencil.clear = 0x00000000; break; case 24: r300->state.depth.scale = 1.0 / (GLfloat) 0xffffff; depth_fmt = R200_DEPTH_FORMAT_24BIT_INT_Z; - //r300->state.stencil.clear = 0xff000000; + r300->state.stencil.clear = 0x00ff0000; break; default: fprintf(stderr, "Error: Unsupported depth %d... exiting\n", @@ -2307,7 +2321,7 @@ void r300InitState(r300ContextPtr r300) } /* Only have hw stencil when depth buffer is 24 bits deep */ - r300->state.hw_stencil = (ctx->Visual.stencilBits > 0 && + r300->state.stencil.hw_stencil = (ctx->Visual.stencilBits > 0 && ctx->Visual.depthBits == 24); memset(&(r300->state.texture), 0, sizeof(r300->state.texture)); -- 2.7.4