summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian <brian.paul@tungstengraphics.com>2007-07-10 13:53:21 -0600
committerBrian <brian.paul@tungstengraphics.com>2007-07-10 13:53:21 -0600
commit1deafdb1dec24c2920ab92098f1433273b2ccbdd (patch)
tree620113d9c9ebee3dd3a80df46771252c3e03c78f
parentf6dffd6ee70473dcbf65420a9c635049199f7a4e (diff)
Do depth testing with integer values.
Using floats (and float->ushort->float conversion) introduces errors. Only GLushort depth buffers work for now...
-rw-r--r--src/mesa/drivers/x11/xm_surface.c12
-rw-r--r--src/mesa/pipe/softpipe/sp_quad_depth_test.c39
-rw-r--r--src/mesa/pipe/softpipe/sp_surface.h4
3 files changed, 41 insertions, 14 deletions
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]);
};