checkpoint: implement z/depth testing

This commit is contained in:
Brian 2007-06-20 17:20:02 -06:00
parent 3c0790ca92
commit ecfa794037
13 changed files with 154 additions and 20 deletions

View file

@ -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;
}

View file

@ -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
/**

View file

@ -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

View file

@ -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);

View file

@ -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;

View file

@ -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;

View file

@ -32,30 +32,81 @@
#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;
GLuint j;
struct softpipe_surface *sps = softpipe_surface(softpipe->framebuffer.zbuf);
GLfloat zzzz[QUAD_SIZE]; /**< Z for four pixels in quad */
/* 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);
/* 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();
}
/* XXX write updated zquad to zbuffer */
sps->write_quad_z(sps, quad->x0, quad->y0, zzzz);
qs->next->run(qs->next, quad);
}

View file

@ -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 * );

View file

@ -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;
}

View file

@ -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;

View file

@ -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]);
};

View file

@ -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,

View file

@ -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 );