summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMatthew McClure <[email protected]>2013-10-22 15:48:00 -0700
committerJosé Fonseca <[email protected]>2013-10-29 15:53:48 +0000
commitbe0b67a1436eb2b899f9874725b2a68eb26f9f3f (patch)
tree0520a19b3579cc98ec2e61fef69934782625602e /src
parentd0eaf6752d6faa8a17e3270b9e64b7c09ef705c2 (diff)
util,llvmpipe: correctly set the minimum representable depth value
Reviewed-by: Roland Scheidegger <[email protected]> Reviewed-by: Jose Fonseca <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/gallium/auxiliary/util/u_format.c41
-rw-r--r--src/gallium/auxiliary/util/u_format.h11
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_surface.c31
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 a8aa5719d39..9ef3bb53ff2 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 84f16d503d7..dc777c35c19 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 e6aac319447..89098410280 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 );