Mesa (master): gallivm: Fix 4 x unorm8 -> 4 x float conversion.

Jose Fonseca jrfonseca at kemper.freedesktop.org
Fri Jul 2 10:50:27 UTC 2010


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

Author: José Fonseca <jfonseca at vmware.com>
Date:   Thu Jul  1 18:27:39 2010 +0100

gallivm: Fix 4 x unorm8 -> 4 x float conversion.

Also fix the test.

---

 src/gallium/auxiliary/gallivm/lp_bld_conv.c |   19 ++++++++++++++-----
 src/gallium/auxiliary/gallivm/lp_bld_pack.c |   18 ++++++++++++++++--
 src/gallium/drivers/llvmpipe/lp_test_conv.c |    2 +-
 3 files changed, 31 insertions(+), 8 deletions(-)

diff --git a/src/gallium/auxiliary/gallivm/lp_bld_conv.c b/src/gallium/auxiliary/gallivm/lp_bld_conv.c
index 5e7260d..44428f8 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_conv.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_conv.c
@@ -330,15 +330,24 @@ lp_build_conv(LLVMBuilderRef builder,
 
    /*
     * Truncate or expand bit width
+    *
+    * No data conversion should happen here, although the sign bits are
+    * crucial to avoid bad clamping.
     */
 
-   assert(!tmp_type.floating || tmp_type.width == dst_type.width);
+   {
+      struct lp_type new_type;
+
+      new_type = tmp_type;
+      new_type.sign   = dst_type.sign;
+      new_type.width  = dst_type.width;
+      new_type.length = dst_type.length;
 
-   lp_build_resize(builder, tmp_type, dst_type, tmp, num_srcs, tmp, num_dsts);
+      lp_build_resize(builder, tmp_type, new_type, tmp, num_srcs, tmp, num_dsts);
 
-   tmp_type.width  = dst_type.width;
-   tmp_type.length = dst_type.length;
-   num_tmps        = num_dsts;
+      tmp_type = new_type;
+      num_tmps = num_dsts;
+   }
 
    /*
     * Scale to the widest range
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_pack.c b/src/gallium/auxiliary/gallivm/lp_bld_pack.c
index dfe83b3..7748f8f 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_pack.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_pack.c
@@ -430,7 +430,10 @@ lp_build_pack(LLVMBuilderRef builder,
 
 
 /**
- * Truncate or expand the bitwidth
+ * Truncate or expand the bitwidth.
+ *
+ * NOTE: Getting the right sign flags is crucial here, as we employ some
+ * intrinsics that do saturation.
  */
 void
 lp_build_resize(LLVMBuilderRef builder,
@@ -442,7 +445,18 @@ lp_build_resize(LLVMBuilderRef builder,
    LLVMValueRef tmp[LP_MAX_VECTOR_LENGTH];
    unsigned i;
 
-   assert(!src_type.floating || src_type.width == dst_type.width);
+   /*
+    * We don't support float <-> int conversion here. That must be done
+    * before/after calling this function.
+    */
+   assert(src_type.floating == dst_type.floating);
+
+   /*
+    * We don't support double <-> float conversion yet, although it could be
+    * added with little effort.
+    */
+   assert((!src_type.floating && !dst_type.floating) ||
+          src_type.width == dst_type.width);
 
    /* We must not loose or gain channels. Only precision */
    assert(src_type.length * num_srcs == dst_type.length * num_dsts);
diff --git a/src/gallium/drivers/llvmpipe/lp_test_conv.c b/src/gallium/drivers/llvmpipe/lp_test_conv.c
index 081f2d3..cf41b40 100644
--- a/src/gallium/drivers/llvmpipe/lp_test_conv.c
+++ b/src/gallium/drivers/llvmpipe/lp_test_conv.c
@@ -167,7 +167,7 @@ test_one(unsigned verbose,
    unsigned i, j;
    void *code;
 
-   if (src_type.width * src_type.length != dst_type.width * dst_type.length ||
+   if (src_type.width * src_type.length != dst_type.width * dst_type.length &&
        src_type.length != dst_type.length) {
       return TRUE;
    }




More information about the mesa-commit mailing list