From ecfa794037e8be351ecfec0229d1e3b1677ae369 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 20 Jun 2007 17:20:02 -0600 Subject: [PATCH] checkpoint: implement z/depth testing --- src/mesa/drivers/x11/xm_surface.c | 14 ++++ src/mesa/drivers/x11/xm_tri.c | 4 +- src/mesa/drivers/x11/xmesaP.h | 11 ++- src/mesa/pipe/softpipe/sp_context.c | 3 + src/mesa/pipe/softpipe/sp_context.h | 1 + src/mesa/pipe/softpipe/sp_quad.c | 6 ++ src/mesa/pipe/softpipe/sp_quad_depth_test.c | 79 ++++++++++++++++---- src/mesa/pipe/softpipe/sp_state.h | 6 ++ src/mesa/pipe/softpipe/sp_state_blend.c | 26 +++++++ src/mesa/pipe/softpipe/sp_state_derived.c | 2 +- src/mesa/pipe/softpipe/sp_surface.h | 5 ++ src/mesa/state_tracker/st_atom.c | 1 + src/mesa/state_tracker/st_atom_framebuffer.c | 14 ++++ 13 files changed, 153 insertions(+), 19 deletions(-) diff --git a/src/mesa/drivers/x11/xm_surface.c b/src/mesa/drivers/x11/xm_surface.c index ee06b77377d..a937df3adef 100644 --- a/src/mesa/drivers/x11/xm_surface.c +++ b/src/mesa/drivers/x11/xm_surface.c @@ -241,3 +241,17 @@ xmesa_get_color_surface(GLcontext *ctx, GLuint buf) return (struct pipe_surface *) xrb->pSurface; } + +struct pipe_surface * +xmesa_get_z_surface(GLcontext *ctx, GLuint i) +{ + return NULL; +} + + +struct pipe_surface * +xmesa_get_stencil_surface(GLcontext *ctx, GLuint i) +{ + return NULL; +} + diff --git a/src/mesa/drivers/x11/xm_tri.c b/src/mesa/drivers/x11/xm_tri.c index 6158ef30f91..9f17083f901 100644 --- a/src/mesa/drivers/x11/xm_tri.c +++ b/src/mesa/drivers/x11/xm_tri.c @@ -1443,7 +1443,7 @@ do { \ #endif - +#if 0 GLboolean xmesa_get_cbuf_details( GLcontext *ctx, void **ptr, GLuint *cpp, @@ -1480,7 +1480,7 @@ GLboolean xmesa_get_cbuf_details( GLcontext *ctx, *format = 0; return GL_FALSE; } - +#endif /** diff --git a/src/mesa/drivers/x11/xmesaP.h b/src/mesa/drivers/x11/xmesaP.h index c36b0966d95..1d5df3d9353 100644 --- a/src/mesa/drivers/x11/xmesaP.h +++ b/src/mesa/drivers/x11/xmesaP.h @@ -580,16 +580,23 @@ extern void xmesa_register_swrast_functions( GLcontext *ctx ); #define ENABLE_EXT_timer_query 0 /* may not have 64-bit GLuint64EXT */ #endif - +#if 0 GLboolean xmesa_get_cbuf_details( GLcontext *ctx, void **ptr, GLuint *cpp, GLint *stride, GLuint *format ); - +#endif struct pipe_surface; struct pipe_surface * xmesa_get_color_surface(GLcontext *ctx, GLuint buf); +struct pipe_surface * +xmesa_get_z_surface(GLcontext *ctx, GLuint i); + +struct pipe_surface * +xmesa_get_stencil_surface(GLcontext *ctx, GLuint i); + + #endif diff --git a/src/mesa/pipe/softpipe/sp_context.c b/src/mesa/pipe/softpipe/sp_context.c index 593be0e1328..f27d2dd8bc8 100644 --- a/src/mesa/pipe/softpipe/sp_context.c +++ b/src/mesa/pipe/softpipe/sp_context.c @@ -65,9 +65,11 @@ struct pipe_context *softpipe_create( void ) softpipe->pipe.destroy = softpipe_destroy; softpipe->pipe.set_framebuffer_state = softpipe_set_framebuffer_state; + softpipe->pipe.set_alpha_test_state = softpipe_set_alpha_test_state; softpipe->pipe.set_blend_state = softpipe_set_blend_state; softpipe->pipe.set_clip_state = softpipe_set_clip_state; softpipe->pipe.set_clear_color_state = softpipe_set_clear_color_state; + softpipe->pipe.set_depth_state = softpipe_set_depth_test_state; softpipe->pipe.set_point_state = softpipe_set_point_state; softpipe->pipe.set_viewport = softpipe_set_viewport; softpipe->pipe.set_setup_state = softpipe_set_setup_state; @@ -87,6 +89,7 @@ struct pipe_context *softpipe_create( void ) softpipe->prim.cull = prim_cull( softpipe ); softpipe->quad.blend = sp_quad_blend_stage(softpipe); + softpipe->quad.depth_test = sp_quad_depth_test_stage(softpipe); softpipe->quad.shade = sp_quad_shade_stage(softpipe); softpipe->quad.output = sp_quad_output_stage(softpipe); diff --git a/src/mesa/pipe/softpipe/sp_context.h b/src/mesa/pipe/softpipe/sp_context.h index ebe39fa8bf0..d01fc38b81b 100644 --- a/src/mesa/pipe/softpipe/sp_context.h +++ b/src/mesa/pipe/softpipe/sp_context.h @@ -80,6 +80,7 @@ struct softpipe_context { struct pipe_alpha_test_state alpha_test; struct pipe_clip_state clip; struct pipe_clear_color_state clear_color; + struct pipe_depth_state depth_test; struct pipe_point_state point; struct pipe_scissor_rect scissor; struct pipe_poly_stipple poly_stipple; diff --git a/src/mesa/pipe/softpipe/sp_quad.c b/src/mesa/pipe/softpipe/sp_quad.c index 168872c64d0..32085ab8c45 100644 --- a/src/mesa/pipe/softpipe/sp_quad.c +++ b/src/mesa/pipe/softpipe/sp_quad.c @@ -7,6 +7,7 @@ void sp_build_quad_pipeline(struct softpipe_context *sp) { + /* build up the pipeline in reverse order... */ sp->quad.first = sp->quad.output; @@ -15,6 +16,11 @@ sp_build_quad_pipeline(struct softpipe_context *sp) sp->quad.first = sp->quad.blend; } + if (sp->depth_test.enabled) { + sp->quad.depth_test->next = sp->quad.first; + sp->quad.first = sp->quad.depth_test; + } + /* XXX always enable shader? */ if (1) { sp->quad.shade->next = sp->quad.first; diff --git a/src/mesa/pipe/softpipe/sp_quad_depth_test.c b/src/mesa/pipe/softpipe/sp_quad_depth_test.c index 756141db173..76a6ee1bb60 100644 --- a/src/mesa/pipe/softpipe/sp_quad_depth_test.c +++ b/src/mesa/pipe/softpipe/sp_quad_depth_test.c @@ -32,29 +32,80 @@ #include "sp_headers.h" #include "sp_surface.h" #include "sp_quad.h" - +#include "pipe/p_defines.h" static void depth_test_quad(struct quad_stage *qs, struct quad_header *quad) { -#if 0 struct softpipe_context *softpipe = qs->softpipe; - GLfloat dest[4][QUAD_SIZE], result[4][QUAD_SIZE]; - GLuint i; - - /* XXX we're also looping in output_quad() !?! */ - - for (i = 0; i < softpipe->framebuffer.num_cbufs; i++) { - struct softpipe_surface *sps - = softpipe_surface(softpipe->framebuffer.cbufs[i]); - - sps->read_quad_f_swz(sps, quad->x0, quad->y0, dest); + GLuint j; + struct softpipe_surface *sps = softpipe_surface(softpipe->framebuffer.zbuf); + GLfloat zzzz[QUAD_SIZE]; /**< Z for four pixels in quad */ - /* XXX do blend here */ +#if 0 + assert(sps); /* shouldn't get here if there's no zbuffer */ +#else + if (!sps) + return; +#endif + /* XXX get zquad from zbuffer */ + sps->read_quad_z(sps, quad->x0, quad->y0, zzzz); + + switch (softpipe->depth_test.func) { + case PIPE_FUNC_NEVER: + quad->mask = 0x0; + break; + case PIPE_FUNC_LESS: + for (j = 0; j < QUAD_SIZE; j++) { + if (quad->mask & (1 << j)) { + if (quad->outputs.depth[j] >= zzzz[j]) { + /* fail */ + quad->mask &= (1 << j); + } + else if (softpipe->depth_test.writemask) { + /* pass, and update Z buffer */ + zzzz[j] = quad->outputs.depth[j]; + } + } + } + break; + case PIPE_FUNC_EQUAL: + for (j = 0; j < QUAD_SIZE; j++) { + if (quad->mask & (1 << j)) { + if (quad->outputs.depth[j] != zzzz[j]) { + /* fail */ + quad->mask &= (1 << j); + } + else if (softpipe->depth_test.writemask) { + /* pass, and update Z buffer */ + zzzz[j] = quad->outputs.depth[j]; + } + } + } + break; + case PIPE_FUNC_LEQUAL: + for (j = 0; j < QUAD_SIZE; j++) { + if (quad->mask & (1 << j)) { + if (quad->outputs.depth[j] > zzzz[j]) { + /* fail */ + quad->mask &= (1 << j); + } + else if (softpipe->depth_test.writemask) { + /* pass, and update Z buffer */ + zzzz[j] = quad->outputs.depth[j]; + } + } + } + break; + /* XXX fill in remaining cases */ + default: + abort(); } -#endif + + /* XXX write updated zquad to zbuffer */ + sps->write_quad_z(sps, quad->x0, quad->y0, zzzz); qs->next->run(qs->next, quad); } diff --git a/src/mesa/pipe/softpipe/sp_state.h b/src/mesa/pipe/softpipe/sp_state.h index 5a657c4a8f9..6253b9c9e53 100644 --- a/src/mesa/pipe/softpipe/sp_state.h +++ b/src/mesa/pipe/softpipe/sp_state.h @@ -38,6 +38,9 @@ void softpipe_set_framebuffer_state( struct pipe_context *, const struct pipe_framebuffer_state * ); +void softpipe_set_alpha_test_state( struct pipe_context *, + const struct pipe_alpha_test_state * ); + void softpipe_set_blend_state( struct pipe_context *, const struct pipe_blend_state * ); @@ -47,6 +50,9 @@ void softpipe_set_clear_color_state( struct pipe_context *, void softpipe_set_clip_state( struct pipe_context *, const struct pipe_clip_state * ); +void softpipe_set_depth_test_state( struct pipe_context *, + const struct pipe_depth_state * ); + void softpipe_set_viewport( struct pipe_context *, const struct pipe_viewport * ); diff --git a/src/mesa/pipe/softpipe/sp_state_blend.c b/src/mesa/pipe/softpipe/sp_state_blend.c index 1fd7a44105b..c364d8a3196 100644 --- a/src/mesa/pipe/softpipe/sp_state_blend.c +++ b/src/mesa/pipe/softpipe/sp_state_blend.c @@ -45,3 +45,29 @@ void softpipe_set_blend_state( struct pipe_context *pipe, softpipe->dirty |= G_NEW_BLEND; } + +/** XXX move someday? Or consolidate all these simple state setters + * into one file. + */ +void +softpipe_set_depth_test_state(struct pipe_context *pipe, + const struct pipe_depth_state *depth) +{ + struct softpipe_context *softpipe = softpipe_context(pipe); + + softpipe->depth_test = *depth; + + softpipe->dirty |= G_NEW_DEPTH_TEST; +} + +void +softpipe_set_alpha_test_state(struct pipe_context *pipe, + const struct pipe_alpha_test_state *alpha) +{ + struct softpipe_context *softpipe = softpipe_context(pipe); + + softpipe->alpha_test = *alpha; + + softpipe->dirty |= G_NEW_ALPHA_TEST; +} + diff --git a/src/mesa/pipe/softpipe/sp_state_derived.c b/src/mesa/pipe/softpipe/sp_state_derived.c index 8ab325b72d4..5aee4be6b8e 100644 --- a/src/mesa/pipe/softpipe/sp_state_derived.c +++ b/src/mesa/pipe/softpipe/sp_state_derived.c @@ -134,7 +134,7 @@ void softpipe_update_derived( struct softpipe_context *softpipe ) if (softpipe->dirty & (G_NEW_SETUP | G_NEW_FS)) calculate_vertex_layout( softpipe ); - if (softpipe->dirty & (G_NEW_BLEND | G_NEW_FS)) + if (softpipe->dirty & (G_NEW_BLEND | G_NEW_DEPTH_TEST | G_NEW_ALPHA_TEST | G_NEW_FS)) sp_build_quad_pipeline(softpipe); softpipe->dirty = 0; diff --git a/src/mesa/pipe/softpipe/sp_surface.h b/src/mesa/pipe/softpipe/sp_surface.h index fc9557dee3a..05b125d17b6 100644 --- a/src/mesa/pipe/softpipe/sp_surface.h +++ b/src/mesa/pipe/softpipe/sp_surface.h @@ -77,6 +77,11 @@ struct softpipe_surface { void (*write_mono_row_ub)( struct softpipe_surface *, GLuint count, GLint x, GLint y, GLubyte rgba[NUM_CHANNELS] ); + + void (*read_quad_z)(struct softpipe_surface *, + GLint x, GLint y, GLfloat zzzz[QUAD_SIZE]); + void (*write_quad_z)(struct softpipe_surface *, + GLint x, GLint y, const GLfloat zzzz[QUAD_SIZE]); }; diff --git a/src/mesa/state_tracker/st_atom.c b/src/mesa/state_tracker/st_atom.c index e1d187f2db9..5fcd9d7af59 100644 --- a/src/mesa/state_tracker/st_atom.c +++ b/src/mesa/state_tracker/st_atom.c @@ -44,6 +44,7 @@ static const struct st_tracked_state *atoms[] = { &st_update_framebuffer, &st_update_clear_color, + &st_update_depth, &st_update_clip, &st_update_fs, &st_update_point, diff --git a/src/mesa/state_tracker/st_atom_framebuffer.c b/src/mesa/state_tracker/st_atom_framebuffer.c index f203e1df60b..8e98cbc2df0 100644 --- a/src/mesa/state_tracker/st_atom_framebuffer.c +++ b/src/mesa/state_tracker/st_atom_framebuffer.c @@ -39,6 +39,12 @@ extern struct pipe_surface * xmesa_get_color_surface(GLcontext *ctx, GLuint i); +extern struct pipe_surface * +xmesa_get_z_surface(GLcontext *ctx, GLuint i); + +extern struct pipe_surface * +xmesa_get_stencil_surface(GLcontext *ctx, GLuint i); + /** * Update framebuffer state (color, depth, stencil, etc. buffers) @@ -58,6 +64,14 @@ update_framebuffer_state( struct st_context *st ) framebuffer.cbufs[i] = xmesa_get_color_surface(st->ctx, i); } + if (st->ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer) { + framebuffer.zbuf = xmesa_get_z_surface(st->ctx, i); + } + + if (st->ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer) { + framebuffer.sbuf = xmesa_get_stencil_surface(st->ctx, i); + } + if (memcmp(&framebuffer, &st->state.framebuffer, sizeof(framebuffer)) != 0) { st->state.framebuffer = framebuffer; st->pipe->set_framebuffer_state( st->pipe, &framebuffer ); -- 2.30.2