Mesa (master): gallivm: more integer texture format fetch fixes

Roland Scheidegger sroland at kemper.freedesktop.org
Fri Jan 11 02:11:08 UTC 2013


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

Author: Roland Scheidegger <sroland at vmware.com>
Date:   Thu Jan 10 11:16:40 2013 -0800

gallivm: more integer texture format fetch fixes

Change the texel type to int/uint instead of float throughout the sampling
code which makes it easier to catch errors (as llvm will complain about wrong
types if we mistakenly treat these values as real floats somewhere).
This should also get things like e.g. sampler swizzles (for unused channels)
right.
This fixes piglit texture_integer_glsl130 test.
Border color not working (crashing) yet.
(These formats are not exposed yet in llvmpipe.)

v2: couple cleanups according to José's comments

Reviewed-by: José Fonseca <jfonseca at vmware.com>

---

 src/gallium/auxiliary/gallivm/lp_bld_format.h      |    2 +-
 src/gallium/auxiliary/gallivm/lp_bld_format_aos.c  |    2 +
 .../auxiliary/gallivm/lp_bld_format_aos_array.c    |    6 +-
 src/gallium/auxiliary/gallivm/lp_bld_format_soa.c  |   44 +++++++++++------
 src/gallium/auxiliary/gallivm/lp_bld_sample_aos.c  |    2 +-
 src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c  |   53 ++++++++++++++------
 6 files changed, 74 insertions(+), 35 deletions(-)

diff --git a/src/gallium/auxiliary/gallivm/lp_bld_format.h b/src/gallium/auxiliary/gallivm/lp_bld_format.h
index 3608a68..8fb173b 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_format.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_format.h
@@ -93,7 +93,7 @@ lp_build_unpack_rgba_soa(struct gallivm_state *gallivm,
                          LLVMValueRef rgba_out[4]);
 
 void
-lp_build_rgba8_to_f32_soa(struct gallivm_state *gallivm,
+lp_build_rgba8_to_fi32_soa(struct gallivm_state *gallivm,
                           struct lp_type dst_type,
                           LLVMValueRef packed,
                           LLVMValueRef *rgba);
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_format_aos.c b/src/gallium/auxiliary/gallivm/lp_bld_format_aos.c
index e5c93f0..6a1bf67 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_format_aos.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_format_aos.c
@@ -710,6 +710,8 @@ lp_build_fetch_rgba_aos(struct gallivm_state *gallivm,
       return res;
    }
 
+   assert(!util_format_is_pure_integer(format_desc->format));
+
    assert(0);
    return lp_build_undef(gallivm, type);
 }
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_format_aos_array.c b/src/gallium/auxiliary/gallivm/lp_bld_format_aos_array.c
index 9642b9e..3402a0b 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_format_aos_array.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_format_aos_array.c
@@ -148,7 +148,7 @@ lp_build_fetch_rgba_aos_array(struct gallivm_state *gallivm,
 
    tmp_type = dst_type;
    if (pure_integer) {
-      assert(dst_type.floating);
+       /* some callers expect (fake) floats other real ints. */
       tmp_type.floating = 0;
       tmp_type.sign = src_type.sign;
    }
@@ -160,8 +160,8 @@ lp_build_fetch_rgba_aos_array(struct gallivm_state *gallivm,
    lp_build_context_init(&bld, gallivm, tmp_type);
    res = lp_build_format_swizzle_aos(format_desc, &bld, res);
 
-   /* Bitcast to floats (for pure integers) */
-   if (pure_integer) {
+   /* Bitcast to floats (for pure integers) when requested */
+   if (pure_integer && dst_type.floating) {
       res = LLVMBuildBitCast(builder, res, lp_build_vec_type(gallivm, dst_type), "");
    }
 
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_format_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_format_soa.c
index afeb340..9eb6ef5 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_format_soa.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_format_soa.c
@@ -114,7 +114,6 @@ lp_build_unpack_rgba_soa(struct gallivm_state *gallivm,
    assert(format_desc->block.height == 1);
    assert(format_desc->block.bits <= type.width);
    /* FIXME: Support more output types */
-   assert(type.floating);
    assert(type.width == 32);
 
    lp_build_context_init(&bld, gallivm, type);
@@ -162,10 +161,11 @@ lp_build_unpack_rgba_soa(struct gallivm_state *gallivm,
                input = LLVMBuildSIToFP(builder, input,
                                        lp_build_vec_type(gallivm, type), "");
          }
-         else {
-            /* FIXME */
-            assert(0);
-            input = lp_build_undef(gallivm, type);
+         else if (format_desc->channel[chan].pure_integer) {
+            /* Nothing to do */
+         } else {
+             /* FIXME */
+             assert(0);
          }
 
          break;
@@ -203,10 +203,11 @@ lp_build_unpack_rgba_soa(struct gallivm_state *gallivm,
                input = LLVMBuildFMul(builder, input, scale_val, "");
             }
          }
-         else {
-            /* FIXME */
-            assert(0);
-            input = lp_build_undef(gallivm, type);
+         else if (format_desc->channel[chan].pure_integer) {
+            /* Nothing to do */
+         } else {
+             /* FIXME */
+             assert(0);
          }
 
          break;
@@ -254,16 +255,28 @@ lp_build_unpack_rgba_soa(struct gallivm_state *gallivm,
 }
 
 
+/**
+ * Convert a vector of rgba8 values into 32bit wide SoA vectors.
+ *
+ * \param dst_type  The desired return type. For pure integer formats
+ *                  this should be a 32bit wide int or uint vector type,
+ *                  otherwise a float vector type.
+ *
+ * \param packed    The rgba8 values to pack.
+ *
+ * \param rgba      The 4 SoA return vectors.
+ */
 void
-lp_build_rgba8_to_f32_soa(struct gallivm_state *gallivm,
-                          struct lp_type dst_type,
-                          LLVMValueRef packed,
-                          LLVMValueRef *rgba)
+lp_build_rgba8_to_fi32_soa(struct gallivm_state *gallivm,
+                           struct lp_type dst_type,
+                           LLVMValueRef packed,
+                           LLVMValueRef *rgba)
 {
    LLVMBuilderRef builder = gallivm->builder;
    LLVMValueRef mask = lp_build_const_int_vec(gallivm, dst_type, 0xff);
    unsigned chan;
 
+   /* XXX technically shouldn't use that for uint dst_type */
    packed = LLVMBuildBitCast(builder, packed,
                              lp_build_int_vec_type(gallivm, dst_type), "");
 
@@ -282,7 +295,8 @@ lp_build_rgba8_to_f32_soa(struct gallivm_state *gallivm,
       if (stop < 32)
          input = LLVMBuildAnd(builder, input, mask, "");
 
-      input = lp_build_unsigned_norm_to_float(gallivm, 8, dst_type, input);
+      if (dst_type.floating)
+         input = lp_build_unsigned_norm_to_float(gallivm, 8, dst_type, input);
 
       rgba[chan] = input;
    }
@@ -372,7 +386,7 @@ lp_build_fetch_rgba_soa(struct gallivm_state *gallivm,
       tmp = lp_build_fetch_rgba_aos(gallivm, format_desc, tmp_type,
                                     base_ptr, offset, i, j);
 
-      lp_build_rgba8_to_f32_soa(gallivm,
+      lp_build_rgba8_to_fi32_soa(gallivm,
                                 type,
                                 tmp,
                                 rgba_out);
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample_aos.c b/src/gallium/auxiliary/gallivm/lp_bld_sample_aos.c
index 7d7e351..9371e1c 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_sample_aos.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_sample_aos.c
@@ -1673,7 +1673,7 @@ lp_build_sample_aos(struct lp_build_sample_context *bld,
    /*
     * Convert to SoA and swizzle.
     */
-   lp_build_rgba8_to_f32_soa(bld->gallivm,
+   lp_build_rgba8_to_fi32_soa(bld->gallivm,
                              bld->texel_type,
                              packed, unswizzled);
 
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
index f1d2f51..57298a4 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
@@ -1448,6 +1448,19 @@ lp_build_sample_soa(struct gallivm_state *gallivm,
    bld.perquadf_type.length = type.length > 4 ? ((type.length + 15) / 16) * 4 : 1;
    bld.perquadi_type = lp_int_type(bld.perquadf_type);
 
+   /* always using the first channel hopefully should be safe,
+    * if not things WILL break in other places anyway.
+    */
+   if (bld.format_desc->colorspace == UTIL_FORMAT_COLORSPACE_RGB &&
+       bld.format_desc->channel[0].pure_integer) {
+      if (bld.format_desc->channel[0].type == UTIL_FORMAT_TYPE_SIGNED) {
+         bld.texel_type = lp_type_int_vec(type.width, type.width * type.length);
+      }
+      else if (bld.format_desc->channel[0].type == UTIL_FORMAT_TYPE_UNSIGNED) {
+         bld.texel_type = lp_type_uint_vec(type.width, type.width * type.length);
+      }
+   }
+
    /*
     * There are other situations where at least the multiple int lods could be
     * avoided like min and max lod being equal.
@@ -1516,6 +1529,13 @@ lp_build_sample_soa(struct gallivm_state *gallivm,
                           coords,
                           texel_out);
    }
+
+   else if (is_fetch) {
+      lp_build_fetch_texel(&bld, unit, coords,
+                           explicit_lod, offsets,
+                           texel_out);
+   }
+
    else {
       LLVMValueRef lod_ipart = NULL, lod_fpart = NULL;
       LLVMValueRef ilevel0 = NULL, ilevel1 = NULL;
@@ -1535,18 +1555,6 @@ lp_build_sample_soa(struct gallivm_state *gallivm,
                       static_state->wrap_t);
       }
 
-      if (is_fetch) {
-         lp_build_fetch_texel(&bld, unit, coords,
-                              explicit_lod, offsets,
-                              texel_out);
-
-         if (static_state->target != PIPE_BUFFER) {
-            apply_sampler_swizzle(&bld, texel_out);
-         }
-
-         return;
-      }
-
       lp_build_sample_common(&bld, unit,
                              &s, &t, &r,
                              derivs, lod_bias, explicit_lod,
@@ -1620,7 +1628,8 @@ lp_build_sample_soa(struct gallivm_state *gallivm,
          bld4.float_size_in_type = lp_type_float(32);
          bld4.float_size_in_type.length = dims > 1 ? 4 : 1;
          bld4.int_size_in_type = lp_int_type(bld4.float_size_in_type);
-         bld4.texel_type = type4;
+         bld4.texel_type = bld.texel_type;
+         bld4.texel_type.length = 4;
          bld4.perquadf_type = type4;
          /* we want native vector size to be able to use our intrinsics */
          bld4.perquadf_type.length = 1;
@@ -1684,11 +1693,25 @@ lp_build_sample_soa(struct gallivm_state *gallivm,
             texel_out[j] = lp_build_concat(gallivm, texelouttmp[j], type4, num_quads);
          }
       }
+
+      lp_build_sample_compare(&bld, coords, texel_out);
    }
 
-   lp_build_sample_compare(&bld, coords, texel_out);
+   if (static_state->target != PIPE_BUFFER) {
+      apply_sampler_swizzle(&bld, texel_out);
+   }
 
-   apply_sampler_swizzle(&bld, texel_out);
+   /*
+    * texel type can be a (32bit) int/uint (for pure int formats only),
+    * however we are expected to always return floats (storage is untyped).
+    */
+   if (!bld.texel_type.floating) {
+      unsigned chan;
+      for (chan = 0; chan < 4; chan++) {
+         texel_out[chan] = LLVMBuildBitCast(builder, texel_out[chan],
+                                            lp_build_vec_type(gallivm, type), "");
+      }
+   }
 }
 
 void




More information about the mesa-commit mailing list