Stencil support
Reflex from mesa demos doesn't work TODO - double side stencil I hope that I didn't break anything
This commit is contained in:
parent
02eb36fa8d
commit
e2e4a5c992
|
@ -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;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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<<R300_RB3D_ZS1_DEPTH_FUNC_SHIFT);
|
||||
r300->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<<R300_RB3D_ZS1_DEPTH_FUNC_SHIFT);
|
||||
/*
|
||||
R300_STATECHANGE(r300, zb);
|
||||
r300->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<<R300_RB3D_ZS1_FRONT_FUNC_SHIFT) |
|
||||
(R300_ZS_REPLACE<<R300_RB3D_ZS1_FRONT_FAIL_OP_SHIFT) |
|
||||
(R300_ZS_REPLACE<<R300_RB3D_ZS1_FRONT_ZPASS_OP_SHIFT) |
|
||||
(R300_ZS_REPLACE<<R300_RB3D_ZS1_FRONT_ZFAIL_OP_SHIFT) |
|
||||
(R300_ZS_ALWAYS<<R300_RB3D_ZS1_BACK_FUNC_SHIFT) |
|
||||
(R300_ZS_REPLACE<<R300_RB3D_ZS1_BACK_FAIL_OP_SHIFT) |
|
||||
(R300_ZS_REPLACE<<R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT) |
|
||||
(R300_ZS_REPLACE<<R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT) ;
|
||||
r300->hw.zs.cmd[R300_ZS_CNTL_2] = r300->state.stencil.clear;
|
||||
}
|
||||
|
||||
/* Make sure we have enough space */
|
||||
|
@ -315,6 +337,11 @@ static void r300Clear(GLcontext * ctx, GLbitfield mask, GLboolean all,
|
|||
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)
|
||||
fprintf(stderr, "%s: swrast clear, mask: %x\n",
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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,7 +623,8 @@ static void r300DepthMask(GLcontext* ctx, GLboolean mask)
|
|||
return;
|
||||
|
||||
R300_STATECHANGE(r300, zs);
|
||||
r300->hw.zs.cmd[R300_ZS_CNTL_0] = mask
|
||||
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,8 +873,9 @@ 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]);
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -1997,6 +2005,12 @@ void r300ResetHwState(r300ContextPtr r300)
|
|||
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);
|
||||
|
||||
r300UpdateTextureState(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));
|
||||
|
|
Loading…
Reference in New Issue