gallivm: Fix 4 x unorm8 -> 4 x float conversion.
authorJosé Fonseca <jfonseca@vmware.com>
Thu, 1 Jul 2010 17:27:39 +0000 (18:27 +0100)
committerJosé Fonseca <jfonseca@vmware.com>
Fri, 2 Jul 2010 10:50:00 +0000 (11:50 +0100)
Also fix the test.

src/gallium/auxiliary/gallivm/lp_bld_conv.c
src/gallium/auxiliary/gallivm/lp_bld_pack.c
src/gallium/drivers/llvmpipe/lp_test_conv.c

index 5e7260dc21407c868e6c815720b967f65086c38b..44428f884d181ce8a4b7938f9c96b69c5ced2939 100644 (file)
@@ -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
index dfe83b36c4212275ef416287f1eb97ca4022cd6f..7748f8f09994132db7e4165c2676671fd4f129f6 100644 (file)
@@ -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);
index 081f2d324b27150b1d8eb7402a64c26ab082f13f..cf41b40581f3857bf651e1bda699b238f45fec8e 100644 (file)
@@ -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;
    }