From d0bc5293d6e1e9c34fa822b7c2928932ed22462c Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 10 Dec 2008 18:02:27 -0700 Subject: gallium: added draw_set_mrd() function to fix polygon offset The Minimum Resolvable Depth factor depends on the driver and can't just be computed from the number of Z buffer bits. Glean's polygon offset test now passes with softpipe. Still need to determine the MRD factor for other gallium drivers, if they use the draw module's polygon offset stage... --- src/gallium/auxiliary/draw/draw_context.c | 12 ++++++++++++ src/gallium/auxiliary/draw/draw_context.h | 1 + src/gallium/auxiliary/draw/draw_pipe_offset.c | 3 +-- src/gallium/auxiliary/draw/draw_private.h | 2 ++ src/gallium/drivers/softpipe/sp_state_surface.c | 20 ++++++++++++++++++++ 5 files changed, 36 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index 74deb44bd2..fab8fc95fc 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -103,6 +103,18 @@ void draw_flush( struct draw_context *draw ) } +/** + * Specify the Minimum Resolvable Depth factor for polygon offset. + * This factor potentially depends on the number of Z buffer bits, + * the rasterization algorithm and the arithmetic performed on Z + * values between vertex shading and rasterization. It will vary + * from one driver to another. + */ +void draw_set_mrd(struct draw_context *draw, double mrd) +{ + draw->mrd = mrd; +} + /** * Register new primitive rasterization/rendering state. diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h index 1d40c6c3be..a29bb01d81 100644 --- a/src/gallium/auxiliary/draw/draw_context.h +++ b/src/gallium/auxiliary/draw/draw_context.h @@ -72,6 +72,7 @@ void draw_enable_line_stipple(struct draw_context *draw, boolean enable); void draw_enable_point_sprites(struct draw_context *draw, boolean enable); +void draw_set_mrd(struct draw_context *draw, double mrd); boolean draw_install_aaline_stage(struct draw_context *draw, struct pipe_context *pipe); diff --git a/src/gallium/auxiliary/draw/draw_pipe_offset.c b/src/gallium/auxiliary/draw/draw_pipe_offset.c index 1fea5e6dcb..8ddc4ee617 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_offset.c +++ b/src/gallium/auxiliary/draw/draw_pipe_offset.c @@ -122,9 +122,8 @@ static void offset_first_tri( struct draw_stage *stage, struct prim_header *header ) { struct offset_stage *offset = offset_stage(stage); - float mrd = 1.0f / 65535.0f; /* XXX this depends on depthbuffer bits! */ - offset->units = stage->draw->rasterizer->offset_units * mrd; + offset->units = stage->draw->rasterizer->offset_units * stage->draw->mrd; offset->scale = stage->draw->rasterizer->offset_scale; stage->tri = offset_tri; diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 37c4c87f87..a16b45d340 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -172,6 +172,8 @@ struct draw_context boolean force_passthrough; /**< never clip or shade */ + double mrd; /**< minimum resolvable depth value, for polygon offset */ + /* pipe state that we need: */ const struct pipe_rasterizer_state *rasterizer; struct pipe_viewport_state viewport; diff --git a/src/gallium/drivers/softpipe/sp_state_surface.c b/src/gallium/drivers/softpipe/sp_state_surface.c index ba8c9eece7..8877b18af9 100644 --- a/src/gallium/drivers/softpipe/sp_state_surface.c +++ b/src/gallium/drivers/softpipe/sp_state_surface.c @@ -101,6 +101,26 @@ softpipe_set_framebuffer_state(struct pipe_context *pipe, } #endif + /* Tell draw module how deep the Z/depth buffer is */ + { + int depth_bits; + double mrd; + if (sp->framebuffer.zsbuf) { + depth_bits = pf_get_component_bits(sp->framebuffer.zsbuf->format, + PIPE_FORMAT_COMP_Z); + } + else { + depth_bits = 0; + } + if (depth_bits > 16) { + mrd = 0.0000001; + } + else { + mrd = 0.00002; + } + draw_set_mrd(sp->draw, mrd); + } + sp->framebuffer.width = fb->width; sp->framebuffer.height = fb->height; -- cgit v1.2.3