From 1deafdb1dec24c2920ab92098f1433273b2ccbdd Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 10 Jul 2007 13:53:21 -0600 Subject: Do depth testing with integer values. Using floats (and float->ushort->float conversion) introduces errors. Only GLushort depth buffers work for now... --- src/mesa/drivers/x11/xm_surface.c | 12 ++++++--- src/mesa/pipe/softpipe/sp_quad_depth_test.c | 39 +++++++++++++++++++++++------ src/mesa/pipe/softpipe/sp_surface.h | 4 +-- 3 files changed, 41 insertions(+), 14 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/drivers/x11/xm_surface.c b/src/mesa/drivers/x11/xm_surface.c index 30c9049cbf..5158e42d9a 100644 --- a/src/mesa/drivers/x11/xm_surface.c +++ b/src/mesa/drivers/x11/xm_surface.c @@ -43,6 +43,7 @@ #include "renderbuffer.h" #include "pipe/p_state.h" +#include "pipe/p_defines.h" #include "pipe/softpipe/sp_context.h" #include "pipe/softpipe/sp_surface.h" @@ -245,7 +246,7 @@ xmesa_get_color_surface(GLcontext *ctx, GLuint buf) static void read_quad_z(struct softpipe_surface *sps, - GLint x, GLint y, GLfloat zzzz[QUAD_SIZE]) + GLint x, GLint y, GLuint zzzz[QUAD_SIZE]) { struct xmesa_surface *xmsurf = xmesa_surface(sps); struct gl_renderbuffer *rb = xmsurf->rb; @@ -254,22 +255,24 @@ read_quad_z(struct softpipe_surface *sps, GET_CURRENT_CONTEXT(ctx); rb->GetRow(ctx, rb, 2, x, y, temp); rb->GetRow(ctx, rb, 2, x, y + 1, temp + 2); + /* convert from GLushort to GLuint */ for (i = 0; i < 4; i++) { - zzzz[i] = USHORT_TO_FLOAT(temp[i]); + zzzz[i] = temp[i]; } } static void write_quad_z(struct softpipe_surface *sps, - GLint x, GLint y, const GLfloat zzzz[QUAD_SIZE]) + GLint x, GLint y, const GLuint zzzz[QUAD_SIZE]) { struct xmesa_surface *xmsurf = xmesa_surface(sps); struct gl_renderbuffer *rb = xmsurf->rb; GLushort temp[4]; GLuint i; GET_CURRENT_CONTEXT(ctx); + /* convert from GLuint to GLushort */ for (i = 0; i < 4; i++) { - CLAMPED_FLOAT_TO_USHORT(temp[i], zzzz[i]); + temp[i] = zzzz[i]; } rb->PutRow(ctx, rb, 2, x, y, temp, NULL); rb->PutRow(ctx, rb, 2, x, y + 1, temp + 2, NULL); @@ -283,6 +286,7 @@ create_z_surface(XMesaContext xmctx, struct gl_renderbuffer *rb) xmsurf = CALLOC_STRUCT(xmesa_surface); if (xmsurf) { + xmsurf->sps.surface.format = PIPE_FORMAT_U_Z16; xmsurf->sps.surface.width = rb->Width; xmsurf->sps.surface.height = rb->Height; xmsurf->sps.read_quad_z = read_quad_z; diff --git a/src/mesa/pipe/softpipe/sp_quad_depth_test.c b/src/mesa/pipe/softpipe/sp_quad_depth_test.c index fcd6a22e1d..0b5d909b2d 100644 --- a/src/mesa/pipe/softpipe/sp_quad_depth_test.c +++ b/src/mesa/pipe/softpipe/sp_quad_depth_test.c @@ -39,15 +39,38 @@ static void depth_test_quad(struct quad_stage *qs, struct quad_header *quad) { struct softpipe_context *softpipe = qs->softpipe; - GLuint j; struct softpipe_surface *sps = softpipe_surface(softpipe->framebuffer.zbuf); - GLfloat zzzz[QUAD_SIZE]; /**< Z for four pixels in quad */ + GLuint bzzzz[QUAD_SIZE]; /**< Z values fetched from depth buffer */ + GLuint qzzzz[QUAD_SIZE]; /**< Z values from the quad */ GLuint zmask = 0; + GLuint j; + GLfloat scale; assert(sps); /* shouldn't get here if there's no zbuffer */ + /* + * To increase efficiency, we should probably have multiple versions + * of this function that are specifically for Z16, Z32 and FP Z buffers. + * Try to effectively do that with codegen... + */ + if (sps->surface.format == PIPE_FORMAT_U_Z16) + scale = 65535.0; + else + assert(0); /* XXX fix this someday */ + + /* + * Convert quad's float depth values to int depth values. + * If the Z buffer stores integer values, we _have_ to do the depth + * compares with integers (not floats). Otherwise, the float->int->float + * conversion of Z values (which isn't an identity function) will cause + * Z-fighting errors. + */ + for (j = 0; j < QUAD_SIZE; j++) { + qzzzz[j] = (GLuint) (quad->outputs.depth[j] * scale); + } + /* get zquad from zbuffer */ - sps->read_quad_z(sps, quad->x0, quad->y0, zzzz); + sps->read_quad_z(sps, quad->x0, quad->y0, bzzzz); switch (softpipe->depth_test.func) { case PIPE_FUNC_NEVER: @@ -57,19 +80,19 @@ depth_test_quad(struct quad_stage *qs, struct quad_header *quad) * Like this: quad->mask &= (quad->outputs.depth < zzzz); */ for (j = 0; j < QUAD_SIZE; j++) { - if (quad->outputs.depth[j] < zzzz[j]) + if (qzzzz[j] < bzzzz[j]) zmask |= 1 << j; } break; case PIPE_FUNC_EQUAL: for (j = 0; j < QUAD_SIZE; j++) { - if (quad->outputs.depth[j] == zzzz[j]) + if (qzzzz[j] == bzzzz[j]) zmask |= 1 << j; } break; case PIPE_FUNC_LEQUAL: for (j = 0; j < QUAD_SIZE; j++) { - if (quad->outputs.depth[j] <= zzzz[j]) + if (qzzzz[j] <= bzzzz[j]) zmask |= (1 << j); } break; @@ -86,12 +109,12 @@ depth_test_quad(struct quad_stage *qs, struct quad_header *quad) */ for (j = 0; j < QUAD_SIZE; j++) { if (quad->mask & (1 << j)) { - zzzz[j] = quad->outputs.depth[j]; + bzzzz[j] = qzzzz[j]; } } /* write updated zquad to zbuffer */ - sps->write_quad_z(sps, quad->x0, quad->y0, zzzz); + sps->write_quad_z(sps, quad->x0, quad->y0, bzzzz); } qs->next->run(qs->next, quad); diff --git a/src/mesa/pipe/softpipe/sp_surface.h b/src/mesa/pipe/softpipe/sp_surface.h index ac66ffe891..450542abdd 100644 --- a/src/mesa/pipe/softpipe/sp_surface.h +++ b/src/mesa/pipe/softpipe/sp_surface.h @@ -79,9 +79,9 @@ struct softpipe_surface { GLubyte rgba[NUM_CHANNELS] ); void (*read_quad_z)(struct softpipe_surface *, - GLint x, GLint y, GLfloat zzzz[QUAD_SIZE]); + GLint x, GLint y, GLuint zzzz[QUAD_SIZE]); void (*write_quad_z)(struct softpipe_surface *, - GLint x, GLint y, const GLfloat zzzz[QUAD_SIZE]); + GLint x, GLint y, const GLuint zzzz[QUAD_SIZE]); }; -- cgit v1.2.3