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...
This commit is contained in:
Brian Paul 2008-12-10 18:02:27 -07:00
parent 8137da952b
commit d0bc5293d6
5 changed files with 36 additions and 2 deletions

View file

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

View file

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

View file

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

View file

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

View file

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