Mesa (master): gallivm: specialized x8z24 depthtest path

Keith Whitwell keithw at kemper.freedesktop.org
Sat Oct 9 10:46:37 UTC 2010


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

Author: Keith Whitwell <keithw at vmware.com>
Date:   Wed Oct  6 18:21:56 2010 +0100

gallivm: specialized x8z24 depthtest path

Avoid unnecessary masking of non-existant stencil component.

---

 src/gallium/drivers/llvmpipe/lp_bld_depth.c |   95 ++++++++++++++++++++++++++-
 src/gallium/drivers/llvmpipe/lp_state_fs.c  |   30 +--------
 2 files changed, 94 insertions(+), 31 deletions(-)

diff --git a/src/gallium/drivers/llvmpipe/lp_bld_depth.c b/src/gallium/drivers/llvmpipe/lp_bld_depth.c
index 7eabe05..09b82fb 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_depth.c
+++ b/src/gallium/drivers/llvmpipe/lp_bld_depth.c
@@ -71,6 +71,7 @@
 #include "gallivm/lp_bld_arit.h"
 #include "gallivm/lp_bld_bitarit.h"
 #include "gallivm/lp_bld_const.h"
+#include "gallivm/lp_bld_conv.h"
 #include "gallivm/lp_bld_logic.h"
 #include "gallivm/lp_bld_flow.h"
 #include "gallivm/lp_bld_intr.h"
@@ -446,7 +447,7 @@ lp_build_occlusion_count(LLVMBuilderRef builder,
  * \param format_desc  description of the depth/stencil surface
  * \param mask  the alive/dead pixel mask for the quad (vector)
  * \param stencil_refs  the front/back stencil ref values (scalar)
- * \param z_src  the incoming depth/stencil values (a 2x2 quad)
+ * \param z_src  the incoming depth/stencil values (a 2x2 quad, float32)
  * \param zs_dst_ptr  pointer to depth/stencil values in framebuffer
  * \param facing  contains float value indicating front/back facing polygon
  */
@@ -454,7 +455,7 @@ void
 lp_build_depth_stencil_test(LLVMBuilderRef builder,
                             const struct pipe_depth_state *depth,
                             const struct pipe_stencil_state stencil[2],
-                            struct lp_type type,
+                            struct lp_type z_src_type,
                             const struct util_format_description *format_desc,
                             struct lp_build_mask_context *mask,
                             LLVMValueRef stencil_refs[2],
@@ -463,6 +464,7 @@ lp_build_depth_stencil_test(LLVMBuilderRef builder,
                             LLVMValueRef face,
                             LLVMValueRef counter)
 {
+   struct lp_type type;
    struct lp_build_context bld;
    struct lp_build_context sbld;
    struct lp_type s_type;
@@ -473,6 +475,95 @@ lp_build_depth_stencil_test(LLVMBuilderRef builder,
    LLVMValueRef orig_mask = mask->value;
    LLVMValueRef front_facing = NULL;
 
+   /* Prototype a simpler path:
+    */
+   if (z_src_type.floating &&
+       format_desc->format == PIPE_FORMAT_X8Z24_UNORM &&
+       depth->enabled) 
+   {
+      LLVMValueRef zscaled;
+      LLVMValueRef const_ffffff_float;
+      LLVMValueRef const_8_int;
+      LLVMTypeRef int32_vec_type;
+
+      /* We know the values in z_dst are all >= 0, so allow
+       * lp_build_compare to use signed compare intrinsics:
+       */
+      type.floating = 0;
+      type.fixed = 0;
+      type.sign = 1;
+      type.norm = 1;
+      type.width = 32;
+      type.length = z_src_type.length;
+
+      int32_vec_type = LLVMVectorType(LLVMInt32Type(), z_src_type.length);
+
+      const_8_int = lp_build_const_int_vec(type, 8);
+      const_ffffff_float = lp_build_const_vec(z_src_type, (float)0xffffff);
+
+      zscaled = LLVMBuildFMul(builder, z_src, const_ffffff_float, "zscaled");
+      z_src = LLVMBuildFPToSI(builder, zscaled, int32_vec_type, "z_src");
+      
+      /* Load current z/stencil value from z/stencil buffer */
+      z_dst = LLVMBuildLoad(builder, zs_dst_ptr, "zsbufval");
+      z_dst = LLVMBuildLShr(builder, z_dst, const_8_int, "z_dst");
+
+      /* compare src Z to dst Z, returning 'pass' mask */
+      z_pass = lp_build_compare(builder,
+                                type,
+                                depth->func, z_src, z_dst);
+
+      lp_build_mask_update(mask, z_pass);
+
+      /* No need to worry about old stencil contents, just blend the
+       * old and new values and shift into the correct position for
+       * storage.
+       */
+      if (depth->writemask) {
+         type.sign = 0;
+         lp_build_context_init(&bld, builder, type);
+
+         z_dst = lp_build_select(&bld, mask->value, z_src, z_dst);
+         z_dst = LLVMBuildShl(builder, z_dst, const_8_int, "z_dst");
+         LLVMBuildStore(builder, z_dst, zs_dst_ptr);
+      }
+
+      if (counter)
+         lp_build_occlusion_count(builder, type, mask->value, counter);
+
+      return;
+   }
+
+   /*
+    * Depths are expected to be between 0 and 1, even if they are stored in
+    * floats. Setting these bits here will ensure that the lp_build_conv() call
+    * below won't try to unnecessarily clamp the incoming values.
+    */
+   if(z_src_type.floating) {
+      z_src_type.sign = FALSE;
+      z_src_type.norm = TRUE;
+   }
+   else {
+      assert(!z_src_type.sign);
+      assert(z_src_type.norm);
+   }
+
+   /* Pick the depth type. */
+   type = lp_depth_type(format_desc, z_src_type.width*z_src_type.length);
+
+   /* FIXME: Cope with a depth test type with a different bit width. */
+   assert(type.width == z_src_type.width);
+   assert(type.length == z_src_type.length);
+
+   /* Convert fragment Z from float to integer */
+   lp_build_conv(builder, z_src_type, type, &z_src, 1, &z_src, 1);
+
+   zs_dst_ptr = LLVMBuildBitCast(builder,
+                                 zs_dst_ptr,
+                                 LLVMPointerType(lp_build_vec_type(type), 0), "");
+
+
+
    /* Sanity checking */
    {
       const unsigned z_swizzle = format_desc->swizzle[0];
diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c
index 07b4f74..b7a51cd 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_fs.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c
@@ -119,7 +119,6 @@ generate_depth_stencil(LLVMBuilderRef builder,
                        LLVMValueRef counter)
 {
    const struct util_format_description *format_desc;
-   struct lp_type dst_type;
 
    if (!key->depth.enabled && !key->stencil[0].enabled && !key->stencil[1].enabled)
       return;
@@ -127,37 +126,10 @@ generate_depth_stencil(LLVMBuilderRef builder,
    format_desc = util_format_description(key->zsbuf_format);
    assert(format_desc);
 
-   /*
-    * Depths are expected to be between 0 and 1, even if they are stored in
-    * floats. Setting these bits here will ensure that the lp_build_conv() call
-    * below won't try to unnecessarily clamp the incoming values.
-    */
-   if(src_type.floating) {
-      src_type.sign = FALSE;
-      src_type.norm = TRUE;
-   }
-   else {
-      assert(!src_type.sign);
-      assert(src_type.norm);
-   }
-
-   /* Pick the depth type. */
-   dst_type = lp_depth_type(format_desc, src_type.width*src_type.length);
-
-   /* FIXME: Cope with a depth test type with a different bit width. */
-   assert(dst_type.width == src_type.width);
-   assert(dst_type.length == src_type.length);
-
-   /* Convert fragment Z from float to integer */
-   lp_build_conv(builder, src_type, dst_type, &src, 1, &src, 1);
-
-   dst_ptr = LLVMBuildBitCast(builder,
-                              dst_ptr,
-                              LLVMPointerType(lp_build_vec_type(dst_type), 0), "");
    lp_build_depth_stencil_test(builder,
                                &key->depth,
                                key->stencil,
-                               dst_type,
+                               src_type,
                                format_desc,
                                mask,
                                stencil_refs,




More information about the mesa-commit mailing list