Mesa (master): util,llvmpipe: correctly set the minimum representable depth value

Jose Fonseca jrfonseca at kemper.freedesktop.org
Tue Oct 29 15:56:18 UTC 2013


Module: Mesa
Branch: master
Commit: be0b67a1436eb2b899f9874725b2a68eb26f9f3f
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=be0b67a1436eb2b899f9874725b2a68eb26f9f3f

Author: Matthew McClure <mcclurem at vmware.com>
Date:   Tue Oct 22 15:48:00 2013 -0700

util,llvmpipe: correctly set the minimum representable depth value

Reviewed-by: Roland Scheidegger <sroland at vmware.com>
Reviewed-by: Jose Fonseca <jfonseca at vmware.com>

---

 src/gallium/auxiliary/util/u_format.c           |   41 +++++++++++++++++++++++
 src/gallium/auxiliary/util/u_format.h           |   11 ++++++
 src/gallium/drivers/llvmpipe/lp_state_surface.c |   31 +++++++----------
 3 files changed, 64 insertions(+), 19 deletions(-)

diff --git a/src/gallium/auxiliary/util/u_format.c b/src/gallium/auxiliary/util/u_format.c
index a8aa571..9ef3bb5 100644
--- a/src/gallium/auxiliary/util/u_format.c
+++ b/src/gallium/auxiliary/util/u_format.c
@@ -208,6 +208,47 @@ util_format_is_supported(enum pipe_format format, unsigned bind)
 }
 
 
+/**
+ * Calculates the MRD for the depth format. MRD is used in depth bias
+ * for UNORM and unbound depth buffers. When the depth buffer is floating
+ * point, the depth bias calculation does not use the MRD. However, the
+ * default MRD will be 1.0 / ((1 << 24) - 1).
+ */
+double
+util_get_depth_format_mrd(enum pipe_format format)
+{
+   struct util_format_description *format_desc;
+   /*
+    * Depth buffer formats without a depth component OR scenarios
+    * without a bound depth buffer default to D24.
+    */
+   double mrd = 1.0 / ((1 << 24) - 1);
+   unsigned depth_channel;
+
+   format_desc = (struct util_format_description *)
+                     util_format_description(format);
+
+   assert(format_desc);
+
+   /*
+    * Some depth formats do not store the depth component in the first
+    * channel, detect the format and adjust the depth channel. Get the
+    * swizzled depth component channel.
+    */
+   depth_channel = format_desc->swizzle[0];
+
+   if (format_desc->channel[depth_channel].type == UTIL_FORMAT_TYPE_UNSIGNED &&
+       format_desc->channel[depth_channel].normalized) {
+      int depth_bits;
+
+      depth_bits = format_desc->channel[depth_channel].size;
+      mrd = 1.0 / ((1ULL << depth_bits) - 1);
+   }
+
+   return mrd;
+}
+
+
 void
 util_format_read_4f(enum pipe_format format,
                     float *dst, unsigned dst_stride,
diff --git a/src/gallium/auxiliary/util/u_format.h b/src/gallium/auxiliary/util/u_format.h
index 84f16d5..dc777c3 100644
--- a/src/gallium/auxiliary/util/u_format.h
+++ b/src/gallium/auxiliary/util/u_format.h
@@ -544,6 +544,17 @@ util_format_is_depth_and_stencil(enum pipe_format format)
           util_format_has_stencil(desc);
 }
 
+
+/**
+ * Calculates the MRD for the depth format. MRD is used in depth bias
+ * for UNORM and unbound depth buffers. When the depth buffer is floating
+ * point, the depth bias calculation does not use the MRD. However, the
+ * default MRD will be 1.0 / ((1 << 24) - 1).
+ */
+double
+util_get_depth_format_mrd(enum pipe_format format);
+
+
 /**
  * Return whether this is an RGBA, Z, S, or combined ZS format.
  * Useful for initializing pipe_blit_info::mask.
diff --git a/src/gallium/drivers/llvmpipe/lp_state_surface.c b/src/gallium/drivers/llvmpipe/lp_state_surface.c
index e6aac31..8909841 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_surface.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_surface.c
@@ -57,31 +57,24 @@ llvmpipe_set_framebuffer_state(struct pipe_context *pipe,
    assert(fb->height <= LP_MAX_HEIGHT);
 
    if (changed) {
-
       util_copy_framebuffer_state(&lp->framebuffer, fb);
 
       if (LP_PERF & PERF_NO_DEPTH) {
 	 pipe_surface_reference(&lp->framebuffer.zsbuf, NULL);
       }
 
-      /* Tell draw module how deep the Z/depth buffer is */
-      /* FIXME: mrd constant isn't right should use a value derived from
-       * current primitive not a constant (for float depth buffers) */
-      if (lp->framebuffer.zsbuf) {
-         int depth_bits;
-         double mrd;
-         depth_bits = util_format_get_component_bits(lp->framebuffer.zsbuf->format,
-                                                     UTIL_FORMAT_COLORSPACE_ZS,
-                                                     0);
-         if (depth_bits > 16) {
-            mrd = 0.0000001;
-         }
-         else {
-            mrd = 0.00002;
-         }
-         lp->mrd = mrd;
-         draw_set_mrd(lp->draw, mrd);
-      }
+      /* Tell draw module how deep the Z/depth buffer is.
+       *
+       * If no depth buffer is bound, send the utility function the default
+       * format for no bound depth (PIPE_FORMAT_NONE).
+       *
+       * FIXME: mrd constant isn't right should use a value derived from
+       * current primitive not a constant (for float depth buffers)
+       */
+      lp->mrd = util_get_depth_format_mrd((lp->framebuffer.zsbuf) ?
+                  lp->framebuffer.zsbuf->format : PIPE_FORMAT_NONE);
+
+      draw_set_mrd(lp->draw, lp->mrd);
 
       lp_setup_bind_framebuffer( lp->setup, &lp->framebuffer );
 




More information about the mesa-commit mailing list