From ca710a0a7f0ae7e637e3e73cc4edac0a81f6fe1c Mon Sep 17 00:00:00 2001 From: Vladimir Dergachev Date: Sat, 15 Jan 2005 20:44:23 +0000 Subject: On the way to getting stencil working. --- src/mesa/drivers/dri/r300/r300_context.h | 1 + src/mesa/drivers/dri/r300/r300_reg.h | 1 + src/mesa/drivers/dri/r300/r300_render.c | 6 +- src/mesa/drivers/dri/r300/r300_state.c | 142 ++++++++++++++++++++++++++++++- 4 files changed, 146 insertions(+), 4 deletions(-) (limited to 'src/mesa/drivers/dri/r300') diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h index 32607227e17..f0a186d3967 100644 --- a/src/mesa/drivers/dri/r300/r300_context.h +++ b/src/mesa/drivers/dri/r300/r300_context.h @@ -616,6 +616,7 @@ struct r300_state { struct r300_aos_rec aos[R300_MAX_AOS_ARRAYS]; int aos_count; + int hw_stencil; }; diff --git a/src/mesa/drivers/dri/r300/r300_reg.h b/src/mesa/drivers/dri/r300/r300_reg.h index 1eab9f81500..d07eb75a01c 100644 --- a/src/mesa/drivers/dri/r300/r300_reg.h +++ b/src/mesa/drivers/dri/r300/r300_reg.h @@ -1069,6 +1069,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_STENCIL_ENABLE 0x00000000 /* UNKNOWN yet.. */ #define R300_RB3D_ZSTENCILCNTL_1 0x4F04 /* functions */ diff --git a/src/mesa/drivers/dri/r300/r300_render.c b/src/mesa/drivers/dri/r300/r300_render.c index cdf972a46d9..2f832d27513 100644 --- a/src/mesa/drivers/dri/r300/r300_render.c +++ b/src/mesa/drivers/dri/r300/r300_render.c @@ -584,8 +584,8 @@ static void r300_check_render(GLcontext *ctx, struct tnl_pipeline_stage *stage) /* I'm almost certain I forgot something here */ #if 0 /* This should work now.. */ FALLBACK_IF(ctx->Color.AlphaEnabled); // GL_ALPHA_TEST + FALLBACK_IF(ctx->Color.BlendEnabled); // GL_BLEND #endif - //FALLBACK_IF(ctx->Color.BlendEnabled); // GL_BLEND FALLBACK_IF(ctx->Fog.Enabled); // GL_FOG FALLBACK_IF(ctx->Line.SmoothFlag); // GL_LINE_SMOOTH FALLBACK_IF(ctx->Line.StippleFlag); // GL_LINE_STIPPLE @@ -597,11 +597,11 @@ static void r300_check_render(GLcontext *ctx, struct tnl_pipeline_stage *stage) FALLBACK_IF(ctx->Polygon.OffsetFill); // GL_POLYGON_OFFSET_FILL FALLBACK_IF(ctx->Polygon.SmoothFlag); // GL_POLYGON_SMOOTH FALLBACK_IF(ctx->Polygon.StippleFlag); // GL_POLYGON_STIPPLE - FALLBACK_IF(ctx->Stencil.Enabled); // GL_STENCIL_TEST + //FALLBACK_IF(ctx->Stencil.Enabled); // GL_STENCIL_TEST FALLBACK_IF(ctx->Multisample.Enabled); // GL_MULTISAMPLE_ARB /* One step at a time - let one texture pass.. */ - for (i = 2; i < ctx->Const.MaxTextureUnits; i++) + for (i = 1; i < ctx->Const.MaxTextureUnits; i++) FALLBACK_IF(ctx->Texture.Unit[i].Enabled); diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index 32b77fbb14f..f4dd8bece75 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -470,6 +470,21 @@ static void r300Enable(GLcontext* ctx, GLenum cap, GLboolean state) r300->hw.zs.cmd[R300_ZS_CNTL_0] = newval; break; + + case GL_STENCIL_TEST: + if (r300->state.hw_stencil) { + R300_STATECHANGE(r300, zs); + if (state) { + r300->hw.zs.cmd[R300_ZS_CNTL_0] |= + R300_STENCIL_ENABLE; + } else { + r300->hw.zs.cmd[R300_ZS_CNTL_0] &= + ~R300_STENCIL_ENABLE; + } + } else { + FALLBACK(&r300->radeon, RADEON_FALLBACK_STENCIL, state); + } + break; case GL_CULL_FACE: r300UpdateCulling(ctx); @@ -548,7 +563,6 @@ static void r300DepthFunc(GLcontext* ctx, GLenum func) break; } - fprintf(stderr, "ZS_CNTL_1=%08x\n", r300->hw.zs.cmd[R300_ZS_CNTL_1]); } @@ -596,6 +610,122 @@ static void r300PointSize(GLcontext * ctx, GLfloat size) R300_STATECHANGE(r300, vps); r300->hw.vps.cmd[R300_VPS_POINTSIZE] = r300PackFloat32(1.0); } +/* ============================================================= + * Stencil + */ + +static void r300StencilFunc(GLcontext * ctx, GLenum func, + GLint ref, GLuint mask) +{ + 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)); + + R200_STATECHANGE(rmesa, zs); + + rmesa->hw.zs.cmd[R300_ZS_CNTL_1] &= ~(R300_ZS_MASK << R300_RB3D_ZS1_STENCIL_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)); + + switch (ctx->Stencil.Function[0]) { + case GL_NEVER: + rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |= + R300_ZS_NEVER << R300_RB3D_ZS1_STENCIL_FUNC_SHIFT; + break; + case GL_LESS: + rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |= + R300_ZS_LESS << R300_RB3D_ZS1_STENCIL_FUNC_SHIFT; + break; + case GL_EQUAL: + rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |= + R300_ZS_EQUAL << R300_RB3D_ZS1_STENCIL_FUNC_SHIFT; + break; + case GL_LEQUAL: + rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |= + R300_ZS_LEQUAL << R300_RB3D_ZS1_STENCIL_FUNC_SHIFT; + break; + case GL_GREATER: + rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |= + R300_ZS_GREATER << R300_RB3D_ZS1_STENCIL_FUNC_SHIFT; + break; + case GL_NOTEQUAL: + rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |= + R300_ZS_NOTEQUAL << R300_RB3D_ZS1_STENCIL_FUNC_SHIFT; + break; + case GL_GEQUAL: + rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |= + R300_ZS_GEQUAL << R300_RB3D_ZS1_STENCIL_FUNC_SHIFT; + break; + case GL_ALWAYS: + rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |= + R300_ZS_ALWAYS << R300_RB3D_ZS1_STENCIL_FUNC_SHIFT; + break; + } + + rmesa->hw.zs.cmd[R300_ZS_CNTL_2] |= refmask; +} + +static void r300StencilMask(GLcontext * ctx, GLuint mask) +{ + r300ContextPtr rmesa = R300_CONTEXT(ctx); + + R200_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] |= ctx->Stencil.WriteMask[0] << R300_RB3D_ZS2_STENCIL_WRITE_MASK_SHIFT; +} + +static int translate_stencil_op(int op) +{ + switch (op) { + case GL_KEEP: + return R300_ZS_KEEP; + case GL_ZERO: + return R300_ZS_ZERO; + case GL_REPLACE: + return R300_ZS_REPLACE; + case GL_INCR: + return R300_ZS_INCR; + case GL_DECR: + return R300_ZS_DECR; + case GL_INCR_WRAP_EXT: + return R300_ZS_INCR_WRAP; + case GL_DECR_WRAP_EXT: + return R300_ZS_DECR_WRAP; + case GL_INVERT: + return R300_ZS_INVERT; + } +} + +static void r300StencilOp(GLcontext * ctx, GLenum fail, + GLenum zfail, GLenum zpass) +{ + r300ContextPtr rmesa = R300_CONTEXT(ctx); + + R200_STATECHANGE(rmesa, zs); + rmesa->hw.zs.cmd[R300_ZS_CNTL_1] &= ~((R300_ZS_MASK << R300_RB3D_ZS1_STENCIL_FAIL_OP_SHIFT) + | (R300_ZS_MASK << R300_RB3D_ZS1_STENCIL_ZPASS_OP_SHIFT) + | (R300_ZS_MASK << R300_RB3D_ZS1_STENCIL_ZFAIL_OP_SHIFT) + ); + + rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |= + (translate_stencil_op(ctx->Stencil.FailFunc[0]) << R300_RB3D_ZS1_STENCIL_FAIL_OP_SHIFT) + |(translate_stencil_op(ctx->Stencil.ZFailFunc[0]) << R300_RB3D_ZS1_STENCIL_ZFAIL_OP_SHIFT) + |(translate_stencil_op(ctx->Stencil.ZPassFunc[0]) << R300_RB3D_ZS1_STENCIL_ZPASS_OP_SHIFT); + +} + +static void r300ClearStencil(GLcontext * ctx, GLint s) +{ + r300ContextPtr rmesa = R300_CONTEXT(ctx); + + /* Not sure whether this is correct.. */ + R200_STATECHANGE(rmesa, zs); + rmesa->hw.zs.cmd[R300_ZS_CNTL_2] = + ((GLuint) ctx->Stencil.Clear | + (0xff << R200_STENCIL_MASK_SHIFT) | + (ctx->Stencil.WriteMask[0] << R200_STENCIL_WRITEMASK_SHIFT)); +} /* ============================================================= * Window position and viewport transformation @@ -1673,6 +1803,10 @@ void r300InitState(r300ContextPtr r300) exit(-1); } + /* Only have hw stencil when depth buffer is 24 bits deep */ + r300->state.hw_stencil = (ctx->Visual.stencilBits > 0 && + ctx->Visual.depthBits == 24); + memset(&(r300->state.texture), 0, sizeof(r300->state.texture)); r300ResetHwState(r300); @@ -1699,6 +1833,12 @@ void r300InitStateFuncs(struct dd_function_table* functions) functions->CullFace = r300CullFace; functions->FrontFace = r300FrontFace; + /* Stencil related */ + functions->ClearStencil = r300ClearStencil; + functions->StencilFunc = r300StencilFunc; + functions->StencilMask = r300StencilMask; + functions->StencilOp = r300StencilOp; + /* Viewport related */ functions->Viewport = r300Viewport; functions->DepthRange = r300DepthRange; -- cgit v1.2.3