gallium: added draw_set_mrd() function to fix polygon offset
authorBrian Paul <brian.paul@tungstengraphics.com>
Thu, 11 Dec 2008 01:02:27 +0000 (18:02 -0700)
committerBrian Paul <brian.paul@tungstengraphics.com>
Thu, 11 Dec 2008 01:06:44 +0000 (18:06 -0700)
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
src/gallium/auxiliary/draw/draw_context.h
src/gallium/auxiliary/draw/draw_pipe_offset.c
src/gallium/auxiliary/draw/draw_private.h
src/gallium/drivers/softpipe/sp_state_surface.c

index 74deb44bd28545240b6234d5aa522f042c925004..fab8fc95fcaf09e20154a306bca4c39e5211cd95 100644 (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.
index 1d40c6c3bef28d6efe73e838ba03a95463c2dd8f..a29bb01d81468e4d62610d143be1559717b7a97f 100644 (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);
index 1fea5e6dcbc5bb5c7f23519d510f1f151a4f929e..8ddc4ee6178c33b6f7e1a3c14a13c0de6d65a4ab 100644 (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;
index 37c4c87f87fc23d3fcbc53edcc4359bdb42b6adc..a16b45d340ae2ed281d83d37c60e2743868d6963 100644 (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;
index ba8c9eece72462fa52cf60c3b75741ead3417aed..8877b18af90654f93cf4eafe9d0d3693c7301c3e 100644 (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;