diff options
-rw-r--r-- | src/gallium/auxiliary/util/u_format.c | 41 | ||||
-rw-r--r-- | src/gallium/auxiliary/util/u_format.h | 11 | ||||
-rw-r--r-- | 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 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 ); |