nir/format_convert: Add support for unpacking signed integers
authorJason Ekstrand <jason.ekstrand@intel.com>
Mon, 13 Aug 2018 16:41:41 +0000 (11:41 -0500)
committerJason Ekstrand <jason.ekstrand@intel.com>
Wed, 29 Aug 2018 19:04:02 +0000 (14:04 -0500)
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
src/compiler/nir/nir_format_convert.h

index 45532b74884f6542dfdd676834d8afaa899ca673..b1345f7263b6483a22de3ce46c540de35179855a 100644 (file)
@@ -51,30 +51,51 @@ nir_mask_shift_or(struct nir_builder *b, nir_ssa_def *dst, nir_ssa_def *src,
 }
 
 static inline nir_ssa_def *
-nir_format_unpack_uint(nir_builder *b, nir_ssa_def *packed,
-                       const unsigned *bits, unsigned num_components)
+nir_format_unpack_int(nir_builder *b, nir_ssa_def *packed,
+                      const unsigned *bits, unsigned num_components,
+                      bool sign_extend)
 {
    assert(num_components >= 1 && num_components <= 4);
+   const unsigned bit_size = packed->bit_size;
    nir_ssa_def *comps[4];
 
-   if (bits[0] >= packed->bit_size) {
-      assert(bits[0] == packed->bit_size);
+   if (bits[0] >= bit_size) {
+      assert(bits[0] == bit_size);
       assert(num_components == 1);
       return packed;
    }
 
    unsigned offset = 0;
    for (unsigned i = 0; i < num_components; i++) {
-      assert(bits[i] < 32);
-      nir_ssa_def *mask = nir_imm_int(b, (1u << bits[i]) - 1);
-      comps[i] = nir_iand(b, nir_shift(b, packed, -offset), mask);
+      assert(bits[i] < bit_size);
+      assert(offset + bits[i] <= bit_size);
+      nir_ssa_def *lshift = nir_imm_int(b, bit_size - (offset + bits[i]));
+      nir_ssa_def *rshift = nir_imm_int(b, bit_size - bits[i]);
+      if (sign_extend)
+         comps[i] = nir_ishr(b, nir_ishl(b, packed, lshift), rshift);
+      else
+         comps[i] = nir_ushr(b, nir_ishl(b, packed, lshift), rshift);
       offset += bits[i];
    }
-   assert(offset <= packed->bit_size);
+   assert(offset <= bit_size);
 
    return nir_vec(b, comps, num_components);
 }
 
+static inline nir_ssa_def *
+nir_format_unpack_uint(nir_builder *b, nir_ssa_def *packed,
+                       const unsigned *bits, unsigned num_components)
+{
+   return nir_format_unpack_int(b, packed, bits, num_components, false);
+}
+
+static inline nir_ssa_def *
+nir_format_unpack_sint(nir_builder *b, nir_ssa_def *packed,
+                       const unsigned *bits, unsigned num_components)
+{
+   return nir_format_unpack_int(b, packed, bits, num_components, true);
+}
+
 static inline nir_ssa_def *
 nir_format_pack_uint_unmasked(nir_builder *b, nir_ssa_def *color,
                               const unsigned *bits, unsigned num_components)