mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 09:38:07 +02:00
Do depth testing with integer values.
Using floats (and float->ushort->float conversion) introduces errors. Only GLushort depth buffers work for now...
This commit is contained in:
parent
f6dffd6ee7
commit
1deafdb1de
3 changed files with 41 additions and 14 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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]);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue