summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Ekstrand <[email protected]>2018-08-13 11:41:41 -0500
committerJason Ekstrand <[email protected]>2018-08-29 14:04:02 -0500
commitea4f2008647d5fd32ac11a8ff81c7b7cb7496d38 (patch)
treed6e067e46fd43b5abda9c9a7f5f4fe3cec4fa277
parent80c424148b47b6615f8e8c4886257a5c7323ef25 (diff)
nir/format_convert: Add support for unpacking signed integers
Reviewed-by: Kenneth Graunke <[email protected]>
-rw-r--r--src/compiler/nir/nir_format_convert.h37
1 files changed, 29 insertions, 8 deletions
diff --git a/src/compiler/nir/nir_format_convert.h b/src/compiler/nir/nir_format_convert.h
index 45532b74884..b1345f7263b 100644
--- a/src/compiler/nir/nir_format_convert.h
+++ b/src/compiler/nir/nir_format_convert.h
@@ -51,31 +51,52 @@ 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)
{